138 lines
5.2 KiB
Python
138 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Extract the work-queue index from WORK-QUEUE.md into a tab-separated table.
|
|
|
|
Real extraction from the troupe repo's single source of truth
|
|
(/root/troupe-standup/WORK-QUEUE.md). One row per UNIQUE '## Q' heading (45
|
|
blocks); the duplicate heading lines are counted via 'dup_count'. Writes
|
|
workflow.tsv and a rendered workflow.md. Prints the row count and SHA-256 so the
|
|
artifact can be re-verified later.
|
|
"""
|
|
import hashlib
|
|
import re
|
|
|
|
SRC = "/root/troupe-standup/WORK-QUEUE.md"
|
|
OUT = "/root/.hermes/wizard-outputs/ledger/workflow.tsv"
|
|
MD_OUT = "/root/.hermes/wizard-outputs/ledger/workflow.md"
|
|
|
|
q_re = re.compile(r"^## (Q\d+)") # heading id prefix
|
|
pipe_re = re.compile(r"^### Pipe verification — Run (\d+) \(([^)]*)\), (\d{4}-\d{2}-\d{2})")
|
|
closed_re = re.compile(r"closed at `([0-9a-f]{7,40})`")
|
|
done_re = re.compile(r"^\*\*Done mean?s?:\*\*", re.M)
|
|
sha_re = re.compile(r"`([0-9a-f]{7,40})`")
|
|
|
|
with open(SRC, encoding="utf-8") as fh:
|
|
lines = fh.read().split("\n")
|
|
|
|
blocks = []
|
|
current = None
|
|
pipe_count = 0
|
|
|
|
for i, line in enumerate(lines, start=1):
|
|
head = q_re.match(line.strip())
|
|
if head:
|
|
# Close the previous block, start a new one.
|
|
if current is not None:
|
|
current["pipe_runs"] = pipe_count
|
|
blocks.append(current)
|
|
qid = head.group(1)
|
|
rest = line[head.end():].strip()
|
|
# The heading is "## Q<n> — Title *(meta)" or a §-variant. The meta is the
|
|
# trailing "*(...)" wrapper: find the LAST "*(" (the title may contain its
|
|
# own parens). The wrapper's "*(" also lives next to a literal "*" in the
|
|
# content, so a plain "([^*]*)" capture is not safe.
|
|
kw = rest.rfind("*(")
|
|
if kw != -1:
|
|
title = rest[:kw].strip()
|
|
title = title.lstrip(" \t\u2014\u2013\u2022\u003a\u2013")
|
|
open_paren = kw + 1 # position of "("
|
|
depth = 1
|
|
j = open_paren + 1
|
|
while j < len(rest) and depth > 0:
|
|
if rest[j] == "(":
|
|
depth += 1
|
|
elif rest[j] == ")":
|
|
depth -= 1
|
|
j += 1
|
|
meta = rest[open_paren + 1:j - 1]
|
|
else:
|
|
title = rest.lstrip(" \t\u2014\u2013\u2022\u003a\u2013")
|
|
meta = ""
|
|
current = {
|
|
"q_id": qid,
|
|
"heading_line": i,
|
|
"title": title,
|
|
"meta": meta,
|
|
"has_done": False,
|
|
"has_closure": False,
|
|
"pipe_runs": 0,
|
|
"closure_sha": None,
|
|
"sha_refs": 0,
|
|
}
|
|
pipe_count = 0
|
|
continue
|
|
|
|
if current is None:
|
|
continue # not a heading, and not inside a block -> ignore
|
|
|
|
# Per-line evidence detection for the block currently open.
|
|
if pipe_re.match(line.strip()):
|
|
pipe_count += 1
|
|
if done_re.search(line):
|
|
current["has_done"] = True
|
|
if "closed at `" in line:
|
|
current["has_closure"] = True
|
|
cm = closed_re.search(line)
|
|
if cm and current["closure_sha"] is None:
|
|
current["closure_sha"] = cm.group(1)
|
|
current["sha_refs"] += len(sha_re.findall(line))
|
|
|
|
if current is not None:
|
|
current["pipe_runs"] = pipe_count
|
|
blocks.append(current)
|
|
|
|
# Deduplicate by q_id; first occurrence is canonical. 'dup_count' = how many
|
|
# extra heading lines carried the same q_id (all of them have 1).
|
|
from collections import Counter
|
|
|
|
counts = Counter(b["q_id"] for b in blocks)
|
|
seen = set()
|
|
rows = []
|
|
for b in blocks:
|
|
if b["q_id"] in seen:
|
|
continue
|
|
seen.add(b["q_id"])
|
|
b["dup_count"] = counts[b["q_id"]] - 1
|
|
rows.append(b)
|
|
|
|
COLS = ["q_id", "heading_line", "title", "meta", "dup_count",
|
|
"has_done", "has_closure", "pipe_runs", "closure_sha", "sha_refs"]
|
|
|
|
def tsv_row(b):
|
|
return "\t".join([
|
|
b["q_id"], str(b["heading_line"]), b["title"], b["meta"], str(b["dup_count"]),
|
|
str(int(b["has_done"])), str(int(b["has_closure"])), str(b["pipe_runs"]),
|
|
b["closure_sha"] or "none", str(b["sha_refs"]),
|
|
])
|
|
|
|
out = "\n".join(["\t".join(COLS)] + [tsv_row(b) for b in rows]) + "\n"
|
|
with open(OUT, "w", encoding="utf-8") as fh:
|
|
fh.write(out)
|
|
|
|
digest = hashlib.sha256(out.encode("utf-8")).hexdigest()
|
|
with open(MD_OUT, "w", encoding="utf-8") as fh:
|
|
fh.write("# Work-queue index (extracted from WORK-QUEUE.md)\n\n")
|
|
fh.write("Extracted rows: " + str(len(rows)) + " unique blocks "
|
|
"(" + str(len(rows) + sum(b["dup_count"] for b in rows)) + " heading lines; "
|
|
+ str(sum(b["dup_count"] for b in rows)) + " duplicate heading lines).\n\n")
|
|
fh.write("| q_id | heading_line | title | meta | dup_count | has_done | has_closure | pipe_runs | closure_sha | sha_refs |\n")
|
|
fh.write("|---|---|---|---|---|---|---|---|---|---|\n")
|
|
for b in rows:
|
|
fh.write("| {qid} | {line} | {title} | {meta} | {d} | {h} | {c} | {pr} | {sha} | {s} |\n".format(
|
|
qid=b["q_id"], line=b["heading_line"], title=b["title"], meta=b["meta"],
|
|
d=b["dup_count"], h="1" if b["has_done"] else "0",
|
|
c="1" if b["has_closure"] else "0", pr=b["pipe_runs"],
|
|
sha=b["closure_sha"] or "none", s=b["sha_refs"]))
|
|
fh.write("\n")
|
|
|
|
print("rows={n} sha256={digest}".format(n=len(rows), digest=digest))
|