diff --git a/scripts/wake-digest.py b/scripts/wake-digest.py index 3fb9e88..490fa40 100755 --- a/scripts/wake-digest.py +++ b/scripts/wake-digest.py @@ -132,17 +132,44 @@ def sec_pause(): return newest, span +def ruled_pendings(reviewed_text): + """ + The set of PENDING ids that rulings actually DISPOSE OF. + + Resolved by the PENDING each ruling NAMES in its header, never by the REVIEWED + number. Those numbering sequences have drifted apart: REVIEWED-84 rules on + PENDING-87. Matching on the number alone suppressed PENDING-84 from the wake + digest on the very morning the steward's pulling thread pointed at it, and + closing that item later produced no visible change because it had never been + counted. Measured at the time: 9 suppressed, 8 correctly, 1 falsely. + + A ruling whose header names no PENDING (REVIEWED-78, -81, -82 …) suppresses + nothing. + + The correction runs in BOTH directions, and an earlier draft of this docstring + claimed otherwise — that it could only ever surface more, never fewer. That was + an overclaim, caught by the change proof rather than by reading. Measured against + the live files at the time of the fix: 3 items surfaced that had been falsely + hidden (PENDING-78, -81, -82 — like-numbered rulings exist, concerning other + matters), and 2 stopped being shown that were genuinely ruled (PENDING-87 by + REVIEWED-84, PENDING-88 by REVIEWED-85 — no REVIEWED-87 or -88 exists, so the + number-match had never suppressed them). Net 18 → 19 visible. Number-matching + was wrong in both directions; only subject-matching is right in either. + """ + return set(re.findall(r"^## REVIEWED-\S+\s*—\s*PENDING-(\S+?)\s*—", reviewed_text, re.M)) + + def sec_pending(): t = read(PENDING) if t is None: warn.append("PENDING.md unreadable") return [] rt = read(REVIEWED) or "" - rev = {m for m in re.findall(r"^## REVIEWED-(\S+)", rt, re.M)} + ruled = ruled_pendings(rt) items = [] for h, ln in open_items(t): m = re.match(r"PENDING-(\S+?)\s*—", h) - if m and m.group(1) in rev: + if m and m.group(1) in ruled: continue items.append((h, ln, tag_of(t, h))) if not items: @@ -452,6 +479,16 @@ def selftest(): chk("tag_of reads a tag", tag_of("## PENDING-9 — t\n**Date:** d\n**Tag:** [ESCALATE]\n", "PENDING-9 — t") == "[ESCALATE]") chk("tag_of returns '' when absent", tag_of("## PENDING-9 — t\n", "PENDING-9 — t") == "") + chk("ruled_pendings resolves by the NAMED pending, not the REVIEWED number", + ruled_pendings("## REVIEWED-84 — PENDING-87 — Order attestation") == {"87"}) + chk("ruled_pendings does NOT suppress the like-numbered item [the 2026-08-01 bug]", + "84" not in ruled_pendings("## REVIEWED-84 — PENDING-87 — Order attestation")) + chk("ruled_pendings ignores a ruling that names no PENDING", + ruled_pendings("## REVIEWED-82 — Read-only MCP server: eyes on the substrate") == set()) + chk("ruled_pendings handles non-numeric families", + ruled_pendings("## REVIEWED-9 — PENDING-S2 — hook-aware deposit") == {"S2"}) + chk("ruled_pendings returns empty on empty input [positive control]", + ruled_pendings("") == set()) chk("extract_anchor pulls verbatim", extract_anchor("noise\n**PULLING THREAD:** do the thing.\n\nmore", "PULLING THREAD") == "do the thing.")