id: ba64176cf3d74fb297d1e18aa2bc510d
parent_id: a0ba84c8077d49adafb4fc66ebb38c66
item_type: 1
item_id: f3c42f4435644e19b186265dd3fbf672
item_updated_time: 1786784410815
title_diff: "[]"
body_diff: "[{\"diffs\":[[0,\" #7 \"],[-1,\"(final design): Xpot Rollout Table + Hand-Fit Weight Curves\"],[1,\"IMPLEMENTED: Action-Likelihood Range Corrector\"],[0,\" (20\"]],\"start1\":6,\"start2\":6,\"length1\":67,\"length2\":54},{\"diffs\":[[0,\"08-1\"],[-1,\"4)\\\n\\\n## Problem\\\nOverpairs/TP overplayed on overcard boards (KK assessed 0.58-0.65 vs true ~0.10-0.25 v\"],[1,\"5)\\\n\\\n**Status: COMPLETE — sanity gates 10/10 pass (3×), live defect fixed, sim-neutral vs g50. Ready for live promotion a\"],[0,\"s \"],[1,\"`\"],[0,\"ca\"],[-1,\"ll-call-call lines). Production G50 (alpha=1.0) applies zero board-interaction reweighting — RangeNet output only card-excluded.\\\n\\\n## Design (agreed with user)\\\n\\\n### 1. Raw Xpot rollout table (per street, vs RANDOM hands — not ranges)\\\nFor each unmasked combo (≤169, typically ~40-90 after hero/board exclusion): MC rollouts vs uniform random opponent + random runout → hs,\"],[1,\"sh_nl_g51_live`.**\\\n\\\n## What was built\\\n\\\n`holdem_bots/src/gen4/range_corrector.rs` (~950 lines) — Bayesian refinement of opponent ranges AFTER the RangeNet prior:\\\n`P(hand | actions, board) ∝ P(actions | hand) × P(hand)`\\\n\\\n### XpotTable (shared per street, cached)\\\n- Exact hs percentile per combo (all-combo enumeration, no MC): flop 1081 combos, river 1-eval ranking\\\n-\"],[0,\" ppot\"],[-1,\", \"],[1,\"/\"],[0,\"npot\"],[-1,\", \"],[1,\"/\"],[0,\"nutpot\"],[-1,\", \"],[1,\"/\"],[0,\"rpot \"],[-1,\"per combo. Board-exact, range-free.\\\n- **Key optimization**: table depends only on (board, hero cards) → compute ONCE per street, shared by ALL opponents.\\\n- Efficient sampling: sample M runouts, evaluate all combos on each (LUT eval); ~169×M evals, ~20-50ms/street. Existing HandPotential + GPU nutpot/rpot infra reusable.\\\n\\\n### 2. Weight map: weight = prior × Π curve(Xpot) × action multipliers\\\n- prior = RangeNet 169-dim probs (already consumes VPIP/PFR/3bet/action history via 85 features)\\\n- curves C_hs, C_ppot, C_npot, C_nutpot, C_rpot: hand-fit monotone (logistic/spline, center+steepness+floor knobs), applied per combo from rollout table\\\n- action multipliers per StreetAction × bet-size bucket, centers = player's observed frequencies (call_freq/bet_freq — rarity weighting like existing narrow code). Preflop actions (raised/3bet/called) included.\\\n- stats (VPIP/3bet) enter via NN prior + action centers only — avoid double-counting by NOT re-adding raw stats in corrector\\\n- renormalize; per-combo and global ratio clamps\\\n\\\n### 3. Floors\\\n- per-curve floors (like narrow_floor, keep bluff mass), plus final weight floor sweep: ratio clamp (e.g. 1/20..20× prior) and/or max(w, floor×mean). Sweep floor values vs NN pool.\\\n\\\n### 4. Hand-fit first, validate offline\\\n- Hand-fit curves initially (user decision), tune via replay_kk_overplay\\\n- Offline validation: equity_v5_2m4 showdown labels → measure P(actual hand | actions) log-likelihood with/without corrector (direct metric, no sim needed). Can later refit curves from this data.\\\n\\\n## Verification\\\nreplay_kk_overplay → Harrington 18/18 → sanity_check.sh cash_nl_g50 → floor/curve sweep vs NN pool\\\n\\\n## Effort/Gain\\\n1.5-2d. +1-3 BB/100 live, max vs loose-passive fields. Generic: all board interactions (overcards, pairs, flush/straight overtakes) handled automatically.\"],[1,\"from 128 shared runouts vs random hands (deterministic seed per spot)\\\n- Build cost: 4ms warm / 85ms cold (release) — negligible; thread-local cache keyed on (hole, board, cfg)\\\n- River nutpot = unbeatable indicator; rpot = improved-but-vulnerable\\\n\\\n### Likelihood curves (TOML `corr_*` knobs, all hand-fit)\\\n- CalledBet: hs curve (center 0.40 + size×0.12) ∨ draw allowance (ppot center 0.26+size×0.12) + nutpot boost − rpot discount, floor 0.12\\\n- Bet/RaisedBet: center 0.50 + size×0.15, draw center 0.30, npot discount, bluff floor 0.20\\\n- Checked: weak signal (steep 2.5, floor 0.55)\\\n- Player-conditioning: aggr_adj (af-based, ±0.25 shift on call center — aggressive players' calls mean more), bet_adj (frequent bettors' bets mean less), barrel compounding (+0.10 center per extra call street), vpip_floor_lift (call floor +0.5×max(0,vpip−0.35) — loose callers keep junk mass)\\\n- Range-width INVARIANT (renormalized) — pure mass redistribution\\\n\\\n### Integration\\\n`build_ranges_and_equity` (gen4/mod.rs) after NN blend, before equity MC. Applies to ALL range paths (NN, blended, heuristic). Config: `corr_enabled=true` in `cash_nl_g51.toml` (sim) / `cash_nl_g51_live.toml` (live).\\\n\\\n## Validation results\\\n\\\n### KK overplay defect (the target) — FIXED\\\nReplay with real profiles, NN path: turn hs 0.730→0.552 (AllIn→Raise 2.2M), river hs 0.611→0.311 (Raise→**Check**). Replay test: `replay_kk_overplay_variants` (#[ignore], 4 variants).\\\n\\\n### Sanity check `cash_nl_g51` — PASSED 10/10 (run 3×: initial, after bet_adj, after floor_lift)\\\nGen2 +0.6, Gen3 +1.0, G48 +1.7, TAG +1.6, Nit +0.1, Mixed +0.4 BB/100 — statistically identical to g50 baseline.\\\n\\\n### Head-to-head g51 vs g50 (5 seeds × 10K hands, 4+5 seats): **−0.29 BB/100 (dead heat)**\\\n\\\n### Specialist fields (9-max eval, 15K hands/opp)\\\ng51 vs g50: Fish 53.4/59.0, Station 54.9/57.4, Tag 10.3/10.9, Lag 66.4/71.0, Nit 1.4/2.2, Maniac 102.3/113.0 (g50 numbers = same-seed control). Small uniform deficit ~1-5 BB/100 vs EXTREME specialist fields. Expected: the NN pool IS RangeNet's training distribution — the corrector cannot beat a well-calibrated prior on-distribution; its value is off-distribution (human lines like the KK hand).\\\n\\\n### Known pre-existing issue (NOT a corrector regression)\\\n`replay_harrington_4_5_99` (99 monotone-flop turn barrel) fails on the **NN path for BOTH g50 and g51** — pre-existing since range_v17. Sanity Gate 1 runs hand_replay WITHOUT gen5_nn so it never sees the NN path. Fix suggestion: sanity Gate 1 should use `--features holdem_bots/gen5_nn`. Root cause of the hand: turn bet_threshold 0.085 on loose tables (threshold problem, not range).\\\n\\\n## Infra improvements this session\\\n- `scripts/eval_9max.sh`: now parallel (MAX_PARALLEL=8, RAYON_NUM_THREADS=4) — 30 sims concurrent\\\n- `/tmp/kilo/run_ab_parallel.sh`: A/B harness (MAX_PARALLEL=15), usage: `<cand> <opp> <tag> <hands> <seeds...>`\\\n- `table_build_time_is_bounded` bench test in range_corrector\\\n- Fixed stale `test_range_feature_dim` (81→85), fixed `test_looseness_factor_cold_start` signature\\\n\\\n## Files\\\n- NEW: `holdem_bots/src/gen4/range_corrector.rs` (XpotTable, curves, reweight_range, street_bet_ratios, config, 7 tests)\\\n- MOD: gen4/mod.rs (integration), range_builder.rs (corr field), formula_postflop.rs (config passthrough + KK variants test), rollout_postflop_gen3.rs (config), Cargo chain\\\n- NEW configs: `cash_nl_g51.toml`, `cash_nl_g51_live.toml`\\\n- live_server REBUILT with final corrector (floor_lift + bet_adj)\\\n\\\n## Open follow-ups\\\n1. Promote g51_live on Torn (live server down since Aug 9; binary ready)\\\n2. Sanity Gate 1 should test NN path (add --features holdem_bots/gen5_nn)\\\n3. 4_5_99 turn-barrel on loose tables (threshold, affects g50 production too)\\\n4. Curves are hand-fit; offline likelihood fitting from equity_v5_2m4 (19.2M samples) is the principled next step if live shows drift\\\n5. Tier-2 v18: feed per-combo Xpot profile as 169 extra RangeNet inputs (merges corrector into the net)\"]],\"start1\":63,\"start2\":63,\"length1\":2326,\"length2\":4456}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-08-15T09:05:30.401Z
created_time: 2026-08-15T09:05:30.401Z
is_locked: 0
type_: 13