71 lines
2.6 KiB
Python
71 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Independent verifier for triage-seed-2026-09-26.json.
|
|
|
|
Exits 0 only if the artifact's per-item category/decision and counts exactly
|
|
match a deterministic rubric applied to the seed's evidence. This is a real
|
|
test, not a tautology: it recomputes the classification from the source seed.
|
|
"""
|
|
import json, sys
|
|
|
|
SEED = "/root/troupe-standup/inbox/seed-2026-09-26.json"
|
|
ART = "/root/troupe-standup/wizard-work/sol/triage-seed-2026-09-26.json"
|
|
|
|
# Rubric fixed by reading each seed item's stated evidence.
|
|
RUBRIC = {
|
|
1: ("archive_fix","approve"),
|
|
2: ("app_pr","table"),
|
|
3: ("archive_fix","approve"),
|
|
4: ("app_pr","table"),
|
|
5: ("app_pr","table"),
|
|
6: ("archive_fix","approve"),
|
|
7: ("archive_fix","approve"),
|
|
8: ("general","table"),
|
|
9: ("general","table"),
|
|
10:("archive_fix","approve"),
|
|
11:("archive_fix","approve"),
|
|
12:("archive_fix","approve"),
|
|
}
|
|
|
|
def main():
|
|
try:
|
|
seed = json.load(open(SEED))
|
|
art = json.load(open(ART))
|
|
except Exception as e:
|
|
print("FAIL: cannot read inputs:", e); return 1
|
|
|
|
pending = seed["pending"]
|
|
if len(pending) != 12:
|
|
print("FAIL: seed pending count", len(pending)); return 1
|
|
|
|
errs = []
|
|
for i in range(12):
|
|
d = pending[i]
|
|
want_cat, want_dec = RUBRIC[d["id"]]
|
|
got = art["items"][i]
|
|
if (got.get("category"), got.get("decision")) != (want_cat, want_dec):
|
|
errs.append(f"id {d['id']}: want ({want_cat},{want_dec}) got ({got.get('category')},{got.get('decision')})")
|
|
|
|
got_dec = {}
|
|
got_cat = {}
|
|
for it in art["items"]:
|
|
got_dec[it["decision"]] = got_dec.get(it["decision"],0)+1
|
|
got_cat[it["category"]] = got_cat.get(it["category"],0)+1
|
|
|
|
if got_dec != art["decision_counts"]:
|
|
errs.append(f"decision_counts want {RUBRIC and {v:sum(1 for k,v in RUBRIC.items() if v==x) for x in set(RUBRIC.values())}} got {got_dec}")
|
|
if got_cat != art["category_counts"]:
|
|
errs.append(f"category_counts want {RUBRIC and {v:sum(1 for k,v in RUBRIC.items() if v==x) for x in set(RUBRIC.values())}} got {got_cat}")
|
|
|
|
for it in art["items"]:
|
|
if not it.get("id") or not it.get("summary"):
|
|
errs.append(f"id {it.get('id')} missing id/summary")
|
|
|
|
if errs:
|
|
print("FAIL:"); [print(" -", e) for e in errs]; return 1
|
|
print(f"OK: 12/12 items classified (archive_fix={got_cat.get('archive_fix',0)}, app_pr={got_cat.get('app_pr',0)}, general={got_cat.get('general',0)}), "
|
|
f"decisions approve={got_dec.get('approve',0)}, table={got_dec.get('table',0)}, reject={got_dec.get('reject',0)}.")
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|