# Verification Pass - 2026-07-04 **Status:** FAIL - stop before league self-play. **Implementation start commit:** `bb52ef9`. **Primary checkpoint under audit:** `/mnt/2tbhdd/coolrl-lost-cities-artifacts/jax-ppo-static-opponents/2026-07-04_230150_jax-ppo-cautious/latest`. **Verification artifacts:** `/mnt/2tbhdd/coolrl-lost-cities-artifacts/verification/2026-07-04_phase1/`. ## Decision Do not start snapshot-pool league self-play from the current ladder artifacts. The duplicate/Wilson protocol is reproducible, and the obvious seat-perspective bug was not found, but the cautious anchor is not a trustworthy permanent Elo anchor: it stalls heavily in mirror play and gives the trained policy a very clean win while the trained policy opens almost all colors. ## Transcript Audit Transcript file: ```text docs/reports/verification-pass-2026-07-04-transcripts.txt ``` Rendered protocol: 10 fixed shuffle-bank deck orders, duplicate seat-swapped, for 20 total games of gate-3 checkpoint vs `heuristic_cautious`. Summary from the transcript dump: | Metric | Value | | --- | ---: | | Games | 20 | | Agent mean score diff | +144.500 | | Agent score diff min/max | -93 / +230 | | Agent opened colors mean | 5.000 | | Mean game length | 159.200 | | Length min / p50 / p95 / max | 63 / 109 / 400 / 400 | | Max-steps rate | 0.150 | | Handshake play events | 86 | | Cautious openings | 78 | | Cautious low openings below rank 7 | 3 | | Cautious discards immediately playable by opponent | 162 | Interpretation: the sample confirms the concern behind this pass. The agent is not winning by a restrained 2-3 color expert pattern; it opens all 5 colors on average and still wins by a wide margin. The cautious policy is also leaking many immediately useful discard tops. ## Protocol Recheck The original ladder evaluation was audited in code. The `eval` path uses: - explicit shuffle banks generated from `evaluation.shuffle_bank_seed`; - duplicate seat-swapped loops over learner seat 0 and learner seat 1; - Wilson confidence intervals from aggregate wins. The protocol itself is not the main failure. The failure is that the original gate summary omitted `max_steps_rate` and score-diff distribution canaries. Recomputed gate-3 duplicate evaluation with distribution canaries: ```text /mnt/2tbhdd/coolrl-lost-cities-artifacts/verification/2026-07-04_phase1/gate3_reverification_distribution.json ``` | Metric | Value | | --- | ---: | | Games | 20,000 | | Win rate | 0.95960 | | Wilson 95% | [0.95678, 0.96224] | | Mean score diff | +142.9178 | | Score diff p05 / p50 / p95 | +21 / +152 / +227 | | Opened colors/game | 4.98965 | | Positive expeditions/game | 4.09470 | | Play action rate | 0.27639 | | Mean game length | 185.3179 | | Game length p50 / p95 / max | 115 / 400 / 400 | | Max-steps rate | 0.24070 | The 24.07% forced-end rate is a high-severity canary failure for using this gate as a clean league baseline. ## Perspective And Mirror Tests New tests added: - hand-authored heuristic behavior checks for weak unopened hands, strong balanced opens, and P1 own-board perspective; - static-policy duplicate mirror checks for all three heuristic policies; - gate-3 checkpoint duplicate self-mirror check, skipped on CPU-only runs and executed under CUDA JAX locally. Commands run: ```bash uv run pytest -q tests/lost_cities_jax/test_ppo_stack.py uv run --with 'jax[cuda12]' pytest -q \ tests/lost_cities_jax/test_ppo_stack.py::test_gate3_checkpoint_duplicate_self_mirror_score_diff_is_zero ``` Results: - CPU focused tests: 11 passed, 1 skipped. - CUDA checkpoint self-mirror test: 1 passed. Mirror evaluation artifacts: ```text /mnt/2tbhdd/coolrl-lost-cities-artifacts/verification/2026-07-04_phase1/mirror_discard_only.json /mnt/2tbhdd/coolrl-lost-cities-artifacts/verification/2026-07-04_phase1/mirror_heuristic_balanced.json /mnt/2tbhdd/coolrl-lost-cities-artifacts/verification/2026-07-04_phase1/mirror_heuristic_cautious.json /mnt/2tbhdd/coolrl-lost-cities-artifacts/verification/2026-07-04_phase1/mirror_gate3_checkpoint.json ``` | Mirror policy | Mean diff | Win/loss symmetry | Max-steps rate | Play action rate | Mean length | | --- | ---: | --- | ---: | ---: | ---: | | `discard_only` | 0.0 | exact | 0.0000 | 0.0000 | 44.0000 | | `heuristic_balanced` | 0.0 | exact | 0.4683 | 0.0422 | 231.1210 | | `heuristic_cautious` | 0.0 | exact | 0.8956 | 0.0053 | 368.8435 | | gate-3 checkpoint | 0.0 | exact | 0.0000 | 0.7839 | 45.4292 | Interpretation: the broad P0/P1 perspective bug is unlikely. Duplicate mirror score differences cancel exactly. The serious issue is heuristic quality: `heuristic_cautious` mirror play almost never opens expeditions and reaches forced termination in 89.56% of games. ## Exploiter Baseline Frozen opponent: gate-3 checkpoint. New exploiter: random init PPO, same 8192 x 400 rollout shape, 250 updates, shaping annealed by the standard schedule. Training run: ```text /mnt/2tbhdd/coolrl-lost-cities-artifacts/verification/2026-07-04_235948_jax-ppo-gate3-exploiter/ ``` Final train-row canaries: | Metric | Value | | --- | ---: | | return_mean | +0.24118 | | play_action_rate | 0.71362 | | opened_colors_mean | 4.91016 | | positive_expeditions_mean | 2.07922 | | game_length_mean | 49.12524 | | max_steps_rate | 0.00000 | Duplicate exploiter evaluation: ```text /mnt/2tbhdd/coolrl-lost-cities-artifacts/verification/2026-07-04_phase1/exploiter_vs_gate3_duplicate.json ``` | Metric | Value | | --- | ---: | | Games | 20,000 | | Exploiter win rate | 0.67115 | | Wilson 95% | [0.66461, 0.67763] | | Mean score diff | +24.1371 | | Score diff p05 / p50 / p95 | -50 / +21 / +110 | | Opened colors/game | 4.89710 | | Positive expeditions/game | 2.12865 | | Play action rate | 0.74612 | | Mean game length | 48.0017 | | Max-steps rate | 0.00000 | This is now the measured exploitability baseline. It is not by itself a stop condition, but it reinforces that the current gate-3 checkpoint is not a finished robust policy. ## Findings | Severity | Finding | Evidence | Consequence | | --- | --- | --- | --- | | High | `heuristic_cautious` is a stalling anchor, not a strong cautious baseline. | Mirror max-steps rate 89.56%, play action rate 0.0053. | Do not use it as a permanent Elo anchor without fixing/replacing it. | | High | Gate-3 result is contaminated by forced-end games and over-opening. | Gate-3 max-steps rate 24.07%, opened colors/game 4.98965. | The ladder PASS remains reproducible, but it should not become a league baseline. | | Medium | Cautious discards many immediately playable cards to the opponent. | Transcript sample: 162 such discards in 20 games. | The agent may be exploiting discard leakage rather than learning robust play. | | Medium | A same-budget PPO exploiter beats the gate-3 checkpoint. | Exploiter duplicate win rate 67.115%, mean diff +24.1371. | League success should reduce this number, but Phase 2 should wait for anchor repair. | | Low | No broad seat perspective bug found. | Static and checkpoint duplicate mirrors have exact zero mean diff. | Seat symmetry is not the likely explanation for the ladder result. | ## Stop Condition Phase 1 did not pass cleanly. Per the work order, Phase 2 is not started. Recommended next work: 1. Replace or repair `heuristic_balanced` and `heuristic_cautious` so mirror play has near-zero forced-end rate and realistic play/open rates. 2. Add `max_steps_rate` and game-length quantiles to every gate report. 3. Rerun the static ladder gates with the repaired anchors before initializing a snapshot-pool league.