"""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)