Sanity Check & Live Promotion Policy

# Sanity Check & Live Promotion Policy + Optimization Protocol

> Vollständige Policy: Gates, Hotfix-Ausnahmen, bekannte offene Issues, Optimierungs-Protokoll (2026-08-23 ergänzt, dual-opponent erweitert).

## Sanity Gates (vor jeder Live-Promotion)
`scripts/sanity_check.sh <bot>` — ALLE Gates müssen passen:
1. **Gate 1**: Harrington-Replays (`HARRINGTON_BOT=<bot>` cargo test hand_replay, inkl. NN-Pfad)
2. **Gate 2**: 1000-Hände-Selfplay-Audit
3. **Gate 3**: vs. alte Generationen (4 CAND + 5 OPP × 5000h × 5 Seeds): Gen2/Gen3/G48/TAG/Nit
4. **Gate 4**: Mixed Table
5. **Gate 5**: Cross-Generation-Championship — CAND muss **Platz 1** sein (Jan, 2026-08-22: „Live-Bar = Turnier-Sieg"; vorher ≥G48)
6. **Gate 6**: Format-Matrix 1v1/3v3/4v4 vs. 10 Gegnern inkl. chump/flock; Zelle fail < −0.5 BB/100

Dazu: **Dominanz-Matrix** (`scripts/dominance_matrix.sh`, Pre-Gen6-Qualitätsbar): 17 Gegner × 1v1/3v3/4v4/5v5 + Heritage-Feld. Vollständige Fehlerfreiheit vor Gen-6-Start.

## Hotfix-Pfad (Live-Bug ohne vollständige Gates)
Hand-Tests (Gate 1) + 1 neue Regression + 1000-Hände-Selfplay-Audit.

## Bekannt offen (#[ignore])
- `replay_harrington_7_6` (KK River Value-Bet vs capped Line — sequence-aware Ranges nötig)
- 4_5_99: Policy-Entscheidung ausstehend (Turn-Barrel ohne eq_cc-Gate; Harrington sagt Check; als Meinungsdifferenz dokumentiert)

## Optimierungs-Protokoll (Jan, 2026-08-23; dual-opponent 18:45)
Für jede neue Version/Generation:

1. **Reihenfolge = Backward Induction**: River zuerst, dann Turn, dann Flop, dann Preflop. Innerhalb einer Street: Bet zuerst, dann Raise, dann Call. Terminale Entscheidungen zuerst messen — frühere Streets werden gegen bereits korrekte Downstream-Politik optimiert.
2. **Coordinate Descent, DUAL-OPPONENT mit Pareto-Akzeptanz**: Parameter einzeln sweepten gegen BEIDE Referenzgegner (Ziel-Gen, z.B. Gen1, UND die eigene Baseline als Spiegel). Übernahme nur bei Pareto-Improvement: kein Mean-Regress gegen irgendeinen Gegner (Tie-Toleranz 0.3 BB/100). Verhindert Single-Opponent-Overfitting (b_more-Fall). Iterieren bis keine Verbesserung außerhalb des Rauschens (Noise-Floor: 50K×3 Seeds ≈ ±1 BB/100; feste Seeds). **Bundles**: eng gekoppelte Knob-Paare gemeinsam sweepten.
3. **Mess-Reihenfolge**: (a) Baseline-Selbstspiel/Stabilität, (b) Dual-Sweep vs. Referenzgegner, (c) Sanity vs. alten Bots, (d) Dominanz-Matrix/Championship. Self-Play allein ist blind für symmetrische Leaks — unähnliche Gegner als Guard.
4. **Stereotypen-Invariante**: Abgeleitete Persönlichkeiten MÜSSEN alle schlechter sein als der Default (single-dimensionale Verschlechterungen). Schlägt eine Ableitung den Default, ist der Default nicht optimal → zurück in den Sweep.
5. **Knob-Semantik vor dem Sweep verifizieren** (Wirkrichtung, aktiver Code-Pfad, Landscape-Flachheit — call_turn_base war flach weil Pot-Odds-Anteil dominiert; Config-Loading per Regressionstest abgesichert).
6. **Nächtliche Kette**: Generation für Generation (Gen2 fertig → Gen3 → ...), jede mit vollem Protokoll bei 1/10-Handzahl (50K), finaler Voll-Run 500K.

## Infra
- A/B: `/tmp/kilo/run_ab_parallel.sh <cand> <opp> <tag> <hands> <seeds...>` (MAX_PARALLEL=15)
- Isolation Gen2: `/tmp/kilo/isolate_gen2.sh <bot>` (4 CAND + 5 Gen2 × 5000h × 5 Seeds)
- Championship beliebig: `/tmp/kilo/champ_any.sh <bot> [hands]`
- Benchmarks: `scripts/gen2_benchmark.sh <bot_type> <label> [hands] [seeds...]` (Duelle + 4way + 8way + 3v3/5v4/4v5 vs Flock/Chump/Gen1)
- Sweep (dual-opponent): `scripts/gen2_sweep.sh [hands]`
- Selbstspiel-Mirror: `scripts/gen2_selfplay.sh [hands]`

id: d632cea3d15f4323bbac7eda687f2467
parent_id: 2c8da247905946c3aa19eb4936e16323
created_time: 2026-07-07T11:44:40.189Z
updated_time: 2026-08-23T16:38:49.947Z
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: 1783424680190
user_created_time: 2026-07-07T11:44:40.189Z
user_updated_time: 2026-08-23T16:38:49.947Z
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