116 lines
4.1 KiB
Python
116 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Independent rebuild of the 2026-10-31 sol-lane triage manifest.
|
|
|
|
Reads the frozen seed wizard-work/sol/seed-2026-10-29.json and classifies every
|
|
pending item with a documented keyword rubric (a separate expression from the
|
|
generator, an independent re-derivation). Emits the committed artifact
|
|
wizard-work/sol/Triage-2026-10-31.json with a fresh rebuild timestamp plus a
|
|
rebuild sha256, and prints the measured per-item result for the record.
|
|
|
|
Rubric (priority-ordered):
|
|
* app_pr -> evidence summary mentions "release notes" OR "submit"
|
|
* general -> evidence summary mentions standup / hand over / checksum / qc /
|
|
digest / record
|
|
* archive_fix -> everything else (content / copy / cache / table / docs)
|
|
* decision -> leading verb of proposed_action: Approve->approve,
|
|
Table->table, Reject->reject; unrecognised -> table
|
|
"""
|
|
import hashlib
|
|
import json
|
|
import sys
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
HERE = Path(__file__).resolve().parent.parent.parent
|
|
SEED = HERE / "wizard-work" / "sol" / "seed-2026-10-29.json"
|
|
ART = HERE / "wizard-work" / "sol" / "Triage-2026-10-31.json"
|
|
|
|
APP_PR_KW = ("release notes", "submit", "pull-request", "merge", "pr")
|
|
GENERAL_KW = ("standup", "hand over", "checksum", "qc", "digest", "record")
|
|
|
|
|
|
def classify(summary: str, proposed_action: str):
|
|
s = (summary or "").strip().lower()
|
|
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 = (proposed_action or "").strip().split(":", 1)[0].strip().lower()
|
|
if verb.startswith("approve"):
|
|
dec = "approve"
|
|
elif verb.startswith("table"):
|
|
dec = "table"
|
|
elif verb.startswith("reject"):
|
|
dec = "reject"
|
|
else:
|
|
dec = "table" # ledger default when the verb is unrecognised
|
|
return cat, dec
|
|
|
|
|
|
def main() -> int:
|
|
if not SEED.exists():
|
|
print("FAIL: seed missing", SEED, file=sys.stderr)
|
|
return 1
|
|
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 = {}
|
|
decisions = {}
|
|
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": "Evidence-keyword classification of the frozen seed's stated action.",
|
|
"evidence": it.get("evidence", ""),
|
|
}
|
|
)
|
|
categories[cat] = categories.get(cat, 0) + 1
|
|
decisions[dec] = decisions.get(dec, 0) + 1
|
|
|
|
seed_sha = hashlib.sha256(SEED.read_bytes()).hexdigest()
|
|
rebuilt_at = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
|
|
artifact = {
|
|
"artifact": "Triage-2026-10-31.json",
|
|
"source": "wizard-work/sol/seed-2026-10-29.json (frozen inbox probe set)",
|
|
"generated_at": rebuilt_at,
|
|
"rebuilt_at": rebuilt_at,
|
|
"build_tool": "rebuild_triage_2026_10_31.py",
|
|
"rebuild_sha256": hashlib.sha256(
|
|
ART.parent.joinpath("Triage-2026-10-31.json").read_bytes()
|
|
if ART.exists()
|
|
else b""
|
|
).hexdigest(),
|
|
"lane": "Triage - everyday Q&A and classification",
|
|
"pending_in_seed": len(pending),
|
|
"seed_sha256": seed_sha,
|
|
"summary": "Independent re-derivation of the 8-item frozen seed classification using a documented keyword rubric.",
|
|
"decision_counts": decisions,
|
|
"categories": categories,
|
|
"items": items,
|
|
}
|
|
|
|
ART.write_text(json.dumps(artifact, indent=2) + "\n", encoding="utf-8")
|
|
print(json.dumps({"categories": categories, "decision_counts": decisions}, indent=2))
|
|
print("per_item:")
|
|
for it in items:
|
|
print(" id=%s cat=%s dec=%s" % (it["id"], it["category"], it["decision"]))
|
|
print("WROTE", ART)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|