The snapshot was written at v0.6.0 and the marks-guard fix landed after it. Updates the in-flight head commit, the test count, and the ahead-of-origin count so a fresh session is not told a stale number.
129 lines
14 KiB
Markdown
129 lines
14 KiB
Markdown
# Persistent memory — booth
|
||
|
||
_Last updated: 2026-09-22_
|
||
|
||
> **Always check for `/tmp/booth-dev-handoff.md`** — if it exists and its
|
||
> `Written:` stamp is under 8 hours old, read it (it carries the in-flight
|
||
> handoff from the previous session), then delete it. Older than 8 hours:
|
||
> stale — delete it unread.
|
||
|
||
## Repo purpose
|
||
|
||
The Booth is the fleet's **operator-review surface**: agents post work by
|
||
making a folder under `~/booth-data`, the operator looks at it and judges it in
|
||
the browser, and the judgment gets back to the agent that posted it. It was
|
||
built as a file-shuttle and is being converged, unit by unit, onto the review
|
||
loop it turned out to actually be.
|
||
|
||
## Current state / in-flight
|
||
|
||
_As of 2026-09-22:_
|
||
|
||
- **NOTHING IS IN FLIGHT.** U6 (benches) landed, all four review gates closed,
|
||
**released as `v0.6.0`**, with the last open defect closed in `v0.6.1`. Deployed;
|
||
tree clean at `1b394dd`, 611 tests green, 19/19 booths 200 live. ⚠ **NOT PUSHED** — push is the operator's call
|
||
and he did not give it this session; `main` is ahead of `origin/main`.
|
||
→ `persistent-memory.d/2026-09-22-u6-benches-released.md`
|
||
- **v1 is gated on seven units. SIX ARE LANDED. U7 IS THE LAST ONE.** U1
|
||
`ce598b3`; U2 → `v0.2.0`/`v0.2.1`/`v0.2.2`; U5 → `v0.3.0`; U4 → `v0.4.0`;
|
||
U3 → `v0.5.0`; U6 `1c3ce5d` → `v0.6.0`.
|
||
- ⚠ **Before starting U7, read
|
||
`persistent-memory.d/2026-09-21-u7-section-premise-half-wrong.md` AND
|
||
re-count the booths first.** Its premise has degraded twice over: every booth
|
||
that needs navigation is FLAT, and on 2026-09-22 the four large booths it was
|
||
sized against (`pancake-v3-full`/`pancake-v4-full` at 270 items,
|
||
`sindra20-engines`, `sindra-finalists`) had ALL been swept. Largest live booth
|
||
is `miranda-is` at 92 items. Two of 19 booths have subfolders and both are
|
||
reports. Sections buy close to nothing; the rail, filters and grid keyboard
|
||
are the unit.
|
||
- **THE LAST OPEN DEFECT IS CLOSED.** The wrong-shaped `answer` that 500'd the
|
||
gallery and marks pages (pre-existing, measured at `42ea67f`) is fixed at
|
||
`_hydrate` — the placement the session recommended three times and the
|
||
operator never ruled on, **taken under a stated assumption and cheap to move**
|
||
(one condition in one function) if he disagrees. Measured before/after: both
|
||
pages 500 → 200, error visible, the booth's other pick untouched. Two things
|
||
fell out of it that matter more than the fix — U3's `_safe_fragments` lost its
|
||
natural trigger and is now a synthetically-falsified backstop, and that guard's
|
||
own handler could not survive the failure it was handling. Read
|
||
`persistent-memory.d/2026-09-22-a-wrong-shaped-answer-500s-the-gallery.md`
|
||
before touching marks rendering anywhere.
|
||
- ⚠ **TWO OPERATOR DECISIONS ARE OUTSTANDING AND BOTH ARE DELIBERATELY NOT
|
||
DONE.** (1) The single althing note to the 17 handles about `booth link`
|
||
refusing booth URLs — gated as multi-recipient, drafted nowhere, NOT SENT.
|
||
(2) Seeding the bench registry from the board — he said "no seeding yet", so
|
||
`booth bench import --apply` has NOT been run against live data and
|
||
`.benches.json` does not exist in `~/booth-data`.
|
||
- ⚠ **THE 17 CONSUMING HANDLES WERE NEVER TOLD that `keep` stopped meaning
|
||
"waiting on an answer"** — operator decision 2026-09-22, no broadcast, and it
|
||
still stands. **This CHANGES HOW THE 2026-10-06 RE-COUNT READS**: the hold
|
||
rides for free but not-pressing-`keep` has to be learned, so a flat `.forever`
|
||
rate does NOT falsify the diagnosis. Read its entry before measuring.
|
||
- **A remote exists and `main` is AHEAD of it.** `origin` is
|
||
`git@gitea.phasefinal.com:vh/booth.git`; the first push of this repo's history
|
||
was 2026-09-22 (26 commits, `v0.2.0`–`v0.5.0` in one motion). As of this
|
||
snapshot `main` is **11 commits ahead of `origin/main`** — the whole of U6
|
||
including the `v0.6.0` and `v0.6.1` tags. Pushing is the operator's call.
|
||
- **Two dated predictions are pending and must not be run early.** U5's adoption
|
||
re-measure on **2026-09-29**; the `.forever` re-count **on or after
|
||
2026-10-06**. Before the second, read
|
||
`persistent-memory.d/2026-09-22-no-notice-and-what-it-does-to-the-prediction.md`.
|
||
- **FIVE methodology proposals sit with the operator, untracked by his choice**
|
||
— four from earlier rounds plus Kimi's new one: promote "the falsifiable test
|
||
is weaker than the invariant it guards" to its own ambiguity class in
|
||
`/heid-contract-review`. It now has two data points in this repo (five of
|
||
seven U4 falsifiers vacuous; U6 shipped a tie-break falsifier that could not
|
||
fail). They are `/heid*` skill changes, not this repo's work.
|
||
- The booth set churns hard: 26 → 24 → 25 → 23 → **19** across five sessions.
|
||
Re-count rather than trusting any number written here.
|
||
|
||
## Recent decisions
|
||
|
||
- `[2026-09-22]` **The last open defect closed, and building its falsifier found another** — the wrong-shaped answer fixed at `_hydrate`; `_safe_fragments` lost its natural trigger and its handler could not survive the failure it handled → `persistent-memory.d/2026-09-22-a-wrong-shaped-answer-500s-the-gallery.md`
|
||
- `[2026-09-22]` **U6 released as `v0.6.0` — benches, and the number that was two defects** — six of seven v1 units landed, NOT PUSHED → `persistent-memory.d/2026-09-22-u6-benches-released.md`
|
||
- `[2026-09-22]` **Three cold panels on one unit, and what each lens could only see alone** — READ BEFORE DECIDING TO SKIP A GATE; all five passes found something the others structurally could not → `persistent-memory.d/2026-09-22-three-cold-panels-on-one-unit.md`
|
||
- `[2026-09-22]` **U6 landed — three surfaces, three jobs, one predicate** — the seam review caught three real contract defects incl. a per-row `resolve_booth` that would have 404'd the board → `persistent-memory.d/2026-09-22-u6-benches-landed.md`
|
||
- `[2026-09-22]` **The 69% link-board rot was two defects wearing one number** — READ BEFORE SCOPING ANY LINK-BOARD WORK; U5 closed the larger half and full-URL-vs-origin identity is a measured call → `persistent-memory.d/2026-09-22-one-number-was-two-defects.md`
|
||
- `[2026-09-22]` **U3 landed — the page declares the seam, the Booth mounts into it** — ten regexes against author HTML replaced by a substring test and a `+` → `persistent-memory.d/2026-09-22-u3-declared-embed-seam-landed.md`
|
||
- `[2026-09-22]` **A wrong-shaped answer 500s the gallery and the marks page** — PRE-EXISTING (measured at `42ea67f`), NOT U3; the v0.2.2 lesson is only half-implemented → `persistent-memory.d/2026-09-22-a-wrong-shaped-answer-500s-the-gallery.md`
|
||
- `[2026-09-22]` **The browser became a test surface** — READ BEFORE TOUCHING `playwright` IN pyproject; the pinned upper bound is the foot-gun, and these tests SKIP rather than fail → `persistent-memory.d/2026-09-22-the-browser-became-a-test-surface.md`
|
||
- `[2026-09-22]` **A vacuity pass that tries the contract's own mutation agrees with itself** — U3 ran one, reported 7/7, and a cold panel then showed one of the seven was vacuous; READ BEFORE WRITING A *Falsifiable:* LINE → `persistent-memory.d/2026-09-22-seven-of-seven-falsifiers.md`
|
||
- `[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]` **No fleetwide notice for U4, and what that does to the prediction** — READ BEFORE THE 2026-10-06 RE-COUNT; a flat rate does not falsify the diagnosis → `persistent-memory.d/2026-09-22-no-notice-and-what-it-does-to-the-prediction.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`
|
||
- `[2026-09-22]` **U5's adoption prediction split in two** — the handle rides for free, the why must be learned — RE-MEASURE 2026-09-29 → `persistent-memory.d/2026-09-22-u5-adoption-split-in-two.md`
|
||
- `[2026-09-22]` **The U2 bug-hunt panel was not ceremony** — the lock-unlink race and the TTL guard that was failing at its own job → `persistent-memory.d/2026-09-22-u2-bug-hunt-panel.md`
|
||
- `[2026-09-22]` **The lenient reader's blast radius was the whole service** — marks_for runs per booth per index load; a raise there is an outage → `persistent-memory.d/2026-09-22-lenient-reader-blast-radius.md`
|
||
- `[2026-09-22]` **`booth marks` / `booth answer` got real exit codes** — read it before changing anything the 17 consuming handles call → `persistent-memory.d/2026-09-22-cli-exit-codes.md`
|
||
- `[2026-09-22]` **`scripts/booth` went from zero tests to five** — they run the real script under system python3, so they also check INV-1 → `persistent-memory.d/2026-09-22-scripts-booth-got-tests.md`
|
||
- `[2026-09-21]` **v0.2.0 was tagged while a gate was in flight** — the sequencing lesson: if a gate is outstanding, the tag waits → `persistent-memory.d/2026-09-21-v020-tagged-with-a-gate-in-flight.md`
|
||
- `[2026-09-21]` **A write over a damaged `.marks.json` wiped the booth** — the reads-lenient / writes-strict asymmetry, and why it exists → `persistent-memory.d/2026-09-21-marks-write-wiped-judgment.md`
|
||
- `[2026-09-21]` **Seam review and cold panel had zero overlap, twice** — evidence for running both; neither substitutes for the other → `persistent-memory.d/2026-09-21-two-gates-are-complementary.md`
|
||
- `[2026-09-21]` **Every code-changing finding came from the AMBIGUITY pass** — a finding about the /heid-contract-review skill, not about this repo → `persistent-memory.d/2026-09-21-ambiguity-pass-did-the-work.md`
|
||
- `[2026-09-21]` **Deterministic order is a cross-cutting v1 invariant** — operator directive; read before adding ANY ordered surface → `persistent-memory.d/2026-09-21-deterministic-order-invariant.md`
|
||
- `[2026-09-21]` **U2 (marks) landed — one primitive for three mechanisms** — what moved where, and the HTTP mirror remote sessions poll → `persistent-memory.d/2026-09-21-u2-marks-landed.md`
|
||
- `[2026-09-21]` **A partially-answered pick counts as OPEN** — declared, not smuggled; it is the reading that makes U4 correct → `persistent-memory.d/2026-09-21-partial-answer-counts-as-open.md`
|
||
- `[2026-09-21]` **The U2 seam review earned its place, and how** — inline.place indexes by subscript — the miss a cold panel cannot see → `persistent-memory.d/2026-09-21-u2-seam-review-earned-it.md`
|
||
- `[2026-09-21]` **Marks are one `.marks.json` per booth** — operator decision with two rejected alternatives; read before restructuring → `persistent-memory.d/2026-09-21-marks-storage-decision.md`
|
||
- `[2026-09-21]` **U7's section premise is half wrong** — every booth that needs navigation is FLAT — read before starting U7 → `persistent-memory.d/2026-09-21-u7-section-premise-half-wrong.md`
|
||
- `[2026-09-21]` **`sindra-finalists` is U2's flag motivation, caught live** — evidence, not argument → `persistent-memory.d/2026-09-21-sindra-finalists-is-the-motivation.md`
|
||
- `[2026-09-21]` **The information architecture and the v1 gate landed** — the single defect the seven units decompose → `persistent-memory.d/2026-09-21-ia-and-v1-gate-landed.md`
|
||
- `[2026-09-21]` **The `.forever` diagnosis is a falsifiable prediction** — U4's success criterion — re-count a fortnight AFTER U4 lands → `persistent-memory.d/2026-09-21-forever-diagnosis-is-a-prediction.md`
|
||
- `[2026-09-21]` **Extracted from `eshpfi` into its own repo** — test_booth.py is the regression net the v1 rewrite is checked against → `persistent-memory.d/2026-09-21-extracted-from-eshpfi.md`
|
||
|
||
## Tried and abandoned
|
||
|
||
- `[2026-09-21]` **Tagging a release while a review gate was in flight** — cost a same-hour v0.2.1 and a correction to 15 handles → `persistent-memory.d/2026-09-21-tagging-with-a-gate-in-flight.md`
|
||
- `[2026-09-21]` **Letting the write path share the read path's leniency** — a tolerant reader and a tolerant writer are not the same decision → `persistent-memory.d/2026-09-21-tolerant-writer-over-tolerant-reader.md`
|
||
- `[2026-09-21]` **Letting Jinja hot-reload templates in the deployment root** — caused a live outage: 19 of 25 booths at 500. Why auto_reload=False → `persistent-memory.d/2026-09-21-jinja-hot-reload-outage.md`
|
||
- `[2026-09-21]` **Five mechanisms to get one question beside one artifact** — the accretion signature this whole v1 rewrite is undoing → `persistent-memory.d/2026-09-21-five-mechanisms-one-job.md`
|
||
- `[2026-09-21]` **Regex-injecting chrome into arbitrary author HTML** — the defect U3 exists to close → `persistent-memory.d/2026-09-21-regex-injecting-chrome.md`
|
||
- `[2026-09-21]` **A boolean escape hatch as the lifetime mechanism** — why `.forever` is a symptom; the defect U4 exists to close → `persistent-memory.d/2026-09-21-boolean-escape-hatch-as-lifetime.md`
|
||
- `[2026-09-21]` **Letting the link board absorb the announce job** — 69% rot; U5 gave the job a home, which is what unblocks U6 → `persistent-memory.d/2026-09-21-link-board-absorbing-announce.md`
|