Summary
Per-Demo Breakdown
The 8 Failures
All 8 failures arestatusIsFavourite assertions. They share a common root cause: the oracle was sourced from the v4 C# Monte Carlo implementation, while the v6 Node.js server uses a fresh simulation run. When two or more hands have nearly identical win probabilities, the two implementations pick different tiebreakers.
None of these are bugs in the v6 engine. The game renders exactly what the server computed. The discrepancy is between the oracle (v4 C# result) and what the v6 server freshly calculates.
Failure 1: Demo 2, FLOP, hand 0 statusIsFavourite
Test:Demo 2: All hands have action — FLOP — hand 0 statusIsFavourite
Cards at FLOP: AdAs (Pair of Aces) · 6c4d (Pair of Sixes) · JhQh (Pair of Jacks) · 3cJd (Two pair)
Analysis: The oracle (v4 C#) recorded hand 0 as favourite despite hand 2 having more than 6× its win probability. This appears to be an error in the original coredata oracle. The v6 server correctly identifies hand 2 (JhQh — Pair of Jacks, 45%) as the favourite.
Failure 2: Demo 2, FLOP, hand 2 statusIsFavourite
Test:Demo 2: All hands have action — FLOP — hand 2 statusIsFavourite
Same scenario as Failure 1 — the flip side of the same discrepancy. The oracle says hand 2 is not the favourite; the server says it is.
Expected (oracle): false
Actual (server): true
Failure 3: Demo 8, FLOP, hand 1 statusIsFavourite
Test:Demo 8: One hand can't lose — FLOP — hand 1 statusIsFavourite
Cards at FLOP: 3d9s (Pair of Threes) · 5c6d (Pair of Fives) · QhQs (Pair of Queens) · 3h8h (Pair of Threes)
Analysis: Oracle assigns the favourite badge to hand 2 (QQ at 33%) despite hand 1 (56 suited at 47%) having a significantly higher win probability. This is a coredata oracle error — the v6 server is correct.
Failure 4: Demo 8, FLOP, hand 2 statusIsFavourite
Test:Demo 8: One hand can't lose — FLOP — hand 2 statusIsFavourite
The flip side of Failure 3. Oracle says hand 2 is favourite; server says it isn’t.
Expected (oracle): true
Actual (server): false
Failure 5: Demo 15, HOLE, hand 0 statusIsFavourite
Test:Demo 15: All Equal from start — HOLE — hand 0 statusIsFavourite
Cards at HOLE: KsAd · KhAs · KcAh · KdAc (all four hands are AK, different suits)
Analysis: All four hands are genuinely identical in equity (same rank, different suits). The oracle assigns the favourite to hand 0 using a first-index-wins tiebreaker from the v4 C# implementation. The v6 Node.js server uses a different tiebreaker based on the Monte Carlo simulation and arrives at a different index.
This is expected behaviour — with truly equal odds, tiebreaker choice is arbitrary. Neither result is wrong.
Failure 6: Demo 15, HOLE, hand 2 statusIsFavourite
Test:Demo 15: All Equal from start — HOLE — hand 2 statusIsFavourite
Same equal-odds scenario. The server selects a different hand as the single favourite (not hand 0, not hand 2). Both the oracle’s hand 0 and the server’s choice are valid tiebreaker resolutions.
Failure 7: Demo 16, HOLE, hand 0 statusIsFavourite
Test:Demo 16: All Equal but not for long (v2) — HOLE — hand 0 statusIsFavourite
Same equal-odds scenario as Demos 15–16 at HOLE — all four hands are AK (different suits) and truly identical in win probability. The oracle and server disagree on which index holds the tiebreaker.
Failure 8: Demo 16, HOLE, hand 3 statusIsFavourite
Test:Demo 16: All Equal but not for long (v2) — HOLE — hand 3 statusIsFavourite
Flip side of Failure 7. Oracle says hand 3 is not the favourite; server may select hand 3 (or a different index) as the tiebreaker winner.
Assessment
The v6 server→client pipeline is correct. Odds computation, hand evaluation, hand descriptions, winner detection, cantLose detection, dead-hand detection, and game-over triggering all validate against the server’s fresh computation across all 17 demo scenarios and all 4 betting stages.
The 8 failures represent limitations of the oracle data, not bugs in the game engine. Recommended actions:
- Demo 2 and Demo 8: Update the oracle in
demo-records.tsto match the server’s correct favourite calculation. - Demos 15–16: Accept that equal-odds tiebreaker is non-deterministic between implementations. Consider either skipping
statusIsFavouriteassertions when all hands have equal equity, or updating the oracle to match whichever index the v6 server consistently returns.