Public: anyone can read this; the crew can change it.

A table fills, or it dies: an invite link, a seat an agent can take, and open tables that expire #33

open not picked up yet opened this
opened this

Intent. The likeliest way this game is never played is a table that sits at two seats forever — so opening a table comes with the means to fill it: a link you can send, a seat a crew agent can be invited into, and an expiry so the lobby is never a graveyard of half-full tables.

Done looks like

  • [ ] An open table has a share link — the table's own URL, which a guest may open, read and watch, with one line telling them signing in is how they sit down. No secret token: the table is public, the charges are not.
  • [ ] openTable takes fill: "wait" | "start_when_full"; with start_when_full the table starts itself the moment the last seat is taken, in the same transaction as that join, and emits table.started exactly once. A test races two joins and asserts one start.
  • [ ] An open table that has not started within its open_seconds (default 24h, validated range) is abandoned: a terminal status, nobody is scored, the lobby shows it under finished, and the same lazy catch-up #11 uses does it at read time — no timer, no job.
  • [ ] The host may start early once SEATS_MIN are seated (that rule is already #8's startTable; this issue only makes the page and the terminal offer it at the right moment, from canStart).
  • [ ] Agents sit down the way people do: the MCP join_table tool is enough, and README.md shows the two lines that put a crew agent in a seat — no new door, no invite token, no impersonation.
  • [ ] The lobby sorts open tables by how close they are to full and shows seats as 3 of 5, so a visitor can see where one more player matters.
  • [ ] Tests: a table fills and starts once; a table expires and cannot then be joined or started; a guest opening the link sees the table and no charge; start_when_full with the host as the last seat.

Files src/db.ts, src/actions.ts, src/actions.test.ts, src/routes.ts, src/pages/*.ts, src/tty.ts, src/server.test.ts, README.md.

Risks Two people taking the last seat at the same moment is the one race here — the join and the start are one transaction or the table starts twice. An expiry that runs at read time must be idempotent for the same reason #11's catch-up must be. Keep open_seconds in the same validated style as the turn window and the deadline, and put the number in RULES.md §2 with the others.

Brief that fits @ledger — a state change as a row, with the race written down. (A person assigns.)

commented

Note: #83 is changing the deadline validation in openTable (from 2 × turn window to the windows a binding actually takes) and the clock defaults with it. The open_seconds expiry this issue adds sits beside that validation — write it against the rule as #83 leaves it, and keep the refusals in the same voice.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs