Files
booth/persistent-memory.d/2026-09-22-forever-had-a-live-positive-control.md
T
vh c3a97c1b64 feat(u4): a booth's lifetime is derived from its state, not from a boolean
`.forever` was the only way to say three different things — "this is durable",
"I have not answered yet", "I am still looking" — and the census said it was
carrying all three: 17 of 24 live booths (70%, up from 54% the day before).
Three of the four booths in the fleet awaiting an answer had been pinned by
hand as well, and 10 of the 17 were younger than the TTL, so the sentinel had
bought them nothing and was pressed pre-emptively.

Only the first meaning is what `keep` means. The other two are facts the
service already held and did not consult.

    KEPT       `.forever` present                      never swept  (unchanged)
    HELD       an open pick, or marks we cannot read   never swept  (new)
    EPHEMERAL  everything else                         24h          (unchanged)

Viewing is activity: a deliberately-served response from a booth's own page
route writes `.viewed`, which is a dotfile and not a `.lock` dotfile, so
`_newest_mtime` already counts it. There is no new arithmetic — `booth_age_seconds`,
`is_expired` and `expires_in` are unchanged. Machine reads are excluded on
purpose: an agent must not be able to hold its own booth open by polling for
the answer it is waiting on.

The hold is unbounded, and what makes that safe is visibility plus two exits
that already existed. Every surface whose chrome the Booth owns says
`held until answered` where the countdown was, and `booth rm` / the UI x /
`DELETE /b/<n>` take a held booth exactly as they take a kept one. A hold is
protection from the timer, never from the operator.

Three cross-frontier panels ran and each found a class the others could not:

  * the paraphrase panel found that two reads of one file are not one read of
    one state — the contract's `is_held(marks_for(c), read_error(c))` could
    resolve to `([], None)`, the pair that deletes. `hold_read` is one read.
  * the code-review panel found, 4-of-4, that the booth header's board branch
    rendered no lifetime at all; and that five of seven invariant tests passed
    under the change that defeats them.
  * the bug-hunt panel found four more paths where a failed read still
    authorized a delete, and a `record_view` that followed a planted symlink.

`is_held` became `hold_reason`, which returns the reason rather than a bool
beside a string that can disagree with it.

Prediction, to re-count on or after 2026-10-06: the `.forever` rate falls to
the booths that are genuinely durable references. Only 4 booths carry marks at
all, so this rests on both halves of the unit; a null result cannot distinguish
a wrong diagnosis from a habit that outlived its need.

406 tests (341 before). Contract: docs/contracts/u4_derived_lifetime.contract.md
2026-09-22 09:44:25 -07:00

2.1 KiB

The .forever diagnosis got a live positive control

2026-09-22 · booth

The U4 diagnosis was that .forever is the only way to say three different things — "this is durable", "I have not answered yet", "I am still looking" — and that only the first is what keep means. That was an argument. On 2026-09-22 it stopped being one.

Census of ~/booth-data, whole population, every value a deterministic file fact:

live booths 24
carrying .forever 17 (70%, up from 54% on 2026-09-21)
carrying .marks.json at all 4
of those, with an open pick 4 of 4
open pick AND .forever 3

Three of the four booths in the entire fleet that were waiting on an answer had also been pinned by hand. That is the "not yet" case caught in the act, not inferred from a rate.

The staleness distribution says it from the other side: 10 of the 17 kept booths were under one day old — younger than the TTL, so the sentinel had bought them nothing and was pressed pre-emptively. Only 4 were old enough (2.4-4.6 days) that keep is the reason they still existed.

⚠ A number I got wrong, caught by a cross-frontier arm, kept here because the class repeats. The contract first said "12 are under 1.5 days old — younger than the TTL". The TTL is 24 hours. 1.5 days is not younger than 24 hours. The measurement was sound and the sentence was not; the claim only holds at the one-day line, where it is 10 rather than 12. Nobody on the Claude side caught it, including the author twice.

⚠ The hold's live blast radius is SMALL — only 4 booths have marks at all — so the .forever re-count prediction rests on BOTH halves of U4 and on the sentinel becoming unnecessary rather than forbidden. RE-COUNT A FORTNIGHT AFTER U4 LANDS, i.e. on or after 2026-10-06. If the rate does not move, the honest readings are "the diagnosis was wrong" OR "the habit outlived the need", and a bare re-count cannot tell those apart. The three open-pick-plus-.forever booths are the ones to watch, because for them the mechanism is now unambiguous.