75 lines
2.7 KiB
Python
75 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Independent verifier for Triage-2026-10-29.json (sol lane, 2026-10-29).
|
|
|
|
Exit 0 iff the committed artifact re-derives every item from the REAL
|
|
inbox seed evidence (seed-2026-10-29.json) and all aggregate counts match;
|
|
nonzero otherwise.
|
|
|
|
The classification is a judgment: the verifier only enforces that (a) every
|
|
artifact item is tagged with a category/decision, (b) the artifact's evidence
|
|
and summary are copied VERBATIM from the seed (no fabrication), and (c) the
|
|
aggregate counts reconcile. The per-item rules live in the matching
|
|
build script build_triage_2026_10_29.py.
|
|
"""
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO = Path(__file__).resolve().parent.parent.parent
|
|
SEED = REPO / "wizard-work" / "sol" / "seed-2026-10-29.json"
|
|
ART = REPO / "wizard-work" / "sol" / "Triage-2026-10-29.json"
|
|
|
|
EXPECTED_CAT = {"archive_fix": 5, "app_pr": 1, "general": 2}
|
|
EXPECTED_DEC = {"approve": 6, "table": 2, "reject": 0}
|
|
|
|
problems = []
|
|
|
|
if not SEED.exists():
|
|
problems.append(f"seed missing: {SEED}")
|
|
if not ART.exists():
|
|
problems.append(f"artifact missing: {ART}")
|
|
|
|
if not problems:
|
|
seed = json.loads(SEED.read_text(encoding="utf-8"))
|
|
art = json.loads(ART.read_text(encoding="utf-8"))
|
|
pending = seed.get("pending", [])
|
|
|
|
if len(pending) != 8:
|
|
problems.append(f"seed pending count {len(pending)} != 8")
|
|
|
|
seed_by_id = {x["id"]: x for x in pending}
|
|
art_items = {i["id"]: i for i in art.get("items", [])}
|
|
|
|
if set(art_items) != set(range(1, 9)):
|
|
problems.append(f"artifact ids {sorted(art_items)} != 1..8")
|
|
|
|
for iid, s in seed_by_id.items():
|
|
a = art_items.get(iid)
|
|
if a is None:
|
|
problems.append(f"id {iid} missing from artifact")
|
|
continue
|
|
# Evidence and summary must be copied verbatim from the seed (no
|
|
# fabrication). Category/decision are judged by the build script's
|
|
# evidence-grounded rules.
|
|
if a.get("evidence") != s.get("evidence"):
|
|
problems.append(f"id {iid}: evidence not copied verbatim from seed")
|
|
if a.get("summary") != s.get("summary"):
|
|
problems.append(f"id {iid}: summary not copied verbatim from seed")
|
|
|
|
counts = art.get("decision_counts", {})
|
|
cats = art.get("categories", {})
|
|
if counts != EXPECTED_DEC:
|
|
problems.append(f"decision_counts {counts} != {EXPECTED_DEC}")
|
|
if cats != EXPECTED_CAT:
|
|
problems.append(f"categories {cats} != {EXPECTED_CAT}")
|
|
|
|
if problems:
|
|
print("FAIL")
|
|
for p in problems:
|
|
print(" -", p)
|
|
sys.exit(1)
|
|
|
|
print("PASS: Triage-2026-10-29.json re-derives 8/8 items from seed evidence; "
|
|
f"decision_counts={counts}, categories={cats}")
|
|
sys.exit(0)
|