id: 38c788074c2e4ed49bf13e01c35a5e61
parent_id: 1a3736233bfe4b0f9078d4ddb6bdc6bd
item_type: 1
item_id: 60976d006f58404387784a6b90ebf04c
item_updated_time: 1782623988213
title_diff: "[]"
body_diff: "[{\"diffs\":[[0,\"racker\\\n\\\n\"],[1,\"> \"],[0,\"Updated \"]],\"start1\":28,\"start2\":28,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\"06-2\"],[-1,\"3 (session 2).\\\n\"],[1,\"8. \"],[0,\"Prod\"]],\"start1\":51,\"start2\":51,\"length1\":23,\"length2\":11},{\"diffs\":[[0,\"h_nl\"],[-1,\".toml` = `ng_preflop` + `g3_postflop_rollout`.\\\nServer: `live_server` on 127.0.0.1:8088 (debug log).\\\n\\\n---\\\n\\\n## D4 — Dealer button almost always reported as seat 0 ✅ FIXED & VERIFIED\\\n\\\n**Root cause:** React renders dealer chip AFTER blind messages → `snap.dealerSeat` always `undefined` at `buildGameStart()`.\\\n\\\n**Fix (three layers):**\\\n1. SB-seat derivation (parser.ts) — button = previous active player CCW from SB\\\n2. DOM chip confirmation (index.ts) — `confirmed_dealer_seat` sent with `waiting_for_action`\\\n3. Server correction (table_state.rs) — corrects `button_seat` + `is_dealer` before `decide()`\\\n\\\n**Also fixed:** `hero_position_label()` counts dealt-in players (excludes SittingOut). Now running (server restarted this session).\\\n\\\n**Committed:** super_marvin `8b330e1`, userscripts `d203f4d`.\\\n\\\n---\\\n\\\n## Hands Audit Notebook\\\n\\\nDetailed analysis in **Hands Audit** notebook (`56a8e67a02b64db68edbe5e58fb205c6`).\\\n\\\n---\\\n\\\n## STILL OPEN — Bot Strategy\\\n\\\n### B7: Bot too passive postflop (range model too tight) — PARTIALLY ADDRESSED\\\n**Root cause:** Gen 3 opponent ranges are binary (0/1) with tight cutoff → win_prob underestimated → folds top pair.\\\n**Hand evidence:** Hand #175 (KJo top pair fold, win_prob=0.217 vs 0.245 pot odds), Hand #159 (AhTd pair+flush draw fold), Hand #29 (ATs flop fold at 18:1).\\\n**This session:** Added `range_looseness=0.30` + `range_floor=0.03` — widens opponent ranges to model loose tables. Committed `d641780`.\\\n**Still needed:** Lower `bet_adj_cap` from 2.0 → 1.0-1.5 for multi-way pots.\\\n\\\n### B9: Preflop too tight for premiums in SB\\\nHand #3: AQo folded at 4:1 pot odds. ng_preflop SB thresholds too conservative.\\\n\\\n### B8: `num_callers` counts ALL calls (incl. SB post + limpers)\\\nFile: `strategy_bot.rs:119-122`. Inflates call threshold.\\\n\\\n### B1: All-in without stack/sizing awareness\\\nFile: `rollout_postflop_gen3.rs:1040`.\\\n\\\n---\\\n\\\n## STILL OPEN — Userscript\\\n\\\n### U5: `clickWhenReady` retry doesn't re-validate hand ID\\\nFold click sometimes doesn't register → hero stays in hand (Hand #167: bot folded but hero called $9000).\\\n\\\n### U6: Events lost on observer re-attachment\\\n\\\n---\\\n\\\n## STILL OPEN — Data Pipeline\\\n\\\n### D1: Missing ante events (chronic) — pot undercounted\\\n### D2: Timestamp-based hand IDs (recurring)\\\n\\\n---\\\n\\\n## RESOLVED\\\n\\\n- [x] **D5: Stale hole cards across hands** — Fixed: `lastHeroCards` tracking in parser.ts (commit `c38af6e`, v0.1.5)\\\n- [x] **U4: Player names containing \\\"flop\\\"/\\\"turn\\\"/\\\"river\\\"** — Fixed: word-boundary regex (commit `c38af6e`, v0.1.5)\\\n- [x] **D4: Dealer button stuck at seat 0** — SB derivation + chip confirmation + server correction\\\n- [x] **U3: k/M suffix raise parsing** — `parseAmount` handles k/M suffixes\\\n- [x] **U1: seenTexts never cleared** — `resetHand()` clears seenTexts\\\n- [x] **D3: SB amount=0** — Client-side SB synthesis + server-side derivation\\\n- [x] **Range too tight (table-adaptive)** — `range_looseness` + `range_floor` params (commit `d641780`)\\\n- [x] **powf(0) raise gate** — `aggression_adjustment()` floors to 1.0\\\n- [x] **B3: Suited one-gappers** — ng_preflop uses 169-hand ranking tables\\\n- [x] **B4: 93.5% fold rate facing postflop bets** — `call_adj_cap=1.2`\\\n- [x] **B5: 85% check rate when first-in** — `bet_adj_cap=2.0` (still needs further lowering)\\\n- [x] **B6: SB completion too tight** — 0.60 threshold\\\n- [x] **Preflop re-raise pot odds** — `reraise_potodds_call_ratio`\\\n- [x] **f64::MAX sentinel** — Fixed\\\n- [x] **action_commits_me cost** — Fixed\\\n- [x] **Rigid 50% pot bet sizing** — Dynamic sizing\\\n- [x] **sweep_mode in production** — `sweep_mode = false`\\\n- [x] **U2 (partial)** — forceFlush synthesizes SB+BB\\\n\\\n---\\\n\\\n## Production Config (cash_nl.toml — Gen 3)\\\n\\\n| Parameter | Value | Purpose |\\\n|-----------|-------|---------|\\\n| \"],[1,\"_g4_live.toml` (Gen 4 adaptive).\\\n> Server: `live_server` on 127.0.0.1:8088.\\\n\\\n---\\\n\\\n## Current Open Issues\\\n\\\n### Strategy Issues\\\n\\\n| ID | Issue | Status | Details |\\\n|---|---|---|---|\\\n| **S1** | Passive postflop play | 🔄 Open | Bot rarely bets first-in postflop. Most first-in decisions default to CHECK. Needs higher `bet_flop_base` / `strong_hands_fraction`. |\\\n| **S2** | Cold start waste | 🔄 Open | Observer resets to Gen 3 defaults for ~5 hands after restart, even with profile files on disk. Fix: check loaded profile `hands_observed` on startup. |\\\n| **S3** | Preflop looseness not wired | 🔄 Open | `g4_adaptive_preflop` computes VPIP-based looseness factor but doesn't apply it to NG preflop thresholds (TODO at `adaptive_preflop.rs:120`). |\\\n| **S4** | Range prediction 13% miss | 🔄 Open | 87% hit rate concentrated misses vs very tight/loose opponents. S-curve construction may need per-VPIP-tier parameters. |\\\n\\\n### Fixed Issues (2026-06-27)\\\n\\\n| ID | Issue | Fix |\\\n|---|---|---|\\\n| ~~B1~~ | All-in without stack/sizing awareness | Pot odds gate in `should_raise()`: large bet penalty + SPR penalty + hard equity gate (hs<0.60 → threshold≥0.65) |\\\n| ~~B7~~ | Bot too passive postflop | `range_tightness_scale=0.8` compensates for narrowed ranges. 3 rounds of curve sweeps tuned thresholds. `bet_turn_base=0.58`. |\\\n| ~~B8~~ | `num_callers` counts limpers | Fixed: `num_callers` now only counts callers who answered the last raise |\\\n| ~~Call mismatch~~ | SB call computed as full BB | `reconcile_missing_blinds()` runs before every non-blind preflop action |\\\n| ~~Range too tight~~ | Binary ranges | Gen 4 S-curve range construction with configurable narrowing + looseness |\\\n\\\n### Userscript Issues\\\n\\\n| ID | Issue | Status |\\\n|---|---|---|\\\n| **U5** | `clickWhenReady` retry doesn't re-validate hand ID | 🔄 Open |\\\n| **D1** | Missing ante events (chronic) — pot undercounted | 🔄 Open |\\\n\\\n---\\\n\\\n## Parameter Sweep Results Summary\\\n\\\n### 19-param sweep (initial)\\\nTop 5: `nut_draw_ppot_thresh` +4.60, `call_turn_small_bet` +4.44, `rope_a_dope_otb` +3.57\\\n\\\n### Curve tuning sweep (3 rounds, applied to live config)\\\n| Round | Best param | Value | Δ |\\\n|---|---|---|---|\\\n| R1 | `bet_turn_base` | 0.58 | +459 |\\\n| R1 | `scurve_steepness_mult` | 0.3 | +45 |\\\n| R2 | `narrow_center_offset` | 0.2 | +46 |\\\n| R2 | `range_tightness_scale` | 0.8 | +31 |\\\n| R3 | `strong_hands_fraction` | 0.30 | +18 |\\\n| R3 | `call_w_draw` | 0.75 | +16 |\\\n\\\n### Validation sweep (2026-06-27)\\\n- g4_live vs chump: **+253 BB/100** (g2 baseline: +191 BB/100 → +62 improvement)\\\n- g4_live vs flock: +2.2 BB/100 (3/10 seeds crashed due to flock_bot raise bug — now fixed)\\\n\\\n---\\\n\\\n## Current Live Config Values (`cash_nl_g4_live.toml`)\\\n\\\n```\\\nmc_samples = 50000\\\nstrong_hands_fraction = 0.30\\\n\"],[0,\"call\"]],\"start1\":78,\"start2\":78,\"length1\":3717,\"length2\":2740},{\"diffs\":[[0,\"ase \"],[-1,\"| 0.50 | Base call threshold |\\\n| call_adj_cap | 1.2 | Call threshold adjustment cap |\\\n| bet_adj_cap | 2.0 | ← **still needs lowering (B7)** |\\\n| \"],[1,\"= 0.45\\\ncall_ppot_base = 0.25\\\ncall_w_draw = 0.75\\\ncall_w_pot_odds = 0.70\\\n\"],[0,\"bet_\"]],\"start1\":2820,\"start2\":2820,\"length1\":152,\"length2\":79},{\"diffs\":[[0,\"ase \"],[-1,\"| 0.52 | Flop betting threshold |\\\n| \"],[1,\"= 0.30\\\n\"],[0,\"bet_\"]],\"start1\":2905,\"start2\":2905,\"length1\":44,\"length2\":15},{\"diffs\":[[0,\"ase \"],[-1,\"| 0.70 | Turn betting threshold |\\\n| \"],[1,\"= 0.58\\\n\"],[0,\"rais\"]],\"start1\":2926,\"start2\":2926,\"length1\":44,\"length2\":15},{\"diffs\":[[0,\"ase \"],[-1,\"|\"],[1,\"=\"],[0,\" 0.80\"],[-1,\" | Value raise threshold |\\\n| **range_looseness** | **0.30** | Medium-tier hands at 30% weight |\\\n| **range_floor** | **0.03** | Min 3% weight for all hands |\\\n| sweep_mode | false | Production mode |\\\n\\\n---\\\n\\\n## Priority Remaining Fixes\\\n\\\n1. **B7** (bet_adj_cap) — lower from 2.0 → 1.0-1.5\\\n2. **B8** (num_callers) — count only post-last-raise callers\\\n3. **B9** (preflop premiums SB) — check ng_preflop thresholds\\\n4. **U5** (clickWhenReady) — re-validate hand ID on retry\\\n5. **B1** (all-in sizing) — stack-depth check\\\n6. **D1** (missing antes) — pot accuracy\"],[1,\"\\\nraise_w_protection = 0.35\\\nbluff_hs_max = 0.05\\\nsemi_bluff_max_bet_ratio = 0.30\\\nrange_looseness = 0.05\\\nrange_use_scurve = true\\\nscurve_steepness_mult = 0.3\\\nscurve_floor = 0.05\\\nnarrow_strength_mult = 1.0\\\nnarrow_center_offset = 0.2\\\nrange_tightness_scale = 0.8\\\n```\\\n\\\n---\\\n\\\n## Next Session Audit Plan\\\n\\\n1. Start live server, resume play\\\n2. Trigger hand audits — replay recent hands through replay engine\\\n3. Run parameter sweeps targeting S1 (passive postflop):\\\n   - Increase `bet_flop_base` (0.30 → 0.35-0.40)\\\n   - Increase `strong_hands_fraction` (0.30 → 0.35-0.40)\\\n   - Sweep `bet_adj_cap` (currently 2.0, try 1.5)\\\n4. Fix S2 (cold start) and S3 (preflop looseness)\"]],\"start1\":2944,\"start2\":2944,\"length1\":561,\"length2\":667}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-06-28T05:27:39.568Z
created_time: 2026-06-28T05:27:39.568Z
type_: 13