Let the banker check the cash box against the chips on the table #50

Closed
jheaps wants to merge 1 commits from feature/casino-holdem-bank-audit into feature/casino-holdem-fewer-taps
Owner

I'd run out of things I could find by auditing the UI, so I took the prompt's suggestion and read what people who actually run home games complain about. The recurring problem isn't a dealing mistake, it's a banking one:

"the last two guys go to cash out at the end of some all-night game and there isn't enough cash to cover the chips they have"

Every chip on the table is a promise to pay cash for it later. Nothing in here checked that the promise could be kept — and you can't notice by eye. It's always a rebuy nobody wrote down, or chips taken without paying, and it stays silent until the box is empty and two people are still holding chips. Stacked on #49.

The books now add up, or say why not

HoldemState.bankReconciliation compares cash taken in against every chip that could be handed back — stacks, chips in front of players, and the pot waiting to be won. The sidebar shows both numbers and what they mean:

Cash Chips Verdict
$300 $300 Balanced — the cash covers every chip on the table.
$300 $460 $160 more in chips than cash taken. Someone's rebuy probably wasn't recorded — the box will be short at cash-out.
$450 $300 $150 more cash than chips in play. Someone has paid for chips they haven't been given.

Money in the middle counts as chips in play, so an open pot isn't reported as a shortfall — otherwise it would cry wolf during almost every hand.

Players who had bought in were missing from the settle-up

sessionStandings was built from the hand log, so anybody not yet in a recorded hand didn't appear at all. Somebody hands over $200, sits down, folds a few — and the banker's own record doesn't mention them. Then they turn up at cash-out holding chips the list never accounted for.

Anyone with money in the game is in the list now, whether or not they've played a logged hand, and their row reads as level rather than as a loss.

The settle-up number was already computed and hidden

cashPosition — chips in front of them less the cash they handed over — was calculated for every player and written to the CSV, but never shown on screen. It's the number you read while counting out cash at the end of the night, so it's a column now.

Validation

15 new tests (127 total, all passing): a buy-in with no hands played appears and reads as level; empty chairs stay out; a player who cashed out shows what they took; both directions of imbalance are caught; an open pot is not a discrepancy; six played-and-settled hands never knock the books out; a proper rebuy balances while a chip grab doesn't; float dust isn't an alarm.

Playwright through real play — seated → blinds posted → pot open → hand settled → $100 rebuy — balanced at every step, plus the three seeded verdicts above and a fresh table where the panel stays hidden. No console errors.

Scope note

This adds nothing to configure and no new panel to manage — it surfaces data the model already computed and fixes a gap in who gets counted. It passes the test I've been applying to anything feature-shaped: does it shorten the path to an answer while running the game? Settling up at 2am is exactly that moment.

Sources: How to Run a Poker Home Game, How to Handle Poker Buy-Ins With Friends

