Nothing in flight. The in-flight section is rewritten to the post-release state and carries the five things a fresh session must not do: push (main is 8 ahead of origin/main), seed the registry, send the 17-handle note, run either dated prediction early, or start U7 without re-counting the booths first. Two new detail files: the release itself, and what each of the five review passes could only see alone -- the strongest evidence this repo has for running all of them rather than picking one. The earlier U6 entry is reconciled; it was written while the gates were still out and said NOT TAGGED. Restored in the rewrite: the warning that the 17 handles were never told `keep` stopped meaning "waiting on an answer", which is load-bearing for how the 2026-10-06 re-count reads, and the fact that a remote now exists.
3.6 KiB
U6 landed — three surfaces, three jobs, one predicate
2026-09-22 · booth
The sixth of seven v1 units. Only U7 is left. 444 → 555 tests, suite green, deployed and verified live: 23/23 booths 200, and the board renders 156 dead of 221 rows — the exact count an independent shell measurement produced before a line of code was written, from two different implementations.
What shipped
booth/benches.py(new, stdlib-only AND sibling-free):Bench,normalize_bench_url, lenientread_benches, strictupsert_bench,set_bench_state,remove_bench,order_benches. Registry at~/booth-data/.benches.json— a dotfile at the DATA ROOT, keyed by id, so two rows with one identity are impossible by construction.links.booth_target— ONE predicate for "is this a booth URL", consumed by three callers (the CLI refusal, the board's dead marker,bench import). Host-agnostic and path-shaped; percent-decodes the name.booth linkrefuses a booth URL, namesbooth new --why, and writes nothing — not even the board directory.- The board marks dead rows. Removal stays the operator's two clicks through the bulk control that already existed. Nothing in the unit deletes a row.
booth bench add|ls|state|rm|import;importwrites nothing without--applyand never toucheslinks.md.docs/archive/links-2026-09-22.md— the board archived verbatim into git.
The decision that mattered most, and it was measured
Identity is the FULL normalized URL, not the origin. Collapsing the 43
non-booth rows by origin gives 19 groups; by full URL, 35. The difference is not
duplication — it is eight distinct gitea repos merged into one, three
unrelated HuggingFace model cards merged into one, and the two LRPG surfaces
on 10.100.10.50:8321, which are the IA doc's own example of two real benches,
merged into one. Origin identity destroys more than it dedups. Full-URL identity
still collapses both cases the doc names (talk 5→1, Peedlar 3→1).
Query is IN the identity (three ShutterChute rows differ only by ?token= and
are three real links); fragment is OUT; credentials are REFUSED, not stripped.
The seam review earned it again — three real contract defects
Run in-session against the real .py files, after the cold panel was dispatched:
- SR-1 — the contract claimed
test_stdlib_onlyalready forbids sibling imports. It does not: its failure set is{r for r in roots if r != "booth" and ...}, which exemptsboothon purpose. Only test_manifest.py has the strict copy. INV-9 would have shipped untested. - SR-2 — the contract named
resolve_boothas the dead marker's existence check. That function is a closure insidecreate_appand raises HTTPException(404) — per row, one swept booth would 404 the whole board page. - SR-7 — booth links are emitted through
quote(name, safe=""), so a predicate comparing the raw segment marks every encoded-name booth dead forever.
SR-4 and SR-5 were verified rather than assumed: both list_booths and
sweep_once skip a child that is not a directory AND one whose name starts with
a dot, so the registry is safe from the sweeper by two guards, not one. Had
either been absent the design would have eaten its own registry on tick one.
How it closed
All three cold gates came back and were folded in full, with exactly one finding
declined. Released as v0.6.0 — see 2026-09-22-u6-benches-released and
2026-09-22-three-cold-panels-on-one-unit. The tag waited for the gates, per
the v0.2.0 lesson, and that sequencing was right: the panels produced ten code
fixes after this entry was first written.