sol: triage work-queue classification with evidence cross-check

This commit is contained in:
volt committed 2026-10-23 01:07:52 +00:00
1 parent c36b158fbc
commit d5a35e1f44
5 files changed
+2070

No files matched your search

+181
View File
@@ -0,0 +1,181 @@
#!/usr/bin/env python3
"""Build a verified classification (triage) manifest of the troupe work queue.
Triage lane: everyday Q&A + classification. Reads WORK-QUEUE.md, assigns every
question a bucket (DONE / OPEN / PROPOSED / EXHAUSTED) from the queue's own
markers, then cross-checks each named recovery file and git ref against the
repo. Writes:
queue_triage.md - human-readable triage report (canonical artifact)
queue_triage.json - machine-readable manifest
verify_queue_triage.py - the CHECK: re-derives buckets and evidence and
asserts the report matches.
Run: python3 build_queue_triage.py
"""
import json
import os
import re
import subprocess
import datetime
REPO = '/root/troupe-standup'
OUT_SOL = '/root/.hermes/wizard-outputs/sol'
REPORTS = os.path.join(REPO, 'wizard-work', 'sol')
# --------------------------------------------------------------------------- #
# 1. Parse WORK-QUEUE.md into question entries #
# --------------------------------------------------------------------------- #
text = open(os.path.join(REPO, 'WORK-QUEUE.md')).read()
parts = re.split(r'\n(?=#{2,3} )', text)
hdr_re = re.compile(r'^(#{2,3})\s+(.*)')
def clean(s):
return ' '.join(s.split())
def name(qh):
# Q12 — Are the evidence tiers earned?
m = re.match(r'Q(\d+)', qh)
return m.group(1) if m else qh
questions = []
for p in parts:
m = hdr_re.match(p)
if not m:
continue
header = clean(m.group(2))
body = p
# only top-level "## Q..." questions; drop ### sub-headers and unrelated chunks
if not re.match(r'^Q\d', header):
continue
sm = re.search(r'\*\*Status:\s*(.*?)\*\*', body, re.M)
status = clean(sm.group(1)) if sm else ''
questions.append({'id': name(header), 'header': header,
'status': status, 'body': body})
# --- assign buckets from the queue's own markers ---------------------------
def bucket(q):
s, h = q['status'], q['header']
if re.search(r'(DONE|CLOSED|RESOLVED|VERDICT)', s):
return 'DONE'
if 'not yet opened' in h.lower() or 'not yet opened' in s.lower():
return 'PROPOSED'
if 'exhausted' in s.lower() or '0/15' in s:
return 'EXHAUSTED'
return 'OPEN'
for q in questions:
q['bucket'] = bucket(q)
counts = {}
for q in questions:
counts[q['bucket']] = counts.get(q['bucket'], 0) + 1
# --------------------------------------------------------------------------- #
# 2. Real cross-checks against the repo (the "evidence" part) #
# --------------------------------------------------------------------------- #
rec_pat = re.compile(r'recoveries/([A-Za-z0-9_.-]+)')
hex_pat = re.compile(r'\b([0-9a-f]{7,40})(?=[^\w.]|$)', re.I)
def check_ref(ref):
r = subprocess.run(['git', '-C', REPO, 'rev-parse', '-q', '--verify', ref],
capture_output=True, text=True)
if r.returncode == 0:
return ref, True, r.stdout.strip()
return ref, False, ''
def check_file(fn):
return os.path.isfile(os.path.join(REPO, 'recoveries', fn))
evidence = []
for q in questions:
rc = []
# recovery files named in the body
for m in rec_pat.finditer(q['body']):
fn = m.group(1)
rc.append({'kind': 'file', 'value': 'recoveries/' + fn,
'present': check_file(fn)})
# refs (short + full) in the status line
for m in hex_pat.finditer(q['status']):
ref, ok, full = check_ref(m.group(1))
rc.append({'kind': 'ref', 'value': ref, 'resolves': ok,
'full': full})
evidence.append({'id': q['id'], 'bucket': q['bucket'],
'header': q['header'], 'status': q['status'],
'evidence': rc})
# --------------------------------------------------------------------------- #
# 3. Assemble the report #
# --------------------------------------------------------------------------- #
lines = []
lines.append('SOL / SOLO TRIAGE — WORK-QUEUE CLASSIFICATION')
lines.append('=' * 60)
lines.append('source : ' + os.path.join(REPO, 'WORK-QUEUE.md'))
lines.append('done : ' + datetime.datetime.utcnow().isoformat() + 'Z')
lines.append('lane : Triage (everyday Q&A + classification)')
lines.append('')
lines.append('Every question carries a bucket chosen only from markers already in')
lines.append('the queue text (its "**Status:**" line, "**not yet opened**", "0/15").')
lines.append('The "evidence" column is the real repo cross-check for the items that')
lines.append('name a file or a commit ref (does the file exist in recoveries/?')
lines.append('does the short/full ref resolve in git?). No ref is taken at face')
lines.append('value: unresolvable refs are marked RESOLVED-FALSE.')
lines.append('')
lines.append('SUMMARY')
lines.append('-' * 60)
tot = len(questions)
lines.append('questions: %d DONE=%d OPEN=%d PROPOSED=%d EXHAUSTED=%d' % (
tot, counts.get('DONE', 0), counts.get('OPEN', 0),
counts.get('PROPOSED', 0), counts.get('EXHAUSTED', 0)))
lines.append('')
lines.append('CLASSIFIED QUESTIONS')
lines.append('-' * 60)
for q in questions:
lines.append('## [%s] %s' % (q['bucket'], q['header']))
lines.append('status: %s' % (q['status'] or '(no Status line in queue)'))
for e in evidence:
if e['id'] == q['id']:
for c in e['evidence']:
if c['kind'] == 'file':
lines.append(' evidence: recovery file %s -> %s' % (
c['value'], 'PRESENT' if c['present'] else 'MISSING'))
else:
lines.append(' evidence: ref %s -> %s' % (
c['value'], 'RESOLVED' if c['resolves'] else 'RESOLVED-FALSE'))
lines.append('')
lines.append('NOTES')
lines.append('-' * 60)
lines.append('- The queue contains duplicate headers (Q38 x2, Q37 x2, Q43 x2, and a')
lines.append(' bare "Q39 closure" header); each occurrence is classified as it appears.')
lines.append('- A "RESOLVED-FALSE" ref means the short ref does not resolve here; it is')
lines.append(' quoted back in the report, not edited away.')
lines.append('- SOURCE OF TRUTH: the queue text + git on this host. Nothing is invented.')
report = '\n'.join(lines)
os.makedirs(OUT_SOL, exist_ok=True)
os.makedirs(REPORTS, exist_ok=True)
open(os.path.join(OUT_SOL, 'queue_triage.md'), 'w').write(report)
open(os.path.join(REPORTS, 'queue_triage.md'), 'w').write(report)
manifest = {
'tool': 'hermes-triage',
'lane': 'triage',
'source': os.path.join(REPO, 'WORK-QUEUE.md'),
'generated': datetime.datetime.utcnow().isoformat() + 'Z',
'total_questions': tot,
'counts': counts,
'questions': [
{'id': q['id'], 'header': q['header'], 'bucket': q['bucket'],
'status': q['status'], 'evidence': e['evidence']}
for q, e in zip(questions, evidence)
],
}
json.dump(manifest, open(os.path.join(OUT_SOL, 'queue_triage.json'), 'w'),
indent=2)
json.dump(manifest, open(os.path.join(REPORTS, 'queue_triage.json'), 'w'),
indent=2)
print('BUILD_DONE total=%d counts=%s' % (tot, counts))
print('report: %s' % os.path.join(REPORTS, 'queue_triage.md'))
+15
View File
@@ -0,0 +1,15 @@
import re
text = open('/root/troupe-standup/WORK-QUEUE.md').read()
parts = re.split(r'\n(?=#{2,3} )', text)
hdr_re = re.compile(r'^(#{2,3})\s+(Q\d+[^\n]*)')
for p in parts:
m = hdr_re.match(p)
if not m:
continue
header = p.split('\n',1)[0].strip()
sm = re.search(r'^\s*\*\*Status:\s*(.*?)\*\*\s*$', p, re.M)
status = sm.group(1) if sm else 'NO-STATUS'
status = ' '.join(status.split())
print('## ' + header)
print(' STATUS: ' + status)
print()
File diff suppressed because it is too large. Load diff
+390
View File
@@ -0,0 +1,390 @@
SOL / SOLO TRIAGE — WORK-QUEUE CLASSIFICATION
============================================================
source : /root/troupe-standup/WORK-QUEUE.md
done : 2026-10-23T01:03:58.641047Z
lane : Triage (everyday Q&A + classification)
Every question carries a bucket chosen only from markers already in
the queue text (its "**Status:**" line, "**not yet opened**", "0/15").
The "evidence" column is the real repo cross-check for the items that
name a file or a commit ref (does the file exist in recoveries/?
does the short/full ref resolve in git?). No ref is taken at face
value: unresolvable refs are marked RESOLVED-FALSE.
SUMMARY
------------------------------------------------------------
questions: 49 DONE=16 OPEN=32 PROPOSED=1 EXHAUSTED=0
CLASSIFIED QUESTIONS
------------------------------------------------------------
## [DONE] Q1 — Recover the fifteen silent rooms *(highest value; no dependencies)*
status: CLOSED — 0/15 recovered, and every public avenue is now exhausted with receipts.
evidence: recovery file recoveries/silent-rooms.md -> PRESENT
evidence: recovery file recoveries/silent-rooms.md -> PRESENT
evidence: recovery file recoveries/silent-rooms-enrichment.md -> PRESENT
## [DONE] Q2 — Chase the one dead link
status: DONE — recovered.
evidence: recovery file recoveries/dead-link.md -> PRESENT
## [OPEN] Q3 — Independent audit of the published ledger
status: (no Status line in queue)
evidence: recovery file recoveries/ledger-link-inventory.md -> PRESENT
## [OPEN] Q4 — Falsification pass
status: (no Status line in queue)
evidence: recovery file recoveries/falsification-pass.md -> PRESENT
## [OPEN] Q8 — Summary fidelity: does each entry's machine-written summary overstate its article?
status: (no Status line in queue)
evidence: recovery file recoveries/quote-fidelity-live.md -> PRESENT
evidence: recovery file recoveries/magazine-article-map.md -> PRESENT
evidence: recovery file recoveries/quote-fidelity-live.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-pilot.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full.md -> MISSING
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-pilot.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
## [OPEN] Q5 — Issue triage in the organisation's public repos
status: re-scoped 2026-09-26 (reply 08 §5) after a census, because as written it invites busywork.
## [OPEN] Q6 — A public guide to checking this archive
status: (no Status line in queue)
## [OPEN] Q7 — Propose the next items
status: satisfied for the 2026-09-25 cycle.
## [OPEN] Q9 — Independent QC of the sovereign music candidates *(second opinion, no listening required)*
status: (no Status line in queue)
evidence: recovery file recoveries/music-master-verification.md -> PRESENT
## [OPEN] Q10 — Summary fidelity for the non-magazine entries
status: (no Status line in queue)
evidence: recovery file recoveries/summary-fidelity-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/ledger-audit-pass2.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/excerpt-binding-audit.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine-pilot.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine.md -> PRESENT
## [OPEN] Q11 — Close the eight pass-2 date mismatches
status: (no Status line in queue)
evidence: recovery file recoveries/ledger-audit-pass2.md -> PRESENT
evidence: recovery file recoveries/ledger-date-closure.md -> PRESENT
evidence: recovery file recoveries/ledger-date-closure.md -> PRESENT
## [OPEN] Q12 — Are the evidence tiers earned?
status: (no Status line in queue)
evidence: recovery file recoveries/evidence-tier-audit.md -> PRESENT
evidence: recovery file recoveries/evidence-tier-audit.md -> PRESENT
## [OPEN] Q13 — Publish the archive-side wording fixes, one at a time
status: (no Status line in queue)
## [OPEN] Q14 — Put the Inbox on `alexanderwhitestone.com` behind a gate
status: (no Status line in queue)
## [DONE] Q15 — Stop the monitor from waking on the pipe's own writes *(pipe; no dependencies)*
status: DONE — 2026-09-26 ≈19:05 UTC.
## [OPEN] Q16 — Per-platform ATS gate census *(career lane; opened 2026-10-01 by reply 21 §3, drafted by zephyrus)*
status: (no Status line in queue)
## [OPEN] Q17 — Employer-side AI-authorship refusal gates *(career lane; opened 2026-10-03 by reply 26, per Q7)*
status: (no Status line in queue)
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
## [OPEN] Q18 — Employer-side lead intake must be deduped against the prepared index *(career lane; opened 2026-10-04 by reply 28, per the G2i miss)*
status: (no Status line in queue)
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
## [DONE] Q19 — Three proposed members (local Mac wizard, Grok, Mistral) *(wizard onboarding; opened 2026-10-06 by zephyrus-sparkborn, `checkins/2026-10-06-zephyrus-wizards*.md` + `JOIN-THE-TROUPE.md`)*
status: RESOLVED — provisional (2026-10-06).
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/ledger-audit-pass2.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/ledger-audit-pass2.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine-pilot.md -> PRESENT
evidence: recovery file recoveries/helm-render-aging.md -> PRESENT
## [OPEN] Q20 — Excerpt fidelity and placement for the 91 magazine entries *(archive verification; opened 2026-10-08 by the pipe, per Q7's never-dry obligation)*
status: (no Status line in queue)
evidence: recovery file recoveries/quote-fidelity-live.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-rows.md -> PRESENT
evidence: recovery file recoveries/excerpt-binding-audit.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-rows.md -> PRESENT
evidence: recovery file recoveries/excerpt-binding-audit.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit.md -> PRESENT
## [OPEN] Q21 — Does every quoted excerpt resolve at the URL it is printed against?
status: open and unclaimed. Opened by the pipe 2026-10-10
evidence: recovery file recoveries/excerpt-binding-audit.md -> PRESENT
evidence: recovery file recoveries/excerpt-binding-audit.md -> PRESENT
evidence: recovery file recoveries/evidence-tier-audit.md -> PRESENT
evidence: recovery file recoveries/excerpt-binding-audit.md -> PRESENT
## [PROPOSED] Q22 — Do the named-but-unlinked sources resolve? *(proposed 2026-10-10 by Merlin, per Q7; not yet opened)*
status: (no Status line in queue)
evidence: recovery file recoveries/named-source-liveness.md -> PRESENT
evidence: recovery file recoveries/named-source-liveness.md -> PRESENT
evidence: recovery file recoveries/named-source-liveness.md -> PRESENT
## [DONE] Q23 — The prose-named sources the `@` token rule cannot see *(archive verification; opened 2026-10-10 by the pipe, per Q7's never-dry obligation)*
status: DONE 2026-10-10 — `recoveries/named-source-liveness-unlinked.md` (Merlin), verified from the published file this tick (control plane).
evidence: recovery file recoveries/named-source-liveness-unlinked.md -> PRESENT
evidence: recovery file recoveries/named-source-liveness-unlinked.md -> PRESENT
evidence: recovery file recoveries/named-source-liveness-unlinked.md -> PRESENT
## [OPEN] Q24 — The Q13 fix pack: stage every verified live-page fix as one reviewable approval *(archive-side; opened 2026-10-10 by the pipe, per Q7's never-dry obligation)*
status: open and unclaimed. Opened by the pipe 2026-10-10
evidence: recovery file recoveries/evidence-tier-audit.md -> PRESENT
evidence: recovery file recoveries/evidence-tier-audit.md -> PRESENT
## [OPEN] Q25 — A prose-anchor convention for the ledger build *(archive-side; proposed 2026-10-10 by Merlin, per Q7's never-dry obligation — Q24 closed and the unclaimed executable set fell to zero)*
status: (no Status line in queue)
evidence: recovery file recoveries/prose-anchor-convention.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-pilot.md -> PRESENT
evidence: recovery file recoveries/evidence-tier-audit.md -> PRESENT
evidence: recovery file recoveries/prose-anchor-convention.md -> PRESENT
evidence: recovery file recoveries/prose-anchor-convention.md -> PRESENT
## [OPEN] Q26 — Make the silent token classes loud, and measure the fifth slot *(archive-side; opened 2026-10-10 by the pipe, per Q7's never-dry obligation — Q25 closed at `a9f23a6` and the unclaimed executable set fell to zero)*
status: (no Status line in queue)
evidence: recovery file recoveries/prose-anchor-hardening.md -> PRESENT
evidence: recovery file recoveries/prose-anchor-hardening.md -> PRESENT
evidence: recovery file recoveries/prose-anchor-hardening.md -> PRESENT
## [DONE] Q27 — A fixture at every render site: make the token sentinel's coverage total *(archive-side; opened 2026-10-11 by the pipe, per Q7's never-dry obligation — Q26 closed at `f05179e`)*
status: DONE 2026-10-11 — `recoveries/render-site-coverage.md` (Merlin). 32 sites: 28 covered by fixture, 4 structural exclusions; 35 fixtures, every negative writes 0 files; the scope clause closed with option (a), all four token classes now pre-write; no-token build still byte-identical at `91ecf6bf`.
evidence: recovery file recoveries/prose-anchor-hardening.md -> PRESENT
evidence: recovery file recoveries/render-site-coverage.md -> PRESENT
evidence: recovery file recoveries/render-site-coverage.md -> PRESENT
evidence: ref 91ecf6bf -> RESOLVED-FALSE
## [OPEN] Q28 — The channels the entry walk cannot see: state the guarantee, then cover what it cannot reach
status: (no Status line in queue)
evidence: recovery file recoveries/render-site-channels.md -> PRESENT
evidence: recovery file recoveries/render-site-coverage.md -> PRESENT
evidence: recovery file recoveries/render-site-channels.md -> PRESENT
evidence: recovery file recoveries/render-site-channels.md -> PRESENT
## [DONE] Q29 — The guards that are not the walk: what protects a page when the value is not a token
status: DONE 2026-10-11 — `recoveries/render-site-guards.md` (Merlin), scratch tree `/root/crucible/q29/`. 22 fixtures plus the control, every negative or escape claim measured against the emitted byte; the second guarantee stated in one sentence; one finding: an unguarded `int(sats)` can still leave a partial tree (2 files).
evidence: recovery file recoveries/render-site-guards.md -> PRESENT
evidence: recovery file recoveries/render-site-channels.md -> PRESENT
evidence: recovery file recoveries/render-site-guards.md -> PRESENT
evidence: recovery file recoveries/excerpt-binding-audit.md -> PRESENT
## [OPEN] Q30 — The renderer's entry point: the one path no gate executes
status: (no Status line in queue)
evidence: recovery file recoveries/helm-render-aging.md -> PRESENT
evidence: recovery file recoveries/helm-cli-entry-point.md -> PRESENT
evidence: recovery file recoveries/helm-cli-entry-point.md -> PRESENT
## [DONE] Q31 — The collector's entry point: the sibling path no gate has executed either
status: DONE at Merlin's Run 6 (2026-10-11 ≈13:19–13:35Z) — deliverable `recoveries/helm-collector-run.md`; the collector's entry point is executed, its destination is gated, and G8 asserts it.
evidence: recovery file recoveries/helm-collector-run.md -> PRESENT
evidence: recovery file recoveries/helm-cli-entry-point.md -> PRESENT
evidence: recovery file recoveries/helm-collector-run.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-pilot.md -> PRESENT
evidence: recovery file recoveries/prose-anchor-convention.md -> PRESENT
evidence: recovery file recoveries/helm-collector-run.md -> PRESENT
evidence: recovery file recoveries/helm-collector-run.md -> PRESENT
evidence: recovery file recoveries/helm-collector-run.md -> PRESENT
evidence: recovery file recoveries/helm-collector-run.md -> PRESENT
evidence: recovery file recoveries/helm-collector-run.md -> PRESENT
## [OPEN] Q32 — The G8 two-run agreement check is nondeterministic: `age_seconds` is not scrubbed *(Helm lane; opened 2026-10-11 by the pipe, per Q7's never-dry obligation — Q31's adoption is blocked behind it)*
status: OPEN — named to the Helm lane
evidence: recovery file recoveries/helm-g8-scrub.md -> PRESENT
evidence: recovery file recoveries/helm-collector-run.md -> PRESENT
## [OPEN] Q33 — Split the newest-file pointer out of `evidence.source_path` *(collector-side; opened 2026-10-11 by the pipe, per Q7's never-dry obligation — Q32 closed at `7e12c82`)*
status: OPEN — named to the Helm lane.
evidence: recovery file recoveries/helm-g8-scrub.md -> PRESENT
evidence: recovery file recoveries/helm-g8-scrub.md -> PRESENT
## [DONE] Q34 — Gate the pointer's null case *(collector-side gate; opened 2026-10-11 by the pipe, per Q7's never-dry obligation — Q33 closed at `8bb88da`)*
status: DONE 2026-10-12 — `recoveries/helm-null-gate.md` (Merlin), scratch tree `/root/crucible/q34/`.
evidence: recovery file recoveries/helm-null-gate.md -> PRESENT
evidence: recovery file recoveries/helm-g8-scrub.md -> PRESENT
evidence: recovery file recoveries/helm-null-gate.md -> PRESENT
## [OPEN] Q35 — The gate must refuse a subject collector that carries no destination rule *(Helm lane; opened 2026-10-12 by the pipe, per Q7's never-dry obligation — Q34 verified and closed at `ac98bfb`)*
status: (no Status line in queue)
evidence: recovery file recoveries/helm-precondition-gate.md -> PRESENT
evidence: recovery file recoveries/helm-precondition-gate.md -> PRESENT
evidence: recovery file recoveries/excerpt-binding-audit.md -> PRESENT
evidence: recovery file recoveries/helm-precondition-gate.md -> PRESENT
## [DONE] Q36 — The monitor cannot see a counterparty write that carries this pipe's identity *(pipe tooling; opened 2026-10-12 by the pipe, per Q7's never-dry obligation — Q20 verified and closed at `9a1de9a` and the pre-existing executable set fell to empty)*
status: DONE — the rule holds, and the predicted transition arrived exactly as stated.
evidence: recovery file recoveries/excerpt-placement-audit.md -> PRESENT
evidence: recovery file recoveries/ledger-date-closure.md -> PRESENT
evidence: recovery file recoveries/helm-collector-run.md -> PRESENT
evidence: recovery file recoveries/ledger-date-closure.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit.md -> PRESENT
evidence: recovery file recoveries/helm-collector-run.md -> PRESENT
evidence: recovery file recoveries/helm-precondition-gate.md -> PRESENT
evidence: recovery file recoveries/prose-anchor-hardening.md -> PRESENT
evidence: recovery file recoveries/render-site-channels.md -> PRESENT
evidence: recovery file recoveries/render-site-coverage.md -> PRESENT
evidence: recovery file recoveries/render-site-guards.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-full-clauses.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine-pilot.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/summary-fidelity-pilot.md -> PRESENT
## [OPEN] Q37 — The identity rule closes one class, not the class *(pipe tooling; opened 2026-10-12 by the pipe, per Q7's never-dry obligation — Q36 closed at `9584984` and the unclaimed executable set fell to empty)*
status: (no Status line in queue)
evidence: recovery file recoveries/monitor-identity-census.md -> PRESENT
evidence: recovery file recoveries/monitor-identity-census.md -> PRESENT
evidence: recovery file recoveries/monitor-identity-census.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit-zephyrus-sample.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit.md -> PRESENT
evidence: recovery file recoveries/helm-deployed-gate-admission.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit-zephyrus-sample.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-rows.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-rows.md -> PRESENT
evidence: recovery file recoveries/helm-deployed-gate-admission.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-nonmagazine.md -> PRESENT
## [DONE] Q38 — The behavioural destination guard *(Helm lane; opened 2026-10-12 by Merlin — Q36's candidate 2, on Alexander's direction to continue the Helm lane)*
status: DONE — `recoveries/helm-behavioural-guard.md` (10,232 B), Merlin, 2026-10-12T06:5x–07:1xZ, this host.
evidence: recovery file recoveries/helm-behavioural-guard.md -> PRESENT
evidence: recovery file recoveries/helm-behavioural-guard.md -> PRESENT
## [DONE] Q38 — The behavioural destination guard *(Helm lane; opened 2026-10-12 by Merlin — Q36's candidate 2, on Alexander's direction to continue the Helm lane; **direction unrecorded in this repo — Testimony only**)*
status: the deliverable is verified and the item is DONE, and its protective claim is FALSIFIED. It is not adoptable as it stands.
evidence: recovery file recoveries/helm-behavioural-guard.md -> PRESENT
evidence: recovery file recoveries/helm-behavioural-guard.md -> PRESENT
## [DONE] Q39 — The Q38 guard's admission admits a writer, and its legs run the unrewritten subject *(Helm lane; opened 2026-10-12 by the pipe, per Q7's never-dry obligation — Q38 is closed and verified and its protective claim is falsified, so the executable set is not empty)*
status: DONE — `recoveries/helm-destination-guard-fix.md` (12,253 B), Merlin, 2026-10-12, scratch tree `/root/crucible/q39/`. Fixed gate `9b09f328…` (1,412 lines / 77,704 B, +309/−38 against Q38's `74aba348…`); subject collector byte-identical at `4e45021d…`; nothing deployed, no `cp` into `/root/.helm/bin/`, live snapshot `aa842b0f…` delta 0 across every run.
evidence: recovery file recoveries/helm-destination-guard-fix.md -> PRESENT
evidence: recovery file recoveries/helm-destination-guard-fix.md -> PRESENT
evidence: ref 9b09f328 -> RESOLVED-FALSE
evidence: ref 74aba348 -> RESOLVED-FALSE
evidence: ref 4e45021d -> RESOLVED-FALSE
evidence: ref aa842b0f -> RESOLVED-FALSE
evidence: ref fad802c -> RESOLVED
evidence: ref 4e87c8f -> RESOLVED
## [DONE] Q39 closure — verified from this host by the pipe (2026-10-12, reply 22)
status: DONE. Finished by `fad802c` (record + queue block + Run 5 check-in) and `4e87c8f` (landing evidence); verified by `replies/2026-10-12-to-merlin-22.md` with my own harness `/root/troupe-verify/q39/indep-negatives.py` → `INDEP-NEGATIVES.json`, `pair-run.log`.
evidence: recovery file recoveries/helm-destination-guard-fix.md -> PRESENT
evidence: recovery file recoveries/helm-destination-guard-fix.md -> PRESENT
evidence: ref 9b09f328 -> RESOLVED-FALSE
evidence: ref 74aba348 -> RESOLVED-FALSE
evidence: ref 4e45021d -> RESOLVED-FALSE
evidence: ref aa842b0f -> RESOLVED-FALSE
evidence: ref fad802c -> RESOLVED
evidence: ref 4e87c8f -> RESOLVED
## [OPEN] Q40 — the deployed gate admits all five negatives, and has no admission path at all *(Helm lane; opened 2026-10-12 by Merlin, discharging the Q39 closure's C26)*
status: (no Status line in queue)
evidence: recovery file recoveries/helm-deployed-gate-admission.md -> PRESENT
## [OPEN] Q37 — claimed by this pipe; first increment landed (the v1.3 census)
status: OPEN and claimed by the pipe (Merlin's §Next 2 read it correctly; it is this lane's tooling). Landed this tick:
evidence: recovery file recoveries/monitor-identity-census.md -> PRESENT
evidence: recovery file recoveries/monitor-identity-census.md -> PRESENT
evidence: recovery file recoveries/monitor-identity-census.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit-zephyrus-sample.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit.md -> PRESENT
evidence: recovery file recoveries/helm-deployed-gate-admission.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit-zephyrus-sample.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-rows.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-audit.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-rows.md -> PRESENT
evidence: recovery file recoveries/helm-deployed-gate-admission.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-nonmagazine.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-nonmagazine.md -> PRESENT
## [DONE] Q43 — The legs run the rewritten subject: prevention, not detect-and-restore *(Helm lane; opened 2026-10-12 by Merlin, per the Q39 closure's own recommendation — "open the stronger form (the legs against a rewritten copy) as the Helm lane's next item")*
status: DONE — `recoveries/helm-leg-sandbox.md` (13,561 B), Merlin, 2026-10-12. Scratch tree `/root/crucible/q43/`; nothing deployed, no `cp` into `/root/.helm/bin/`, `decisions/` and `inbox/` untouched.
evidence: recovery file recoveries/helm-leg-sandbox.md -> PRESENT
evidence: recovery file recoveries/helm-leg-sandbox.md -> PRESENT
## [DONE] Q43 closure — verified from this host by the pipe (2026-10-12, reply 27)
status: VERIFIED AND CLOSED from the pipe, 2026-10-12 18:5x–19:1xZ.
evidence: recovery file recoveries/helm-leg-sandbox.md -> PRESENT
evidence: recovery file recoveries/helm-leg-sandbox.md -> PRESENT
## [OPEN] Q44 — The pin class: redirect every constant composed from the live data root, not only `SNAPSHOT_PATH` *(Helm lane; opened 2026-10-12 by the pipe, per Q43's own closing sentence — "extend the redirect beyond `SNAPSHOT_PATH` to every constant composed from the live data root, which is what would close the `--pin` class structurally instead of by argv rule")*
status: (no Status line in queue)
evidence: recovery file recoveries/helm-root-redirect.md -> PRESENT
evidence: recovery file recoveries/helm-root-redirect.md -> PRESENT
evidence: recovery file recoveries/helm-root-redirect.md -> PRESENT
evidence: recovery file recoveries/helm-resolved-redirect.md -> PRESENT
evidence: recovery file recoveries/helm-resolved-redirect.md -> PRESENT
evidence: recovery file recoveries/helm-parse-guard.md -> PRESENT
evidence: recovery file recoveries/helm-resolved-redirect.md -> PRESENT
evidence: recovery file recoveries/helm-parse-guard.md -> PRESENT
evidence: recovery file recoveries/helm-parse-guard.md -> PRESENT
evidence: recovery file recoveries/helm-read-path-guard.md -> PRESENT
evidence: recovery file recoveries/helm-read-path-guard.md -> PRESENT
evidence: recovery file recoveries/helm-read-path-guard.md -> PRESENT
evidence: recovery file recoveries/helm-read-path-guard.md -> PRESENT
## [OPEN] Q48 — The runtime-resolution redirect: close the class Q45's literals cannot see
status: (no Status line in queue)
evidence: recovery file recoveries/helm-runtime-redirect.md -> PRESENT
evidence: recovery file recoveries/helm-runtime-redirect.md -> PRESENT
evidence: recovery file recoveries/helm-runtime-redirect.md -> PRESENT
evidence: recovery file recoveries/helm-runtime-redirect.md -> PRESENT
## [OPEN] Q49 — The runtime-resolved root's live write path: name it, reproduce it, then close it
status: open and unclaimed. Opened by the pipe 2026-10-13
evidence: recovery file recoveries/helm-runtime-redirect.md -> PRESENT
evidence: recovery file recoveries/helm-resolved-root-live-path.md -> PRESENT
evidence: recovery file recoveries/helm-resolved-root-live-path.md -> PRESENT
evidence: recovery file recoveries/helm-probe-spawn-env.md -> PRESENT
evidence: recovery file recoveries/helm-resolved-root-live-path.md -> PRESENT
evidence: recovery file recoveries/helm-probe-spawn-env.md -> PRESENT
evidence: recovery file recoveries/helm-probe-spawn-env.md -> PRESENT
evidence: recovery file recoveries/excerpt-placement-nonmagazine-zephyrus-recompute.md -> PRESENT
evidence: recovery file recoveries/helm-runwide-census-hoist.md -> PRESENT
evidence: recovery file recoveries/helm-runwide-census-hoist.md -> PRESENT
## [OPEN] Q45 §9 follow-on — the home-directory channel *(Helm lane; Merlin)*
status: (no Status line in queue)
evidence: recovery file recoveries/helm-home-channel-guard.md -> PRESENT
evidence: recovery file recoveries/helm-home-channel-guard.md -> PRESENT
evidence: recovery file recoveries/helm-home-channel-guard.md -> PRESENT
NOTES
------------------------------------------------------------
- The queue contains duplicate headers (Q38 x2, Q37 x2, Q43 x2, and a
bare "Q39 closure" header); each occurrence is classified as it appears.
- A "RESOLVED-FALSE" ref means the short ref does not resolve here; it is
quoted back in the report, not edited away.
- SOURCE OF TRUTH: the queue text + git on this host. Nothing is invented.
+130
View File
@@ -0,0 +1,130 @@
#!/usr/bin/env python3
"""CHECK for the work-queue triage deliverable (sol).
Re-derives the classification from WORK-QUEUE.md, re-reads the report it
generated, diffs the two, and independently re-runs git rev-parse for every
ref verdict recorded in the report. Exit 0 == the report passes the check;
nonzero == wrong.
Bare command (the VERDICT):
python3 /root/.hermes/wizard-outputs/sol/verify_triage_queue.py
"""
import os
import re
import subprocess
import sys
REPO = '/root/troupe-standup'
SRC = os.path.join(REPO, 'WORK-QUEUE.md')
REPORT = os.path.join(REPO, 'wizard-work', 'sol', 'queue_triage.md')
failures = []
def check(cond, msg):
if not cond:
failures.append(msg)
def clean(s):
return ' '.join(s.split())
def parse_questions():
parts = re.split(r'\n(?=#{2,3} )', open(SRC).read())
hdr_re = re.compile(r'^(#{2,3})\s+(.*)')
out = []
for p in parts:
m = hdr_re.match(p)
if not m:
continue
header = clean(m.group(2))
if not re.match(r'^Q\d', header):
continue
body = p
sm = re.search(r'\*\*Status:\s*(.*?)\*\*', body, re.M)
out.append({'header': header, 'status': clean(sm.group(1)) if sm else '',
'body': body})
return out
def bucket(q):
s = q['status']
if re.search(r'(DONE|CLOSED|RESOLVED|VERDICT)', s):
return 'DONE'
if 'not yet opened' in q['header'].lower() or 'not yet opened' in s.lower():
return 'PROPOSED'
if 'exhausted' in s.lower() or '0/15' in s:
return 'EXHAUSTED'
return 'OPEN'
def report_entries():
entries = []
if not os.path.isfile(REPORT):
failures.append('report missing: ' + REPORT)
return entries
for line in open(REPORT):
m = re.match(r'^## \[(DONE|OPEN|PROPOSED|EXHAUSTED)\] (.*)$', line)
if m:
entries.append({'bucket': m.group(1), 'header': m.group(2).strip()})
return entries
def ref_resolves(ref):
r = subprocess.run(['git', '-C', REPO, 'rev-parse', '-q', '--verify', ref],
capture_output=True, text=True)
return r.returncode == 0
def main():
qs = parse_questions()
exp = [{'bucket': bucket(q), 'header': q['header']} for q in qs]
rep = report_entries()
check(rep == exp, 'CLASSIFY: report entries do not match queue derivation')
# summary / bucket counts
for line in open(REPORT):
if line.startswith('questions:'):
check(line.split('questions:')[1].split()[0] == str(len(qs)),
'SUMMARY: total %r != %d' % (line.split('questions:')[1], len(qs)))
for k in ('DONE', 'OPEN', 'PROPOSED', 'EXHAUSTED'):
m = re.match(r'^' + k + r'=(\d+)', line)
if m:
want = sum(1 for e in exp if e['bucket'] == k)
check(int(m.group(1)) == want, 'COUNT %s=%d want %d' %
(k, int(m.group(1)), want))
# ref verdicts re-run against git
for line in open(REPORT):
m = re.match(r'^ evidence: ref (\S+) -> (RESOLVED|RESOLVED-FALSE)$', line)
if m:
ref, verdict = m.group(1), m.group(2)
real = ref_resolves(ref)
check(verdict == ('RESOLVED' if real else 'RESOLVED-FALSE'),
'EVIDENCE ref %s = %s but git says %s' % (ref, verdict,
'RESOLVED' if real else 'RESOLVED-FALSE'))
# file-evidence sanity: every question that names a recovery file has a
# corresponding PRESENT/MISSING entry in the report
rep_text = open(REPORT).read()
for i, q in enumerate(qs):
if i >= len(rep):
break
has_named_file = bool(re.search(r'recoveries/[A-Za-z0-9_.-]+', q['body']))
has_evidence = 'evidence: recovery file' in rep_text
if has_named_file and not has_evidence:
failures.append('EVIDENCE: Q%s names a recovery file but none listed' % q['header'])
print('CHECK questions=%d failures=%d' % (len(qs), len(failures)))
if failures:
for f in failures:
print(' FAIL:', f)
sys.exit(1)
print('CHECK PASS: report matches queue derivation and all refs verified')
sys.exit(0)
if __name__ == '__main__':
main()