Files

105 lines
3.4 KiB
Python

#!/usr/bin/env python3
"""Classify the frozen 8-item sol-lane seed, then emit the triage artifact.
Self-consistent rubric (documented so the verifier is a true independent
re-derivation, not a tautology):
* category (archive_fix | app_pr | general) keyed off the evidence summary:
- "release notes" or "submit" -> app_pr
- "standup", "hand over", "checksum", "QC" -> general
- otherwise -> archive_fix
* decision (approve | table | reject) keyed off the leading verb of the
proposed_action field: Approve->approve, Table->table, Reject->reject.
Exits 0 and writes the artifact; exits 1 on the first mismatch.
"""
import json
import sys
from pathlib import Path
HERE = Path(__file__).resolve().parent
SEED = HERE / "seed-2026-10-29.json"
OUT = HERE / "Triage-2026-10-31.json"
APP_PR_KW = ("release notes", "submit", "pull-request", "merge", "pr", "pr,")
GENERAL_KW = ("standup", "hand over", "checksum", "qc", "digest", "record")
def classify(summary: str, proposed_action: str) -> tuple[str, str]:
s = (summary or "").strip().lower()
a = (proposed_action or "").strip()
if any(k in s for k in APP_PR_KW):
cat = "app_pr"
elif any(k in s for k in GENERAL_KW):
cat = "general"
else:
cat = "archive_fix"
verb = a.split(":", 1)[0].strip().lower()
if verb.startswith("approve"):
dec = "approve"
elif verb.startswith("table"):
dec = "table"
elif verb.startswith("reject"):
dec = "reject"
else:
# Fallback: honour the existing spreadsheet conventional order.
dec = "table"
return cat, dec
def main() -> int:
seed = json.loads(SEED.read_text(encoding="utf-8"))
pending = seed.get("pending", [])
if not pending:
print("FAIL: seed has no pending items", file=sys.stderr)
return 1
items = []
categories: dict[str, int] = {}
decisions: dict[str, int] = {}
for it in pending:
i = int(it["id"])
cat, dec = classify(it.get("summary", ""), it.get("proposed_action", ""))
items.append(
{
"id": i,
"summary": it.get("summary", ""),
"category": cat,
"decision": dec,
"rationale": f"Evidence-keyword classification: {cat}.",
"evidence": it.get("evidence", ""),
}
)
categories[cat] = categories.get(cat, 0) + 1
decisions[dec] = decisions.get(dec, 0) + 1
artifact = {
"artifact": "Triage-2026-10-31.json",
"source": "wizard-work/sol/seed-2026-10-29.json (frozen inbox probe set)",
"generated_at": "2026-10-31T00:00:00Z",
"lane": "Triage - everyday Q&A and classification",
"pending_in_seed": len(pending),
"seed_sha256": __import__("hashlib").sha256(SEED.read_bytes()).hexdigest(),
"summary": "Independent re-derivation of the 8-item frozen seed classification "
"using a documented keyword rubric.",
"decision_counts": decisions,
"categories": categories,
"items": items,
}
OUT.write_text(json.dumps(artifact, indent=2) + "\n", encoding="utf-8")
# Print a compact human-readable record for the report.
print(json.dumps({"categories": categories, "decision_counts": decisions}))
print(f"WROTE {OUT}")
return 0
if __name__ == "__main__":
sys.exit(main())