GEMMA DEVELOPER AGENTSAVED EVIDENCE

← Weight change

Direct mathematical edit / wsp31-0010

Early deep-thought gate (fitted on depth >= 400, dose 0.1) plus own end-of-thought neurons x9: the strong dose of the gated family

Gemma 4 31B, frozen four-bit baseAuthor: claudeState: parkedVerdict: -

When

Recorded date: 2026-11-12

Ledger date only; exact weight-build/change timestamp is not recorded here. Not a live training event.

Exact tensor-change timestamp: unavailable.

Why change it?

In the unedited batch b001 (three identical arms, 61 episodes finished when read) 14 of the 28 failures end at the 7.5-minute session limit, at least 10 of them with an empty patch and 8 of those without a single file edit (at 110 episodes, 9:40 PM ET: solved 44%, at the limit 35%, empty patch 25%). At about 25 generated tokens per second per stream the limit is a budget of about 11,300 generated tokens. Limit episodes generate 11,341 tokens, 9,149 of them thinking, and 48% of everything they generate lies beyond token 400 of a thought (solved episodes: 24%, 1,631 tokens per episode; `code/cf_budget.py`). The deep parts are re-readings of…

Which part changed?

Early deep-thought gate (fitted on depth >= 400, dose 0.1) plus own end-of-thought neurons x9: the strong dose of the gated family

The source describes adapter targets and mathematical changes. No before/after tensor comparison is available in this viewer.

How was it changed?

Computed directly by author-written code and packaged as a low-rank adapter over the frozen base; not gradient-trained. Spec `B:0.1,N:8` of `code/build_think.py` (families in `code/thinklib.py`; rebuild with `build.sh`). Statistics (`code/data/think_stats.pt`, written by `code/think_job.py` in one GPU-0 hold with `tools/g31.py`, the tools lane's forward pass, whose agreement with the served model is NOT VERIFIED YET in TOOLS.md): one rollout per instance of `tools/data/probe_screen.jsonl` (unedited run s1_base), every fourth instance held out for the pre-test, the rest truncated to 11,000 tokens. Positions per episode: E = last token of a thought (the model's next token was `<channel|>`; the token the history re-rendering merged with a newline is restored),…

Did it improve?

- · No task-level result recorded in this snapshot.

Pending or parked proposal; not established as an applied or promoted update.

Evaluation set: wsp31_screen_v1 · Batch: -. Local screening and historical task scores are not competition scores unless explicitly identified in the source. Different evaluation sets cannot be compared as a gain.

Original evidence

Literal source excerpts follow. They may contain original predictions and superseded counts; use the measured-outcome summary and corrections above for the current result.

Hypothesis
In the unedited batch b001 (three identical arms, 61 episodes finished when read) 14 of the 28 failures end at the
7.5-minute session limit, at least 10 of them with an empty patch and 8 of those without a single file edit (at 110
episodes, 9:40 PM ET: solved 44%, at the limit 35%, empty patch 25%). At about
25 generated tokens per second per stream the limit is a budget of about 11,300 generated tokens. Limit episodes
generate 11,341 tokens, 9,149 of them thinking, and 48% of everything they generate lies beyond token 400 of a thought
(solved episodes: 24%, 1,631 tokens per episode; `code/cf_budget.py`). The deep parts are re-readings of code with
"Wait, ..." restarts. Making long thoughts end sooner should return that wall-clock to tool calls, so that episodes
which now time out without a patch get to edit, test and submit.

Different from the E4B "think briefly" edits (28 / 28 / 25 vs 29, PRIOR_E4B.md): there the session limit was not
reported as binding; here it ends 23% to 35% of unedited episodes, and the edit is built from the state at the logged ends of
thoughts (and, in families B and C, acts only deep inside a long thought), not from a short-vs-long contrast.
Exact recipe
Spec `B:0.1,N:8` of `code/build_think.py` (families in `code/thinklib.py`; rebuild with `build.sh`).

