sol: triage work-queue classification with evidence cross-check
This commit is contained in:
1 parent
c36b158fbc
commit
d5a35e1f44
5 files changed
+2070
No files matched your search
@@ -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'))
|
||||
@@ -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
@@ -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.
|
||||
@@ -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()
|
||||
Reference in new issue
Block a user