|
| 1 | +# HANDOFF 2026-07-24e (~08:35) — VACATION EDITION. Supersedes 24d. |
| 2 | + |
| 3 | +Written for laptop-only work (**no GPU, no Dolphin**) Jul 24–29. Everything |
| 4 | +is on `origin/main`; nothing needed for the laptop tasks lives only on the |
| 5 | +desktop. 24c/24d hold the deep narrative; GOTCHAS #78–81 hold the law. |
| 6 | + |
| 7 | +## State at handoff |
| 8 | + |
| 9 | +- **r17a was STOPPED deliberately at ~08:25** (Bradley's call, to free the |
| 10 | + machine). It had reached epoch 48/100, healthy, all four levers confirmed |
| 11 | + (incl. `probe-reg refit: true, shield_rows: 165` at every refit). |
| 12 | + **Resume point: the epoch-40 trainer snapshot** — epochs 41–48 are lost |
| 13 | + (~1.6h), by design. The stack trace at the end of |
| 14 | + `logs/overnight_newera8_r17a_20260724.log` is the SIGTERM, not a crash. |
| 15 | + - Local: `checkpoints/mewtwo_combo_newera_r17a_r13_policy.bin.trainer.ckpt` |
| 16 | + (+ `_latest.bin`, both 06:27 = epoch 40) |
| 17 | + - **Backed up to `b2:exphil-artifacts/checkpoints/2026-07-24/`** |
| 18 | + - Resume (home, after vacation): |
| 19 | + `nohup setsid devenv shell -- bash scripts/launch_r17a_resume.sh > logs/r17a_launcher_resume.log 2>&1 < /dev/null & disown` |
| 20 | + then confirm the four levers in the drill log (R17A_RUNBOOK.md). |
| 21 | +- GPU idle, no training anywhere. `mix` is safe again, everywhere. |
| 22 | +- Multishine: teacher track DONE (fixture max chain 186, table teacher live |
| 23 | + 103, BC loss 0.00148). Policy gate BLOCKED on the state-stream shift below. |
| 24 | + |
| 25 | +## THE LAPTOP TASK — #8 phase 1, deliberately sized for this trip |
| 26 | + |
| 27 | +**Finding (GOTCHAS #81):** a replay-trained policy does not run on the |
| 28 | +features it was trained on. Same weights: 99.3% button agreement fed PARSED |
| 29 | +fixture states; collapses to a constant (B=100%, X=0.1%, never shines) fed |
| 30 | +LIVE bridge states. Peppi and libmelee disagree on `action_frame` (parsed |
| 31 | +jumpsquat af 0,1,2 vs live 1,2,3; 365 agrees; varies per action). The |
| 32 | +training loss lives entirely in parsed space, so no run can reveal this. |
| 33 | +Plausibly touches EVERY policy; only frame-perfect tech made it visible. |
| 34 | + |
| 35 | +**Phase 1 needs no GPU and no Dolphin, and the data is already committed:** |
| 36 | +`test/fixtures/statestream/` has two same-game pairs — the .slp Dolphin |
| 37 | +wrote AND the recorder's live per-frame trace of that identical run (see its |
| 38 | +README for format and an alignment hint). Write the diff script: |
| 39 | + |
| 40 | +1. Parse each .slp (Peppi is a Rust NIF — CPU fine), align frames to the |
| 41 | + trace on the first jumpsquat entry (NOT frame 0 — menu frames differ). |
| 42 | +2. Emit the mapping table: per action, parsed af vs live af; flag any other |
| 43 | + field that shifts (on_ground timing, action transitions, y). |
| 44 | +3. Land it as `scripts/diff_state_streams.exs` + a test pinning the mapping, |
| 45 | + so the convention can never silently drift again. |
| 46 | + |
| 47 | +**Phase 2 (decision + maybe implementation, discuss before committing):** |
| 48 | +- Option 1: normalize at the embedding boundary — right fix, benefits every |
| 49 | + policy, but touches shared code and needs a Mewtwo regression pass |
| 50 | + (current behaviors may quietly depend on the shift). Can be IMPLEMENTED |
| 51 | + and unit-tested on the laptop behind a flag; live regression waits for home. |
| 52 | +- Option 2: train drills on live-captured pairs (recorder dumps |
| 53 | + `(observed_state, decided_input)`) — narrow, safe, drills only. |
| 54 | +- Option 3: feed parsed-convention features live — inverse of 1. |
| 55 | + |
| 56 | +**Do NOT spend DAgger rounds on this** — DAgger fixes coverage, not |
| 57 | +features (proven twice on 2026-07-23/24). |
| 58 | + |
| 59 | +## Other laptop-sized work, in priority order |
| 60 | + |
| 61 | +1. **Rung-1 design (Mewtwo, top of the ladder, UNSTARTED):** design what the |
| 62 | + expert should SUPERVISE — the go-in decision, not the button sequence. |
| 63 | + Pure thinking + doc + maybe a labeling prototype over parsed replays. |
| 64 | + Corpus: `corpus/archive/mewtwo/` if present locally on the laptop clone; |
| 65 | + otherwise pull from B2 (`scripts/pull_replays.sh`, rclone remote `b2`). |
| 66 | +2. **A3 metric (unmeasured gate):** mean connected aerials per opening, |
| 67 | + next to `FailureScan.dropped_punish`. Parsing + metric + tests, all CPU. |
| 68 | +3. **Full test suite on the laptop** (`mix test`) — it has NOT run since the |
| 69 | + multishine changes (GPU was occupied all night; the 2 touched files pass, |
| 70 | + 30/30). First laptop compile will be long (EXLA CPU backend); the |
| 71 | + devenv shell provides everything. CUDA-tagged tests are excluded by |
| 72 | + default so no GPU is needed. |
| 73 | +4. Housekeeping if bored: `TrainingShards.build/3` has an unused-variable |
| 74 | + warning (`process_fn`, lib/exphil/data/training_shards.ex:78) that spams |
| 75 | + every compile. |
| 76 | + |
| 77 | +## HOME-ONLY queue (needs GPU/Dolphin — after the 29th) |
| 78 | + |
| 79 | +| what | detail | |
| 80 | +|------|--------| |
| 81 | +| resume r17a from ep40 | command above; then score vs `R17_ACCEPTANCE_2026-07-23.md` (armed/min: PASS ≥0.5 / STRONG ≥1.0 / FAIL <0.5 vs r16's 0.17) | |
| 82 | +| re-gate multishine policy | ONLY after #8's fix; use `eval_policy_on_fixture.exs` offline first, then `analyze_policy_shine.exs` live | |
| 83 | +| re-verify the teacher after any af-convention change | its live success partly rides on table-miss → recovery-rule luck (GOTCHAS #81); `demo_expert.exs`, gate ≥5 | |
| 84 | + |
| 85 | +## Tooling map (all committed) |
| 86 | + |
| 87 | +- `scripts/eval_policy_on_fixture.exs` — offline discriminator: high |
| 88 | + agreement + live failure = state-stream problem; low = training problem. |
| 89 | + Run FIRST when any drill policy misbehaves. |
| 90 | +- `scripts/inspect_multishine_table.exs` — table coverage + state purity |
| 91 | + (any `{action, af, gnd}` key carrying 2 inputs ⇒ BC will floor; caught a |
| 92 | + wall-clock-keyed input that cost a 2000-epoch run). LIVE-fidelity number |
| 93 | + is parsed-space only — hint, not verdict. |
| 94 | +- `MULTISHINE_TRACE=1` on `record_multishine.exs` — per-frame y/vy/act/af. |
| 95 | +- `--rollout-cap-per-state N` on `dagger_drill.exs` — opt-in; stops one |
| 96 | + stuck trajectory from swamping the fixture (2609→514 frames last night). |
| 97 | +- `test/fixtures/statestream/` — the #8 dataset (see its README). |
| 98 | +- `test/fixtures/replays/fox_multishine_sloppy_2026-07-07.slp` — the OLD bad |
| 99 | + fixture, kept as the metric's negative example. |
| 100 | + |
| 101 | +## Task list snapshot (rebuild the CLI list from here) |
| 102 | + |
| 103 | +| # | status | task | |
| 104 | +|---|--------|------| |
| 105 | +| 1–4, 6 | DONE | teacher verified / fixture 186 / table gate 103 / BC 0.0015 / docs | |
| 106 | +| 5 | BLOCKED by #8 | policy live gate (home-only once unblocked) | |
| 107 | +| 7 | **STOPPED ep48, resume ep40 ckpt** | r17a — resume + score at home | |
| 108 | +| **8** | **NEXT — laptop phase 1 ready** | state-stream diff → mapping table → choose fix | |
| 109 | + |
| 110 | +Backlog: rung-1 (design on laptop), A3 metric (laptop), PPO arch mismatch, |
| 111 | +#33 five-char / #23 G&W (deferred). |
| 112 | + |
| 113 | +## Caveats |
| 114 | + |
| 115 | +- Laptop environment: the repo's devenv shell should provide Elixir/Rust/ |
| 116 | + Python on any Nix machine; first `mix compile` is slow and EXLA runs CPU. |
| 117 | + If the laptop isn't NixOS, this is the first blocker to solve. |
| 118 | +- `scenarios/gaps.json` stays untracked (runtime data). |
| 119 | +- Bradley is on the babymoon (Navarre FL, Jul 24–29, Grace 33.5 wks) — bias |
| 120 | + toward small, finishable, interruptible units of work. |
0 commit comments