diff --git a/RESEARCH_JOURNAL.md b/RESEARCH_JOURNAL.md index 193483d..7e99ee8 100644 --- a/RESEARCH_JOURNAL.md +++ b/RESEARCH_JOURNAL.md @@ -2,6 +2,29 @@ Append-only. New entries at the top, date-stamped. Never edit old entries. +## 2026-05-31 (e) — v_hack refresh collapses cin_t ONLY under gradient routing; root-caused to the live quarantine, fixed by ablating during extraction + +**When**: 2026-05-31, fix at `cec6542`. Triggered by the 4-arm substrate sweep (tasks 28 route / 29 erase / 30 vanilla, fast/60 steps, seed 41, prog_wide v_hack, refresh-5). + +**Symptom.** On the route arm, the live-grad/v_hack cosine `cin_t` dropped from ~0.32 (steps 0-4) to ~0.04 at step 5, exactly the first refresh step, and stayed low. Looked like the refresh basis was going stale-to-orthogonal. + +**Wrong first hypothesis (recorded so we don't repeat it).** "Re-extraction at the moved weights (delta_S != 0) lands on a different operating point and rotates the basis." Refuted by the data: both the basis AND the teacher gradient are evaluated at the same current weights, so re-extraction should track, not collapse. (User's pushback: "it used to work, and the teacher grad is wrt the changed model too.") + +**Discriminating evidence.** Added a per-refresh diagnostic (`basis_overlap_with_prev` = fraction of the old subspace kept, commit `23589cb`) and read the erase arm, which is identical to route except it has no quarantine knob: + +| arm | quarantine | refresh basis_overlap | cin_t across refresh | +|-----|-----------|----------------------:|---------------------| +| erase (29) | none | 0.828 | 0.34 -> 0.36 (stable) | +| route (earlier run) | delta_S_hack active | n/a (pre-diag) | 0.32 -> 0.04 (collapse) | + +So refresh through a moved-but-non-routed adapter is fine (overlap 0.83, cin_t flat). The collapse is **routing-specific**. + +**Root cause.** The refresh re-extracts the gradient wrt the MAIN knob (`delta_S`) only, but runs the forward through the LIVE adapter including `delta_S_hack`. Once route has quarantined the hack capability into `delta_S_hack`, the main-knob pair gradient `D = G_hack - G_clean` no longer carries the hack direction, so the refreshed v_hack rotates off-hack and `cin_t` drops in one step. The build-time extraction never hits this because `delta_S_hack` is zero-init. + +**Fix (`cec6542`).** Wrap the refresh extraction in `ablate_quarantine` (zero `delta_S_hack` during extract), matching the `delta_S_hack=0` state the build saw. No-op for erase. Validated in `smoke-route --vhack-refresh-every=2` (no crash; route-arm 4B confirmation pending when task 28 runs). + +**Takeaways.** (1) Refresh is sound for projection/erase; only routing needed the fix. (2) `k` is finite throughout (`k_max=12` at extract, `k_use=5` at load/refresh, then global noise-floor drop ~3.75 axes/module) — not unbounded. + ## 2026-05-30 (d) — HEADLINE: vanilla-GRPO student learns 4 of 5 loophole classes; eq_override is the sole holdout (seed 41, n=1) **When**: 2026-05-30, code at `618d9bd` (run launched on `67444b1`+journal). Pueue task 20 (`just run-substrate none 41`), vanilla GRPO, fast/80 steps, mix=0.125, even 5-mode substrate (6 problems/mode, 98 teacher rollouts, 100% cached teacher hack). Log: `logs/20260530T134852_fast_vanilla_seed41_substrate3_none_s41.log`.