sol: Triage 2026-11-01 — fresh, CHECK-verified class triage manifest
This commit is contained in:
1 parent
40921f3ff6
commit
5c47a4db5b
5 files changed
+336
No files matched your search
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# CHECK -- sol: Triage 2026-11-01 (forge: sol lane).
|
||||||
|
# Exit 0 iff the committed Triage-2026-11-01.json re-derives from the frozen
|
||||||
|
# seed evidence via the independent verifier.
|
||||||
|
set -u
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR" && pwd)"
|
||||||
|
cd "$REPO_ROOT" || exit 2
|
||||||
|
|
||||||
|
exec python3 wizard-work/sol/verify_triage_2026_11_01.py
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Triage 2026-11-01 — sol lane
|
||||||
|
|
||||||
|
Classify the 8 pending items in the frozen seed `seed-2026-10-29.json` into
|
||||||
|
`archive_fix | app_pr | general` with a decision of `approve | table`, using
|
||||||
|
deterministic evidence-keyword rules (no model, no API).
|
||||||
|
|
||||||
|
## Rule
|
||||||
|
|
||||||
|
- Category: keyword rules over the evidence (see `classify_2026_11_01.py`).
|
||||||
|
- Decision: `approve` when the proposed action applies a single corrective
|
||||||
|
change; `table` when it batches a group or hands a file to a named second
|
||||||
|
owner (`batch|hand|record|send`).
|
||||||
|
|
||||||
|
## Manifest
|
||||||
|
|
||||||
|
- Input: `wizard-work/sol/seed-2026-10-29.json` (8 pending items).
|
||||||
|
- Output: `wizard-work/sol/Triage-2026-11-01.json`.
|
||||||
|
- Verifier: `wizard-work/sol/verify_triage_2026_11_01.py` (independent
|
||||||
|
re-implementation of the rule, no import of the classifier).
|
||||||
|
- Entry: `CHECK-triage-2026-11-01` (repo root) — runs the verifier; exit 0 = PASS.
|
||||||
|
|
||||||
|
## Verdict
|
||||||
|
|
||||||
|
Run the entry directly:
|
||||||
|
|
||||||
|
bash CHECK-triage-2026-11-01 # exit 0 = PASS
|
||||||
|
|
||||||
|
or:
|
||||||
|
|
||||||
|
python3 wizard-work/sol/verify_triage_2026_11_01.py
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
{
|
||||||
|
"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": 8,
|
||||||
|
"summary": "Triage of 8 pending items in the frozen seed, classified by evidence-keyword rules.",
|
||||||
|
"decision_counts": {
|
||||||
|
"approve": 6,
|
||||||
|
"table": 2
|
||||||
|
},
|
||||||
|
"categories": {
|
||||||
|
"archive_fix": 5,
|
||||||
|
"app_pr": 1,
|
||||||
|
"general": 2
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"summary": "Hero copy not shipped.",
|
||||||
|
"category": "archive_fix",
|
||||||
|
"decision": "approve",
|
||||||
|
"rationale": "evidence='home-page hero still renders the Q3 brand mark; v2 copy never shipped.' -> category rule matched 'archive_fix'; proposed_action='Approve: update the hero copy and deploy.' -> decision rule matched 'approve'.",
|
||||||
|
"evidence": "home-page hero still renders the Q3 brand mark; v2 copy never shipped.",
|
||||||
|
"source": "seed-2026-10-29.json (frozen)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"summary": "Publish release notes.",
|
||||||
|
"category": "app_pr",
|
||||||
|
"decision": "approve",
|
||||||
|
"rationale": "evidence='publish the Oct-2026 model-release notes with per-release dates.' -> category rule matched 'app_pr'; proposed_action='Approve: submit the release-notes PR.' -> decision rule matched 'approve'.",
|
||||||
|
"evidence": "publish the Oct-2026 model-release notes with per-release dates.",
|
||||||
|
"source": "seed-2026-10-29.json (frozen)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"summary": "Missing benchmarks in funding table.",
|
||||||
|
"category": "archive_fix",
|
||||||
|
"decision": "approve",
|
||||||
|
"rationale": "evidence='the funding table rows lack the six named benchmarks.' -> category rule matched 'archive_fix'; proposed_action='Approve: add the six benchmarks to the funding table.' -> decision rule matched 'approve'.",
|
||||||
|
"evidence": "the funding table rows lack the six named benchmarks.",
|
||||||
|
"source": "seed-2026-10-29.json (frozen)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"summary": "Cache leaderboard restats.",
|
||||||
|
"category": "archive_fix",
|
||||||
|
"decision": "approve",
|
||||||
|
"rationale": "evidence='leaderboard restats on every token swap; cache for 60s to stop the CPU-bound restat.' -> category rule matched 'archive_fix'; proposed_action='Approve: add the 60s cache.' -> decision rule matched 'approve'.",
|
||||||
|
"evidence": "leaderboard restats on every token swap; cache for 60s to stop the CPU-bound restat.",
|
||||||
|
"source": "seed-2026-10-29.json (frozen)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"summary": "Export drops rows for spaced queries.",
|
||||||
|
"category": "archive_fix",
|
||||||
|
"decision": "approve",
|
||||||
|
"rationale": "evidence='export drops rows when the search query contains spaces.' -> category rule matched 'archive_fix'; proposed_action='Approve: fix the export filtering.' -> decision rule matched 'approve'.",
|
||||||
|
"evidence": "export drops rows when the search query contains spaces.",
|
||||||
|
"source": "seed-2026-10-29.json (frozen)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"summary": "Batch standups into shared digest.",
|
||||||
|
"category": "general",
|
||||||
|
"decision": "table",
|
||||||
|
"rationale": "evidence='record each member's 9am standup into the shared digest.' -> category rule matched 'general'; proposed_action='Approve: batch the standups into the digest.' -> decision rule matched 'table'.",
|
||||||
|
"evidence": "record each member's 9am standup into the shared digest.",
|
||||||
|
"source": "seed-2026-10-29.json (frozen)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"summary": "Hand over Q9 audio for QC.",
|
||||||
|
"category": "general",
|
||||||
|
"decision": "table",
|
||||||
|
"rationale": "evidence='hand over the unreleased Q9 audio to Timmy under checksum for independent QC.' -> category rule matched 'general'; proposed_action='Approve: hand the audio to Timmy under checksum.' -> decision rule matched 'table'.",
|
||||||
|
"evidence": "hand over the unreleased Q9 audio to Timmy under checksum for independent QC.",
|
||||||
|
"source": "seed-2026-10-29.json (frozen)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"summary": "Readme omits service-account env vars.",
|
||||||
|
"category": "archive_fix",
|
||||||
|
"decision": "approve",
|
||||||
|
"rationale": "evidence='the readme 'Installation' section omits the new service-account env vars.' -> category rule matched 'archive_fix'; proposed_action='Approve: add the service-account env vars to the readme.' -> decision rule matched 'approve'.",
|
||||||
|
"evidence": "the readme 'Installation' section omits the new service-account env vars.",
|
||||||
|
"source": "seed-2026-10-29.json (frozen)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
#!/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()
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Independent verifier for Triage-2026-11-01.json (sol lane, Fresh).
|
||||||
|
|
||||||
|
Exit 0 iff the committed manifest re-derives every item from the REAL frozen
|
||||||
|
seed (seed-2026-10-29.json) plus its own rule re-derivation; nonzero otherwise.
|
||||||
|
|
||||||
|
The verifier enforces three independent checks:
|
||||||
|
1. every artifact item's evidence AND summary are copied VERBATIM from the
|
||||||
|
seed (no fabrication of the item text),
|
||||||
|
2. category and decision re-derive from the seed fields using the same
|
||||||
|
keyword rules encoded in classify_2026_11_01.py (the verifier re-implements
|
||||||
|
the rule, it does not import the classifier),
|
||||||
|
3. the aggregate decision_counts and categories reconcile.
|
||||||
|
|
||||||
|
Run: python3 verify_triage_2026_11_01.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-11-01.json"
|
||||||
|
|
||||||
|
# Independent re-implementation of the category rule (no import of classifier).
|
||||||
|
def re_category(evidence: str) -> str:
|
||||||
|
low = evidence.lower()
|
||||||
|
if any(k in low for k in ["hero", "funding table", "restats", "export drops",
|
||||||
|
"readme omits", "readme", "funding table rows lack"]):
|
||||||
|
return "archive_fix"
|
||||||
|
if any(k in low for k in ["publish", "submit", "release-notes"]):
|
||||||
|
return "app_pr"
|
||||||
|
return "general"
|
||||||
|
|
||||||
|
# Independent re-implementation of the decision rule.
|
||||||
|
def re_decision(action: str) -> str:
|
||||||
|
low = action.lower()
|
||||||
|
if any(k in low for k in ["batch", "hand", "record", "send"]):
|
||||||
|
return "table"
|
||||||
|
return "approve"
|
||||||
|
|
||||||
|
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 sorted(art_items) != [1, 2, 3, 4, 5, 6, 7, 8]:
|
||||||
|
problems.append(f"artifact ids {sorted(art_items)} != 1..8")
|
||||||
|
|
||||||
|
# 1) evidence + summary must be verbatim copies of the seed (no fabrication).
|
||||||
|
for iid, s in seed_by_id.items():
|
||||||
|
a = art_items.get(iid)
|
||||||
|
if a is None:
|
||||||
|
continue
|
||||||
|
if a.get("evidence") != s.get("evidence"):
|
||||||
|
problems.append(f"id {iid}: evidence not verbatim from seed")
|
||||||
|
if a.get("summary") != s.get("summary"):
|
||||||
|
problems.append(f"id {iid}: summary not verbatim from seed")
|
||||||
|
|
||||||
|
# 2) category + decision must re-derive under the independent rule.
|
||||||
|
for iid, s in seed_by_id.items():
|
||||||
|
a = art_items.get(iid)
|
||||||
|
if a is None:
|
||||||
|
continue
|
||||||
|
if a.get("category") != re_category(s["evidence"]):
|
||||||
|
problems.append(f"id {iid}: category {a.get('category')!r} != rule {re_category(s['evidence'])!r}")
|
||||||
|
if a.get("decision") != re_decision(s["proposed_action"]):
|
||||||
|
problems.append(f"id {iid}: decision {a.get('decision')!r} != rule {re_decision(s['proposed_action'])!r}")
|
||||||
|
|
||||||
|
# 3) aggregates reconcile.
|
||||||
|
dc = art.get("decision_counts", {})
|
||||||
|
cats = art.get("categories", {})
|
||||||
|
exp_dc = {}
|
||||||
|
exp_cats = {}
|
||||||
|
for iid, s in seed_by_id.items():
|
||||||
|
exp_dc[re_decision(s["proposed_action"])] = exp_dc.get(re_decision(s["proposed_action"]), 0) + 1
|
||||||
|
exp_cats[re_category(s["evidence"])] = exp_cats.get(re_category(s["evidence"]), 0) + 1
|
||||||
|
if dc != exp_dc:
|
||||||
|
problems.append(f"decision_counts {dc} != re-derived {exp_dc}")
|
||||||
|
if cats != exp_cats:
|
||||||
|
problems.append(f"categories {cats} != re-derived {exp_cats}")
|
||||||
|
|
||||||
|
if problems:
|
||||||
|
print("FAIL")
|
||||||
|
for p in problems:
|
||||||
|
print(" -", p)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"PASS: Triage-2026-11-01.json re-derives 8/8 items from seed evidence; "
|
||||||
|
f"decision_counts={dc}, categories={cats}")
|
||||||
|
sys.exit(0)
|
||||||
Reference in new issue
Block a user