You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Closes#1609. UI: muchq/muchq.github.io PR on branch claude/rummy-dealers-choice.
Every rummy table is dealer's choice:
Tablelibs/cards/rummy/table.{h,cc}: startGame opens it choosing, seat 0 dealing. The dealer's chooseVariant deals; the seat after the dealer opens. A deal won by play credits the winner a hand and passes the deal on. Below two seats the table closes. The dealer's chair follows its holder on leaves, including mid-deal. A dealer the room shows disconnected lets any seat deal.
Rule change: seven cards a seat at every table size (was ten at two).
Serdetable_serde: v2 row. A v1 row (one deal) loads as a one-deal table; ten-card rows still load.
Wiremodel/rummy.smithy: chooseVariant; the view gains variant, dealNumber, standings, choosing, lastDeal; phase choosing. A deal's end rides the view's lastDeal; gameEnded is the table's (standings, dealsPlayed).
Hub: each deal is a game to room stats and the event log (game_started on deal, game_finished on its end), credited in the deal-ending commit. The room listing restages on deal start and end.
Stats: a member upsert updates presence only; stats move only by a finish's increments. A sibling's stale presence write could erase a remote deal's credit, which rummy now makes common.
rummy_e2e_test: next dealer's choice and rotation, away dealer, dealer leaving between deals, table close; whole seeded games at 2/3/4 seats against the engine.
rummy_wire_test: goldens for the choosing view, refusals, dealt views, a deal's end, the table's end.
hub_e2e_test: event log records each deal as a game.
Postgres-gated: pg_hub_store_test (PresenceWritesLeaveStatsToTheirIncrements), pg_hub_e2e_test (restart mid-deal). Ran locally against Postgres 16.
Locally: bazel test //domains/games/... 181/181 with Postgres and CI=1; mutation checks on dealer rotation, away dealer, room staging, event log and the empty-turn guard. Played end to end in headless Chromium against a local hub.
Review panel ran on the first push; its survivors are the last commit. Not fixed here:
Four lenses + Bugbot. Bugbot found no bugs. Correctness and resource-safety clean — review-fix commit still holds (mid-deal dealer pass, presence-only upsert). Altitude is right: TableState over one-deal GameState, deal-as-game stats/events with lastDeal vs table gameEnded, Gin/500 correctly underbuilt. Known won’t-fix (#1295 stuck connected, golf-style unknown-fate event lines) accepted as documented. build-and-test / sanitize still running at post time.
Verdict: LGTM with test fold-ins. Design and the presence/stats race fix look solid; leftovers are unpinned hub refusals / standings.
Survivors (verified):
Tests — chooseVariant during a live deal unpinned at hub/wire. Engine has NoChoosingWhileADealIsInPlay (status code only). Wire/e2e pin non-dealer choice and unknown variants, and refuse draws between deals, but never send chooseVariant while phase == "playing". Assert "not between deals" on the stream (and pin the reason in the unit test).
Tests — leave mid-deal never pins non-zero standings on gameEnded.ALeaveMidDealClosesTheTableWithItsStandings / LeavingMidGameAbandonsItWithNoWinner close on deal 1 with handsWon: 0. After a won deal, leave mid-next-deal is untested — zeroing getWins() on close would stay green. Compaction while choosing is covered; close-with-prior-wins is not.
Tests (soft) — between-deals view has no KeysOf / view-level variant pin. Dealt view has a full golden + KeysOf. Deal-end asserts choosing / lastDeal / standings dumps only; dropping or renaming view-level variant between deals would not fail the wire suite the way a dealt-view rename would.
Altitude (named, ship): Seven-card at every seat size is hitchhiking on dealer’s choice (Gin wants ten at two anyway) — fine as the named companion it already is; serde still loads ten-card rows. Presence-only ON CONFLICT is the right altitude for the stats race; Memory still full-replaces (harmless single-writer).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1609. UI: muchq/muchq.github.io PR on branch
claude/rummy-dealers-choice.Every rummy table is dealer's choice:
libs/cards/rummy/table.{h,cc}:startGameopens it choosing, seat 0 dealing. The dealer'schooseVariantdeals; the seat after the dealer opens. A deal won by play credits the winner a hand and passes the deal on. Below two seats the table closes. The dealer's chair follows its holder on leaves, including mid-deal. A dealer the room shows disconnected lets any seat deal.table_serde: v2 row. A v1 row (one deal) loads as a one-deal table; ten-card rows still load.model/rummy.smithy:chooseVariant; the view gainsvariant,dealNumber,standings,choosing,lastDeal; phasechoosing. A deal's end rides the view'slastDeal;gameEndedis the table's (standings,dealsPlayed).game_startedon deal,game_finishedon its end), credited in the deal-ending commit. The room listing restages on deal start and end.Tests:
table_test,table_serde_test(frozen payload, v1 rows, hostile rows),game_state*for seven cards.rummy_e2e_test: next dealer's choice and rotation, away dealer, dealer leaving between deals, table close; whole seeded games at 2/3/4 seats against the engine.rummy_wire_test: goldens for the choosing view, refusals, dealt views, a deal's end, the table's end.hub_e2e_test: event log records each deal as a game.pg_hub_store_test(PresenceWritesLeaveStatsToTheirIncrements),pg_hub_e2e_test(restart mid-deal). Ran locally against Postgres 16.Locally:
bazel test //domains/games/...181/181 with Postgres andCI=1; mutation checks on dealer rotation, away dealer, room staging, event log and the empty-turn guard. Played end to end in headless Chromium against a local hub.Review panel ran on the first push; its survivors are the last commit. Not fixed here:
connectedin the room (golf_hub: restored members are never reaped — a deploy turns the 5-minute grace into forever-membership, breaking room share links (muchq.github.io#260) #1295), so other seats can't deal; leaving is the way out.Gin (#1610) and Rummy 500 (#1611) are next.
Generated by Claude Code