Rematches, seats that travel by phrase, the keeper's bell with the hour where they live, the host's leave for the gallery to talk, and seats doubted before they are dropped

Ported from Wiz-War, where each earned its keep. All on the ledger:
galleryTalk, challenge and rematch lines, gallery chat signed with a
name, held seats on a rematch table's room line. Twenty-two protocol
checks against a scratch server and a replay after restart.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
Eric Wagoner
2026-09-23 12:19:03 -04:00
co-authored by Claude Fable 5.1
parent 65d62f2ab3
commit 6dce3b82f0
14 changed files with 521 additions and 28 deletions
+22 -3
View File
@@ -21,9 +21,26 @@ README.
read-only view showing only what every seat could see, counted for the
table (*3 in the gallery*). While the table is laid, a watcher is offered
a seat first; the gallery is the afterthought.
- **Table talk** is the chat panel, seated players only. Each line is a
ledger line, so it replays with the game, and the hall counts lines said
while you were away.
- **Table talk** is the chat panel, seated players only unless the host
*lets the Peanut Gallery talk*; then a watcher signs a name no seat holds
and their lines read *Name (gallery)*. Each line is a ledger line, so it
replays with the game, and the hall counts lines said while you were away.
- **A rematch**: a finished table may call for one. A new table of the same
size opens with the same bots, seats held for the same people, and the
caller as host; a second call finds it already open. Held seats refuse
strangers until their players are back.
- **The keeper's bell**: while a table is laid, a seated player may
*Challenge the keeper*. A seat is held under the keeper's name, the call
goes on the ledger, and the keeper's phone rings through Sentry. The note
beside the button says what hour it is where the keeper lives, so a
caller knows whether to wait ten minutes or come back tomorrow.
- **A seat travels by phrase**: *Transfer seat* in the masthead mints four
words good for ten minutes and one use; the hall's *bring a seat from
another device* claims them. The browser that claims holds the seat too.
- **Held seats are doubted before they are dropped**: the hall forgets a
seat only on the second refusal in a row from the server. A restart, a
stale answer or the wrong backend answer with ignorance, and ignorance
is not deletion.
- **The ledger** is the append-only JSONL file that *is* the game: room,
seats, start (seed and rules revision), each seat's submitted input, the
turn that resolves them, talk, over. A room is its ledger replayed
@@ -102,6 +119,8 @@ Every game gets the same tools, installed by `deploy.sh` on every deploy:
before its reply goes out.
- Sentry: one project per game; `sentry-slack-alert.sh` routes every issue
to `#<slug>-notifications`, run once by the keeper with their own token.
- `KEEPER` and `KEEPER_TZ` in the service unit name the keeper a table may
call and where they sleep.
## The look