Statistics (`code/data/think_stats.pt`, written by `code/think_job.py` in one GPU-0 hold with `tools/g31.py`, the
tools lane's forward pass, whose agreement with the served model is NOT VERIFIED YET in TOOLS.md): one rollout per
instance of `tools/data/probe_screen.jsonl` (unedited run s1_base), every fourth instance held out for the pre-test,
the rest truncated to 11,000 tokens. Positions per episode: E = last token of a thought (the model's next token was
`<channel|>`; the token the history re-rendering merged with a newline is restored), up to 40; thought positions
at depth < 100 (80), 100..399 (60), >= 400 (120); 80 positions outside thoughts. Depth = tokens since `<|channel>`.

Family B (gated, state side), layers 30, 32, ..., 48, one neuron per layer replaced outright (`set`): the
neuron `j_L` with the smallest mean |activation| over all sampled positions. Gate row = `(3 / sigma) (w - (theta /
cbar) m)`: `w` = unit diagonal-LDA probe on `mlp_in[L]` (late thought positions, depth >= 400, against early thought
positions, depth < 100, and positions outside thoughts), `theta` = 95% quantile of the probe on the negatives,
`sigma` = sd on the positives, `m` = unit mean `mlp_in` (the model has no bias; `m . x` is `cbar` at every position).
Up row = `m / cbar` (reads 1). Down column = `clipdiv(d_L / |d_L|, w_post_L) * dose * |d_L| * rms_y_L / (gbar_L *
layer_scalar_L)` with `gbar_L` = mean activation of the new neuron on the late positions and `d_L` as in family A
(E minus other thought positions): at an average late position the write moves `resid_post` by `dose * d_L`.

Family N (weights only, the model's own end-of-thought neurons): the down_proj columns of the MLP neurons of
layers 57, 58, 59 whose direct write lens is dedicated to token 101 `<channel|>` are multiplied by `1 + dose`. Selection
(`code/end_neurons.py`, CPU, no activations): for neuron j, `x_j = final_norm_w * post_ff_norm_w * down[:, j]`,
`z_j = ((E[101] - mean_vocab E) . x_j) / sqrt(x_j^T Cov_vocab(E) x_j)` (the z-score of `<channel|>` in the neuron's
write lens over the 262,144-token vocabulary, exact); selected `z_j >= 6`, at most 16 per layer, layers 48..59
searched: 2 neurons in layer 57 (4238 z 16.9, 18123 z 11.8), 2 in layer 58 (1622 z 10.9, 15419 z 6.5), 16 in layer
59 (14974 z 22.7, 6539 z 18.6, 3378 z 12.0, 18515 z 11.2, ...); none in layers 48..56. Lists and columns:
`code/data/end_neurons.pt`. Control for this family: for each selected neuron, a neuron of the same layer with
`|z| < 1` nearest in column norm (pool of 4000, seed 4242), scaled by the same factor.

Gate variant g2 (`code/think_refit.py`, CPU refit from the saved MLP inputs): sharpness 12 instead of 3 (positions below the threshold then sit where gelu_tanh is 0, not at its negative lobe, which in the first version lowered p(`<channel|>`) at the true ends of thoughts); classes as above. This entry uses `code/data/think_stats_g2.pt`: the class means and neurons of `think_stats.pt` with these gates in place of the first version described under Family B.

Control (`ctrl/`): same code path and statistics; the written unit direction has the sign of every coordinate
flipped at random (seed 1000 + layer) before `clipdiv`. Per-coordinate magnitudes are unchanged, so the control has
the same norm in the stream, in the raw MLP output and in |dW|_F, the same read vector / gate, and a write direction
with cosine about 0 to the edit's. It is the right control for "this direction, not a write of this size at these
positions".
For the family N part the control scales, by the same factor 9, 20 other neurons (one per selected neuron, same layer,
`|z| < 1`, nearest in column norm). The control of the combination was not pre-tested as one adapter; its two parts
were (row `G2B0p1c` below; family N control at factor 4 in the first pass: no change from unedited).

Built as intended; approximations: bf16 storage of the factors (8 significant bits), the 5% `clipdiv` mask, and the
bias-free threshold (the constant is read from the mean-input direction).

Checker:

```
saved queue/early-gate-b01-end-neurons-x9/edit r 16 modules 33 max rel_fro 0.1999
saved queue/early-gate-b01-end-neurons-x9/ctrl r 16 modules 33 max rel_fro 0.19988
OK edit: 33 modules changed (of 33 present), r=16, max |dW|_F/|W|_F 0.1999 at 59.down_proj
OK ctrl: 33 modules changed (of 33 present), r=16, max |dW|_F/|W|_F 0.1999 at 59.down_proj
```

Pre-test (teacher-forced on the held-out episodes, truncated to 8,000 tokens, `code/think_report.py`; forward pass
NOT VERIFIED YET against the server; arms named family+dose, a trailing `c` is the control). `dlp101` = change of
log p(`<channel|>`) at thought positions by depth class and at E; `explen ratio` = expected thought tokens under the
arm's end hazard along the logged thoughts, relative to the unedited model, for thoughts logged shorter / longer
than 400 tokens; `dlpnext` = change of the log-prob of the logged token (collateral); `top1 agree` = share of
positions whose top token is unchanged (`think` = first token after a thought, `tool` = tool name); `p101 non` =
mean p(`<channel|>`) outside thoughts.

```
episodes 5 ['PyCQA__flake8.cf15', 'Mimino666__langdet', 'Delgan__loguru-130', 'PyCQA__pyflakes-27', 'HIPS__autograd.ac0'] arms per episode [11, 11, 11, 11, 11]
n by class {'E': 29, 'early': 2051, 'mid': 3020, 'late': 3870, 'non': 750, 'think_pt': 29, 'tool_pt': 29}
base expected/logged thought tokens: short 2708/2712 (23 thoughts)  long 6227/6258 (6 thoughts)
base mean lp101: early -24.99 mid -25.83 late -24.72 E -0.79 non -20.54
arm      | dlp101 early  mid  late     E | explen ratio short long | dlpnext early  late   non think  tool | top1 agree early late think tool | p101 non
G2B0p1   |   0.57   1.96   5.10  -0.18 |     0.93  0.33        |  -0.02  -0.36   0.00  -0.00  -0.00 |  0.98  0.87  1.00  1.00 | 0.0001 (base 0.0001)
G2B0p1N8 |   0.85   2.25   6.37   0.03 |     0.76  0.21        |  -0.02  -0.57  -0.03  -0.02   0.00 |  0.97  0.82  1.00  1.00 | 0.0017 (base 0.0001)
G2B0p1c  |   0.05   0.12   0.46   0.01 |     1.00  1.00        |  -0.00  -0.04   0.00  -0.01  -0.00 |  0.99  0.96  1.00  1.00 | 0.0001 (base 0.0001)
```

Greedy reading of the same passes (the harness decodes at temperature 0): along each logged thought, the first
position where `<channel|>` is the arm's top token. `cut<end` = share of thoughts that would end before their
logged end, `extends` = share where `<channel|>` is not the top token even at the logged end, `tokens kept` =
tokens up to the first cut / logged tokens, `E top=101` = share of logged thought ends where `<channel|>` is top
(the unedited forward pass itself reproduces only this share of the logged ends, see `base`).

```
arm      | short thoughts: n  cut<end  extends  tokens kept | long (>=400): n  cut<end  extends  tokens kept  median cut depth | E top=101 | thought positions (not E) with top=101
base     |  23    0.00     0.13       1.00 |   6    0.17     0.17       0.99     1284 | 0.83 (29) | 0.0001 | outside thoughts (non, think, tool points): n 808, top=101 0, top unchanged 1.000
G2B0p1   |  23    0.13     0.17       0.93 |   6    0.67     0.00       0.40      327 | 0.76 (29) | 0.0172 | outside thoughts (non, think, tool points): n 808, top=101 0, top unchanged 0.995
G2B0p1N8 |  23    0.35     0.09       0.82 |   6    1.00     0.00       0.21      148 | 0.83 (29) | 0.0568 | outside thoughts (non, think, tool points): n 808, top=101 2, top unchanged 0.978
G2B0p1c  |  23    0.00     0.13       1.00 |   6    0.17     0.17       0.99     1284 | 0.83 (29) | 0.0001 | outside thoughts (non, think, tool points): n 808, top=101 0, top unchanged 0.989
```
Held-out gate (share of positions with gate pre-activation > 0 by class and by thought depth):

```
30 auc 0.884 {'E': '0.07', 'early': '0.11', 'mid': '0.34', 'late': '0.69', 'non': '0.03', 'think_pt': '0.00', 'tool_pt': '0.00'} {'d3-50': '0.05', 'd50-100': '0.19', 'd100-200': '0.31', 'd200-400': '0.37', 'd400-800': '0.66', 'd800-1600': '0.67', 'd1600-5000': '0.83'}
32 auc 0.865 {'E': '0.00', 'early': '0.10', 'mid': '0.33', 'late': '0.66', 'non': '0.05', 'think_pt': '0.00', 'tool_pt': '0.00'} {'d3-50': '0.05', 'd50-100': '0.17', 'd100-200': '0.29', 'd200-400': '0.37', 'd400-800': '0.63', 'd800-1600': '0.64', 'd1600-5000': '0.80'}
34 auc 0.894 {'E': '0.00', 'early': '0.10', 'mid': '0.35', 'late': '0.72', 'non': '0.05', 'think_pt': '0.00', 'tool_pt': '0.03'} {'d3-50': '0.05', 'd50-100': '0.17', 'd100-200': '0.31', 'd200-400': '0.39', 'd400-800': '0.69', 'd800-1600': '0.70', 'd1600-5000': '0.85'}
36 auc 0.859 {'E': '0.00', 'early': '0.12', 'mid': '0.34', 'late': '0.65', 'non': '0.02', 'think_pt': '0.00', 'tool_pt': '0.00'} {'d3-50': '0.08', 'd50-100': '0.18', 'd100-200': '0.29', 'd200-400': '0.38', 'd400-800': '0.65', 'd800-1600': '0.58', 'd1600-5000': '0.79'}
38 auc 0.817 {'E': '0.00', 'early': '0.13', 'mid': '0.33', 'late': '0.57', 'non': '0.01', 'think_pt': '0.00', 'tool_pt': '0.00'} {'d3-50': '0.09', 'd50-100': '0.19', 'd100-200': '0.28', 'd200-400': '0.37', 'd400-800': '0.59', 'd800-1600': '0.46', 'd1600-5000': '0.75'}
40 auc 0.801 {'E': '0.00', 'early': '0.14', 'mid': '0.32', 'late': '0.57', 'non': '0.01', 'think_pt': '0.00', 'tool_pt': '0.00'} {'d3-50': '0.10', 'd50-100': '0.19', 'd100-200': '0.28', 'd200-400': '0.36', 'd400-800': '0.58', 'd800-1600': '0.46', 'd1600-5000': '0.75'}
42 auc 0.766 {'E': '0.00', 'early': '0.16', 'mid': '0.29', 'late': '0.52', 'non': '0.01', 'think_pt': '0.00', 'tool_pt': '0.00'} {'d3-50': '0.14', 'd50-100': '0.18', 'd100-200': '0.26', 'd200-400': '0.32', 'd400-800': '0.53', 'd800-1600': '0.44', 'd1600-5000': '0.69'}
44 auc 0.748 {'E': '0.00', 'early': '0.13', 'mid': '0.26', 'late': '0.48', 'non': '0.01', 'think_pt': '0.00', 'tool_pt': '0.00'} {'d3-50': '0.11', 'd50-100': '0.16', 'd100-200': '0.23', 'd200-400': '0.29', 'd400-800': '0.48', 'd800-1600': '0.40', 'd1600-5000': '0.63'}
46 auc 0.765 {'E': '0.00', 'early': '0.12', 'mid': '0.27', 'late': '0.51', 'non': '0.00', 'think_pt': '0.00', 'tool_pt': '0.00'} {'d3-50': '0.09', 'd50-100': '0.15', 'd100-200': '0.23', 'd200-400': '0.30', 'd400-800': '0.51', 'd800-1600': '0.42', 'd1600-5000': '0.67'}
48 auc 0.744 {'E': '0.00', 'early': '0.14', 'mid': '0.25', 'late': '0.47', 'non': '0.01', 'think_pt': '0.00', 'tool_pt': '0.00'} {'d3-50': '0.12', 'd50-100': '0.15', 'd100-200': '0.22', 'd200-400': '0.27', 'd400-800': '0.47', 'd800-1600': '0.40', 'd1600-5000': '0.63'}
```

Not tested: free-running generation under the edit (no rollouts, no served probe in this turn), so whether a thought
that is ended early is followed by a sensible tool call is only covered by the `think` / `tool` columns above.

Runner facts (2026-11-12 21:42:14 EST): source `wsp31/authors/claude/queue/early-gate-b01-end-neurons-x9/`; served copy `wsp31/queue/frozen/claude__early-gate-b01-end-neurons-x9/`; sha256 over files, edit `a5531ed82023b2d60e3805360b10aa9d289dcc09d0999b8473a2a7e7debf8361`, control `3f4dd3ebc7aeee94bf4686e99f969e3fb1ce03c3029f6246e312577e07ce07d6`; both passed the checker.
Prediction (written before the run)
predicted_gain_120: -7 to 9

Behaviour that should move: this is the strong end of the gated family. The gate is the g2 version (fitted on depth
>= 400, so it starts to fire from depth 100 to 400) at dose 0.1, plus the model's own end-of-thought neurons at 9
times their write. Pre-test of this adapter: every one of the 6 long thoughts is cut (median depth 148, 21% of their
tokens kept), 35% of the 23 short thoughts are cut before their logged end (82% of their tokens kept), logged ends stay
as decisive as unedited (`E top=101` 0.83). With entries deep-thought-gate-g3-b03 (long 0.53, short 1.00) and
deep-gate-b01-end-neurons-x9 (long 0.48, short 0.95) it gives three doses of "how much thinking is cut" by the same
mechanism.
- thinking tokens per episode: down 40% to 60% (5,700 to between 2,300 and 3,400);
- episodes ending at the 7.5-minute limit: down by a third to two thirds of the unedited arm's rate (35% at 110
  episodes: to 12-24%); empty patches down in the same proportion (25%: to 9-17%);
- tool calls per episode: up by 2 to 5; episodes at the 30-call cap up by at most 8 points (unedited 17%);
- if cutting thoughts is good at all, this entry should gain at least as much as the two weaker doses; if it gains
  less than they do, the cut has started to remove thinking the tasks need (collateral inside deep thoughts is the
  largest of my entries: log-prob of the logged token -0.57 at depth >= 400, top token unchanged at 82% of them, most
  of which is the intended early end).
Control (`ctrl/`): thinking tokens per episode within 8% of the unedited arm, session-limit rate within 6 points,
gain between -4 and +4 (identical unedited arms already differ by a few tasks).

The hypothesis is wrong if (a) thinking tokens per episode fall by less than 10%: the teacher-forced cut does not
transfer to free-running episodes (the model re-opens the thought it was made to close); or (b) thinking falls by
20% or more and the limit rate falls, but the edit does not gain tasks: long thoughts are then a symptom of hard
tasks and not the cause of the failures; or (c) the control shows the same fall in thinking tokens: then it is not
this direction. A rise of episodes that stop at the 30-tool-call cap by more than 8 points over the unedited arm would mean the saved time went into
more calls and not into finishing.

Caveats written before the run: the pre-test has only 5 held-out episodes (6 long thoughts); the lane's forward pass
reproduces only 83% of the logged thought ends on the unedited model (agreement with the server NOT VERIFIED YET);
nothing was generated under the edit, so the first tool call after a thought that was cut short is untested.
Unedited reference (b001): at 61 episodes solved 54%, at the session limit 23%, thinking tokens per episode 5,700
(solved 4,637, limit 9,149). At 110 episodes (9:40 PM ET): solved 44%, at the session limit 35%, empty patch 25%, at
the 30-tool-call cap 17%; 8.6% of calls think 800 tokens or more, 17.6% think 400 or more. The percentages predicted
above are relative to whatever the unedited arm of the same batch shows.
Result
Pending.
Verdict and notes
Parked 2026-11-13 09:12:02 EST, not screened: rounds began on 13 Nov 2026 and each author keeps two waiting entries. The author can put it back in a later round (an empty file `RESUBMIT` in `wsp31/authors/claude/queue/early-gate-b01-end-neurons-x9/`); it then counts as one of that round's entries and is served from the frozen copy, unchanged.