Files
troupe-standup/wizard-work/ledger/workqueue-census-v2/extract_workqueue.py
T
volt 926f9a1c59 volt: pin the workqueue census to its source (Q135)
The census was red at HEAD (96 rows vs 97 headings), named its source by
absolute host path, and decided its verdict from the worktree at read time.
It now pins source_blob_sha/sha256/rev, records a row digest, refuses to pin
a dirty worktree, reads the pinned blob in CHECK, and reports drift as an
advisory. 9 selftest cells; the non-decay claim is measured on real commits.
2026-10-31 09:44:40 +00:00

278 lines
10 KiB
Python

#!/usr/bin/env python3
"""Corrected, complete census of every numbered work-queue (Q) item.
Extract lane: data extraction and tables. One row per "## Q<n> ..." heading in
WORK-QUEUE.md, built from the source with a real parser and verified by an
INDEPENDENT re-derivation in CHECK (the old census's CHECK re-imported its own
extractor, so it could never fail; that is the fault this version removes).
Output (all in this directory):
workqueue-census.tsv one row per Q heading, tab-separated
workqueue-census.md markdown table of the same rows
extract_manifest.json schema + counts + provenance (extracted_at_utc = NOW)
README.md documentation for this artifact
CHECK real verification (independent re-derivation)
Provenance (Q135, 2026-10-31). The manifest used to name its source by
absolute host path (`/root/troupe-standup/WORK-QUEUE.md`), which is the
Q69/Q106/Q109 host-pin class, and it carried no pin to the bytes it read, so
the artifact's own rows could not be re-derived by anyone who reads it after
the queue has moved on. It now records:
* source repo-relative path (`WORK-QUEUE.md`), never a host path
* source_rev `git rev-parse HEAD` at generation
* source_blob_sha `git rev-parse HEAD:WORK-QUEUE.md` -- the pinned bytes
* source_sha256 sha256 of the bytes actually read
* source_lines line count of those bytes
* row_digest sha256 of the emitted TSV data rows
The pin is honest or the extractor refuses. If the worktree's WORK-QUEUE.md
differs from the HEAD blob, this exits 1 and writes nothing, because a pin to
a blob that does not contain the rows in the TSV is a false provenance claim;
`--allow-dirty` writes the snapshot anyway and records `source_blob_sha: null`
with `source_matches_head_blob: false`, so CHECK grades the worktree bytes and
says so.
Conventions
-----------
* A row is created for every line matching '## <Qnum> ...' where the '<Qnum>' is
'Q' followed by digits (continuation labels such as 'closure', 'section 9
follow-on', 'verified', 'claimed' are kept verbatim in the title).
* q : the label 'Q<num>' (dupes kept as separate rows).
* title : verbatim heading text after '## <Qnum>' (trimmed).
* status : the first '**Status:' line in the block, whitespace collapsed,
truncated at the first sentence end, single trailing period;
empty when no such marker precedes the next heading.
* done_implies : the first '**Done means:' line in the block, trimmed; empty
when no such marker precedes the next heading.
"""
import hashlib
import json
import os
import re
import subprocess
import sys
from datetime import datetime, timezone
HERE = os.path.dirname(os.path.abspath(__file__))
REPO_ROOT = os.path.abspath(os.path.join(HERE, "..", "..", ".."))
SRC = os.path.join(REPO_ROOT, "WORK-QUEUE.md")
OUT = HERE
# '## Q' + digits, then anything (heading title begins). Captures Q1..Q98
# headings, including continuation/closure labels that follow the number.
HEADING_RE = re.compile(r"^##\s+Q(\d+)(.*)$")
STATUS_RE = re.compile(r"^\*\*Status:\s*(.*)$")
DONE_RE = re.compile(r"^\*\*Done means:\s*(.*)$")
def _sentence(s):
s = re.sub(r"\s+", " ", s).strip()
m = re.search(r"\.\s", s)
if m:
s = s[: m.start()] + "."
if s.endswith("."):
s = s[: -1]
return s + "."
def split_blocks(lines):
"""Return list of dicts: idx (heading line number), qid, title, body.
A 'block' is the heading line plus the following lines up to (but not
including) the next '## Q<n>' heading line.
"""
blocks = []
current = None
for i, line in enumerate(lines):
m = HEADING_RE.match(line)
if m:
if current is not None:
blocks.append(current)
current = {
"line": i,
"qid": "Q" + m.group(1),
"title": m.group(2).strip(),
"body": [],
}
else:
if current is not None:
current["body"].append((i, line))
if current is not None:
blocks.append(current)
return blocks
def derive(block):
status = ""
done_implies = ""
for _, line in block["body"]:
if status == "":
sm = STATUS_RE.match(line)
if sm:
status = _sentence(sm.group(1))
if done_implies == "":
dm = DONE_RE.match(line)
if dm:
done_implies = dm.group(1).strip()
return status, done_implies
def extract(lines):
rows = []
for block in split_blocks(lines):
status, done_implies = derive(block)
rows.append(
{
"q": block["qid"],
"title": block["title"],
"status": status,
"done_implies": done_implies,
"line": block["line"] + 1,
}
)
return rows
def _sha256(data):
return hashlib.sha256(data).hexdigest()
def _git(args, cwd):
"""Run git, returning stdout stripped, or None when git or the object is absent."""
try:
proc = subprocess.run(["git", "-C", cwd] + args,
capture_output=True, text=True)
except OSError:
return None
if proc.returncode != 0:
return None
return proc.stdout.strip()
def pin_source(repo_root, raw):
"""Return (provenance dict, error). The pin is the HEAD blob or a refusal."""
blob_sha = _git(["rev-parse", "HEAD:" + "WORK-QUEUE.md"], repo_root)
rev = _git(["rev-parse", "HEAD"], repo_root)
if blob_sha is None or rev is None:
return None, ("cannot read WORK-QUEUE.md at HEAD (git missing, not a "
"repository, or the path is untracked) -- pass "
"--allow-dirty to snapshot the worktree instead")
try:
blob = subprocess.run(["git", "-C", repo_root, "cat-file", "blob", blob_sha],
capture_output=True)
except OSError:
return None, "git cat-file is unavailable -- pass --allow-dirty"
if blob.returncode != 0:
return None, "cannot read blob %s -- pass --allow-dirty" % blob_sha
if _sha256(blob.stdout) != _sha256(raw):
return None, ("the worktree's WORK-QUEUE.md is not the HEAD blob (%s): "
"commit it first, or pass --allow-dirty to snapshot the "
"worktree and record that the pin is absent" % blob_sha[:12])
return {"source_rev": rev, "source_blob_sha": blob_sha,
"source_matches_head_blob": True}, None
USAGE = """usage: extract_workqueue.py [--allow-dirty]
(no flag) pin the source to the HEAD blob; refuse (rc 1) if the
worktree's WORK-QUEUE.md is not that blob
--allow-dirty snapshot the worktree anyway; the manifest records
source_blob_sha: null and source_matches_head_blob: false
-h, --help this text
Writes workqueue-census.tsv, workqueue-census.md and extract_manifest.json to
this directory. Exit 0 clean, 1 refused (source not pinned and not allowed to
be dirty), 2 usage error.
"""
def main():
argv = sys.argv[1:]
unknown = [a for a in argv if a not in ("--allow-dirty", "-h", "--help")]
if unknown:
print("usage error: unknown argument(s) %r" % unknown, file=sys.stderr)
print(USAGE, file=sys.stderr)
return 2
if "-h" in argv or "--help" in argv:
print(USAGE)
return 0
allow_dirty = "--allow-dirty" in argv
with open(SRC, "rb") as fh:
raw = fh.read()
lines = raw.decode("utf-8").splitlines()
prov, err = ({"source_rev": None, "source_blob_sha": None,
"source_matches_head_blob": False}, None)
if not allow_dirty:
prov, err = pin_source(REPO_ROOT, raw)
if err is not None:
print("REFUSED: " + err, file=sys.stderr)
return 1
else:
prov["source_rev"] = _git(["rev-parse", "HEAD"], REPO_ROOT)
assert prov is not None
rows = extract(lines)
tsv_path = os.path.join(OUT, "workqueue-census.tsv")
md_path = os.path.join(OUT, "workqueue-census.md")
json_path = os.path.join(OUT, "extract_manifest.json")
data = "".join(
f"{r['q']}\t{r['title']}\t{r['status']}\t{r['done_implies']}\n" for r in rows
)
with open(tsv_path, "w", encoding="utf-8") as fh:
fh.write("q\ttitle\tstatus\tdone_implies\n")
fh.write(data)
distinct = sorted({r["q"] for r in rows})
reopened = sorted(q for q in distinct if sum(1 for r in rows if r["q"] == q) > 1)
with open(md_path, "w", encoding="utf-8") as fh:
fh.write("# Work queue census v2 (extract lane)\n\n")
fh.write(
"One row per '## Q<n> ...' heading in WORK-QUEUE.md. Extracted from "
f"{len(rows)} headings; {len(distinct)} distinct q labels; "
f"{len(reopened)} reopened ({', '.join(reopened)}). "
"extracted_at_utc is the measurement moment, not a constant.\n\n"
)
fh.write("| q | title | status | done_implies |\n")
fh.write("|---|---|---|---|\n")
for r in rows:
fh.write(f"| {r['q']} | {r['title']} | {r['status']} | {r['done_implies']} |\n")
manifest = {
"schema": "workqueue-census-v2",
"source": "WORK-QUEUE.md",
"source_rev": prov["source_rev"],
"source_blob_sha": prov["source_blob_sha"],
"source_matches_head_blob": prov["source_matches_head_blob"],
"source_sha256": _sha256(raw),
"source_lines": len(lines),
"rows": len(rows),
"columns": ["q", "title", "status", "done_implies"],
"row_digest": _sha256(data.encode("utf-8")),
"distinct_q_labels": len(distinct),
"reopened_q_labels": reopened,
"extracted_at_utc": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
"generated_by": "extract_workqueue.py",
"verification": "CHECK (independent re-derivation, does not import extractor)",
}
with open(json_path, "w", encoding="utf-8") as fh:
json.dump(manifest, fh, indent=2)
print(f"rows: {len(rows)}")
print(f"distinct labels: {len(distinct)}; reopened: {reopened}")
print(f"source pin: rev={prov['source_rev']} blob={prov['source_blob_sha']}"
if prov["source_blob_sha"] else
"source pin: ABSENT (--allow-dirty; the manifest says so)")
print(f"written: {tsv_path}, {md_path}, {json_path}")
return 0
if __name__ == "__main__":
sys.exit(main())