# EXP-08: v(S) via measurable transfer, twin-brain ablation separates genuine from surface-matched fake (program M1)

- Date: 2026-10-07 (iter1, iter2), 2026-10-08 (iter8 corrected-eval rerun), reproduced 2026-10-09 and 2026-10-10 | Cadence version: v0.75.0 / `88f4dde` (iter1, iter2); 0.78.0 / `750c8ef` (iter8 fixed run, current numbers); reproduced bit-identically on v0.80.0 (`9c3fd0e` per HANDOFF.md, and `19bee92`) | Program iter: iter1, iter2, iter5 (drift check), iter8
- Script: `exp/EXP-08_vs_transfer_separation.py` (current, #164 reset fix) and `.py.bak` (pre-fix eval) | Evidence: `exp/EXP-08-iter1.out` (K=4, pre-fix), `exp/EXP-08.out` (iter2, pre-fix), `exp/EXP-08-fixed.out` (iter8, current), `exp/EXP-08-v080.out`, `exp/EXP-08-v080-19bee92.out` (v0.80 reproductions)

## Summary
- Question: does measured transfer (snapshot a brain, feed one twin a witness, compare on an exogenous held-out task T) separate a genuine witness from a surface-matched fake, where interior (graph/content) scoring gave 0.0% separation in `wash_sim.rs`?
- Setup: K=8 contexts, 2 actions, `modules=(16, 8)`, 1600-step continuing-stream witness, 16 seeds (iter2 and later). Three witnesses ingested by byte-identical twins of the same snapshot: genuine (teaches T), fake_random (reward independent of context/action, Bernoulli matched to genuine's +1 rate), fake_wrong (teaches T' = the fully anti-correlated rule). Transfer = greedy accuracy on T after minus before. Own-task diagnostic: each twin also scored on T'. iter1 was K=4, 8 seeds, 1200 steps, random wrong rule.
- Prediction: no directional prediction in prose; the pass criterion was fixed in code before running: SEPARATES if genuine transfer > 0.15, separation > 0.15 and max fake transfer < 0.10.
- Result (current, iter8 fixed eval, 16 seeds, v0.78): genuine +0.422 (SEM 0.045), fake_random -0.109, fake_wrong -0.578; separation genuine minus fake_random +0.531, genuine minus fake_wrong +1.000; baseline on T 0.578; own-task diagnostic fake_wrong on T' 1.000, genuine on T' 0.000. accG = 1.00 on all 16 seeds. Identical numbers on v0.80 (`EXP-08-v080.out`, `EXP-08-v080-19bee92.out`). Superseded pre-fix numbers: iter2 genuine +0.219 (SEM 0.060), fake_random +0.008, fake_wrong -0.242, baseline 0.523, fake_wrong on T' 0.719, 5/16 seeds no genuine transfer; iter1 genuine +0.375, both fakes +0.062, separation +0.312.
- Verdict: CROSSED (program milestone M1), on the corrected-eval numbers. The iter1/iter2 numbers are SUPERSEDED by the iter8 rerun (program log: "ALL prior M1/M2/M4 numbers are superseded"); the verdict itself held and got stronger. Scope: the fake is surface-matched only, on a small bandit, given an exogenous T.

## Reflection
- What it means: on this bandit, ingesting a witness that teaches the held-out task moves the twin toward T, and fakes with matched surface statistics do not (or move it away). Learning the wrong task fully (fake_wrong reaches 1.000 on T') registers as negative worth on T, so worth measured this way is task-specific. It does not show anything about interior-feature-matched fakes (M2), about where T comes from (M5), or about tasks that are not saturated.
- Process: (1) Eval bug #164: probes ran back-to-back without `reset()` while training used 1-step episodes; iter4 had wrongly concluded greedy `act()` was pure and dropped the clone. The pre-fix iter2 "+0.219, ~3.6 sigma" and "partial mastery, 5/16 seeds no transfer" were largely the bug. The stale "act() is PURE" sentence is still in the current `eval_on` docstring. (2) After the fix the effect is at ceiling: genuine and fake_wrong both learn their rule to 1.00 on every seed, so tG = 1 - acc0 and tFw = -acc0 exactly. The per-seed spread and the SEM 0.045 come entirely from baseline accuracy, and the +1.000 genuine-vs-wrong separation is by construction. The informative contrast is fake_random (-0.109). (3) The script docstring is also stale in step 4 ("evaluate ... via a save/load clone"); the code evaluates the twin directly. iter1 to iter2 changed K, seeds, steps and the wrong rule in place in one script, so the iter1 configuration is not reproducible from the current file. (4) Version drift was checked and is clean: bit-identical on v0.78 pre-fix (iter5, log line only; no output file was saved for that rerun) and on v0.80 post-fix (two saved runs). (5) Stale records: the EXP-08 entry in EXPERIMENT-RESULTS.md, the M1 status line in VS-TRANSFER-PROGRAM.md SOLVED-CRITERIA and the EXP-03 row of EXPERIMENT-QUEUE.md still carry the pre-fix +0.219 and were never updated to the iter8 numbers; the iter8 log line "fake_wrong 1.00 on T', 0.00 transfer" is also misworded (fake_wrong transfer to T is -0.578).
- Lesson: once a measure saturates, separation numbers stop measuring the mechanism and start measuring the baseline; report which contrast still carries information. Also: a "probe is pure" check must match the training episode semantics, not just compare clone versus direct.
- Next: spawned EXP-09 (M4 coordinated prior) and EXP-10 (M2 additive per-mind attribution); backlog item 4 asks for larger tasks, interference and lifting mastery. Its v0.80 reproduction is the standing drift probe used by the monitor.
