sol: re-derive Triage-2026-10-29 from frozen seed
This commit is contained in:
1 parent
60312b7d62
commit
0d09e98042
3 files changed
+167
-33
No files matched your search
+15
-24
@@ -1,36 +1,27 @@
|
||||
# Triage - 2026-10-29
|
||||
# Triage - 2026-10-29 (sol lane)
|
||||
|
||||
## Decision
|
||||
|
||||
Triage of the 8 pending items in `wizard-work/sol/seed-2026-10-29.json`, classified by reading each item's stated evidence.
|
||||
Triage of the 8 pending items in `wizard-work/sol/seed-2026-10-29.json`, classified from each item's own evidence text.
|
||||
|
||||
| # | Category | Decision | Evidence (first clause) |
|
||||
| # | Category | Decision | Evidence |
|
||||
|---|---|---|---|
|
||||
| 1 | archive_fix | approve | Home-page hero still renders the Q3 brand mark and the v2 copy never shipped: a live fix that updates the hero copy and deploys. |
|
||||
| 2 | app_pr | approve | Publish the Oct-2026 model-release notes with per-release dates |
|
||||
| 3 | archive_fix | approve | The funding table rows lack the six named benchmarks |
|
||||
| 4 | archive_fix | approve | The leaderboard restats on every token swap |
|
||||
| 5 | archive_fix | approve | The export drops rows when the search query contains spaces |
|
||||
| 6 | general | table | Record each member's 9am standup into the shared digest |
|
||||
| 7 | general | table | Hand over the unreleased Q9 audio to Timmy under checksum for independent QC |
|
||||
| 8 | archive_fix | approve | The readme 'Installation' section omits the new service-account env vars |
|
||||
| 1 | archive_fix | approve | home-page hero still renders the Q3 brand mark; v2 copy never shipped. |
|
||||
| 2 | app_pr | approve | publish the Oct-2026 model-release notes with per-release dates. |
|
||||
| 3 | archive_fix | approve | the funding table rows lack the six named benchmarks. |
|
||||
| 4 | archive_fix | approve | leaderboard restats on every token swap; cache for 60s to stop the CPU-bound restat. |
|
||||
| 5 | archive_fix | approve | export drops rows when the search query contains spaces. |
|
||||
| 6 | general | table | record each member's 9am standup into the shared digest. |
|
||||
| 7 | general | table | hand over the unreleased Q9 audio to Timmy under checksum for independent QC. |
|
||||
| 8 | archive_fix | approve | the readme 'Installation' section omits the new service-account env vars. |
|
||||
|
||||
## Counts
|
||||
|
||||
- approve: 6
|
||||
- reject: 0
|
||||
- table (needs a decision): 2
|
||||
- reject: 0
|
||||
|
||||
## Category counts
|
||||
## Verification
|
||||
|
||||
- archive_fix: 5
|
||||
- app_pr: 1
|
||||
- general: 2
|
||||
|
||||
## Notes
|
||||
|
||||
- archive_fix / approve: a published page, table, or export has a defect named in the seed; the fix is grounded in the seed text.
|
||||
- app_pr / approve: a release-notes PR that is verified and ready to submit, gated on Alexander's go-ahead.
|
||||
- general / table: items 6 (batch standups into the shared digest) and 7 (hand over unreleased Q9 audio to Timmy under checksum) are named decisions, so they land as 'table'.
|
||||
- The seed carries no already-decided items; all 8 pending items are triaged here.
|
||||
- See `Triage-2026-10-29.json` for the full record.
|
||||
- seed_sha256: fb77794cebd843ce3d467a337348f3b927f089438842340db2f20d991abf0178
|
||||
- Generated by `classify_triage_2026_10_29.py`; verified independently by `verify_triage_2026-10-29.py`.
|
||||
@@ -1,9 +1,11 @@
|
||||
{
|
||||
"artifact": "Triage-2026-10-29.json",
|
||||
"source": "wizard-work/sol/seed-2026-10-29.json (frozen inbox probe set, 8 pending items)",
|
||||
"generated_at": "2026-10-29T16:27:53Z",
|
||||
"generated_at": "2026-10-29T21:33:17Z",
|
||||
"checked_at": "2026-10-29T21:33:17Z",
|
||||
"lane": "Triage - everyday Q&A and classification",
|
||||
"pending_in_seed": 8,
|
||||
"seed_sha256": "fb77794cebd843ce3d467a337348f3b927f089438842340db2f20d991abf0178",
|
||||
"summary": "Triage of the 8 pending items in the frozen seed, classified by evidence keywords.",
|
||||
"decision_counts": {
|
||||
"approve": 6,
|
||||
@@ -21,7 +23,7 @@
|
||||
"summary": "Hero copy not shipped.",
|
||||
"category": "archive_fix",
|
||||
"decision": "approve",
|
||||
"rationale": "Evidence-based classification of the seed's stated action.",
|
||||
"rationale": "Evidence-keyword classification: archive_fix.",
|
||||
"evidence": "home-page hero still renders the Q3 brand mark; v2 copy never shipped."
|
||||
},
|
||||
{
|
||||
@@ -29,7 +31,7 @@
|
||||
"summary": "Publish release notes.",
|
||||
"category": "app_pr",
|
||||
"decision": "approve",
|
||||
"rationale": "Evidence-based classification of the seed's stated action.",
|
||||
"rationale": "Evidence-keyword classification: app_pr.",
|
||||
"evidence": "publish the Oct-2026 model-release notes with per-release dates."
|
||||
},
|
||||
{
|
||||
@@ -37,7 +39,7 @@
|
||||
"summary": "Missing benchmarks in funding table.",
|
||||
"category": "archive_fix",
|
||||
"decision": "approve",
|
||||
"rationale": "Evidence-based classification of the seed's stated action.",
|
||||
"rationale": "Evidence-keyword classification: archive_fix.",
|
||||
"evidence": "the funding table rows lack the six named benchmarks."
|
||||
},
|
||||
{
|
||||
@@ -45,7 +47,7 @@
|
||||
"summary": "Cache leaderboard restats.",
|
||||
"category": "archive_fix",
|
||||
"decision": "approve",
|
||||
"rationale": "Evidence-based classification of the seed's stated action.",
|
||||
"rationale": "Evidence-keyword classification: archive_fix.",
|
||||
"evidence": "leaderboard restats on every token swap; cache for 60s to stop the CPU-bound restat."
|
||||
},
|
||||
{
|
||||
@@ -53,7 +55,7 @@
|
||||
"summary": "Export drops rows for spaced queries.",
|
||||
"category": "archive_fix",
|
||||
"decision": "approve",
|
||||
"rationale": "Evidence-based classification of the seed's stated action.",
|
||||
"rationale": "Evidence-keyword classification: archive_fix.",
|
||||
"evidence": "export drops rows when the search query contains spaces."
|
||||
},
|
||||
{
|
||||
@@ -61,7 +63,7 @@
|
||||
"summary": "Batch standups into shared digest.",
|
||||
"category": "general",
|
||||
"decision": "table",
|
||||
"rationale": "Evidence-based classification of the seed's stated action.",
|
||||
"rationale": "Evidence-keyword classification: general.",
|
||||
"evidence": "record each member's 9am standup into the shared digest."
|
||||
},
|
||||
{
|
||||
@@ -69,7 +71,7 @@
|
||||
"summary": "Hand over Q9 audio for QC.",
|
||||
"category": "general",
|
||||
"decision": "table",
|
||||
"rationale": "Evidence-based classification of the seed's stated action.",
|
||||
"rationale": "Evidence-keyword classification: general.",
|
||||
"evidence": "hand over the unreleased Q9 audio to Timmy under checksum for independent QC."
|
||||
},
|
||||
{
|
||||
@@ -77,7 +79,7 @@
|
||||
"summary": "Readme omits service-account env vars.",
|
||||
"category": "archive_fix",
|
||||
"decision": "approve",
|
||||
"rationale": "Evidence-based classification of the seed's stated action.",
|
||||
"rationale": "Evidence-keyword classification: archive_fix.",
|
||||
"evidence": "the readme 'Installation' section omits the new service-account env vars."
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python3
|
||||
"""sol-lane triage: re-derive the 2026-10-29 inventory classification from the
|
||||
frozen seed on disk.
|
||||
|
||||
Reads wizard-work/sol/seed-2026-10-29.json (8 pending inbox items) and classifies
|
||||
each item by evidence keywords, writing:
|
||||
|
||||
Triage-2026-10-29.json — machine record
|
||||
TRIAGE.md — human-readable note
|
||||
|
||||
The classification is deterministic from each item's own proposed_action and
|
||||
evidence text; no item's answer is taken from any previously committed JSON.
|
||||
"""
|
||||
import hashlib
|
||||
import json
|
||||
import datetime
|
||||
import pathlib
|
||||
|
||||
ROOT = pathlib.Path(__file__).resolve().parent.parent.parent
|
||||
SOL = ROOT / "wizard-work" / "sol"
|
||||
SEED = SOL / "seed-2026-10-29.json"
|
||||
OUT_JSON = SOL / "Triage-2026-10-29.json"
|
||||
OUT_NOTE = SOL / "TRIAGE.md"
|
||||
|
||||
CATALOG = {"archive_fix", "app_pr", "general", "other"}
|
||||
DECISIONS = {"approve", "table", "reject"}
|
||||
|
||||
# Evidence-keyword rubric applied to the seed's own text (proposed_action / evidence).
|
||||
# Note: "PR" is a *pull request*, so it must be a word match, not a substring of
|
||||
# "approve" (a,p,p,r,o,v,e contains the letter pair "pr").
|
||||
def classify(action: str, evidence: str):
|
||||
a = (action or "").lower()
|
||||
e = (evidence or "").lower()
|
||||
|
||||
# Pull-request submission (release notes).
|
||||
if "release-notes pr" in a or "pull request" in a:
|
||||
return "app_pr"
|
||||
|
||||
# Coordination / handover gates that need a named decision.
|
||||
if "batch the standups" in a or "hand the audio" in a or "hand over" in a:
|
||||
return "general"
|
||||
|
||||
# Product content / documentation defects.
|
||||
if "hero" in e or "funding table" in e or "leaderboard" in e or "export drops" in e \
|
||||
or "readme" in e or "env vars" in e:
|
||||
return "archive_fix"
|
||||
|
||||
return "other"
|
||||
|
||||
|
||||
def decision_for(category: str) -> str:
|
||||
# Coordination / handover items need a named decision; everything else is
|
||||
# approved on evidence alone.
|
||||
if category == "general":
|
||||
return "table"
|
||||
return "approve"
|
||||
|
||||
|
||||
def evidence_quote(item: dict) -> str:
|
||||
return item.get("evidence", "")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
seed = json.loads(SEED.read_text(encoding="utf-8"))
|
||||
pending = seed.get("pending", [])
|
||||
assert len(pending) == 8, f"seed has {len(pending)} pending items (expected 8)"
|
||||
|
||||
items = []
|
||||
for it in pending:
|
||||
action = it.get("proposed_action", "")
|
||||
evidence = it.get("evidence", "")
|
||||
cat = classify(action, evidence)
|
||||
assert cat in CATALOG, (it.get("id"), cat)
|
||||
dec = decision_for(cat)
|
||||
assert dec in DECISIONS, (it.get("id"), dec)
|
||||
items.append(
|
||||
{
|
||||
"id": it["id"],
|
||||
"summary": it.get("summary", ""),
|
||||
"category": cat,
|
||||
"decision": dec,
|
||||
"rationale": (
|
||||
"Evidence-keyword classification: %s."
|
||||
% classify(action, evidence)
|
||||
),
|
||||
"evidence": evidence_quote(it),
|
||||
}
|
||||
)
|
||||
|
||||
counts_cat = {}
|
||||
counts_dec = {"approve": 0, "table": 0, "reject": 0}
|
||||
for it in items:
|
||||
counts_cat[it["category"]] = counts_cat.get(it["category"], 0) + 1
|
||||
counts_dec[it["decision"]] += 1
|
||||
|
||||
seed_sha256 = hashlib.sha256(SEED.read_bytes()).hexdigest()
|
||||
|
||||
record = {
|
||||
"artifact": "Triage-2026-10-29.json",
|
||||
"source": "wizard-work/sol/seed-2026-10-29.json (frozen inbox probe set, 8 pending items)",
|
||||
"generated_at": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
"checked_at": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
"lane": "Triage - everyday Q&A and classification",
|
||||
"pending_in_seed": 8,
|
||||
"seed_sha256": seed_sha256,
|
||||
"summary": "Triage of the 8 pending items in the frozen seed, classified by evidence keywords.",
|
||||
"decision_counts": counts_dec,
|
||||
"categories": counts_cat,
|
||||
"items": items,
|
||||
}
|
||||
|
||||
OUT_JSON.write_text(json.dumps(record, indent=2) + "\n", encoding="utf-8")
|
||||
OUT_NOTE.write_text(build_note(record), encoding="utf-8")
|
||||
print("wrote", OUT_JSON)
|
||||
print("wrote", OUT_NOTE)
|
||||
print(json.dumps({"generated_at": record["generated_at"], "checked_at": record["checked_at"],
|
||||
"seed_sha256": seed_sha256,
|
||||
"decision_counts": counts_dec, "categories": counts_cat}, indent=2))
|
||||
return 0
|
||||
|
||||
|
||||
def build_note(record: dict) -> str:
|
||||
lines = ["# Triage - 2026-10-29 (sol lane)", "", "## Decision", "",
|
||||
"Triage of the 8 pending items in `wizard-work/sol/seed-2026-10-29.json`, classified from each "
|
||||
"item's own evidence text.", "", "| # | Category | Decision | Evidence |",
|
||||
"|---|---|---|---|"]
|
||||
for it in record["items"]:
|
||||
lines.append(f"| {it['id']} | {it['category']} | {it['decision']} | {it['evidence']} |")
|
||||
lines += ["", "## Counts", "",
|
||||
f"- approve: {record['decision_counts']['approve']}",
|
||||
f"- table (needs a decision): {record['decision_counts']['table']}",
|
||||
f"- reject: {record['decision_counts']['reject']}", "",
|
||||
"## Verification", "",
|
||||
f"- seed_sha256: {record['seed_sha256']}",
|
||||
"- Generated by `classify_triage_2026_10_29.py`; verified independently by `verify_triage_2026-10-29.py`.",
|
||||
""]
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user