From d553d79e5a8344e5e865fb3542d27a3170032fef Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 03:07:28 +0000 Subject: [PATCH] =?UTF-8?q?board:=20retroactive=20hygiene=20for=20#1167/#1?= =?UTF-8?q?168=20=E2=80=94=20the=20gate-builders=20skipped=20the=20gate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both PRs added a deliverable and merged with no board entry in-commit, which is the retroactive-hygiene anti-pattern the Mandatory Board-Hygiene Rule names by that name. Recording it rather than quietly backfilling, because the subject of both PRs is making exactly this class of lapse mechanical rather than remembered. Carries the measured numbers that justify each gate's scope: the append-only gate's four verification levels including a real fire test, and the citation backlog (2314 / 37 OK / 124 DECAYED / 2153 UNVERIFIABLE) that forced line-scoping over file-scoping. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv --- .claude/board/LATEST_STATE.md | 9 +++++++++ .claude/board/PR_ARC_INVENTORY.md | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/.claude/board/LATEST_STATE.md b/.claude/board/LATEST_STATE.md index d9ba10f25..03aba79ba 100644 --- a/.claude/board/LATEST_STATE.md +++ b/.claude/board/LATEST_STATE.md @@ -1,3 +1,12 @@ +## 2026-09-04 — two mechanical board gates land, and they were shipped WITHOUT their own hygiene — INVENTORY DELTA + +- ADDED `.claude/tools/append_only_gate.py` + `.github/workflows/append-only-gate.yml` (#1167) — 8 protected board files, compared against `git merge-base` (not the raw base ref, which reports a shrink whenever the base moved ahead). Absent-at-base = new, silent; deleted = FAIL; unresolvable ref = fail closed with a `fetch-depth: 0` hint. Verified at four levels: 7 self-test cases (3 fire / 4 silent), the real git path against `b67f1958`, an END-TO-END fire test (`ISSUES.md` shortened 2591 → 2541 lines → exit 1), and the fail-closed arm (`origin/main~200` → exit 1). +- ADDED `.claude/tools/citation_decay.py` + `.github/workflows/citation-decay.yml` (#1168) — a NO-NEW-DECAY gate on `path:LINE` citations, scoped to the lines a PR actually adds. +- MEASURED backlog, which is why the scope is lines and not files: **2314 citations / 37 OK / 124 DECAYED / 2153 UNVERIFIABLE** across `.claude/plans` + `.claude/board`. File-level scoping was tried and rejected on evidence — `EPIPHANIES.md` alone carries 10 pre-existing decays and the board-hygiene rule means nearly every PR touches it, so a file-scoped gate would fire on essentially every PR. **A gate that fires on everything carries exactly as much information as one that never fires.** +- The 93% unverifiable rate is not a defect in the scanner: the house style cites bare basenames, which no scanner can resolve to a file. That is a finding about the citation convention, not about the tool. +- THREE defects were caught centrally rather than by the workers: the citation regex's lookbehind included `.`, so it could not match ANY `.claude/...` path — i.e. most of what this workspace actually cites, found only because a probe citation was silently ignored; the file-vs-line scoping above; and an `f.citing_line` / `f.cite_line` mismatch in my own filter patch. +- **VIOLATION, recorded rather than quietly fixed:** both PRs added a deliverable and shipped with NO board entry in-commit. That is exactly the retroactive-hygiene anti-pattern the Mandatory Board-Hygiene Rule names, committed by the session that was building gates to make board discipline mechanical. This commit is the retroactive fix; the fact that it was needed is the entry's point. + ## 2026-09-03 — branch: new plans must carry D-ids (the gate, not the backfill) — INVENTORY DELTA - ADDED `.claude/tools/plan_dids.py` — fails when a plan file carries no D-id. Reads the pattern out of `supersession_index.py`'s SOURCE rather than importing it: that module has no `__main__` guard, so `import` runs the whole generator and prints the index (measured — the first version did this). Hard-errors if the definition is renamed, rather than falling back to a local copy. diff --git a/.claude/board/PR_ARC_INVENTORY.md b/.claude/board/PR_ARC_INVENTORY.md index 260938024..98ea4fee9 100644 --- a/.claude/board/PR_ARC_INVENTORY.md +++ b/.claude/board/PR_ARC_INVENTORY.md @@ -1,3 +1,12 @@ +## 2026-09-04 — lance-graph PR #1167 (merged `fdc6d8a9`) + #1168 (merged `c5e84447`) — the two mechanical board gates + +- **Added:** `.claude/tools/append_only_gate.py` + `append-only-gate.yml` (#1167 — 8 protected files never shrink, merge-base comparison, fail-closed); `.claude/tools/citation_decay.py` + `citation-decay.yml` (#1168 — `path:LINE` citations, scoped to added lines only). +- **Measured:** append-only gate verified at four levels incl. a real end-to-end fire (`ISSUES.md` 2591 → 2541 → exit 1) and the fail-closed arm. Citation backlog 2314 / 37 OK / 124 DECAYED / 2153 UNVERIFIABLE — the 93% unverifiable is the bare-basename house style, not a scanner defect. +- **Locked:** line-scoping, not file-scoping — measured: `EPIPHANIES.md` alone has 10 pre-existing decays and nearly every PR touches it, so a file-scoped gate fires on everything and therefore says nothing. +- **Deferred:** the 124-decay backlog (a separate, deliberate cleanup); a convention change that would make bare-basename citations resolvable. +- **Violation:** both PRs shipped without board hygiene in-commit and are discharged retroactively here — noted because the subject of both PRs is making this class of lapse mechanical. +- **Confidence:** High on both gates (each disable-verified red-then-green); Medium on the citation gate's long-run signal, since 93% of the corpus is invisible to it. + > **⊘ TRUNCATION RESTORED (2026-08-30).** The #1081 hygiene commit > (`25b9e4c9`) destroyed this append-only file — 5876 → 32 lines — via the > destructive-prepend one-liner: `open(p, "w").write(entry + open(p).read())`