fix(coord): unbrick the backlog allocator — the partition guard measured the wrong maximum - #166
Merged
Merged
Conversation
…wrong maximum
Filing BACKLOG #1000, the first legitimate item in the post-partition public
sequence, made EVERY backlog allocation in the repository throw:
REFUSING TO ALLOCATE. The all-refs backlog maximum (1000) has reached the
public floor (1000).
I filed #1000 and I caused this. It is not a latent bug that #1000 revealed -- the
guard's premise held right up until a public number legitimately reached the floor,
and mine was the first.
ONE MEASUREMENT WAS SERVING TWO INCOMPATIBLE PURPOSES. Get-Floor returned a single
maximum, used for:
- the emit start, which wants the max over EVERYTHING so a number is never
re-issued. Correct as written.
- the residual detector, which wants the maintainer-internal sequence's high-water
to see it running out of room below the partition. It read the union instead.
Public items are SUPPOSED to be >= 1000 -- that is the whole design -- so the
detector fired on the partition being used correctly. Get-Floor now returns both
`Floor` and `SubFloorMax`; the emit start keeps the union, the detector reads only
the sub-floor band (353 on this tree, so it is quiet).
THE REFUSAL IS REMOVED, NOT REWRITTEN TO BE UNREACHABLE. Once an internal item is
allocated at or above the boundary it is indistinguishable, in the published files,
from a legitimate public item at the same number -- both are `## N.` with N >= floor.
A refusal arm would have to fire on correct input or never fire at all, and a branch
that cannot fire reads as protection while providing none. Detecting a real breach
needs an internal-side input this repository does not have. What remains is an honest
warning at 90% of the boundary.
THE COMMENT'S LOAD-BEARING CLAIM WAS CHALLENGED AND SURVIVED. It justified the guard
with "Get-Floor already swept every ref, internal ones included", and that was
suspected of being false. Measured instead of repeated: 490 vault-ish
remote-tracking refs exist, 489 carry docs/BACKLOG.md, and 67 item numbers live ONLY
there -- including #240-#247, the numbers the Ledger erratum records as re-issued
over cited work. The claim is TRUE and the sweep is why the floor is trustworthy.
What is false is the inference that seeing internal numbers means being able to
detect the breach. The comment now says which is which.
SECOND DEFECT, ALSO MINE: -ShowFloor lied. I added it earlier today and it returned
19 lines BEFORE the guard, so it printed `next: 1001` while every real allocation
threw. A peer session listed it among six verifications, got a green answer, and
recorded it as fact. The residual warning is now computed ONCE, above the -ShowFloor
block, and both paths read that one expression -- they cannot drift apart. -ShowFloor
also prints the sub-floor maximum, because a bare floor cannot answer the question
the partition raises.
Negative controls, in the existing source-text seam (tests/test_ledger_check.py) --
executing the allocator to test it would either spend a real number or write to
.git/mefor-coord/alloc/**, and a test that mutates the ledger registry to check the
ledger registry is its own hazard:
- the sub-floor measurement must exist, and Floor must survive for the emit start
- `$observed -ge $PublicBacklogFloor` must never reappear (the regression verbatim)
- $residualWarning must be computed before the -ShowFloor block and read by both
PROVEN TO FAIL: re-planting the exact regression makes the second test red; removing
the plant makes it green. 29 tests pass.
DISCLOSURE -- I spent a real number proving this. The regression probe allocated
BACKLOG #1001, which is now a permanent hole; claims are never released, and the
precedent for exactly this is #315/#317, the probe allocations made verifying the
previous floor fix. Next backlog number is #1002. Verified after the fix: a real
allocation succeeds, the ADR path still works (next 0160), -List works, and
-ShowFloor leaves the high-water ratchet untouched.
No BACKLOG number is filed for this work: the allocator is the thing that was broken.
"A control nobody has watched fail is an assumption wearing a green tick" -- this one
had never been watched fail on LEGITIMATE input, which is the harder half. That is
BACKLOG #1000's own thesis, and #1000 is the item that broke it.
ruff clean; docs/LEDGER-GATE.md documents both maximums and why the refusal is gone.
wshallwshall
enabled auto-merge (squash)
August 4, 2026 02:23
…allocator in tests
Revision after an independent design pass. The mechanism from the previous commit
holds; four things about the patch did not.
1. THE REFUSAL NOW HAS A REAL TRIGGER instead of being removed. Refusing nothing was
the safe correction, not the right one. PUBLIC_BACKLOG_FLOOR is a constant in a
source file, so it can be LOWERED -- a bad revert, a merge resolved wrongly, a
tidy-up -- and NEITHER the pre-commit gate NOR CI can catch that: both read only
the current value and have no memory of the previous one. Drop it to 900 and a new
public #900 lands on top of an internal #900, green all the way. A ratchet outside
the constant is the only instrument that can see it, so alloc.ps1 now keeps
.boundary-highwater beside its registry and refuses when the constant falls beneath
a value this clone already allocated against. Locally observable, genuinely
reachable.
Three quantities, three purposes, never crossed:
$observed (union max) -> the next number, ONLY
$subFloorMax (below boundary) -> the warning, ONLY
$boundarySeen (highest floor) -> the refusal, ONLY
2. "THIS CLONE CANNOT SEE THE INTERNAL LEDGER" IS FALSE AND IS NOT THE ARGUMENT.
Measured: 490 vault-ish remote-tracking refs, 489 carrying docs/BACKLOG.md, 67
numbers living only there including the #242-#246 band ADR 0115 cites. The premise
fails for four other reasons, any one fatal, and they are now written down: an
integer has NO PROVENANCE (a legitimate public item at the boundary and an internal
breach are the same observation -- which is exactly how #1000 read as a breach);
the refs are a FOSSIL (newest 2026-07-26, no refspec advances them, and they say
314 while the real vault is at 315); they are CLONE-LOCAL (a fresh clone has none);
and they are MASKED (internal 314 < public 353).
3. $observed STAYS THE UNION MAXIMUM, with the trap recorded. Repointing it at the
sub-boundary max -- the tempting one-line fix -- makes $start = max(353, 999) + 1 =
1000, a number already merged, and in a fresh clone with an empty registry the
atomic CreateNew has no claim to collide with and would NOT catch the re-issue.
4. NAMING: $subFloorMax is "the highest number below the boundary", never "the
internal maximum". It includes public pre-partition numbers, so it deliberately
OVER-states the internal high-water and warns early rather than late. Relatedly,
ledger_check.py's high-water 314 is NOT refreshed to 353: 314 is the vault-refs
maximum, 353 is a public number on origin/main, and relabelling one as the other
would plant a fresh false premise inside the comment being fixed.
ledger_check.py's own claim -- that alloc.ps1 "warns if the all-refs maximum reaches
this boundary" -- was the defect written down: wrong instrument, and it asserted a
liveness the fossil ref store does not have. Replaced, not softened.
THE TESTS NOW RUN THE ALLOCATOR. Nothing in tests/ ever had: the two existing
references are read_text() assertions and stayed green through the entire brick. The
seam is the process working directory -- alloc.ps1 has no -Repo switch and reads no
env var, so a throwaway repo gets its own registry AND supplies its own
ledger_check.py, making the boundary injectable. FLOOR=100, not 10: at 10 the warn
tier and the highest sub-boundary number collide and every tier test passes for the
wrong reason. The isolation check runs FIRST, because every later test spends real
numbers if it is false.
PROVEN TO FAIL: the same rig against the PRE-FIX alloc.ps1, with an item at the
boundary, returns rc=1 and "REFUSING TO ALLOCATE ... has reached the public floor
(100)" -- the production brick reproduced at 1/10 scale. Against the fix it allocates
#101. Real registry confirmed untouched by the suite: 62 claims before and after,
.floor-highwater still 1000.
34 tests pass; ruff clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
alloc.ps1 -Kind backlogrefused every allocation, repo-wide, blocking at least two sessions from filing items and blocking PR #105 from renumbering an illegal pre-partition number.What broke
One number served two incompatible purposes.
Get-Floorreturns the maximum over every## N.heading across both backlog files on every ref, and the script used that single value for:max($observed, floor - 1) + 1. Wants the union max, so a number is never re-issued. Correct as written.if ($observed -ge $PublicBacklogFloor) { throw }. Wants the maintainer-internal sequence's high-water, to catch the internal ledger creeping up on the partition. It read the union instead.Public items are supposed to sit at or above the floor — that is the whole of the #107 partition design — so the detector fired on the system working exactly as intended.
BACKLOG #1000was simply the first legitimate public number to get there, and from that moment1000 >= 1000held forever.Raising
PUBLIC_BACKLOG_FLOOR, which the error message itself recommended, would have re-bricked at the new floor the moment a public item reached it. It is a workaround, not a fix.What changed
Two measurements where there was one:
Floor(max over everything swept — what must I not re-issue?, includes public numbers) andSubFloorMax(max below the partition — how much runway does the internal sequence have?).The refusal is removed rather than made unreachable. Once an internal item is allocated at or above the boundary it is indistinguishable, in the published files, from a legitimate public item at the same number — both are
## N.with N ≥ floor. There is no attribute that separates them, so the arrival case cannot be detected from this data. A refusal branch that cannot fire reads as protection and is worse than none, so the detector now only warns, and the comment states that the limit is the data rather than the implementation.-ShowFloorwas a lying instrument and is fixed in the same commit. It returned before the guard, so it printed a confidentnext : 1001while a real allocation threw. Anyone diagnosing this with the inspector concluded the allocator was fine.$residualWarningis now computed above the-ShowFloorblock, so the preview and the real run read one shared expression.Verified by the reviewer, not just reported
$observed -ge $PublicBacklogFloorturnstest_the_residual_detector_does_not_read_the_whole_set_maximumred; removing it turns it green. Reproduced independently.-ShowFloornow reportsfloor 1001 / sub-floor 353 / next 1002, no refusal, guard quiet (353 is far below the 900 warn tier). ADR allocation unaffected.One measurement worth recording, because both the author and the reviewer initially got it backwards
The old comment claimed "Get-Floor already swept every ref, internal ones included." That claim is TRUE — measured: 490 vault-ish remote-tracking refs present, 489 carrying
docs/BACKLOG.md, and 67 item numbers living only there, including#240–#247, precisely the numbers the Ledger erratum records as re-issued over cited work. The sweep is why the floor is trustworthy.What was false was the inference built on top of it: seeing internal numbers is not the same as being able to attribute one. The replacement comment separates the true claim from the false inference instead of deleting both.
BACKLOG #1001is a permanent holeA regression probe spent it as a real allocation before the test seam was in view. Precedent is
#315/#317, probe allocations made verifying the previous floor fix, so it is left as a documented hole rather than hand-releasing a claim — which would establish a "release the verb by hand" habit the registry design deliberately refuses. The next backlog number is#1002.Ledger
No BACKLOG number (the allocator was the broken thing) and no ADR: this restores intended behaviour rather than deciding anything, and ADR 0115 is not the partition ADR —
8e6e7fa3touches three files, none underdocs/adr/. Repo precedent for gate fixes of this class is a plain commit carrying the reasoning.