- Shipped
- September 8, 2026 at 7:11 AM UTC
- Author
- Kamo
- Commit
- 1bc3238
Up to ten players a table, started from any conversation, with anyone else in the organization invitable into it. Every rule lives here; the browser owns none. ## The engine is pure Java and it is proved by enumeration HandEvaluator ranks all C(52,5) = 2,598,960 five-card hands in its own test and checks the count in each category against the textbook distribution — 40 straight flushes, 624 quads, 3,744 full houses, 5,108 flushes, 10,200 straights, 54,912 trips, 123,552 two pair, 1,098,240 pair, 1,302,540 high card. That is the perft of poker: an evaluator that ranks the wheel ace-high, or reads a kicker off the wrong slot, passes every hand anybody would think to write down and fails here, because the miscounted hands have to go somewhere and the totals stop adding up. PotSolver's randomised test found a real defect before this shipped: with two folded players committed above the last player standing, 102 chips vanished into neither a pot nor a refund. An uncalled bet needs TWO caps — nobody contests more than the largest anybody else put in, AND nobody contests more than the largest any player still in the hand put in. A solver that destroys money in a state it believes unreachable is the bug that surfaces the day it turns out to be reachable. HoldemEngine gets the three rules everybody gets wrong: the big blind's option (posting is not acting), an incomplete all-in NOT re-opening the betting, and a minimum raise that tracks the last raise rather than the blind. ## Chips are not cheddar HOLDEM_SEATS.STACK moves on every action; the wallet moves exactly TWICE per seat. Charging per bet would put a cross-namespace round trip inside a thirty-second action clock and turn one evening into four hundred unreadable ledger rows. The buy-in is two-phase: the seat row is written first and the idempotency key **************** is DERIVED from it, so a retry after a crash, a timeout or a duplicate click is a no-op rather than a second $20. HoldemSettlementSweep finishes any seat left half-bought, which is safe precisely because the key is derived and not generated. ## holdem.member.{memberId}, and why it could not be per table Every seated player needs a DIFFERENT redaction of the same table — their own two cards and nobody else's — and a railbird a third. A per-table subject can carry one payload, so it would contain either everybody's hole cards or nobody's; neither is poker. Eleven recipients mean eleven frames, each built for the person it is addressed to. The SEND half of StompDestinationAuthz matters more here than anywhere: a frame carries hole cards and legal actions, and the felt draws whatever arrives. ## Deadlines are data ACTION_DEADLINE and NEXT_DEAL_AT are columns, enforced by a one-second sweep on every pod with conditional updates guarded by the hand's action sequence. Two pods racing produce one fold; a player who acted a millisecond early is folded by neither; a pod dying mid-hand cannot freeze nine colleagues. Tests: 35 across the evaluator, the solver, the engine, the topic guard, the idempotency keys, and a boot-time compile of every hand-written @Query — a malformed one crash-loops the pod and nothing else catches it.