I'd run out of things I could find by auditing the UI, so I took the prompt's suggestion and read what people who actually run home games complain about. The recurring problem isn't a dealing mistake, it's a **banking** one: > "the last two guys go to cash out at the end of some all-night game and there isn't enough cash to cover the chips they have" Every chip on the table is a promise to pay cash for it later. Nothing in here checked that the promise could be kept — and you can't notice by eye. It's always a rebuy nobody wrote down, or chips taken without paying, and it stays silent until the box is empty and two people are still holding chips. Stacked on #49. ## The books now add up, or say why not `HoldemState.bankReconciliation` compares cash taken in against every chip that could be handed back — stacks, chips in front of players, and the pot waiting to be won. The sidebar shows both numbers and what they mean: | Cash | Chips | Verdict | | --- | --- | --- | | $300 | $300 | Balanced — the cash covers every chip on the table. | | $300 | $460 | **$160 more in chips than cash taken.** Someone's rebuy probably wasn't recorded — the box will be short at cash-out. | | $450 | $300 | **$150 more cash than chips in play.** Someone has paid for chips they haven't been given. | Money in the middle counts as chips in play, so an open pot isn't reported as a shortfall — otherwise it would cry wolf during almost every hand. ## Players who had bought in were missing from the settle-up `sessionStandings` was built from the hand log, so anybody not yet in a **recorded** hand didn't appear at all. Somebody hands over $200, sits down, folds a few — and the banker's own record doesn't mention them. Then they turn up at cash-out holding chips the list never accounted for. Anyone with money in the game is in the list now, whether or not they've played a logged hand, and their row reads as *level* rather than as a loss. ## The settle-up number was already computed and hidden `cashPosition` — chips in front of them less the cash they handed over — was calculated for every player and written to the CSV, but **never shown on screen**. It's the number you read while counting out cash at the end of the night, so it's a column now. ## Validation 15 new tests (**127 total, all passing**): a buy-in with no hands played appears and reads as level; empty chairs stay out; a player who cashed out shows what they took; both directions of imbalance are caught; an open pot is not a discrepancy; six played-and-settled hands never knock the books out; a proper rebuy balances while a chip grab doesn't; float dust isn't an alarm. Playwright through real play — seated → blinds posted → pot open → hand settled → $100 rebuy — **balanced at every step**, plus the three seeded verdicts above and a fresh table where the panel stays hidden. No console errors. ## Scope note This adds nothing to configure and no new panel to manage — it surfaces data the model already computed and fixes a gap in who gets counted. It passes the test I've been applying to anything feature-shaped: does it shorten the path to an answer while running the game? Settling up at 2am is exactly that moment. Sources: [How to Run a Poker Home Game](https://www.pokerlistings.com/blog/how-to-run-a-home-poker-game), [How to Handle Poker Buy-Ins With Friends](https://chipsoffury.com/learn/how-to-handle-poker-buy-ins-with-friends/)
jheaps added 1 commit 2026-09-01 07:33:45 -06:00
Ran out of things I could find by auditing the UI, so I went and read what people
who run home games actually complain about. The recurring one isn't a dealing
mistake, it's a banking one: "the last two guys go to cash out at the end of some
all-night game and there isn't enough cash to cover the chips they have."

Every chip on the table is a promise to pay cash for it later. Nothing in here
checked that the promise could be kept, and there's no way to notice by eye —
it's always a rebuy nobody wrote down, or chips taken without paying, and it
stays silent until the box is empty and two people are still holding chips.

The books now add up, or say why not

HoldemState.bankReconciliation compares the cash taken in against every chip that
could be handed back — stacks, chips in front of players, and the pot waiting to
be won. The sidebar shows both numbers and what they mean:

    Balanced — the cash covers every chip on the table.
    $160 more in chips than cash taken. Someone's rebuy probably wasn't
      recorded — the box will be short at cash-out.
    $150 more cash than chips in play. Someone has paid for chips they
      haven't been given.

Money in the middle counts as chips in play, so an open pot isn't reported as a
shortfall — otherwise it would cry wolf during almost every hand.

Players who had bought in were missing from the settle-up

sessionStandings was built from the hand log, so anybody who hadn't yet been in a
recorded hand didn't appear at all. Somebody hands over $200, sits down, folds a
few, and the banker's own record doesn't mention them — then they turn up at
cash-out holding chips the list never accounted for. Anyone with money in the
game is in the list now, whether or not they've played a logged hand.

The settle-up number was already being computed and hidden

cashPosition — chips in front of them less the cash they handed over — was
calculated for every player and written to the CSV, but never shown on screen.
It's the number you read while counting out cash at the end of the night, so it's
a column now.

15 tests (127 total): a buy-in with no hands played still appears and reads as
level rather than a loss, empty chairs stay out, a player who cashed out shows
what they took, both directions of imbalance are caught, an open pot is not a
discrepancy, six played-and-settled hands never knock the books out, a proper
rebuy balances while a chip grab doesn't, and float dust isn't an alarm.

Validated with Playwright through real play — seated, blinds posted, pot open,
hand settled, rebuy — balanced at every step, plus the three seeded verdicts and
a fresh table where the panel stays hidden.

Sources: pokerlistings.com/blog/how-to-run-a-home-poker-game,
chipsoffury.com/learn/how-to-handle-poker-buy-ins-with-friends/

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
jheaps closed this pull request 2026-09-01 09:32:16 -06:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jheaps/JoshHeaps.Net#50