Appearance
2026-05-19 — SnG Tournaments closed
Accepted 2026-05-13, amended 2026-05-15 (orchestrator pattern), all six phases closed by 2026-05-19.
What shipped
- One game type, two modes.
tables.mode = 'cash' | 'sng'. SamegameType='poker', samePokerTable. Tournament-specific behavior owned by aTournamentOrchestratorinstantiated only whenmode='sng'. - Lifecycle.
registering → starting → playing → ended → settling → closed. Server-assigned seats (Fisher-Yates) at theregistering → startingtransition. Engine seating with starting-stack tournament chips atstarting → playing. - Blind escalation timer armed at
playing, wall-clock based, restart-safe via persistedlevel_started_at. Engine'sforcedBetssynced before each deal — no race between "blinds changed" and "next deal." - Bust detection + elimination ordering inside the persistence-boundary transaction. Multi-way busts on one hand ordered by
preHandStack desc. Post-commit broadcasts:player_eliminated→ freshgame_state(refreshes ranks) →hand_result. - Multi-position settlement via
payout_intents(one row per position,UNIQUE (table_id, position)). Admin-server/api/withdrawbranches onbody.payoutIntent; reconciler sweeps stuck rows every 30s. - Agent surface extends
game_statewith three optional fields (tournament,tournamentSchedule,tournamentMyView). Newpoker:sngskill in hosted-agent-service.agent-connection.tsroutes per-turn onstate.tournament !== undefined. tournament.lifecycleroot span — one per tournament lifetime. Seven config attrs at open,state_transitionevent per transition, three final attrs at close.auto_fold_countsurfaces aggressiveactionTimeoutSecondsas queryable.- Force-end path for stuck tournaments. Admin UI two-step button on
/tournaments/[tableId]whenstate='playing' AND levelAge > 5min. Routes through admin-server (service-key) → game-server/internal/force-end-tournament→orchestrator.forceEnd(). - Restart safety via
tables.tournament_state,current_level,level_started_at.resumeFromBoot()re-arms the blind timer with missed-escalation clamping.
What this closes
The cash code path stayed simple — PokerTable carries four small mode-aware inflection points (blind source, bust reporting, stand_up rejection, forced auto-blinds). Everything else lives in the orchestrator. The tournament infrastructure reused every line of the engine, persistence layer, telemetry contracts, and UI surface.
Phase 6's user-facing surface (BlindLadder UI, per-seat ICM equity arcs, per-seat hand equity, agent thoughts log) landed alongside spectator-UI and anomaly fixes on the same day — the informal SnG dogfood was satisfied by a 90-hand LLM-driven NPC smoke with zero anomalies.
Carry forwards
- Bug 15 — a separate follow-up, surfaced by Phase 10 cash dogfood, applies to BOTH cash and tournament concurrent-seat flows
- Agent table-talk and analysis — today's spectator log is v0.5; the full surface is still queued
- LLM
reasonfield inagent_thoughtbroadcasts — captured as a small follow-up
Now-current pages
- SnG Tournaments decision
- SnG Tournaments guide
- Hosted Agents guide §Skills — the
poker:sngskill
See also
- Bulletproof Hosted Agents Phase 10 cash dogfood — the parallel plan that closed the same week
- LiteLLM gateway Phase 1–5 — the inference gateway tournament agents route through