align / code /scripts /p2 /prereg_hash.py
viai957's picture
Add files using upload-large-folder tool
63f41a6 verified
Raw History Blame Contribute Delete
2.51 kB
#!/usr/bin/env python
"""Print the hash that goes to the external time-stamp store for the SOTA pre-registration.
.venv/bin/python scripts/p2/prereg_hash.py # manifest + overall sha256
.venv/bin/python scripts/p2/prereg_hash.py --json # machine-readable
.venv/bin/python scripts/p2/prereg_hash.py --check HEX # exit 0 iff HEX is the current overall hash
The overall hash covers the registration text (docs/PREREG_SOTA.md) AND the analysis code that
implements it (paired statistics, the report script, the shared contract helpers, this script),
byte for byte, so the time-stamp commits to both what was promised and the code that will compute it.
Any edit to any of them changes the hash; the report prints the current hash next to the registered one.
Where the hash is stored is a user decision (docs/IMPLEMENTATION_LANES.md); this script only computes it.
"""
from __future__ import annotations
import argparse
import hashlib
import json
import sys
from pathlib import Path
REPO = Path(__file__).resolve().parents[2]
#: Order is part of the registration.
FILES = (
"docs/PREREG_SOTA.md",
"align/eval/paired.py",
"align/eval/proof_stats.py",
"scripts/p2/eval_report.py",
"scripts/p2/p2_common.py",
"scripts/p2/prereg_hash.py",
)
def compute(repo: Path = REPO, files=FILES) -> dict:
entries = []
for rel in files:
p = Path(repo) / rel
if not p.is_file():
raise FileNotFoundError(f"registration input missing: {rel}")
entries.append({"path": rel, "sha256": hashlib.sha256(p.read_bytes()).hexdigest()})
manifest = "".join(f"{e['sha256']} {e['path']}\n" for e in entries)
return {"files": entries, "manifest": manifest, "sha256": hashlib.sha256(manifest.encode()).hexdigest()}
def main(argv=None) -> int:
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
ap.add_argument("--json", action="store_true")
ap.add_argument("--check", metavar="HEX")
a = ap.parse_args(argv)
r = compute()
if a.check is not None:
ok = a.check.strip().lower() == r["sha256"]
print("MATCH" if ok else f"MISMATCH (current {r['sha256']})")
return 0 if ok else 1
if a.json:
print(json.dumps({"files": r["files"], "sha256": r["sha256"]}, indent=1))
else:
print(r["manifest"], end="")
print(f"\nPREREG_OVERALL_SHA256: {r['sha256']}")
return 0
if __name__ == "__main__":
sys.exit(main())