feat(booth): kept boards — a .forever sentinel and a standing link board
Agent sessions hand the operator URLs and they drown in terminal scrollback. The Booth is the right home for them — it already has the one property that decides adoption, which is that a session can publish with mkdir and cp, no API key, no schema, no deploy — but everything in it dies in 24h. So: a booth containing `.forever` is never swept, and renders in its own Kept lane at the top of the index. Opt-in per booth, so the ephemeral default is untouched and nobody inherits a cleanup chore. `rm` the sentinel and the board rejoins the sweep; the CLI verbs are sugar over exactly that, which keeps the filesystem-is-the-state model honest. The pin is deliberately NOT wired into is_expired(). That stays a pure age question feeding the `expires_in` countdown; only sweep_once() honours the sentinel. Keeping expiry arithmetic and reaper policy apart means they cannot drift into each other. Kept cards are visually separated per Australis: a 2px top edge in aurora blue, the one accent border the system sanctions. They show "kept" instead of a countdown, and they deliberately lose the one-click wipe button — a × next to the durable stuff is a footgun, so removing a kept board is a two-step act. `booth link <url> [description]` appends to the standing `links` board, creating and keeping it on first use. Entries carry provenance (handle or hostname, plus a timestamp) because a bare URL is unreadable three days later. The append is one printf of one line to an O_APPEND fd — atomic under PIPE_BUF on POSIX — which matters because many agents post to one board and interleaved half-lines would be the obvious failure mode. Seven tests cover the sentinel: detection, survival of a sweep that wipes its neighbour, the deliberate is_expired/sweep_once split, the listing flag, the sentinel not inflating item counts, and both lane-rendering directions. Two of them originally asserted on the bare strings "Kept" and "kept-grid", which passed for the wrong reason — those also appear in the inlined stylesheet served on every page — so they now assert the full class attribute. 55 pass. Also corrects the Homepage card's description, which advertised a flat 24h TTL that is no longer the whole story.
This commit is contained in:
@@ -39,6 +39,50 @@ rsync -a ./out/ nh3-dev:booth-data/my-run/
|
||||
|
||||
Then hand the operator `http://10.100.10.50:8090/b/my-run/`.
|
||||
|
||||
## Kept boards — the one exception to the 24h rule
|
||||
|
||||
A booth containing a **`.forever`** dotfile is **never swept**, and renders in
|
||||
its own **Kept** lane at the top of the index (blue top edge, `★ kept` badge, no
|
||||
countdown, no one-click wipe). Everything else is unchanged: the default is
|
||||
still ephemeral, so nobody inherits a cleanup chore they didn't ask for.
|
||||
|
||||
```bash
|
||||
booth keep my-board # drop the sentinel — exempt from the sweep, forever
|
||||
booth unkeep my-board # remove it — the board rejoins the sweep
|
||||
```
|
||||
|
||||
It is just a file, so the manual forms work identically and are the honest
|
||||
mental model:
|
||||
|
||||
```bash
|
||||
touch ~/booth-data/my-board/.forever # keep
|
||||
rm ~/booth-data/my-board/.forever # unkeep
|
||||
rm -rf ~/booth-data/my-board # delete outright, whenever you like
|
||||
```
|
||||
|
||||
**Why this exists:** agent sessions hand the operator URLs — a booth of renders,
|
||||
a PR, a dashboard — and they drown in terminal scrollback. Kept boards are where
|
||||
those go instead.
|
||||
|
||||
### The standing link board
|
||||
|
||||
```bash
|
||||
booth link <url> [description]
|
||||
```
|
||||
|
||||
Appends one line to the **`links`** board (`$BOOTH_LINKS_BOARD`, default
|
||||
`links`), creating it and marking it kept on first use. Each entry carries
|
||||
provenance — who posted it and when — because a bare URL is unreadable three
|
||||
days later. `links.md` renders as a readable page in the booth.
|
||||
|
||||
The append is a single `printf` of a single line to an `O_APPEND` fd, which is
|
||||
atomic under `PIPE_BUF` on POSIX. That matters here specifically: many agents
|
||||
post to one board, and interleaved half-lines would be the obvious failure.
|
||||
|
||||
Deliberately **not** a database. The board is a markdown file — editable with
|
||||
any editor, greppable, and trivially prunable by hand, which is the whole point
|
||||
of the Booth's filesystem-is-the-state model.
|
||||
|
||||
## Upload for pickup
|
||||
|
||||
The reverse direction — put files in through the web, pick them up by id:
|
||||
|
||||
Reference in New Issue
Block a user