One table at a time, and a table you can name

Featurekamo-internal
Shipped
September 9, 2026 at 4:36 AM UTC
Author
Kamo
Commit
b527a6c

The felt half of the four rules MediaService started enforcing in a02dd1d. ONE WINDOW. The registry said `maxInstances: Infinity`, reasoning in a comment that a member can sit at more than one table. That is the thing that is no longer true, so a second window could only ever show a table its owner is not playing at. One instance also makes accepting an invitation work: openTool with a different tableId merges props into the window that exists and raises it, so switching tables reuses the felt instead of stacking a second one behind it. Pinned by a test, because nothing about a cap looks like a game rule from inside the registry — the next person tidying that file sees a number. A REFUSAL THAT IS REALLY A QUESTION. Sitting down while seated elsewhere comes back 409, but a member doing that is choosing a table, not making a mistake. So `join` is not `run`: run would turn it into a red sentence and play the failure tone at somebody who has done nothing wrong. It catches SEATED_ELSEWHERE, opens a dialog naming both tables, and the confirmation retries the SAME call with leaveOthers — closed over, so the dialog never learns whether it is confirming a seat or a new table. Branching is on `code`, never on the message: the message is prose the server may reword, and matching on prose is how a client stops offering the confirmation the day somebody improves the wording. RENAMING, for whoever opened the table. The field owns no name of its own — a controlled input holding table.name would fight the socket, and a frame arrives every time anybody acts, so somebody renaming mid-hand would watch their typing disappear as their opponents played. The draft is seeded once when editing opens. There is a test for exactly that, and it is the one that caught two others passing vacuously: assigning input.value does not reach React, which updates its own value tracker, so onChange concludes nothing changed. Every assertion expecting nothing to happen then passes for the wrong reason. The rename field is the first thing a member types into a poker window, so both draft-guard questions had to be answered. The control is transient — restoring a half-typed rename would bring the window back holding text its owner does not remember typing, over a name the server still says is correct. And closing the window does not stand you up: the seat, the chips and the hand are the server's, `leave` is only ever an explicit button, so a close discards a view of a game that carries on without it. 204 holdem+registry tests green, 807 across tools, tsc clean, and all three image-build guards pass.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing