feat(booth): add The Booth — ephemeral media drop board for CC sessions

A standing user-level web server (nh3-dev :8090) that renders drop-folders
under ~/booth-data as ephemeral media "booths" so Claude Code sessions can
surface A/B renders and smoke results to the operator, then let them self-wipe.

- Scan-and-serve model, no database, no upload API — a booth is just a folder.
  A folder's own index.html is served verbatim; otherwise an auto-gallery of
  images / webm+mp4 video / audio is rendered, with <file>.txt caption sidecars
  folded in (labels A/B pairs).
- 24h TTL from newest mtime in the tree; background sweeper wipes stale booths.
- Path-traversal + symlink-escape guarded; delete via UI button or DELETE API.
- FastAPI + Jinja2, runs from the checkout under systemctl --user (booth.service),
  alongside the other nh3-dev fleet sidecars. 15 tests, all green.
- Homepage tile added (Apps -> The Booth, siteMonitor /healthz).
- Harden the homepage rsync doc: exclude *.bak* and logs/ so --delete can't
  wipe the host's dated services.yaml backups (footgun found deploying this).
This commit is contained in:
vh
2026-07-20 10:17:40 -07:00
parent a5dcad8bd3
commit f4a5ba7c31
13 changed files with 909 additions and 0 deletions
+9
View File
@@ -85,12 +85,21 @@ Current workflow — push this directory onto the host:
```bash
rsync -av --delete \
--exclude='.env' --exclude='.env.*' \
--exclude='*.bak*' --exclude='logs/' \
configs/homepage/ esh-docker-vm:/opt/docker/conf/homepage/
```
The real `.env` lives on `esh-docker-vm` next to the compose file and must
not be overwritten (holds Plex/Jellyfin keys).
> **`--delete` footgun (learned 2026-07-20):** the host keeps dated
> `services.yaml.bak-*` safety copies and a live `logs/` dir that are *not*
> in this repo. A bare `--delete` rsync wipes both. The `--exclude='*.bak*'`
> and `--exclude='logs/'` above protect them. For a one-file tweak, skip
> `--delete` entirely and push the single file:
> `rsync -av configs/homepage/services.yaml esh-docker-vm:/opt/docker/conf/homepage/services.yaml`
> (back up the host copy first: `ssh esh-docker-vm 'cp -a …/services.yaml …/services.yaml.bak-<date>-<what>'`).
The homepage container reloads most files on-change; if a new group in
`settings.yaml` doesn't show up, `docker compose restart` on the host.
+9
View File
@@ -17,6 +17,15 @@
siteMonitor: http://10.0.50.45:3001
description: Uptime monitor (esh-docker-vm)
- Apps:
# Manual entry — the Booth is a user-level systemd service on nh3-dev
# (not a Docker-labeled stack), so it can't auto-discover; list it here.
- The Booth:
href: http://10.100.10.50:8090/
icon: mdi-filmstrip
siteMonitor: http://10.100.10.50:8090/healthz
description: Ephemeral media drop — CC-session A/B & smoke results (nh3-dev, 24h TTL)
# The AI tab is fully Docker-auto-discovered. Each inference service carries
# a homepage.group=AI - <role> label on its compose file (AI - Inference,
# AI - Eval & Retrieval, AI - Gateways & Chat, AI - Speech (TTS),