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
This commit is contained in:
+34
-24
@@ -21,33 +21,37 @@ _As of 2026-09-22:_
|
||||
|
||||
- **v1 is gated on seven units** in `ROADMAP.md`, dependency-ordered
|
||||
**U1 → U2 → {U3, U4, U5} → U7**, with **U6 independent**.
|
||||
- **U1, U2 and U5 are landed and released.** Current version `0.3.0` (`95beede`,
|
||||
tagged), deployed, 341 tests green, tree clean, 24/24 booth pages verified 200
|
||||
and a full layout-probe sweep at 0 occlusions across 27 pages. U1 `ce598b3`;
|
||||
U2 `c7f9437` → `v0.2.0`, `5e41108` → `v0.2.1`, `026a1fc` → `v0.2.2`;
|
||||
U5 `c015a91` + `95beede` → `v0.3.0`.
|
||||
- **THE NEXT UNIT IS THE OPERATOR'S CALL and has not been made.** The session's
|
||||
recommendation is **U4 (derived lifetime)**, on three grounds, none of which
|
||||
need re-deriving: (1) it is the only remaining unit whose defect was
|
||||
re-measured this session — the `.forever` rate is **17 of 24 (70%)**, up from
|
||||
the 54% in the IA doc and the 56% measured on 2026-09-21, and the absolute
|
||||
count rose too (14 → 17), so it is not only the denominator shrinking;
|
||||
(2) U2 built `open_marks` FOR it and says so in the predicate's docstring;
|
||||
(3) the bug-hunt panel's mtime-restore finding was deliberately left open
|
||||
because closing it properly is a TTL doctrine change — and U4 is the unit that
|
||||
owns TTL doctrine, so it closes a loop this session opened on purpose.
|
||||
U3 and U6 are the alternatives: U6 is independent and was *conceptually*
|
||||
unblocked by U5 giving job 5 a home, U3 is where verbatim-booth provenance was
|
||||
deferred to.
|
||||
- **No gate is outstanding.** All three ran on U5 and were folded in: the cold
|
||||
`/heid-contract-review` panel (thread `01M340PNVRS21HPASZT38PXQPN`), the
|
||||
`/heid-code-review` conformance panel (`01M341E9XAPZEFBSPK9HPGAM0S`) and the
|
||||
`/heid-bug-hunt` (`01M343SXX27Z47C3STXXRC7M42`). All three loops are closed
|
||||
with heid.
|
||||
- **U1, U2, U4 and U5 are landed.** U1 `ce598b3`; U2 `c7f9437` → `v0.2.0`,
|
||||
`5e41108` → `v0.2.1`, `026a1fc` → `v0.2.2`; U5 `c015a91` + `95beede` →
|
||||
`v0.3.0`. **U4 landed 2026-09-22** — 396 tests green (341 → 396), deployed and
|
||||
verified live, 24/24 booth pages 200, layout probe clean.
|
||||
- **U4 IS NOT YET RELEASED — the version bump is an open operator decision.**
|
||||
Recommended **v0.3.0 → v0.4.0 (minor)**: U4 changes what `keep` MEANS for 17
|
||||
agent handles ("stop pressing keep when you are only waiting"), which is
|
||||
release-note-worthy at the pre-1.0 bar and the same tier U2 and U5 took. The
|
||||
defensible alternative is v0.3.1 if U4 reads as internal plumbing, since no
|
||||
CLI verb or URL changed shape. **Commits are not releases**, so the work is
|
||||
committed unbumped and untagged; the tag waits on his word and nothing is
|
||||
blocked by the wait.
|
||||
- **THE NEXT UNIT IS THE OPERATOR'S CALL.** U3 (declared embed seam) and U6
|
||||
(benches) are both unblocked; U7 waits on the rest. U6 is independent of
|
||||
everything and was conceptually unblocked by U5 giving job 5 a home; U3 is
|
||||
where verbatim-booth provenance was deferred to, and U4 added a fourth reason
|
||||
to want it — a verbatim booth has no Booth-rendered header, so its lifetime
|
||||
line lives only on the index card and the marks page.
|
||||
- **No gate is outstanding.** All three ran on U4 and were folded in: the
|
||||
`/heid-contract-review` panel (`01M34VX0SH23Y3VC92E7GM4S70`), the
|
||||
`/heid-code-review` panel (`01M34WAFJC3RTERFYBBZJN1SVG`) and the
|
||||
`/heid-bug-hunt` (`01M34Y2R0RAJRSN36Q8K4KAB36`). All loops closed with heid.
|
||||
The U5 round's three are also closed (`01M340PNVRS21HPASZT38PXQPN`,
|
||||
`01M341E9XAPZEFBSPK9HPGAM0S`, `01M343SXX27Z47C3STXXRC7M42`).
|
||||
- **Two dated predictions are pending and must not be forgotten.** U5's adoption
|
||||
re-measure on **2026-09-29** (two counts, see its entry — already at 3 of 24
|
||||
announced and 2 with a `why`, all from peers told nothing), and the `.forever`
|
||||
re-count **a fortnight after U4 lands**, which is U4's success criterion.
|
||||
re-count **on or after 2026-10-06**, a fortnight after U4 landed, which is
|
||||
U4's success criterion. ⚠ Only 4 booths carry marks at all, so the hold's live
|
||||
blast radius is small and the prediction rests on both halves of U4 — see its
|
||||
entry for what a null result would and would not mean.
|
||||
- **Three methodology proposals from this session sit with the operator**, routed
|
||||
by heid rather than decided unilaterally: reshaping the paraphrase gate toward
|
||||
a drift-check for narrative-heavy contracts, a standing
|
||||
@@ -59,6 +63,12 @@ _As of 2026-09-22:_
|
||||
|
||||
## Recent decisions
|
||||
|
||||
- `[2026-09-22]` **U4 landed — lifetime is derived, not declared** — three states, viewing is activity, and no new arithmetic anywhere → `persistent-memory.d/2026-09-22-u4-derived-lifetime-landed.md`
|
||||
- `[2026-09-22]` **The `.forever` diagnosis got a live positive control** — 3 of the 4 booths awaiting an answer were ALSO hand-pinned — RE-COUNT 2026-10-06 → `persistent-memory.d/2026-09-22-forever-had-a-live-positive-control.md`
|
||||
- `[2026-09-22]` **Four independent paths to one fail-open delete** — the bug-hunt panel's class, and the zsh word-splitting trap that shipped an empty bundle → `persistent-memory.d/2026-09-22-four-paths-to-one-fail-open-delete.md`
|
||||
- `[2026-09-22]` **Two reads of one file are not one read of one state** — a TOCTOU seam that composes two correct readers into a fail-open delete → `persistent-memory.d/2026-09-22-two-reads-are-not-one-state.md`
|
||||
- `[2026-09-22]` **Five of seven INV falsifiers did not falsify anything** — read before writing a *Falsifiable:* line; a green test cited one rather than being one → `persistent-memory.d/2026-09-22-vacuous-falsifiers.md`
|
||||
- `[2026-09-22]` **The third one-branch template miss** — this repo's recurring blind spot; read before adding a fact to any template → `persistent-memory.d/2026-09-22-third-one-branch-template-miss.md`
|
||||
- `[2026-09-22]` **The size cap opened a service-wide hang** — a FIFO has st_size 0; a bound that trusts it inherits what it does not mean → `persistent-memory.d/2026-09-22-size-cap-opened-a-hang.md`
|
||||
- `[2026-09-22]` **An existing test stopped me retiring documented behaviour** — the clean fix for the mtime race would have silently changed TTL doctrine → `persistent-memory.d/2026-09-22-doctrine-not-defect.md`
|
||||
- `[2026-09-22]` **Two U5 panels, and prose reached a released outage** — read the detail before assuming a conformance finding stops at its own module → `persistent-memory.d/2026-09-22-u5-panels-reached-a-released-bug.md`
|
||||
|
||||
Reference in New Issue
Block a user