Improvement Ideas — Top 10 (2026-08-14)

# Improvement Ideas — Top 10 (2026-08-14)
ID: f3c42f4435644e19b186265dd3fbf672
Notebook ID: 2c8da247905946c3aa19eb4936e16323
Created: 1786733906375
Updated: 1786789294456
Is Todo: No
Tags: roadmap, gen5, rl, ideas

---

# Idea #9 PROPOSED: Cross-Generation Championship Table (2026-08-21)

**Status: IDEA — fun eval, proposed by Jan.**

Mixed table of our "better" strategies across eras: Gen2 (EHS rollout), Gen3 (range equity),
Gen45/G48 (adaptive formulas), G5x (NN range). Questions it answers:
- Does the Gen5 NN stack actually beat its own ancestors head-on, or only in mirror-family A/B?
- Which generation exploits which (rock-paper dynamics)?
Setup: 9-max, one seat each + fill, 100K+ hands for significance (SD ~80-100 BB/100).
Cheap to run (existing binaries/configs). Do after v22 cycle.

---

# Idea #8 = **GEN 6**: Opponent Mirrors + Decision-Time Rollouts (2026-08-19)

**Status: VISION for next generation. Proposed by Jan. Renamed 2026-08-19: old "Gen 6" (PreflopNet/PPO, −644 BB/100, abandoned) is dropped from the numbering — this is now Gen 6.**

## Concept
Keep per-opponent "mirrors" (behavioral models from observer stats) and, at decision
time, simulate how the hand might develop: sample opponent hole cards from the current
range posterior, sample their actions from an oracle behavioral model, roll the hand
forward, and average EV per hero action.

## Why the pieces now exist
- **Mirror = observer stats → personality class**: already implemented for the
  oracle-in-corrector attempt (class from stats, oracle row lookup). What's missing
  is using it for FORWARD simulation instead of range correction.
- **Range posterior**: RangeNet P(hand|actions) per opponent (v22 per-class in progress).
- **Behavioral oracle**: empirical P(action | strength-decile, facing-size, class)
  from v22 equity_data (regen in overnight chain). Closes the loop:
  posterior → sample hands → sample actions → rollout → EV(hero action).

## Two known constraints (from 2026-08 findings)
1. **Human transfer**: pool-bot P(call|strength) is flatter (2.7:1) than human (8:1) —
   the oracle-in-corrector regression. For LIVE mirrors, blend pool prior with
   live-observed frequencies per opponent (hand_history data) instead of raw oracle.
2. **Cost**: decision-time rollouts multiply tree breadth × MC equity. Path: run
   rollouts OFFLINE as label machinery, distill into an EV/action net (EquityNet
   rollout-phase pattern, parked at Multiway-MAE 0.0448 — could be revived as the
   distillation target with action-aware labels).

## NN for speed (Jan, 2026-08-19)
NN inference is ~µs — the natural tool to replace the expensive part (rollout+MC)
with a fast learned evaluator. Two slots:
- **Distilled EV/action net** = live plays a fast net trained on offline rollout
  labels (revived EquityNet pattern). Primary plan.
- Later: rollout-policy net (cheap action sampler inside the rollout itself,
  MCTS-policy-style) if full oracle sampling inside rollouts is too slow even offline.

## Suggested staging
1. Oracle table regen from v22 (running overnight 2026-08-21)
2. Rollout evaluator in sims vs pool (exact mirrors — no transfer issue on sim side)
3. A/B as candidate; if wins → distill for live (net replaces runtime rollouts)

---

# Idea #7 IMPLEMENTED: Action-Likelihood Range Corrector (2026-08-15)

**Status: COMPLETE, REVIEWED, COMMITTED (042876b), DEPLOYED LIVE (`cash_nl_g51_live`).**

## What was built

`holdem_bots/src/gen4/range_corrector.rs` (~1000 lines) — Bayesian refinement of opponent ranges AFTER the RangeNet prior:
`P(hand | actions, board) ∝ P(actions | hand) × P(hand)`

### XpotTable (shared per street, cached)
- Exact hs percentile per combo (all-combo enumeration, no MC): flop 1081 combos, river 1-eval ranking
- ppot/npot/nutpot/rpot from 128 shared runouts vs random hands (deterministic seed per spot)
- Build cost: 4ms warm / 85ms cold (release); thread-local cache keyed on (hole, board, cfg)
- Early-returns empty on preflop boards (< 3 cards)

