You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browse filesBrowse the repository at this point in the historyBrowse files
authored
feat(coord): read a row's own already-built declaration, at a level that decides nothing (BACKLOG #1393) (#791)
* feat(coord): land the retirement limb, reading an item's prose and not its banner (BACKLOG #1334)
Two of the three limbs were already on main. The third was written on
claude/builder-2-1334-retirement-limb at eaf6d0940 and never merged. Re-measured
before relying on it: not an ancestor of origin/main, merge-tree reports no
conflict, and zero main commits touched either file since the merge base
3760a93. The word "retire" appears zero times in both files on main, against 6
and 4 hits for "demand-gate" as a positive control, so the limb really is absent
by content and not only by ancestry.
Cherry-picked, then corrected, because the corpus moved under it. The 2026-09-03
scoring pass added a summary blockquote to every unscored row, and #1334's quotes
the retirement wording of the three rows it documents, inside the 160-character
window the prose needle allows. The limb therefore flagged #1334 itself: the
worst false positive available, because a reader stopped by the row that
describes the convention never reaches the rows it describes.
judge() reads an item's heading and its own prose and skips the banner block,
which is where a machine writes about a row rather than the row writing about
itself. Item.body_line publishes that boundary from the parser that owns it,
rather than a second definition of it beside that parser.
Level stays advise, never refuse: f349146 established that cannot-close is not
cannot-be-worked, and a retired row can still be scoped.
Measured on the live ledger, both directions. Before: #1332 and #1086 came back
with byte-identical notes. After: #1332 comes back advise and quotes its marker,
while #1086 and #1334 still come back ok.
Anti-vacuity: putting the banner back reds three arms including the live one;
dropping the heading reds the two that carry #1311; replacing the one consult
with None reds seven; swapping the prose needle for the bare word reds the
over-fire arm naming [1086, 1334, 1342].
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs(backlog): record what landed on the dispatch gate's third limb (BACKLOG #1334)
The row said the retirement limb was written but not on main. It is on this pull
request now, so the row says so, and it says what arrived with it.
Two things the note has to carry beyond "done". First, the level is advise and
not refuse, which is the row's own instruction and the reason f349146 exists.
Second, the limb went red on landing: this row's own scoring blockquote quotes
the wording of the three rows it documents, and the prose needle read that as
this row declaring itself. Reading an item's heading and prose while skipping its
banner block fixes it, and the row records that because the next reader to widen
a needle over this file will meet the same trap.
What remains is named rather than implied: the fourth banner key the row offers
as the cleaner answer is still unbuilt, nothing in the ledger declares this state
in a field, and both needles stay wording-sensitive with a live-ledger arm that
reds when the wording drifts.
The banner block is untouched. This row closes by code, so the LANDER flips it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(coord): read a row's own already-built declaration, at a level that decides nothing (BACKLOG #1393)
Four open rows say their work shipped and must not be built again -- #1107, #1130, #1183 and
#1242 -- and every field the dispatch gate reads still says buildable on all four. They stay open
because closing them is a judgement the building seat cannot make, so the ledger accumulates
done-but-open rows by construction. The verb in them is REBUILD, which no verb list matches.
judge() now reads the row's whole text and returns a fourth level, `read`, whose note opens
MUST BE READ. It quotes the sentence that fired and states that the gate read the row, not the
tree. --refuse does not block on it: refusing 35 rows would rebuild the screen #1394 records.
Measured over both ledger files: 657 items, 275 open. The needle fires on 9 rows, 7 of them open
-- the four named plus #81, #1022 and #1244 -- against 35 open rows carrying the bare words.
Two guards carry the self-reference trap. A match may not start on a `## ` heading line, because
this row's own title states the pattern as narration, and may not start after a table pipe or an
opening quotation mark, because this row's own table quotes all four sentences verbatim. Remove
either and the needle flags #1393.
The banner block is read here and deliberately is not by the #1334 retirement limb: #1242 declares
inside its banner and its prose region is two lines long. Both regions come off one
Item.body_line, so neither needle re-derives a boundary the parser owns.
Nine mutations were run, one per arm, and every one reddened.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: wshallwshall <mefordev@messagefoundry.org>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/BACKLOG.md
+51-1Lines changed: 51 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -214,7 +214,7 @@ Ordered by value descending, then difficulty ascending (cheapest first at equal
214
214
| 7 | **#1346** | The vault claim gate reads a registry that does not exist there, so it can never pass | 6 | 3 | _quick win_ | P2 | not started | Not started on the engine side, and the engine side is all I verified. scripts/coord/claim.ps1:69 anchors $repo on $PSScriptRoot and :98 derives the claims directory from git -C $repo, while scripts/hooks/claim_check.py resolves the committing tree's own git-common-dir in _claims_dir() at :170, so the engine's claim tool writes the engine registry wherever it runs; scripts/coord/install-git-hooks.ps1:86 ships claim_check.py and push_guard.py as its only payloads and :58 anchors RepoRoot on its own script, so it cannot install a writer into a second repository. I did not open the MessageFoundry-vault checkout, because CLAUDE.md limits reading that tree to roles/, so whether the vault carries its own claim.ps1 is the one fact that would change this verdict. Value 6 for a gate that cannot be satisfied exactly where it bites, with the commit-body citation as a real but gate-defeating workaround that also manufactures #1347's invisible shape B. Difficulty lowered to 3: the two-repository control arms the row calls unachievable are already buildable from _coord_checkout at tests/test_script_root_anchoring.py:103, which git-inits two independent checkouts, so the remainder is one design ruling plus a scoped change in one small tool and two tests. |
215
215
| 8 | **#1376** | the vault ships all three privileged installers and none of the three installed-vs-source parity instruments | 6 | 3 | _quick win_ | P2 | not started | Not started, and the vault-side state is worse than the filing shows. Measured today against the vault checked out beside this repo: it ships scripts/worktree/install-gate.ps1, scripts/worktree/install-selfheal.ps1 and scripts/coord/install-git-hooks.ps1 and none of tests/test_gate_installed_parity.py, tests/test_selfheal_installed_parity.py or tests/test_installed_coord_hooks.py, against a control of 526 entries in its tests/ tree. Value is above parity-with-a-clean-workaround because the vault's own copies are far adrift and nothing there reports it -- its scripts/hooks/worktree_gate.ps1 is 23,430 bytes dated 2026-07-29 against the engine's 208,171, so running the installer it ships would replace the one machine-wide gate with a July build, and its .git/hooks carries no push_guard.py and no pre-push hook at all. The engine-side workaround is real but one-sided and post-hoc: tests/test_gate_installed_parity.py:46 compares the SHARED installed gate under ~/.claude/hooks against the engine source and would go red after such an install, but tests/test_installed_coord_hooks.py:62 roots its git-hook half at the ENGINE repo, so the vault's per-repo hooks are covered by nothing. Landing it means porting about 1,960 lines into a repo that has pytest infra (pyproject.toml:221 testpaths, tests/conftest.py) but no such seam, and it is less mechanical than it looks, because the ported parity assertions would red on day one against the vault's older sources and so force a ruling on which copy is authoritative. |
216
216
| 9 | **#1385** | three merge-queue attempts on one PR failed three DIFFERENT unrelated tests, and the PR gate cannot see any of it | 6 | 3 | _quick win_ | P2 | partly shipped | Partly shipped, and more has landed since filing than the first pass credited. The visibility half is in -- .github/workflows/failure-signal.yml:71 recovers the pull request number from a merge_group ref and :92 applies ci-red, so an ejection is recorded, though nothing in this tree reads that label (grep for ci-red returns the writing workflow plus prose at CLAUDE.md:302 and docs/METHOD.md:365). The windows-2025 hang limb is no longer undiagnosed either: .github/workflows/ci.yml:852 now passes --max-worker-restart=0, landed 2026-09-02 in 042ef7ff5, and the comment from :826 to :850 reads the mechanism out of the pinned pytest-xdist and records four hangs of 25 to 46 minutes with the inner watchdogs armed, which is this row's process-level deadlock below pytest. What is left is two tests -- tests/test_api_request_timeout.py:99 still runs a route against a 0.1 second deadline, and tests/test_sqlserver_store.py:4039 is unchanged and runs at ci.yml:1772 under a wrapper that retries only a native crash (ci.yml:1769), never exit 1; the hostile-disposition test the row names was already a ratio assertion before filing (tests/test_multipart.py:142). Difficulty falls to 3 because the hard limb landed and the seams exist -- pyproject.toml:195 already ships pytest-rerunfailures and tests/test_load_failover_sqlserver.py:71 marks a sibling flaky -- with the SQL Server arm provable only on the gated CI leg. |
217
-
| 10 | **#1393** | four open rows say their work ALREADY SHIPPED and must not be rebuilt, and every dispatch screen passes them as buildable because the verb is REBUILD not BUILD | 6 | 3 | _quick win_ | P2 | not started | Not started, and I could find no body read anywhere on the dispatch path. judge() at scripts/coord/dispatch_gate.py:134 reads only item.fields at :152 to :154, the string MUST BE READ appears nowhere under scripts/, and the repo's only DO NOT REBUILD matcher is scripts/coord/claim-adjudicate.ps1:170, which adjudicates claim release rather than dispatch and so answers the opposite question. Re-running parse_items over docs/BACKLOG.md at HEAD, all four named rows (#1107, #1130, #1183, #1242) are still open, 36 open rows carry rebuild or already-shipped language on this row's own needle set, and #1020 still holds both its dead bar and the sentence retiring it. Value is a lane-window per occurrence with only the awkward workaround of reading every row, capped below 8 because this is fleet tooling with no product, PHI or deployment axis. The build is a body read, a needle set and a MUST BE READ level on one existing function plus must-fire and must-not-fire arms, and the unmerged #1334 retirement limb at eaf6d0940 already proves that seam. |
217
+
| 10 | **#1393** | four open rows say their work ALREADY SHIPPED and must not be rebuilt, and every dispatch screen passes them as buildable because the verb is REBUILD not BUILD | 6 | 3 | _quick win_ | P2 | partly shipped | Partly shipped 2026-09-03: the body read, the needle and the MUST BE READ level landed on the dispatch gate, firing on 9 rows (7 open) against 35 open rows carrying the bare words; the mirror half, #1020's expired bar, is not built. The filed state was: not started, and I could find no body read anywhere on the dispatch path. judge() at scripts/coord/dispatch_gate.py:134 reads only item.fields at :152 to :154, the string MUST BE READ appears nowhere under scripts/, and the repo's only DO NOT REBUILD matcher is scripts/coord/claim-adjudicate.ps1:170, which adjudicates claim release rather than dispatch and so answers the opposite question. Re-running parse_items over docs/BACKLOG.md at HEAD, all four named rows (#1107, #1130, #1183, #1242) are still open, 36 open rows carry rebuild or already-shipped language on this row's own needle set, and #1020 still holds both its dead bar and the sentence retiring it. Value is a lane-window per occurrence with only the awkward workaround of reading every row, capped below 8 because this is fleet tooling with no product, PHI or deployment axis. The build is a body read, a needle set and a MUST BE READ level on one existing function plus must-fire and must-not-fire arms, and the unmerged #1334 retirement limb at eaf6d0940 already proves that seam. |
218
218
| 11 | **#1398** | a row can be fully built with nothing in its text saying so, and no ledger-reading screen can detect it -- ask the tree, not the banner | 6 | 3 | _quick win_ | P2 | not started | Not started, and there is a live instance of the class. Nothing on the dispatch path asks the tree: scripts/coord/dispatch_gate.py:152 reads only banner fields, and a grep across scripts/ finds only scripts/hooks/claim_check.py:44, which matches a commit message rather than the tree, plus the citation checkers. The class is real -- #1328's remaining limb shipped at scripts/asvs/rescore_handoff_check.py:5 and both f6c96b3b1 and the f769316fa hardening are ancestors of main, while its banner still reads Filed 2026-08-22 - not started -- and I sized the population by grepping origin/main for the literal BACKLOG #N form across tests/, scripts/, messagefoundry/ and .github/: 118 of 275 open rows are cited by code that landed. Value is 6 rather than 7 because the row publishes and prices its own workaround, a per-candidate git grep costing four minutes for nine rows, which is awkward rather than absent, and because a 43 percent flag rate means the output has to be MUST BE READ rather than a verdict or it becomes the noise failure #1394 names. The build is that grep wired into the dispatch path with both controls, a known-unbuilt row returning zero and a known-built row returning nonzero. |
219
219
| 12 | **#1417** | the review gate can report success on a head nobody reviewed: it reads the label from a snapshotted event payload | 6 | 3 | _quick win_ | P2 | not started | Not started, and the defect is intact at HEAD: .github/workflows/review-gate.yml:105 still reads LABELS out of the frozen webhook payload, and line 112 still hard-codes the remedy for the single synchronize action, so any other action can report SUCCESS from a payload snapshotted before the label moved. That gate is the repository's entire automated review requirement, since .github/required-contexts.txt:160 to :166 pins approvals at 0 and states that nothing else reports that a green pull request was never read. VALUE LOWERED 7 to 6, because a workaround exists and is already written down: CLAUDE.md:407 to :414 makes the reader compare the gate run's originating createdAt against the newest reviewed label event, and CLAUDE.md:287 forbids the Lander from merging a pull request carrying no reviewed label, so a seat that reads the label live is not fooled by the stale green. It is awkward rather than clean, because the documented join is this item's rule (4) alone and returns a false clean when the label predates the head. Difficulty 3 holds: the workflow edit is small, but tests/test_merge_gate_controls.py:1044 to :1069 welds the existing control suite to the $LABELS and $ACTION env contract, so reading labels live forces a gh stub into that harness on top of the new staleness assertion. |
220
220
| 13 | **#1420** | the connscale final sample is taken after stop and drain while its docstrings call it in-hold | 6 | 3 | _quick win_ | P2 | part built | SUPERSEDED 2026-09-03 by the item's own MEASURED section: the measurement ran, fix (b) landed, and fix (a) is refused on evidence. The scoring text that follows is the pre-measurement read. Not started -- the ordering is unchanged at harness/load/connscale/runner.py:441 (sampler_stop.set), :450 (driver.stop), :451 (await_drain), :454 (sleep _SETTLE, defined at :92) and :474 (samples.append(final)), _empty_claim_rates still reads samples[0] and samples[-1] at runner.py:1153, and all five sites still call that window in-hold (report.py:119, runner.py:922, runner.py:1150, runner.py:1166, tests/test_connscale_empty_claims_per_msg.py:12). Value holds at 6 on stronger evidence than the harvest argument: the same window feeds a LIVE gate, empty_claims_base_reading at runner.py:1441, switched on at tests/test_connscale_smoke.py:110 and asserted at :539, and the post-drain tail adds empty claims with no reads, so a sign test built to fire on a dead in-hold counter can be satisfied by the tail instead. Left to build is the measurement the row refuses to pre-empt, one run per sweep cell with the final sample in and out, then either narrowing the rate window inside _build_record (runner.py:867) or correcting all five sentences. That is a measurement run plus a small additive change on an existing seam, with tests, so difficulty 3. |
@@ -16539,6 +16539,36 @@ gate on `#1332` today is told `ok` about an item whose first body line says it m
16539
16539
retirement marker in the body**. The retirement text is prose rather than a field, so this one needs a
16540
16540
body read rather than a `fields` lookup -- **or a fourth banner key, which is the cleaner answer if
16541
16541
anyone is already editing the schema.**
16542
+
16543
+
***LANDED 2026-09-03 -- ALL THREE PARTS ARE NOW ON A PULL REQUEST, AND THE THIRD ARRIVED WITH A
16544
+
DEFECT THIS ROW CAUSED.*** The first two parts (`GATED_VERDICTS`, and the `advise` branch for
16545
+
`demand-gate` and `owner-ruling`) were already on `main`. The third part was written on
16546
+
`claude/builder-2-1334-retirement-limb` at `eaf6d0940` and never merged; it is cherry-picked here.
16547
+
`judge()` takes the item's heading and prose, `load_ledger` returns them beside the fields from one
16548
+
read, and the note leads with the marker it quotes, so a reader can check the claim.
16549
+
16550
+
**The level is `advise`, never `refuse`**, for the reason this row already argues: a gated item can
16551
+
legitimately be scoped or researched, and the seat still decides.
16552
+
16553
+
**Measured against the live ledger, both directions.** Before: `#1332` and `#1086` came back with
16554
+
byte-identical notes. After: `#1332` comes back `workable` and names its marker, while `#1086` (the
16555
+
row `#1332` sends builders to) and this row still come back `ok`.
16556
+
16557
+
***THE DEFECT: THIS ROW'S OWN BANNER BROKE THE NEEDLE.*** The limb was written against `main` at
16558
+
`3760a93b`. The 2026-09-03 scoring pass then added a summary blockquote to every unscored row, and
16559
+
the one above quotes the wording of the three rows it describes -- inside the 160-character window
16560
+
the prose needle allows. So the limb flagged **this row**, the worst available false positive: a
16561
+
reader stopped here never reaches the rows this row is about. The fix reads an item's heading and
16562
+
prose and skips its banner block, which is where a machine writes *about* a row rather than the row
16563
+
writing about itself. `Item.body_line` in `scripts/docs/backlog_status_check.py` publishes that
16564
+
boundary so the gate does not re-derive it beside the parser that owns it.
16565
+
16566
+
**What remains after this merges:** the fourth banner key this row offers as the cleaner answer is
16567
+
still unbuilt, and nothing in the ledger yet declares a retirement in a field rather than in prose.
16568
+
Both needles therefore stay wording-sensitive, and `tests/test_coord_dispatch_gate.py` carries the
16569
+
live-ledger arm that goes red when the wording drifts. This row closes by `code`, so the LANDER
16570
+
flips the banner on merge.
16571
+
16542
16572
## 1335. Lane virtualenvs install five fewer extras than CI, so a lane can pass locally and fail on the runner
16543
16573
16544
16574
> 🔢 **Filed 2026-08-23 - not started.** `scripts/worktree/new.ps1:234` builds every lane virtualenv with `dev,harness` (plus `sqlserver` on a switch). CI installs `dev,harness,fhir,dicom,x12,xml,webauthn` **and** the web console package. So a lane's green suite is a strictly weaker signal than the runner's, and the gap is silent.
@@ -19119,6 +19149,26 @@ posture is not weakened. The cost is a documented opt-out that does not work as
19119
19149
> DISPATCHABLE.*** Cost if one is dispatched: **a whole lane-window spent rebuilding shipped code.**
19120
19150
>
19121
19151
> **Scored 2026-09-03 -> P2.** Value **6/10** · Difficulty **3/10** · _quick win_. Not started, and I could find no body read anywhere on the dispatch path. judge() at scripts/coord/dispatch_gate.py:134 reads only item.fields at :152 to :154, the string MUST BE READ appears nowhere under scripts/, and the repo's only DO NOT REBUILD matcher is scripts/coord/claim-adjudicate.ps1:170, which adjudicates claim release rather than dispatch and so answers the opposite question. Re-running parse_items over docs/BACKLOG.md at HEAD, all four named rows (#1107, #1130, #1183, #1242) are still open, 36 open rows carry rebuild or already-shipped language on this row's own needle set, and #1020 still holds both its dead bar and the sentence retiring it. Value is a lane-window per occurrence with only the awkward workaround of reading every row, capped below 8 because this is fleet tooling with no product, PHI or deployment axis. The build is a body read, a needle set and a MUST BE READ level on one existing function plus must-fire and must-not-fire arms, and the unmerged #1334 retirement limb at eaf6d0940 already proves that seam.
19152
+
>
19153
+
> **BUILT 2026-09-03, stacked on PR 767 (BACKLOG #1334).** `judge()` in
19154
+
> `scripts/coord/dispatch_gate.py` now reads the row's whole text -- heading, banner block and prose
19155
+
> -- for a declaration that its work is finished, and returns a fourth level, `read`, whose note
19156
+
> opens MUST BE READ and decides nothing. Measured over both ledger files at this branch's base:
19157
+
> 657 items, 275 open. **The needle fires on 9 rows, 7 of them open** -- the four named here plus
19158
+
> `#81`, `#1022` and `#1244`, each carrying the same kind of sentence -- against **35 open rows**
19159
+
> that merely contain the bare words, so it narrows by a factor of five rather than flagging an
19160
+
> eighth of the live ledger. Two guards carry the self-reference trap and tests pin both: a match
19161
+
> may not begin on a `## ` heading line, because THIS row's own title states the pattern as
19162
+
> narration, and it may not begin after a table pipe or an opening quotation mark, because THIS
19163
+
> row's own table quotes all four sentences verbatim. Remove either guard and the needle flags
19164
+
> `#1393`. The banner block is read here and deliberately is not by the `#1334` retirement limb,
19165
+
> because `#1242` declares inside its banner and its prose region is two lines long; both regions
19166
+
> come off one `Item.body_line`. Nine mutations were run, one per arm, and every one reddened.
19167
+
>
19168
+
> **STILL OPEN, and the remainder is the mirror half.** `#1020`'s expired bar is untouched: this
19169
+
> gate matches no `DO NOT BUILD` token, so it never honoured that bar, and a detector for lapsed
19170
+
> bars inside a tool that honours none would answer a question this tool does not ask. Closing this
19171
+
> row is not the building seat's call either, which is the property the row itself documents.
0 commit comments