The two dated log sections had never been split, so every one of their 29 entries sat inline and the startup index had grown to 372 lines — which is the cost the two-tier scheme exists to remove, paid on every session that reads the file. 27 entries were over threshold. All 29 now have a detail file under persistent-memory.d/ and a one-line index entry that routes rather than restates. Index: 372 -> 93 lines. No archival. The soft cap fired, but every entry in this repo is dated 2026-09-21 or later, so the under-14-days guard held all of them back — and the split alone took the index well under the target without moving anything out of the active file. The in-flight section is rewritten for the post-release state: nothing is in flight, no gate is outstanding, and the next unit is explicitly recorded as the operator's undecided call rather than as a plan. The session's recommendation (U4, on three grounds) is written down so it does not have to be re-derived, alongside the two alternatives and why they are alternatives. Two dated predictions are carried forward with their dates and their instruments: the U5 adoption re-measure on 2026-09-29, which already reads 3 of 24 announced and 2 with a why from peers told nothing, and the .forever re-count a fortnight AFTER U4 lands, which is U4's own success criterion and is destroyed by running it early.
24 lines
1.5 KiB
Markdown
24 lines
1.5 KiB
Markdown
# The size cap opened a service-wide hang
|
|
|
|
_2026-09-22 · booth_
|
|
|
|
**The U5 bug-hunt panel found a service-wide hang that the
|
|
SIZE CAP ITSELF opened — two hours after I added the cap.** `stat` reports
|
|
size 0 for a FIFO and 0 for a symlink to `/dev/zero`, so both sail under a
|
|
byte cap and then `read_text` blocks with no EOF or allocates until the kernel
|
|
intervenes. `list_booths` reads every booth on every `GET /`, so ONE such file
|
|
stalls the front page for the whole service with no error and no recovery
|
|
short of a restart. Reproduced (`timeout` returned 124), fixed with an
|
|
`S_ISREG` check BEFORE the size check in both modules, verified live: the
|
|
index answered 200 in 36 ms with two FIFOs planted. **The reusable shape:
|
|
`st_size` answers a different question than "can this be read", and a bound
|
|
that trusts it inherits everything it does not mean — a hardening fix opened
|
|
a worse hole than the one it closed.** Also adopted: the upload path wrote the
|
|
manifest ABOVE its own cleanup guard (4/4), so a failure orphaned a half-booth
|
|
whose uniquely-named leaked temp then kept it alive forever; replace-over-
|
|
damaged destroyed recoverable bytes (4/4, now QUARANTINED rather than refused
|
|
— marks refuse because judgment is not restatable, a booth's description is);
|
|
and `booth answer` spelled out its own openness test, disagreeing with
|
|
`booth marks` about a partially-answered pick, which is a direct violation of
|
|
U2's INV-2. Full triage in `persistent-memory.d/2026-09-22-u5-panels.md`.
|