Record corrected navigation trial and alias transaction measurements
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
"""Preserve on-disk repair input after visible Apply and before explicit Save."""
|
||||
from pathlib import Path
|
||||
import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import shutil
|
||||
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
trial = root / '.local/text-navigation-native-20260911-v3'
|
||||
destination = trial / 'missing-include-after-apply-before-save'
|
||||
shutil.copytree(trial / 'missing-include', destination)
|
||||
files = {p.relative_to(destination).as_posix(): hashlib.sha256(p.read_bytes()).hexdigest()
|
||||
for p in destination.rglob('*') if p.is_file()}
|
||||
receipt = {'atUtc': datetime.datetime.now(datetime.timezone.utc).isoformat(),
|
||||
'scope': 'Disk snapshot after native Apply all showed All changes saved, before explicit Save all',
|
||||
'files': files, 'missingTargetAbsent': not (destination / 'missing/not-loaded.arcadia').exists(),
|
||||
'brokenIncludeStillOnDisk': b'include "missing/not-loaded.arcadia";' in (destination / 'project.arcadia').read_bytes()}
|
||||
with (trial / 'missing-include-after-apply-before-save.json').open('x', encoding='utf-8', newline='\n') as f:
|
||||
json.dump(receipt, f, ensure_ascii=False, indent=2)
|
||||
f.write('\n')
|
||||
print(json.dumps(receipt, ensure_ascii=False))
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
{
|
||||
"scope": "Manually selected authored roles, locations computed from pinned bytes; no GUI result",
|
||||
"aliases": {
|
||||
"oa_conversation": {
|
||||
"declarations": [
|
||||
{
|
||||
"path": "oa/behavior/scenario_oa_conversation.arcadia",
|
||||
"line": 1,
|
||||
"byteColumn": 13,
|
||||
"span": [
|
||||
12,
|
||||
27
|
||||
],
|
||||
"sourceSha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
|
||||
}
|
||||
],
|
||||
"uses": [
|
||||
{
|
||||
"path": "oa/behavior/scenario_oa_full_scenario.arcadia",
|
||||
"line": 33,
|
||||
"byteColumn": 23,
|
||||
"span": [
|
||||
1130,
|
||||
1145
|
||||
],
|
||||
"sourceSha256": "00a1edf2c9707a0eb62ac070c2d02467874f2c9c1f273cc6ddb53d6d65999a1c"
|
||||
},
|
||||
{
|
||||
"path": "oa/behavior/scenario_oa_conversation.arcadia",
|
||||
"line": 27,
|
||||
"byteColumn": 13,
|
||||
"span": [
|
||||
856,
|
||||
871
|
||||
],
|
||||
"sourceSha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
|
||||
},
|
||||
{
|
||||
"path": "oa/behavior/scenario_oa_conversation.arcadia",
|
||||
"line": 34,
|
||||
"byteColumn": 13,
|
||||
"span": [
|
||||
1030,
|
||||
1045
|
||||
],
|
||||
"sourceSha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
|
||||
},
|
||||
{
|
||||
"path": "oa/behavior/scenario_oa_conversation.arcadia",
|
||||
"line": 54,
|
||||
"byteColumn": 13,
|
||||
"span": [
|
||||
1566,
|
||||
1581
|
||||
],
|
||||
"sourceSha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
|
||||
},
|
||||
{
|
||||
"path": "oa/behavior/scenario_oa_conversation.arcadia",
|
||||
"line": 61,
|
||||
"byteColumn": 13,
|
||||
"span": [
|
||||
1743,
|
||||
1758
|
||||
],
|
||||
"sourceSha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
|
||||
},
|
||||
{
|
||||
"path": "traceability.arcadia",
|
||||
"line": 337,
|
||||
"byteColumn": 9,
|
||||
"span": [
|
||||
8672,
|
||||
8687
|
||||
],
|
||||
"sourceSha256": "48a96f543456c9b5a5798fc795594e4119147fe45f11a6f109f141b7f514560f"
|
||||
}
|
||||
]
|
||||
},
|
||||
"oa_caller": {
|
||||
"declarations": [
|
||||
{
|
||||
"path": "oa/behavior/scenario_oa_conversation.arcadia",
|
||||
"line": 32,
|
||||
"byteColumn": 13,
|
||||
"span": [
|
||||
931,
|
||||
940
|
||||
],
|
||||
"sourceSha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
|
||||
}
|
||||
],
|
||||
"uses": [
|
||||
{
|
||||
"path": "oa/behavior/scenario_oa_full_scenario.arcadia",
|
||||
"line": 28,
|
||||
"byteColumn": 29,
|
||||
"span": [
|
||||
978,
|
||||
987
|
||||
],
|
||||
"sourceSha256": "00a1edf2c9707a0eb62ac070c2d02467874f2c9c1f273cc6ddb53d6d65999a1c"
|
||||
},
|
||||
{
|
||||
"path": "oa/behavior/scenario_oa_conversation.arcadia",
|
||||
"line": 18,
|
||||
"byteColumn": 21,
|
||||
"span": [
|
||||
650,
|
||||
659
|
||||
],
|
||||
"sourceSha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
|
||||
},
|
||||
{
|
||||
"path": "oa/behavior/scenario_oa_conversation.arcadia",
|
||||
"line": 43,
|
||||
"byteColumn": 23,
|
||||
"span": [
|
||||
1295,
|
||||
1304
|
||||
],
|
||||
"sourceSha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
|
||||
},
|
||||
{
|
||||
"path": "traceability.arcadia",
|
||||
"line": 201,
|
||||
"byteColumn": 9,
|
||||
"span": [
|
||||
5258,
|
||||
5267
|
||||
],
|
||||
"sourceSha256": "48a96f543456c9b5a5798fc795594e4119147fe45f11a6f109f141b7f514560f"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
"""Prepare/launch the identified Windows GUI and preserve native trial checkpoints.
|
||||
|
||||
All actual GUI interaction is performed separately with Computer Use.
|
||||
"""
|
||||
import argparse
|
||||
import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
evidence = Path(__file__).resolve().parent
|
||||
trial = root / ".local/text-navigation-native-20260911-v3"
|
||||
fixtures = root / ".local/text-navigation-native-20260911-preparation"
|
||||
runtime = root / ".local/toolchain/llvm-mingw-20260826-ucrt-x86_64/bin/libunwind.dll"
|
||||
oracle = root / ".local/staged-source-oracle-20260911/staged-source-authoring-contract.exe"
|
||||
runtime_sha = "f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4"
|
||||
oracle_sha = "967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c"
|
||||
fixture_manifest_sha = "edd4157fc31823f4494dee91862728b87f12ef51c49b8d1fd86a954bc9ecc1ed"
|
||||
|
||||
def sha(path):
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
def now():
|
||||
return datetime.datetime.now(datetime.timezone.utc).isoformat()
|
||||
|
||||
def record(path, value):
|
||||
with path.open("x", encoding="utf-8", newline="\n") as out:
|
||||
json.dump(value, out, indent=2, ensure_ascii=False)
|
||||
out.write("\n")
|
||||
|
||||
def inventory(folder):
|
||||
result = {}
|
||||
for path in folder.rglob("*"):
|
||||
assert not path.is_symlink() and not (getattr(path.lstat(), "st_file_attributes", 0) & 0x400), path
|
||||
if path.is_file():
|
||||
result[path.relative_to(folder).as_posix()] = sha(path)
|
||||
return result
|
||||
|
||||
def environment():
|
||||
parent = {key.upper(): value for key, value in os.environ.items()}
|
||||
names = ("SystemRoot", "SystemDrive", "ProgramData", "ALLUSERSPROFILE", "PUBLIC")
|
||||
standard = {name: parent[name.upper()] for name in names}
|
||||
assert all("%" not in value for value in standard.values())
|
||||
system = standard["SystemRoot"]
|
||||
return {**standard, "WINDIR": system, "PATH": system + "\\System32;" + system,
|
||||
"USERPROFILE": str(trial / "profile"), "LOCALAPPDATA": str(trial / "profile/local"),
|
||||
"APPDATA": str(trial / "profile/roaming"), "TEMP": str(trial / "tmp"), "TMP": str(trial / "tmp")}
|
||||
|
||||
def verify_fixtures():
|
||||
manifest = fixtures / "fixture-manifest.json"
|
||||
assert sha(manifest) == fixture_manifest_sha
|
||||
for entry in json.loads(manifest.read_text(encoding="utf-8")):
|
||||
path = (fixtures / entry["path"]).resolve()
|
||||
assert path.is_relative_to(fixtures) and path.stat().st_size == entry["bytes"]
|
||||
assert sha(path) == entry["sha256"], entry["path"]
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("action", choices=("launch", "check", "closed"))
|
||||
parser.add_argument("--label")
|
||||
parser.add_argument("--model", choices=("valid", "release1", "ambiguous", "missing-include"), default="valid")
|
||||
args = parser.parse_args()
|
||||
if args.action == "launch":
|
||||
verify_fixtures()
|
||||
receipt_path = evidence / "gui-build-v3.json"
|
||||
receipt = json.loads(receipt_path.read_text(encoding="utf-8"))
|
||||
preserved = json.loads((evidence / "gui-v3-preserved.json").read_text(encoding="utf-8"))
|
||||
assert preserved["buildReceiptSha256"] == sha(receipt_path)
|
||||
binary = Path(preserved["binary"]).resolve()
|
||||
assert binary == evidence / "gui-v3.exe"
|
||||
assert preserved["sha256"] == receipt["sha256"]
|
||||
assert sha(binary) == receipt["sha256"]
|
||||
assert sha(runtime) == runtime_sha and sha(oracle) == oracle_sha
|
||||
trial.mkdir(exist_ok=False)
|
||||
for folder in ("bin", "profile/local", "profile/roaming", "profile/Desktop", "tmp", "screenshots"):
|
||||
(trial / folder).mkdir(parents=True)
|
||||
shutil.copy2(binary, trial / "bin/arcadia-studio.exe")
|
||||
shutil.copy2(runtime, trial / "bin/libunwind.dll")
|
||||
for source, destination in (("valid-baseline", "valid"), ("release1-baseline", "release1"),
|
||||
("ambiguous-open", "ambiguous"), ("missing-include-open", "missing-include")):
|
||||
shutil.copytree(fixtures / source, trial / destination)
|
||||
before = inventory(trial / "bin")
|
||||
record(trial / "binary-before.json", before)
|
||||
record(trial / "source-before.json", {name: inventory(trial / name) for name in ("valid", "release1", "ambiguous", "missing-include")})
|
||||
env = environment()
|
||||
startup = subprocess.STARTUPINFO()
|
||||
startup.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
startup.wShowWindow = 0
|
||||
with (trial / "stdout.log").open("xb") as out, (trial / "stderr.log").open("xb") as err:
|
||||
process = subprocess.Popen([str(trial / "bin/arcadia-studio.exe")], cwd=trial / "bin",
|
||||
env=env, stdout=out, stderr=err, startupinfo=startup)
|
||||
launch = {"atUtc": now(), "pid": process.pid, "binarySha256": receipt["sha256"],
|
||||
"buildReceiptSha256": sha(receipt_path), "source": str(trial / "valid/project.arcadia"),
|
||||
"environment": env, "scope": "Identified local Windows GUI; native verification pending"}
|
||||
record(trial / "launch.json", launch)
|
||||
print(json.dumps(launch, ensure_ascii=False))
|
||||
elif args.action == "check":
|
||||
verify_fixtures()
|
||||
assert args.label and args.label.replace("-", "").isalnum()
|
||||
assert inventory(trial / "bin") == json.loads((trial / "binary-before.json").read_text(encoding="utf-8"))
|
||||
assert sha(oracle) == oracle_sha
|
||||
checkpoint = trial / (args.label + "-sources")
|
||||
shutil.copytree(trial / args.model, checkpoint)
|
||||
env = environment()
|
||||
env["PATH"] = str(trial / "bin") + ";" + env["PATH"]
|
||||
# Removing only the deliberately added duplicate declaration/include restores
|
||||
# the exact valid baseline. These cases are checked only after native repair,
|
||||
# explicit Apply, and a visibly successful Save all.
|
||||
baseline_model = "release1" if args.model == "release1" else "valid"
|
||||
command = [str(oracle), "same", str(fixtures / (baseline_model + "-baseline") / "project.arcadia"), str(checkpoint / "project.arcadia")]
|
||||
result = subprocess.run(command, capture_output=True, env=env)
|
||||
(trial / (args.label + ".stdout.log")).write_bytes(result.stdout)
|
||||
(trial / (args.label + ".stderr.log")).write_bytes(result.stderr)
|
||||
receipt = {"atUtc": now(), "command": command, "exitCode": result.returncode,
|
||||
"model": args.model, "baseline": baseline_model,
|
||||
"oracleSha256": oracle_sha, "files": inventory(checkpoint),
|
||||
"binaryFilesUnchanged": True, "scope": "Complete saved Project/identity, reachable sources and physical Arcadia equality"}
|
||||
record(trial / (args.label + ".json"), receipt)
|
||||
print(result.stdout.decode("utf-8", errors="replace"))
|
||||
print(json.dumps({"label": args.label, "exitCode": result.returncode}))
|
||||
if result.returncode:
|
||||
print(result.stderr.decode("utf-8", errors="replace"))
|
||||
raise SystemExit(result.returncode)
|
||||
else:
|
||||
# The caller must observe process closure independently before this readback.
|
||||
before = json.loads((trial / "binary-before.json").read_text(encoding="utf-8"))
|
||||
after = inventory(trial / "bin")
|
||||
record(trial / "binary-after-close.json", {"atUtc": now(), "files": after, "unchanged": before == after})
|
||||
assert before == after
|
||||
print(json.dumps({"binaryFilesUnchanged": True, "files": len(after)}))
|
||||
Reference in New Issue
Block a user