### Likelihood curves (TOML `corr_*` knobs, off by default)
- CalledBet: hs curve (center 0.40 + 0.12×size) ∨ draw allowance (0.26+0.12×size) + nutpot boost − rpot discount, floor 0.12 (+VPIP floor lift)
- Bet/RaisedBet: center 0.50 + 0.15×size, draw center 0.30, npot discount, bluff floor 0.20 (bet_freq-adjusted center)
- Checked: weak signal (steep 2.5, floor 0.55)
- Player-conditioning: aggr_adj (af ±0.25), bet_adj (BET_FREQ_PIVOT 0.35), barrel compounding (+0.10/call street), vpip_floor_lift (+0.5 × max(0, vpip−0.35), cap 0.60)
- Range-width INVARIANT (renormalized) — pure mass redistribution

### street_bet_ratios (chip units!)
In-order wager reconstruction: Raise{total} contributes the full new level, Call contributes current level, preflop starts at BB level. (First draft mixed chips/BB and saturated every ratio at the 3.0 clamp — caught in review, fixed + regression test.)

### Code review (2026-08-15, before commit)
Independent review found 15 issues; fixed: chips/BB unit bug (high), corrector+NN-blend accidentally nested inside narrow_enabled gate in build_ranges_and_equity (medium — NN would silently disable with narrowing off), unguarded short boards (medium), inert corr_max_boost knob (removed), per-opponent config clone (removed), magic numbers → named constants, leftover comments; added street_bet_ratios + bet_multiplier tests (9 corrector tests total). Not fixed (documented): empty-range-if-NN-returns-None (pre-existing production path), single-combo percentile edge (unreachable).

## Validation

### KK overplay defect (target) — FIXED
Real profiles, NN path: turn hs 0.730→0.535 (AllIn→Raise 2.2M), river 0.611→0.290 (Raise→**Check**). Replay: `replay_kk_overplay_variants` (#[ignore], heuristic/nn/nn+corr).

### Sanity `cash_nl_g51` — PASSED 10/10 (4 runs total incl. post-review)
Gen2 +0.6, Gen3 +1.0, G48 +1.7, TAG +1.5, Nit +0.1, Mixed +0.4 BB/100 — identical to g50 baseline.

### Head-to-head g51 vs g50 (200K hands): −0.29 BB/100 (dead heat)
### Specialist 9-max fields: small uniform deficit ~1-5 BB/100 (Fish 53.4 vs 59.0, Maniac 102 vs 113) — expected on-distribution cost; corrector targets off-distribution human lines.

### Known pre-existing issue
`replay_harrington_4_5_99` (99 mono-flop turn barrel) fails on NN path for g50 AND g51 — sanity Gate 1 runs hand_replay WITHOUT gen5_nn so never tests the production NN path. Root cause: turn bet_threshold 0.085 on loose tables (threshold problem, not range).

## Commits (2026-08-15)
- 0609ebb feat: bump production to range_v17, switch opponent pool to NN variants
- 35b4fc6 feat: add G51 action-likelihood range corrector
- 042876b refactor: remove abandoned Gen6/PPO code and one-off sweep artifacts (17G freed)

## Infra
- `scripts/eval_9max.sh` parallel (MAX_PARALLEL=8 × RAYON 4)
- `/tmp/kilo/run_ab_parallel.sh` A/B harness (MAX_PARALLEL=15)
- live_server REBUILT with final corrector; running binary keeps old inode until restart

## Open follow-ups
1. Sanity Gate 1: add `--features holdem_bots/gen5_nn` (DONE 2026-08-21 — now runs NN path)
2. 4_5_99 turn-barrel fix (bet_threshold on loose tables) — FIXED 2026-08-21 via call-model + position-conditional ranges
3. Offline likelihood fitting from equity_v5_2m4 if live shows drift
4. Tier-2 v18: per-combo Xpot profile as 169 extra RangeNet inputs
5. NN-returns-None fallback (empty range risk in production path)

id: f3c42f4435644e19b186265dd3fbf672
parent_id: 2c8da247905946c3aa19eb4936e16323
created_time: 2026-08-14T18:58:26.375Z
updated_time: 2026-08-21T16:41:32.777Z
is_conflict: 0
latitude: 0.00000000
longitude: 0.00000000
altitude: 0.0000
author: 
source_url: 
is_todo: 0
todo_due: 0
todo_completed: 0
source: joplin-desktop
source_application: net.cozic.joplin-desktop
application_data: 
order: 1786733906375
user_created_time: 2026-08-14T18:58:26.375Z
user_updated_time: 2026-08-21T16:41:32.777Z
encryption_cipher_text: 
encryption_applied: 0
markup_language: 1
is_shared: 0
share_id: 
conflict_original_id: 
master_key_id: 
user_data: 
deleted_time: 0
is_locked: 0
extracted_resource_ids: 
type_: 1