memory: snapshot — U5 released at v0.3.0, and the index goes two-tier

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.
This commit is contained in:
Vuong Hoang
2026-09-22 08:20:51 -07:00
parent 95beede3c3
commit d37b81ab9f
30 changed files with 486 additions and 343 deletions
@@ -0,0 +1,14 @@
# `booth marks` / `booth answer` got real exit codes
_2026-09-22 · booth_
**`booth marks` / `booth answer` got real exit codes**, because
a read that CRASHED was indistinguishable from a read that said no. `marks`
printed a traceback and exited 0 (a caller's `jq` saw success and got
nothing); `answer --wait` read a damaged file as "not yet" and spun for the
full hour before blaming the operator. Now `0 ok · 1 unanswered/timed-out ·
2 no such pick · 3 unreadable`, and `read_error()` was added to `marks.py` so
the CLI can ask the question the browser must not: the page stays lenient, the
machine consumer gets the truth. Also `--wait` now prints ONCE — it was
emitting a whole JSON document per poll, so a captured `--wait` held several
concatenated values and parsed as none of them.