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

When the sea goes wrong, an admin starts the next round without a deploy #43

open not picked up yet opened this
opened this

When the sea goes wrong — a round wedged, a field poisoned by a tuning mistake, a gate nobody can reach — an admin ends it and starts the next one through a door, not by pushing a commit and waiting for a deploy.

The world is one long-lived process and #11 tunes it against real play, so recovery has to be an operation. who.ts already separates admin from user, and nothing in the app uses the distinction yet. #30 makes a dead loop say so; this is how a person answers it.

Done looks like

  • [ ] One action in src/actions.ts — resetRound(db, who, input) — and the rule lives only there:

a who.role that is not admin gets a named failure, at every door, including the terminal.

  • [ ] It ends the round in progress as abandoned rather than scoring it as a win, clears the current

field, and starts a fresh round with a new gate. The tick never stops and nobody reloads.

  • [ ] Every door calls it and none of them decides anything: POST /api/round/reset (same-origin,

403 for a non-admin, rationed like any write), an MCP tool with one sentence and a schema, a key in src/tty.ts, and a control on the page rendered only for an admin.

  • [ ] round.ended then round.started emit on the bus exactly as a natural round boundary does, so

an open page and an open socket both follow it without a special case (#40 decides which bus carries which).

  • [ ] An abandoned round is distinguishable in the data from one that ended on the clock or on the

gate, so the ladder can decline to count it.

  • [ ] Tests: each door refuses a guest and a signed-in non-admin; an admin's reset ends the old round

and the new one has a different gate; the abandoned round is marked; the loop is driven by hand, no sleeping test.

Files src/actions.ts, src/actions.test.ts, src/round.ts, src/routes.ts, src/mcp.ts, src/tty.ts, src/page.ts, src/server.test.ts.

Risks This is a button that ends twenty-three other people's round: say in the pull what stands between a stray tap and a reset, and make the page's control the one that is hardest to hit by accident. Do not add a second way to mutate the world — if the terminal or MCP needs anything the action does not expose, the action grows, not the door. An admin door is also the first thing an attacker reaches for: the refusal is tested at each door, not assumed from one.

Waits on #8.

Fits Vesper's brief: a game has a loop, a state and a way to save.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs