Files
ARCADIA-Studio/harness/experiments/text-navigation-native-20260911/corrections/capture.py
T

64 lines
2.7 KiB
Python

"""Preserve exact current source bytes before a gate and read them back after it."""
import datetime
import hashlib
import json
import pathlib
import re
import subprocess
import sys
import zipfile
root = pathlib.Path(__file__).resolve().parents[2]
evidence = pathlib.Path(__file__).resolve().parent
mode, label = sys.argv[1:]
assert re.fullmatch(r"inputs[0-9]+", label)
def paths():
result = subprocess.run(["git", "ls-files", "-z", "--cached", "--others", "--exclude-standard", "--",
"crates", ".cargo", "Cargo.toml", "Cargo.lock", "docs", "examples", "harness/fixtures"],
cwd=root, check=True, capture_output=True)
return sorted(set(p.decode("utf-8") for p in result.stdout.split(b"\0") if p))
def data(path):
target = (root / path).resolve()
assert target.is_relative_to(root) and target.is_file(), path
return target.read_bytes()
def sha(raw):
return hashlib.sha256(raw).hexdigest()
def write(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")
if mode == "capture":
entries = []
archive = evidence / (label + ".zip")
with zipfile.ZipFile(archive, "x", zipfile.ZIP_DEFLATED) as out:
for path in paths():
raw = data(path)
out.writestr(path, raw)
entries.append({"path": path, "bytes": len(raw), "sha256": sha(raw)})
result = {"atUtc": datetime.datetime.now(datetime.timezone.utc).isoformat(),
"head": subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=root).decode().strip(),
"branch": subprocess.check_output(["git", "branch", "--show-current"], cwd=root).decode().strip(),
"scope": "Exact Windows gate source inputs; no compiler or native result implied.",
"archiveSha256": sha(archive.read_bytes()), "files": entries}
write(evidence / (label + ".json"), result)
print(json.dumps({"files": len(entries), "bytes": sum(e["bytes"] for e in entries), "archiveSha256": result["archiveSha256"]}))
elif mode == "verify":
before = json.loads((evidence / (label + ".json")).read_text(encoding="utf-8"))
current = paths()
expected = [e["path"] for e in before["files"]]
changed = [e["path"] for e in before["files"] if sha(data(e["path"])) != e["sha256"]]
result = {"atUtc": datetime.datetime.now(datetime.timezone.utc).isoformat(),
"changed": changed, "added": sorted(set(current) - set(expected)),
"removed": sorted(set(expected) - set(current))}
result["passed"] = not any(result[k] for k in ("changed", "added", "removed"))
write(evidence / (label + "-readback.json"), result)
print(json.dumps(result))
sys.exit(0 if result["passed"] else 1)
else:
raise ValueError(mode)