feat(u6): benches — a registry with identity, and the rule enforced
The standing link board carried three jobs because only one of them had a surface. Re-measured before contracting, its 221 rows split into 178 booth announcements (156 already dead) and 43 non-booth rows, of which 8 are the same bench re-posted. U5 gave the booth announcement a home; this gives the running service one, and refuses the one shape that now has somewhere better to go. - booth/benches.py (new, stdlib-only and sibling-free): the Bench record, URL normalization as the identity, a lenient read on the render path and a strict read on the write path, atomic replace under an flock, and a stated total order (state rank, name casefolded, id). - links.booth_target: ONE predicate for "is this a booth URL", consumed by the CLI refusal, the board's dead marker and bench import. Host-agnostic, path-shaped, percent-decoded, never raises. - booth link refuses a booth URL, names `booth new --why`, and writes nothing — not the row, not the board directory, not the announcement. - The board marks rows whose booth has been swept. Nothing here deletes a row: removal stays the operator's two clicks through the existing bulk control. - booth bench add|ls|state|rm|import. import writes nothing without --apply and never edits links.md. - docs/archive/links-2026-09-22.md: the board archived verbatim into git. Identity is the FULL normalized URL, not the origin, and that was measured: origin identity collapses the 43 non-booth rows to 19 groups by merging eight distinct gitea repositories into one row, three unrelated HuggingFace model cards into one, and the two LRPG surfaces on 10.100.10.50:8321 — the design doc's own example of two real benches — into one. Full-URL identity still collapses both cases that doc names: talk 5 to 1, Peedlar 3 to 1. booth link is NOT deprecated. Roughly 14 of the 35 distinct non-booth targets are reference bookmarks for which the board is the right and only home; the design doc's plan to deprecate it would have evicted a third of its live content. Corrected there, along with what "normalized URL" means. The seam review found three real defects in the contract before any code: the claim that test_stdlib_only already forbids sibling imports (it exempts `booth` on purpose), naming resolve_booth as the dead marker's existence check (it raises HTTPException(404), so one swept booth would have 404'd the whole board page), and silence on percent-encoding (booth links are emitted through quote(name, safe=""), so a raw comparison marks every encoded booth dead forever). That both list_booths and sweep_once skip the registry was verified against the real functions rather than assumed. 444 -> 555 tests. Deployed and verified live: 23/23 booths 200, and the board renders 156 dead of 221 rows, matching an independent pre-implementation count. NOT TAGGED: both cold gates are in flight (contract review 01M35BWCJ806MT75NA630Y4WFH, code review 01M35CK8YKEKMV7T15JXEF6A8N) and the bug-hunt has not run. Per the v0.2.0 lesson, the tag waits for the gates.
This commit is contained in:
@@ -162,6 +162,7 @@ session that posted the set.
|
||||
```
|
||||
BENCH
|
||||
id : normalized URL (the identity — re-posting UPDATES, never appends)
|
||||
NORMALIZED MEANS THE FULL URL, NOT THE ORIGIN — see below
|
||||
name : what it is
|
||||
owner : the agent handle that registered it
|
||||
state : live → promoted (to Homepage) → retired
|
||||
@@ -173,8 +174,51 @@ BENCH
|
||||
- `booth bench add <url> "<what>"` upserts on the normalized URL. The 5 `talk`
|
||||
rows and 4 `peedlar` rows collapse to one each, by construction.
|
||||
- **`booth link` refuses a `…:8090/b/…` URL** and names the right surface. It
|
||||
survives as a deprecated alias rather than vanishing — 17 handles have the
|
||||
muscle memory, and the teaching moment belongs at the point of use.
|
||||
is **not deprecated** — 17 handles have the muscle memory, the teaching moment
|
||||
belongs at the point of use, and (corrected 2026-09-22, U6) the board has a
|
||||
legitimate residual job: of the 35 distinct non-booth targets on it, roughly
|
||||
**14 are reference bookmarks** — gitea repositories, HuggingFace model cards,
|
||||
a vLLM recipe, a Headscale setup page — for which the board is the right and
|
||||
only home. Deprecating it would evict a third of its live content. It loses
|
||||
exactly one shape, the booth URL, and keeps the rest.
|
||||
|
||||
### What "normalized URL" means, and why it is not the origin
|
||||
|
||||
Corrected 2026-09-22 while U6 was being contracted. This doc said *normalized
|
||||
URL* and left it there; the obvious reading is the origin
|
||||
(`scheme://host:port`), and that reading is **measurably destructive**.
|
||||
|
||||
Collapsing the board's 43 non-booth rows by origin yields 19 groups; by full
|
||||
URL, 35. The 16-group difference is not duplication:
|
||||
|
||||
| what origin identity would merge | rows |
|
||||
|---|---|
|
||||
| eight distinct gitea repositories, issues and package versions | 8 → 1 |
|
||||
| three unrelated HuggingFace model cards | 3 → 1 |
|
||||
| **the two LRPG surfaces on `10.100.10.50:8321`** — this doc's own example of two real benches | 2 → 1 |
|
||||
| two different claude.ai artifact briefs | 2 → 1 |
|
||||
|
||||
Full-URL identity still collapses both cases this doc names — `talk` 5 rows to
|
||||
1, Peedlar's root 3 to 1 — which is the entire win, without the losses.
|
||||
|
||||
The **query string is part of the identity** and the **fragment is not**: three
|
||||
ShutterChute rows differ only by `?token=` and are three genuinely different
|
||||
one-shot links, while a fragment is a position inside a page. Credentials in a
|
||||
URL are **refused rather than stripped** — stripping registers a bench whose URL
|
||||
no longer works while telling the poster it succeeded.
|
||||
|
||||
### One number that was two defects
|
||||
|
||||
This doc's headline **69% rot** is two different defects wearing one number, and
|
||||
U5 already closed the cause of the larger one:
|
||||
|
||||
| defect | rows (2026-09-22) | what fixes it |
|
||||
|---|---|---|
|
||||
| **booth-announcement rot** — a session posts a booth URL because a booth cannot announce itself | 178 rows, 156 already dead | **U5** gave job 5 a home; U6's refusal stops the habit; U6's dead marker clears what landed |
|
||||
| **bench re-post** — an append log with no identity | 8 rows | U6's registry |
|
||||
|
||||
Worth stating plainly because the single figure implies the registry is the big
|
||||
half. It is the smaller one.
|
||||
- Liveness is *flagged*, not enforced. A bench that stops answering gets a
|
||||
marker and a date; deleting is the operator's call. Nothing here deletes the
|
||||
operator's data on a timer.
|
||||
|
||||
Reference in New Issue
Block a user