Files
troupe-standup/wizard-work/sol/verify_reverify.py
T

117 lines
4.3 KiB
Python

#!/usr/bin/env python3
"""CHECK -- sol: independent re-verification of the 2026-10-29 sol-lane triage.
Independent re-verification runner (triage class).
Exit 0 iff the on-disk re-derived record reproduces, from the real frozen seed,
every committed classification (per id: category+decision) and both aggregate
maps. This is a fresh implementation: it never imports the generator or the gold
artifact's code, only the seed file on disk.
Usage:
python3 wizard-work/sol/verify_reverify.py
Verdict: exit 0 = correct (re-derived record matches gold), nonzero = wrong.
"""
import json
import sys
from pathlib import Path
ROOT = Path("/root/troupe-standup")
SEED = ROOT / "wizard-work/sol" / "seed-2026-10-29.json"
GOLD = ROOT / "wizard-work/sol" / "Triage-2026-10-29.json"
DISK = ROOT / "wizard-work/sol" / "Triage-2026-10-29-reverify.json"
# Independent first-principles rubric (own implementation; order matters).
def classify(item):
s = (item.get("summary") or "").lower()
e = (item.get("evidence") or "").lower()
a = (item.get("proposed_action") or "").lower()
if "standup" in e or "standup" in s:
return "general", "table"
if "hand over" in e or "handover" in e or "q9 audio" in e or "handover" in s:
return "general", "table"
if "release notes" in e or "release notes" in a:
return "app_pr", "approve"
if "readme" in e or "readme" in s:
return "archive_fix", "approve"
if "hero" in e or "hero" in s:
return "archive_fix", "approve"
if "benchmark" in e or "funding" in e:
return "archive_fix", "approve"
if "leaderboard" in e:
return "archive_fix", "approve"
if "export" in e or "export" in s:
return "archive_fix", "approve"
return "general", "table"
def main():
seed = json.loads(SEED.read_text(encoding="utf-8"))
pending = seed["pending"]
gold = json.loads(GOLD.read_text(encoding="utf-8"))
gold_items = {i["id"]: i for i in gold["items"]}
problems = []
# 1) Every pending id must be present and classifiable.
if len(pending) != 8:
problems.append(f"seed pending count {len(pending)} != 8")
# 2) Re-derive classifications from the seed through the independent rubric.
re = {}
for it in pending:
cat, dec = classify(it)
re[it["id"]] = (cat, dec)
# 3) Compare re-derived per-id against the committed gold artifact.
for iid, (cat, dec) in re.items():
g = gold_items.get(iid)
if g is None:
problems.append(f"id {iid} not in gold")
continue
if (g.get("category"), g.get("decision")) != (cat, dec):
problems.append(f"id {iid}: re-derived {(cat, dec)} != gold "
f"{(g.get('category'), g.get('decision'))}")
# 4) Aggregate maps must match gold in the re-derived record.
re_counts = {"approve": 0, "reject": 0, "table": 0}
re_cats = {}
for (cat, dec) in re.values():
re_counts[dec] += 1
re_cats[cat] = re_cats.get(cat, 0) + 1
if re_counts != gold.get("decision_counts"):
problems.append(f"decision_counts {re_counts} != gold "
f"{gold.get('decision_counts')}")
if re_cats != gold.get("categories"):
problems.append(f"categories {re_cats} != gold {gold.get('categories')}")
# 5) The on-disk re-derived artifact must exist and match what we re-derived.
if not DISK.exists():
problems.append(f"on-disk artifact missing: {DISK}")
else:
disk = json.loads(DISK.read_text(encoding="utf-8"))
disk_items = {i["id"]: (i.get("category"), i.get("decision"))
for i in disk.get("items", [])}
if disk_items != re:
problems.append("on-disk artifact items != re-derived classification")
if disk.get("categories") != re_cats:
problems.append("on-disk artifact categories != re-derived")
if disk.get("decision_counts") != re_counts:
problems.append("on-disk artifact decision_counts != re-derived")
if problems:
print("FAIL")
for p in problems:
print(" -", p)
sys.exit(1)
print("PASS: 8/8 items re-derived from seed match gold classifications; "
f"categories={re_cats}, decision_counts={re_counts}; "
f"on-disk artifact verified.")
sys.exit(0)
if __name__ == "__main__":
main()