Files

101 lines
3.7 KiB
Python

#!/usr/bin/env python3
"""Deterministic classifier for the frozen 8-item probe seed.
Lane: sol / Triage (everyday Q&A and classification).
Rule (evidence-keyword driven, stdlib only):
Category:
- archive_fix -> evidence describes a defect / omission in deployed content:
hero mark, funding table, leaderboard restat, export rows,
readme env vars.
- app_pr -> evidence is a publish / submit action.
- general -> everything else (batch / handover / coordination).
Decision:
- approve -> proposed_action applies a single corrective change
(update / add / fix / publish) and names no second owner.
- table -> proposed_action batches a group or hands a file to a named
second owner (batch ... digest / hand ... to Timmy).
Input: wizard-work/sol/seed-2026-10-29.json (frozen, 8 pending items)
Output: wizard-work/sol/Triage-2026-11-01.json (manifest)
"""
import json
import re
from pathlib import Path
REPO = Path(__file__).resolve().parent.parent.parent
SEED = REPO / "wizard-work" / "sol" / "seed-2026-10-29.json"
OUT = REPO / "wizard-work" / "sol" / "Triage-2026-11-01.json"
# Evidence keywords -> category. Checked in order; first match wins.
CATEGORY_RULES = [
("archive_fix", ["hero", "funding table", "restats", "export drops",
"readme omits", "readme", "funding table rows lack"]),
("app_pr", ["publish", "submit", "release-notes"]),
]
def classify_category(evidence: str) -> str:
low = evidence.lower()
for cat, kws in CATEGORY_RULES:
if any(k in low for k in kws):
return cat
return "general"
def classify_decision(proposed_action: str) -> str:
low = proposed_action.lower()
# Handover / batch items name a second owner or a group -> table.
if re.search(r"\b(batch|hand|record|send)\b", low):
return "table"
return "approve"
def main() -> None:
seed = json.loads(SEED.read_text(encoding="utf-8"))
pending = seed["pending"]
items = []
for s in pending:
evidence = s["evidence"]
summary = s["summary"]
proposed_action = s["proposed_action"]
items.append({
"id": s["id"],
"summary": summary,
"category": classify_category(evidence),
"decision": classify_decision(proposed_action),
"rationale": (
f"evidence='{evidence}' -> category rule matched '{classify_category(evidence)}';"
f" proposed_action='{proposed_action}' -> decision rule matched '{classify_decision(proposed_action)}'."
),
"evidence": evidence,
"source": "seed-2026-10-29.json (frozen)",
})
decision_counts = {}
categories = {}
for it in items:
decision_counts[it["decision"]] = decision_counts.get(it["decision"], 0) + 1
categories[it["category"]] = categories.get(it["category"], 0) + 1
manifest = {
"artifact": "Triage-2026-11-01.json",
"source": "wizard-work/sol/seed-2026-10-29.json (frozen 8-item probe set)",
"generated_at": "2026-11-01T00:00:00Z",
"lane": "Triage - everyday Q&A and classification",
"pending_in_seed": len(pending),
"summary": "Triage of 8 pending items in the frozen seed, classified by "
"evidence-keyword rules.",
"decision_counts": decision_counts,
"categories": categories,
"items": items,
}
OUT.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
print(f"Wrote {OUT}")
print(f"decision_counts={decision_counts} categories={categories}")
if __name__ == "__main__":
main()