Skip to content

docs(gate): record the ledger-gate coupling where someone can BREAK it, not only where it is relied on - #228

Merged
wshallwshall merged 3 commits into
mainfrom
claude/gate-ledger-coupling-note
Aug 6, 2026
Merged

docs(gate): record the ledger-gate coupling where someone can BREAK it, not only where it is relied on#228
wshallwshall merged 3 commits into
mainfrom
claude/gate-ledger-coupling-note

Conversation

@wshallwshall

Copy link
Copy Markdown
Collaborator

Records a load-bearing coupling where someone can break it, not only where it is relied on. Comment only -- 18 lines added, zero non-comment lines, no behaviour change.

What was missing, which is narrower than it first appeared

ledger_check.py's owns() authorises a ledger number by comparing the worktree that allocated it -- and that only works because the worktree gate forces each session into its own. docs/LEDGER-GATE.md:185 documents that pairing from the dependent's side, ending "The two gates are a pair."

The gate file itself said nothing about it. And the reason it was easy to miss is measurable: "ledger" appears seven times in worktree_gate.ps1, and every one is the opposite relationship -- rule 3c refusing a core.hooksPath repoint, rule 1b refusing a write to alloc/, the pre-commit protection. All of them are this hook protecting the ledger gate's inputs. The dependency runs the other way: owns() relies on rule 1's scope, not on its protection.

Seven mentions of the inverse relationship is precisely why the real one went unrecorded -- including by the author of several of those seven.

Why a comment, and not an item, and not a test

Breaking this does not look like breaking a gate. Widening what rule 1 governs disarms no hook and fails no test. It simply turns owns() into a no-op for the newly-ungoverned paths, and the ledger then merges clean and corrupts silently.

No test can warn about a deliberate design choice, so the warning has to sit at the decision point -- rule 1's own header, where someone about to widen it is already reading. An item would describe the hazard somewhere nobody looks at the moment they create it.

The evidence it cites, rather than the risk it asserts

Commit 341e650d -- the author's own first cut at the rule 1 fix -- widened rule 1 to the whole of .git/mefor-coord/ and thereby exposed alloc/<kind>/<n>.json, so a Write could have forged an allocation that owns() would then authorise. --ci skips that rule entirely.

It was caught by adversarial review, not by any gate, and nothing in the file would have warned its author. That is the gap this closes, from the side that matters.

Verification

0 parse errors; 8 functions with both ConvertTo-WorktreeSlug and Get-SafeForMessage still present as FunctionDefinitionAst; 0 non-ASCII bytes; 239 passed across the 9 runnable gate files. Touches no BACKLOG heading, so no ledger entitlement is involved.

If a conflict appears against the #1041 rule 3d work, it is additive -- this hunk is rule 1's header (:788), that one is rule 3d (:524-570). Keep both.

…t, not only where it is relied on

docs/LEDGER-GATE.md already documents the pairing, in "Ownership keying -- and why it works
now": the ledger gate's ownership check keys on the worktree that allocated a number, that
key was measured broken before this gate existed because co-tenant sessions in the shared
primary all mapped to one worktree, and "the two gates are a pair".

That states the dependency from the DEPENDENT's side. This adds the reverse pointer at rule
1's own header, because the side that can break it had nothing.

WHY A COMMENT IS THE RIGHT INSTRUMENT HERE. Breaking this does not look like breaking a gate.
Widening what rule 1 governs disarms no hook and fails no test -- it quietly turns owns() into
a no-op for the newly-ungoverned paths, and the ledger then merges clean and corrupts
silently, which is the exact defect that registry exists to prevent (measured 3x: d1d0a5a,
5b7d046, 9f3483d). No test can warn about a deliberate design choice; the warning has to sit
at the decision point.

Not hypothetical, and the commit history shows it. The first cut of rule 1b's exemption
(341e650) widened rule 1 to the whole of .git/mefor-coord/ and thereby exposed
alloc/<kind>/<n>.json -- so a Write could forge an allocation that owns() would then
authorise, and --ci skips that rule entirely. It was caught by an adversarial review, not by
any gate, and nothing in this file would have warned the author. That is the gap this closes.

Note the relationship is the OPPOSITE of the one the rest of the file discusses. Elsewhere
this hook PROTECTS the ledger gate's inputs -- rule 3c refuses a core.hooksPath repoint, rule
1b refuses a write to alloc/. This dependency runs the other way: the ledger gate relies on
rule 1's SCOPE, not on its protection. Seven existing mentions of "ledger" in this file are
all the first kind, which is why the second was easy to miss.

Comment only, 18 lines added, zero removed, no behaviour change. Verified 0 parse errors, 8
functions with both helpers still defined by AST, 0 non-ASCII bytes, and 239 passed across the
9 runnable gate files.
@wshallwshall
wshallwshall enabled auto-merge (squash) August 6, 2026 03:18
@wshallwshall
wshallwshall merged commit 132dc68 into main Aug 6, 2026
33 checks passed
@wshallwshall
wshallwshall deleted the claude/gate-ledger-coupling-note branch August 6, 2026 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant