From b4e4b1b3c6f89307840c8afaa5b10c85a14ee8eb Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Tue, 6 Oct 2026 01:10:59 +0200 Subject: [PATCH] R-426: one-register reads the leading verdict; decoys added, exemption removed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DONE/IDEA were searched over the whole state cell, so an open ROADMAP row whose state named ANOTHER row's verdict (`READY — split out after R-86 CLOSED`) escaped as shipped — R-87's shape from R-378, one file over. The gate now reads register_table.leading_verdict(state); all 28 current rows classify unchanged. Decoys: that shape (seen to PASS against the old gate), an id present in the register only as prose (seen to PASS when `have` is loosened to any mention), the existing suffix-id row; genuine: a row with a counterpart, and an `idea` row asserted BY DESIGN — R-424's hole, accepted by the operator 2026-10-05. EXEMPT drops `felhom.eu/one-register`. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS --- scripts/decoy_coverage_gate.py | 3 -- scripts/one_register_gate.py | 17 +++++++--- scripts/test_gate_decoys.py | 58 ++++++++++++++++++++++++++++------ 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/scripts/decoy_coverage_gate.py b/scripts/decoy_coverage_gate.py index 7fcfd3e5..503e1ba9 100644 --- a/scripts/decoy_coverage_gate.py +++ b/scripts/decoy_coverage_gate.py @@ -33,9 +33,6 @@ import sys # Dated 2026-09-01. This list is DEBT, not a settled state: R-426 owns it and names every entry. EXEMPT = { # felhom.eu - ("felhom.eu", "one-register"): - "R-424 — a real defect parked under state `idea` is invisible. Declared in the gate's own " - "docstring as residual hole 1; the decoy passes today.", # felhom-controller ("felhom-controller", "docker-v"): "COVERED IN THE SWEEP, not yet in a suite: an unallowlisted `-v` host path in a new Go file " diff --git a/scripts/one_register_gate.py b/scripts/one_register_gate.py index 1bda5a55..e8e6b515 100644 --- a/scripts/one_register_gate.py +++ b/scripts/one_register_gate.py @@ -21,7 +21,8 @@ WHAT THIS GATE CANNOT SEE — the residual holes, named rather than implied: 1. **A finding filed with the state `idea` escapes.** The state column is a human judgement, and a defect written under `idea` looks exactly like a proposal to this gate. It is the same shape as - the problem it fixes, one level up. + the problem it fixes, one level up. **Accepted by the operator 2026-10-05 (R-424, closed): no + mechanical fix exists; a person reads the roadmap.** test_gate_decoys.py asserts it BY DESIGN. 2. **A finding written in prose with no `R-` identifier escapes entirely.** This gate matches ids. A survey that enumerates a gap and never numbers it is invisible here — that is the previous session's sweep territory and the PROMPT-TEMPLATE rule "an enumerated gap becomes a row". @@ -45,8 +46,9 @@ ROADMAP = os.path.join(ROOT, "documentation", "backlog", "ROADMAP.md") REGISTER = os.path.join(ROOT, "documentation", "backlog", "OPEN-ITEMS.md") ROW = re.compile(r"^\|\s*\*{0,2}R-(\d+[a-z]?)\*{0,2}\s*\|") # 2026-10-03: a suffix id (R-27b, R-27c, R-50b) was skipped unchecked -# DONE and IDEA are matched against the row's STATE cell only, never the whole row: the body of a -# finding routinely contains the word "shipped" while describing something else. +# DONE and IDEA are matched against the LEADING VERDICT of the row's STATE cell only, never the whole +# row (the body of a finding routinely contains the word "shipped" while describing something else) and, +# since 2026-10-06, never the whole cell either (a state can name another row's verdict). # BANKED and PROVEN-LIVE are this project's own done-words and were found by running the gate: a row # reading "BANKED in full" or "first slice PROVEN-LIVE" is shipped work, not an open finding. DONE = re.compile(r"\b(SHIPPED|CLOSED|KILLED|DONE|SUPERSEDED|OBSOLETE|WITHDRAWN|MERGED|DISCHARGED|" @@ -77,10 +79,15 @@ def main(): have = set(rid for rid, _, _ in rows(REGISTER)) offenders, ideas, done, ok = [], 0, 0, 0 for rid, state, line in rows(ROADMAP): - if DONE.search(state): + # R-426 (2026-10-06): the LEADING VERDICT of the state cell, not the whole cell — R-378's lesson, + # one file over. A cell reading `READY — split out after R-86 CLOSED` matched DONE on the other + # row's word and the open finding escaped as shipped (and `READY — was an idea` would escape as + # an idea). Decoy: test_gate_decoys.py `one-register/done-word-about-another-row`. + verdict = register_table.leading_verdict(state) + if DONE.search(verdict): done += 1 continue - if IDEA.search(state): + if IDEA.search(verdict): ideas += 1 continue if rid in have: diff --git a/scripts/test_gate_decoys.py b/scripts/test_gate_decoys.py index c069de55..8d1f3eea 100644 --- a/scripts/test_gate_decoys.py +++ b/scripts/test_gate_decoys.py @@ -76,6 +76,9 @@ COVERS = { "out, and a version const in a new hub sub-package; a comment naming the identifier passes"), "due-checks": ("R-426: a dated check whose id survives only in prose (orphan), the due-TODAY boundary " "(and due-tomorrow, which must pass), and the block's marker named in prose (exit 2)"), + "one-register": ("R-426: an open roadmap row whose state NAMES another row's CLOSED (a live hole until " + "2026-10-06), its id only in register prose, a suffix id; genuine: a row with a counterpart, " + "and an `idea` row (R-424's accepted hole, asserted BY DESIGN)"), "hub-copy": ("R-558: an English retrieval promise in the NEW bundle (the sentences moved " "out of templates.go, so the surface list had to move with them), the same " "in Hungarian, and an INNOCENT control using the identical verbs without the " @@ -137,6 +140,26 @@ def append_to(path, extra): return _plant +def _two_appends(path_a, extra_a, path_b, extra_b): + def _plant(): + ua = append_to(path_a, extra_a)() + ub = append_to(path_b, extra_b)() + + def _clean(): + ub() + ua() + return _clean + return _plant + + +def _open_reg_first_id(): + """The first row id of the OPEN register, read at run time so the genuine article follows the file.""" + for line in io.open(os.path.join(ROOT, "documentation", "backlog", "OPEN-ITEMS.md"), encoding="utf-8"): + m = re.match(r"^\| \*\*(R-\d+[a-z]?)\*\* \|", line) + if m: + return m.group(1) + + T = os.path.join(ROOT, "hub", "internal", "web", "templates") M = os.path.join(ROOT, "manifests") REP = os.path.join(ROOT, "REPORT.md") @@ -280,12 +303,31 @@ decoy("closed-register/open-row-closed-word (BY DESIGN)", "closed_register_gate. # --- one-register (2026-10-03): an open ROADMAP row whose id carries a LETTER SUFFIX ------------ # The gate's id pattern was `R-(\d+)`, so R-27b, R-27c and R-50b were never read. Fixing it convicted -# R-50b at once — a finding that had lived only in ROADMAP.md. This decoy is that shape. (one-register -# stays in decoy_coverage_gate's EXEMPT list for R-424's hole — a finding filed under `idea` — which -# this decoy does not close.) +# R-50b at once — a finding that had lived only in ROADMAP.md. This decoy is that shape. +_ROADMAP = os.path.join(ROOT, "documentation", "backlog", "ROADMAP.md") decoy("one-register/suffix-id-row", "one_register_gate.py", - append_to(os.path.join(ROOT, "documentation", "backlog", "ROADMAP.md"), - u"\n| R-905b | **A finding filed only here.** | S | READY — 2026-10-03 | none |\n")) + append_to(_ROADMAP, u"\n| R-905b | **A finding filed only here.** | S | READY — 2026-10-03 | none |\n")) + +# R-426 (2026-10-06): the rest of the gate's decoys, which took it off the EXEMPT list. +# * done-word-about-another-row PASSED before 2026-10-06 (a live hole): DONE was searched over the whole +# state cell, so an open row whose state NAMED another row's verdict escaped as shipped. R-87's shape +# from R-378, one file over. The gate now reads the leading verdict. +# * id-only-in-register-prose: the open register MENTIONS the id but has no row for it — a label. +# * the genuine articles: an open roadmap row WITH a register row passes; and a row filed under `idea` +# passes BY DESIGN — that is R-424's hole, which the operator accepted on 2026-10-05 (no mechanical +# fix; a person reads the roadmap). Asserted so a future change to it is a decision, not a drift. +decoy("one-register/done-word-about-another-row", "one_register_gate.py", + append_to(_ROADMAP, u"\n| R-905c | **A finding filed only here.** | S | READY — split out after R-86 CLOSED | none |\n")) +decoy("one-register/id-only-in-register-prose", "one_register_gate.py", + _two_appends(_ROADMAP, u"\n| R-905d | **A finding filed only here.** | S | READY — 2026-10-06 | none |\n", + _OPEN_REG, u"\nNote: R-905d is tracked on the roadmap.\n")) +decoy("one-register/genuine-counterpart", "one_register_gate.py", + lambda: append_to(_ROADMAP, u"\n| %s | **The roadmap half of a registered finding.** | S | READY — 2026-10-06 | none |\n" + % _open_reg_first_id())(), + expect="accept") +decoy("one-register/idea-row (BY DESIGN, R-424 accepted)", "one_register_gate.py", + append_to(_ROADMAP, u"\n| R-905e | **A proposal.** | S | idea — 2026-10-06 | none |\n"), + expect="accept") # --- hub-copy: an ENGLISH retrieval promise, planted in the bundle (R-558) ----------------------- # @@ -455,11 +497,7 @@ decoy("hostinstall/comment-names-identifier", "hostinstall_gates.py", _DC_END = u"" -def _dc_live_id(): - for line in io.open(_OPEN_REG, encoding="utf-8"): - m = re.match(r"^\| \*\*(R-\d+[a-z]?)\*\* \|", line) - if m: - return m.group(1) +_dc_live_id = _open_reg_first_id def _dc_plant(row, today=None, prose=u""):