near-toll-audit / pipeline/verify_claims.py · raw
#!/usr/bin/env python3"""Proves every number in THESIS.md and README.md came from the frozen metrics.Re-renders both files from thesis/*_frozen.json and compares bytes. A hand-typed number breaks the match. The memo bodymust also stay under 1,500 words. Run pipeline/freeze.py only to issue a new memo."""import json, pathlib, sysROOT = pathlib.Path(__file__).resolve().parent.parentsys.path.insert(0, str(ROOT / "pipeline"))from build import derived, render # noqa: E402def main(): if not (ROOT / "thesis" / "metrics_frozen.json").exists(): print("memo not frozen yet") return 0 metrics = derived(json.loads((ROOT / "thesis" / "metrics_frozen.json").read_text())) model = json.loads((ROOT / "thesis" / "model_frozen.json").read_text()) grades = json.loads((ROOT / "thesis" / "grades_frozen.json").read_text()) bad = 0 for src, dst in (("thesis/THESIS.tmpl.md", "THESIS.md"), ("thesis/README.tmpl.md", "README.md")): want = render((ROOT / src).read_text(), metrics, model, grades, escape=False) got = (ROOT / dst).read_text() if want != got: bad += 1 print(f"MISMATCH {dst}: it no longer matches a render from the frozen metrics") memo = (ROOT / "THESIS.md").read_text() words = len(memo.split("## The strongest case against this thesis")[0].split()) print(f"memo and README match the frozen metrics: {not bad}; memo body {words} words") if words > 1500: print("memo body is over 1,500 words") return 1 return 1 if bad else 0if __name__ == "__main__": sys.exit(main())