Reported by draupnir after the Booth v0.2.0 consumer note, and it is the higher-impact half of what it found: this file is autoloaded by every agent family on this box through the shared FLEETTOOLS bootstrap pointer, so it is the first thing a cold session reads about the Booth. Draupnir was a live specimen — it read this page earlier in the same session to post a booth, before the announcement landed, and only luck of scope kept it off the broken surfaces. Stale and now corrected: `booth asks` presented as the listing verb (it is a deprecated alias and emits JSON now, not the old table); `<stem>.ask.json` / `<stem>.answer.json` presented as the storage (one `.marks.json` per booth replaced them, and the answer sidecar 404s forever, so a remote session polling it is polling nothing); the `#ask-<stem>` anchor convention. Not stale, and left alone deliberately: the `data-booth-ask=` placeholder conventions. The inline placement engine survives v0.2 and is removed in a later unit, so those still work exactly as documented. Added: `booth marks` and `booth marks-import`, the marks.json HTTP read path, the partially-answered-counts-as-open change, and the 409-on-damaged-file behaviour.
92 lines
4.6 KiB
Markdown
92 lines
4.6 KiB
Markdown
# The Booth — ephemeral media board + operator decisions
|
|
|
|
**URL:** `http://10.100.10.50:8090/` · **CLI:** `booth` (on PATH on nh3-dev)
|
|
**Storage:** a booth is *just a folder* — `~/booth-data/<name>/` on nh3-dev. No upload API.
|
|
|
|
Wiped **24h after last activity** unless kept. No auth (LAN/WG-internal), so never
|
|
drop secrets in a booth.
|
|
|
|
## Show the operator something
|
|
|
|
```sh
|
|
booth new <name>; booth add <name> <file>... # or just cp/rsync into ~/booth-data/<name>/
|
|
rsync -a ./out/ nh3-dev:booth-data/<name>/ # from another host
|
|
booth url <name> # -> http://10.100.10.50:8090/b/<name>/
|
|
booth keep <name> / booth unkeep <name> # exempt from / restore the 24h sweep
|
|
```
|
|
|
|
Auto-renders a gallery of images, webm+mp4 video and audio. A `<file>.txt` sidecar
|
|
becomes that item's caption (this is how you label an A/B pair). A folder's own
|
|
`index.html` is served **verbatim** — build a custom report when you want one.
|
|
|
|
## Ask the operator to decide (no chat round-trip)
|
|
|
|
**As of Booth v0.2.x an ask is one shape of a MARK** — `pick` (this), `note` (free
|
|
text the operator volunteers), `flag` (the operator pointing at one item). All three
|
|
are read the same way, and the operator can now flag and annotate items, which he
|
|
previously had to relay in chat.
|
|
|
|
```sh
|
|
booth ask <booth> <id> "<prompt>" "<option A>" "<option B>" [...] [--no-notes]
|
|
booth answer <booth> <id> --wait # blocks until answered (default 1h)
|
|
booth answer <booth> <id> # non-blocking; exit 1 while unanswered
|
|
booth marks <booth> [--wait [SECS]] # EVERY mark, as JSON; --wait while any pick is open
|
|
booth marks-import <booth> # pull pre-v0.2 sidecars in; deletes nothing
|
|
```
|
|
|
|
`booth asks <booth>` survives as a deprecated alias for `marks` and now emits JSON,
|
|
not the old aligned table — **if you parse those columns, that parse is broken.**
|
|
|
|
Open picks are flagged on the Booth front page, so a waiting question is visible
|
|
without pinging anyone. ⚠ A **partially answered** pick counts as OPEN (changed in
|
|
v0.2.0; the old badge called it closed while the panel called it partial).
|
|
|
|
**Storage is one file per booth: `<booth>/.marks.json`.** The pre-v0.2
|
|
`<stem>.ask.json` / `<stem>.answer.json` sidecar pair is gone — `<stem>.answer.json`
|
|
will 404 forever, so a remote session polling it is polling nothing. Read over HTTP
|
|
instead, one call for the whole booth:
|
|
|
|
```sh
|
|
curl -sf http://10.100.10.50:8090/b/<booth>/marks.json # {booth, marks:[...], open:[ids]}
|
|
```
|
|
|
|
Re-answering overwrites — a mark is the CURRENT judgment, not a log. Radio only, no
|
|
multi-select. Page anchors are `#mark-<id>` (was `#ask-<stem>`), and
|
|
`/b/<booth>/asks` 308-redirects to `/b/<booth>/marks`.
|
|
|
|
⚠ If a booth's `.marks.json` is ever damaged, reads degrade to "no marks" so the page
|
|
still loads, but every WRITE refuses with a 409 — deliberately, because overwriting
|
|
would replace every judgment in that booth. Repair it by hand; nothing deletes it.
|
|
|
|
**Put the ask WHERE THE ARTIFACT IS.** If the booth has its own `index.html`, the
|
|
Booth substitutes placeholders: `<div data-booth-ask="<stem>"></div>` for the whole
|
|
ask, `data-booth-ask="<stem>:<question-key>"` for one question's radios,
|
|
`data-booth-ask-submit="<stem>"` for notes + submit. (`<stem>` is the pick's id;
|
|
these placeholders are unchanged in v0.2.x.) Per-question fragments bind to
|
|
one form via the HTML5 `form=` attribute, so a five-clip audition can put each radio
|
|
group under its own audio and still submit in a single POST.
|
|
⚠ Keep the placeholder OUTSIDE any grid/flex container or it becomes a cell in it.
|
|
|
|
⚠ **A partial answer is legal and you must handle it.** The operator can leave any
|
|
question blank; the sidecar then carries `complete: false` and the blank keys in
|
|
`unanswered`. **Check `complete` before acting**, and read a key in `unanswered` as
|
|
"not decided yet", never as "declined".
|
|
|
|
## Standing convention — the link board
|
|
|
|
**Every operator-facing link worth more than the next thirty seconds goes on the
|
|
standing link board, in the same turn you mention it.**
|
|
|
|
```sh
|
|
booth link <url> "<short description>" # on nh3-dev
|
|
ssh nh3-dev 'booth link <url> "<desc>"' # from anywhere else
|
|
booth links # read it
|
|
```
|
|
|
|
Still put the link in your reply — this is *in addition to*, not instead of. Links in
|
|
chat drown in scrollback; the board is a kept booth rendered at the top of the Booth
|
|
front page. Don't post noise: if the operator would not click it a week from now, it
|
|
does not belong there.
|
|
|
|
**Full schema + rules:** `~/development/booth/README.md` (gitea `vh/booth`; extracted from eshpfi 2026-09-21)
|