docs(backlog): consolidate eight ledger filings into one PR (BACKLOG #1436, #1441, #1444, #1450, #1457, #1458, #1459, #1460, #1461) - #940
Conversation
…t (BACKLOG #1436) A Builder reported the leak gate flags any bare six-digit number as a site code. Measured at 46ea10a: it does not. _ESTATE_ID_SHAPE needs an underscore-joined identifier and matches 0 of 2,038 tracked files; _SITE_CODE_FILE fires only when the leading digits match a loaded [site_prefix], of which two load. The gate as configured flags 0 lines of the tracked tree. Four narrowings were tested against 12 realistic site codes built on the shipped synthetic prefix. All four miss at least one; the underscore anchor misses 8 and only re-derives a detector that already ships. Verdict: change no detector. Scope left open is one paragraph in CONTRIBUTING.md correcting the mental model. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…(BACKLOG #1444) A scoring pass is a SNAPSHOT. Nothing in CI requires a value or difficulty at filing time, so the gap re-opens as fast as items are filed. Measured 2026-09-04 against main at 685d4f5: 278 open items, 5 with no score -- #1424, #1427, #1429, #1430, #1439 -- every one filed 2026-09-03. PR 754 closed this to zero on 2026-09-03, so the gap went 0 to 5 in about a day. Re-measured here with parse_items rather than a hand-rolled scan, against the reporting seat's figures; both the count and the exact five item numbers agreed. Filed as a DECISION rather than a defect. The items are correct: #1427's own banner states that value and difficulty belong to a scoring pass. So moving the gate to filing time needs a ruling before it needs code, and would red on the five existing items on day one -- unshippable without a grandfather baseline, the same shape as #1435. Re-running the pass keeps the convention but is unbounded work with no set cadence. Scoring the current five would not settle it. That is another snapshot, and it decays the same way. The item carries its own score, so it is not an instance of itself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e CLI subcommands logging.lastResort carries filters=[] and formatter=None. Two of the CLI's 32 subcommands install a root handler (serve, supervise); the other 30 run with an empty root handler list, so their WARNING+ records reach stderr through lastResort and bypass the three filters _install_phi_filters puts on every configured handler. Measured with paired controls: a real `messagefoundry backup` run holds root.handlers == [] throughout and loads 18 WARNING+ traceback sites; the same record with configure_logging first comes out PID|[redacted]. Measured at 46ea10a and re-verified at a2eef0f, because main moved 58 commits in between and both measured files changed. The counts are unchanged. #1199's fix landed as 99887f5 (PR 820) in that window; it is per-logger, never appears in __main__.py, and does not close this gap. Files the item only. No fix: the item weighs both candidate remedies and records that remedy (1) empties caplog for the 6 test files that use it, of 40 asserting on captured CLI output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ey-1cb72a # Conflicts: # docs/BACKLOG.md
…rom the file it guards (BACKLOG #1450) The detector exists. scripts/ci/check_required_contexts_drift.py reads the public branches endpoint and set-compares it to the checked-in file, as the job `the required-contexts file matches the server`. Neither .github/required-contexts.txt nor tests/test_required_contexts.py names it, so two readers in one night read those files and concluded the drift was undetectable. One of them briefed this item as a structural impossibility. Measured 2026-09-04, each reading with a positive control: server 13 contexts on both endpoints, file 14, pin 14. The drift job carries no continue-on-error, is not a required context, and is paths-filtered on pull_request, so a server-side change reaches only its 07:00 UTC cron on main, which notifies nobody. Recommends AGAINST a live-API arm in the pytest suite: that suite sits inside a required leg and runs offline and on fork PRs, so a fail-closed network call there would red every PR on an API blip. The gap is routing, not detection. The reconciliation itself is PR 884; this Builder stood down on it after the collision registry flagged the overlap. No file in that diff is touched here. The one thing 884 leaves stale is named in the item. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…main stale (BACKLOG #1450) The item said the guard's paths-filtered pull_request trigger means it does not run on an ordinary PR, so a server-side change is invisible to every merge path. The first half is right and the conclusion is wrong. A PR that touches those paths DOES fire it. Measured on PR 884: run created 2026-09-04T23:55:21Z, event=pull_request. What actually stops it reporting the drift is the checkout. The job runs actions/checkout with no ref:, so on a pull_request event it reads the file as that PR has it and compares against the live server. 884 compares 13 against 13 and passes. The run validates a fix; it cannot report that main is stale. "No pull request triggers it" is falsifiable and false. "No pull-request run can see the drift on main" is true and stronger. Caught by the Lander on review of the ledger entry. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Resolved by the Lander. One hunk, and it is the ledger tail serialising: this branch appends #1436, main appended #1434. Different items, so both sides stand. Main's block keeps the position it holds on main and #1436 follows it, which leaves the next merge of this file less to reconcile. Set-difference control over item numbers: nothing lost, nothing invented, 430 = main's 429 plus #1436. #1069 is absent because main archived it at 7f97202. Three items whose status differs from this branch (#1389, #1392, #1439) follow main; this branch's own diff touches none of them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Resolved by the Lander. The ledger tail serialising: this branch appends its item, main appended another. Different items, so both sides stand, with main's block in the position it holds on main. Set-difference control over item numbers: nothing lost, nothing invented, no duplicate headings. #1069 is absent because main archived it at 7f97202, not because this merge dropped it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Resolved by the Lander. The ledger tail serialising: this branch appends its item, main appended another. Different items, so both sides stand, with main's block in the position it holds on main. Set-difference control over item numbers: nothing lost, nothing invented, no duplicate headings. #1069 is absent because main archived it at 7f97202, not because this merge dropped it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Resolved by the Lander. The ledger tail serialising: this branch appends its item, main appended another. Different items, so both sides stand, with main's block in the position it holds on main. Set-difference control over item numbers: nothing lost, nothing invented, no duplicate headings. #1069 is absent because main archived it at 7f97202, not because this merge dropped it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…G #1457) Dependabot #891 bumped zizmor 1.29.0 to 1.30.0. That release added the `self-repository` audit, which fires one LOW on cla.yml:102 and exits 12. The gate ran on the bump PR and was merged past. Run 33945900593 reported `1 low, 0 medium, 0 high` and exit code 12 at 04:57:02Z; #891 merged at 21:02:26Z. Not a bypass: zizmor is not among the thirteen required contexts, auto-merge was null, and nobody was obliged to stop. Measured on main's own inputs rather than on main: PR 901's zizmor run executed main's pinned 1.30.0 against main's cla.yml blob, which is byte-identical across both, and reported the same finding. Main's last zizmor run predates the bump, so its next scheduled run is the reading that closes the loop. The item deliberately does not name a fix. zizmor's suggested `$/` syntax was not verified against GitHub's documentation, and cla.yml carries a required context on a pull_request_target workflow that the PR changing it cannot test -- the deadlock PR 621 already paid for once. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…rites Value 4, difficulty 3, fill-in, P3, verdict build. Scored at filing. scripts/hooks/usage-headroom-inject.ps1:224 reads latest.json out of the state directory, and that file exists on NONE of the six config roots on this machine, so the injection resolves to "UNKNOWN -- no data" on every spawn it fires for. Observed six times in one session, on every Workflow launch. MEASURED WITH A POSITIVE CONTROL, because an absence needs one. A find for latest.json across every root returns zero; the same sweep for status.json returns three. So the search works and the absence is real rather than a broken pattern. The hook's own header at :10 says the collector IS a statusLine that writes that file, so it appears only where that statusLine runs, and on this machine that is nowhere. VALUE 4 AND NOT 6, which is the judgment in this row. The band-6 shape here is an instrument whose silence looks like success. This one is the opposite and says so in its own output: "UNKNOWN is not zero headroom and it is not full headroom. It is no measurement." An instrument that announces its own blindness is degraded, not deceptive. The row argues that down explicitly and invites the counter-argument rather than asserting the band. IT IS ONE HALF OF A PAIR. #1406 records that the hook never fires on the path that spends most -- a Console spawns a Builder through a Bash(claude:*) grant, which no tool-name matcher can select, and test_claude_settings_contract.py asserts no matcher wiring this hook may select it. So #1406 is "does not fire where it matters most" and this row is "where it does fire, it has nothing to read". Fixing either alone leaves the instrument useless, and neither should be closed on the strength of the other. Both statements are in the row. Number allocated with scripts/coord/alloc.ps1 from this worktree, never picked by reading the file. Appended at the tail, so it conflicts with other ledger work only as an append. Verified: backlog_status_check green (671 items, one status each), the row parses open with all three banner fields and no duplicate, and the status, citation and ledger test legs pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…lity contradicts ADR 0052 AC-2 At [sandbox].mode=subprocess the engine holds one persistent worker tree per traffic-carrying inbound: spawned lazily, never evicted, with no pool and no cap. Per connection that is a process tree, two daemon threads, three pipe fds and a Windows job-object handle -- the resource class AC-2 names, needing no multiplication to see. It also records why the 74 GiB total is retracted: the multiplier counts connections rather than inbounds, linearity was never measured (all five result JSONs record one worker tree), and resident set is bounded by installed RAM. The per-worker figures stand; the scaled framing did not. Scored 6/10 value, 7/10 difficulty, big bet, P2, verdict research -- two candidate shapes, and the row deliberately chooses neither. #1278's block is left untouched: PR 879 is rewriting it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…d seats Two constants carry stale seat assignments, and neither is fixed here. CLOSING_SEAT at scripts/docs/backlog_status_check.py:122 names the ASVS Tracker, the Liaison and the Dispatcher. GATED_VERDICTS at scripts/coord/dispatch_gate.py:160 independently names two of them, so correcting one constant leaves the other emitting. Measured over 670 ledger rows, 132 get a dispatch reason naming a retired seat. A fourth value is a wrong assignment rather than a dangling name: CLOSING_SEAT["code"] tells a Builder the Lander flips the banner, while backlog-hygiene.yml demands the ledger edit of that Builder's own PR. #1461 is the vault half. Three role playbooks hold the same old assignment, including BUILDER.md:216 forbidding the Builder the edit CLAUDE.md:286 assigns it. That is a write outside this repository, so the Lander performs it and needs no owner approval. Filed, not fixed. The 97-row scorecard-rescore value needs PR 929 on main first. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…#1436) Merge of PR 834 into the Lander batch. Rows are re-applied onto main's current file rather than taking the branch's whole ledger, which is eight commits stale and would silently revert #1426, #1440, #1454, #1455 and #1456. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…#1444) Merge of PR 838. #1436 now sits on HEAD from the previous merge, which is the case PR 905 added to the ledger gate: a merge commit has two parents and the gate read only MERGE_HEAD. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…#1441) Merge of PR 850. Rows re-applied onto the accumulated file, never the branch's whole ledger. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…#1450) Merge of PR 886. Rows re-applied onto the accumulated file, never the branch's whole ledger. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…#1457) Merge of PR 903. Rows re-applied onto the accumulated file, never the branch's whole ledger. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…#1459) Merge of PR 925. Rows re-applied onto the accumulated file, never the branch's whole ledger. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…#1458) Merge of PR 926. Rows re-applied onto the accumulated file, never the branch's whole ledger. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…#1460) Merge of PR 936. Rows re-applied onto the accumulated file, never the branch's whole ledger. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
This pull request is green and nobody has marked it read. Every check that has reported is passing and the To clear it, IN THIS ORDER:
DO NOT TRIAGE THIS FROM A seat can find every pull request in this state in one call: The |
Consolidates eight ledger-only pull requests into one, so nine filings cost one merge cycle instead of eight.
Supersedes and closes: #834 (#1436), #838 (#1444), #850 (#1441), #886 (#1450), #903 (#1457), #925 (#1459), #926 (#1458), #936 (#1460, #1461).
Why one PR and not eight
Every merge invalidates every other open pull request, because branch protection is
strict. Eight ledger filings that each append todocs/BACKLOG.mdare therefore eight serial cycles, and each one re-dirties the other seven. Consolidating removes seven of those cycles. Nothing about the rows themselves changes.How it was built, and the trap it avoids
Each branch was merged, not cherry-picked, so every number arrives carried by a real merge parent -- which is what the exemption in
ledger_check.pygrandfathers. Cherry-picking would strip that parentage and the gate would refuse each number as a fresh allocation by a worktree that does not own it.Each merge re-applies only that branch's own
## N.sections onto the accumulated file. It never takes a branch's whole ledger. That matters: measured before building, all eight branches are stale enough that taking any one wholesale would have silently reverted#1426,#1440,#1454,#1455and#1456. All five are asserted present below.This is also the first real exercise of #905. Merge two refused before that landed, with
BLOCKED: BACKLOG item #1436 was not allocated to this worktree, because#1436had arrived from PR 834 ontoHEADand the gate read onlyMERGE_HEAD. It passes now.Verification
Run locally before pushing, with all commit hooks active. No
--no-verifywas used at any point.docs/BACKLOG.mdonly## N.headings removed#1426,#1440,#1454,#1455,#1456scripts/docs/backlog_status_check.pyscripts/hooks/ledger_check.py --ciThe one advisory warning is pre-existing:
#1426is open and carries no value or difficulty score. That is advisory by owner ruling (BACKLOG #1455) and never fails the gate.What a reviewer should check
That the nine rows are the ones the eight superseded pull requests each filed, and nothing else moved.
git diff origin/main...on this branch shows additions only.🤖 Generated with Claude Code