# GOAL_6 Progress — 2026-08-23

Session record for `GOAL_6.md` (can the address itself carry information?,
Experiment 006).
Formal deliverable: `dynamic-memory-lab/results/experiment_006/experiment_006_report.md`.

**GOAL_6: complete — one anti-collapse recipe designed and documented before the
run, isolation proven, gradient path measured, trained under an armed
early-collapse gate, addressing probed in-loop, evaluation staged on the gate
outcome, six-way comparison done. Exit condition reached.**

### Bottom line

    The regulariser worked. It was aimed at the wrong statistic.
    ~21 effective slots held probability mass while all 24 facts
    selected the same argmax.

**Outcome E — address collapse repeats.** Recall **0/48**, composition **0/24**,
interference **0.5833**. Training stopped at **epoch 6 of 30** when the
pre-committed gate tripped.

The trajectory, probed inside the training loop:

| epoch | τ | loss | distinct dominant slots | max share | address entropy | score margin |
|---|---|---|---|---|---|---|
| 1 | 3.000 | 6.4299 | 1 | 1.0000 | 4.5977 | 0.054 |
| 2 | 2.857 | 5.8724 | 1 | 1.0000 | 3.9673 | 0.732 |
| 3 | 2.714 | 5.3278 | 1 | 1.0000 | 1.2166 | 1.124 |
| 4 | 2.571 | 4.8699 | 1 | 1.0000 | 0.3369 | 2.146 |
| 6 | 2.286 | 4.1771 | 1 | 1.0000 | **0.0326** | **5.260** |

Uniform is 4.852. The address ended essentially one-hot, on slot 97 (Experiment
005 collapsed to slot 63 — different slot, identical pattern).

---

## The finding that made the run worth doing

Global slot usage, measured on the same steps:

| epoch | effective slots (usage EMA) | max slot share | aux loss |
|---|---|---|---|
| 1 | 125.7 | 0.9 % | 0.00000 |
| 3 | 62.8 | 7.8 % | 0.00000 |
| 4 | 25.3 | 32.8 % | 0.00400 |
| 6 | 21.2 | 47.5 % | 0.01134 |

**~21 effective slots were carrying mass at the moment every one of the 24 facts
was selecting the same argmax.** Those are not contradictory readings — they are
two different quantities. A query can put 0.47 on slot 97 and scatter the rest:
mean-usage entropy stays high, a utilisation penalty stays satisfied, and the
selection still carries zero information about the input.

**Slot usage being spread is not addressing.** GOAL_6 said so in the abstract
(*"random slot usage is not useful addressability"*); this run turned it into a
measurement. The regulariser penalises concentration of *mass*; collapse is a
property of the *argmax*. That is a flaw in my recipe, not evidence about the
hypothesis — and it is the specific thing GOAL_7-style tweaking would need to fix
before addressability has been tested at all.

---

## The engineering catch that would have invalidated the run

The regulariser needs the address distribution **with a gradient**. The obvious
implementation captures it inside the patched forward. Measured, both conditions,
same model and batch:

| gradient checkpointing | address captured inside forward |
|---|---|
| off | `requires_grad = True` |
| **on** (what every experiment in this program uses) | **`requires_grad = False`** |

`torch.utils.checkpoint` runs the first forward under `no_grad`. An auxiliary
loss built on a tensor captured there adds a **constant**: no gradient, no
effect. The run would have completed, reproduced Experiment 005's collapse, and
supported the conclusion *"the anti-collapse recipe did not help"* — which would
have been false, because the recipe would never have executed.

Fix: the forward stashes the layer input (detached) and the address is
**recomputed outside the checkpointed region** when the penalty is formed. That
is all the regulariser needs — it only requires `∂/∂(query, keys)`, never a path
into the frozen base. Verified live before training; gradient from the
regulariser alone reached `keys` 3.24e-05 and `query.weight` 3.82e-05, with
`values` and `readout` correctly at 0.

---

## The initialisation review

GOAL_6 asked for the zero-readout gradient claim to be confirmed analytically and,
if cheap, by a one-step diagnostic. Both were done, and the analytic claim holds
exactly:

```
delta = R(read)   =>   dL/d(read) = W_Rᵀ · dL/d(delta)   =>   W_R = 0 gives zero
```

| readout std | keys | values | readout | address path |
|---|---|---|---|---|
| **0.0** (Exp 005) | **0** | **0** | 6.72e-03 | **starved** |
| 1e-4 | 3.75e-07 | 3.27e-05 | 6.70e-03 | open |
| **1e-3** (chosen) | 3.76e-06 | 3.28e-04 | 6.72e-03 | open |
| 1e-2 | 3.77e-05 | 3.29e-03 | 6.74e-03 | open |

**Experiment 005's memory could not have learned to address on its first step
even in principle.** Opening the path changed the loss trajectory not at all
(006 is marginally *worse* than 005 at every epoch). And even unlocked, key
gradient stays ~1800× below the readout's — the constant-bias path does not just
start ahead, it stays ahead.

Perturbation from the new init, as required: gate 1 max |logit diff| 0.586, and
**argmax unchanged on 97.7 %** of probe positions; gate 0 remains exactly
bit-identical.

---

## Temperature

Annealed 3.0 → 1.0 over epochs 1–15 (reached 2.286 before the stop). It did not
prevent saturation: at epoch 4, τ was still 2.571 — flattening scores ~2.6× — and
address entropy had already fallen to 0.337.

Recorded *before* the run and worth restating: the diagnostic showed key gradient
scales as 1/τ (3.76e-06 at τ=1 vs 1.25e-06 at τ=3, exactly 3×). Higher
temperature slows key differentiation even as it delays saturation, so the
schedule may have been self-defeating. Not swept, by instruction.

---

## Six-way comparison

| | LoRA r4 | LoRA r8 | LoRA r16 | residual 004 | KV 005 | **KV 006** |
|---|---|---|---|---|---|---|
| epochs | 30 | 30 | 30 | 30 | 30 | **6** |
| params | 2,523,136 | 5,046,272 | 10,092,544 | 2,811,200 | 739,456 | 739,456 |
| **recall** | 48/48 | 48/48 | 48/48 | 48/48 | 0/48 | **0/48** |
| composition | 5/24 | 4/24 | 10/24 | 0/24 | 0/24 | **0/24** |
| control | 8/12 | 6/12 | 5/12 | 3/12 | 6/12 | **2/12** |
| **interference** | 0.0833 | 0.2500 | 0.3333 | 0.5000 | 0.2500 | **0.5833** |
| substantive churn | 8/12 | 10/12 | 9/12 | 9/12 | 8/12 | **10/12** |
| regressions / repairs | 3/2 | 5/2 | 6/2 | 6/0 | 3/0 | **7/0** |
| mean reasoning tokens | 196.7 | 152.1 | 334.6 | 528.6 | 178.6 | **579.0** |
| truncations | 0 | 0 | 3 | 9 | 4 | **11** |
| distinct dominant slots | — | — | — | — | 1 | **1** |

**Comparability caveat, stated everywhere it appears.** Experiment 006 ran **6
epochs, not 30**. Its loss (4.1771 vs 005's 2.9058), interference, churn and
truncation figures describe an **undertrained** memory and are not like-for-like
with the 30-epoch rows. Reading "0.5833 is the worst interference in the program"
as a property of the recipe would be wrong. The addressing statistics *are*
comparable — measured as a trajectory, not at an endpoint.

---

## Addressing at the end, and one trap

| | Exp 005 | **Exp 006** |
|---|---|---|
| distinct top slots across 24 facts | 1 | **1** |
| distinct top slots, all probe records | 1/128 | **1/128** |
| dominant slot | 63 | **97** |
| mean read entropy | 0.7562 | **0.6042** |
| between-fact entropy | 0 | **0** (max 3.1781) |
| paraphrase agreement | — | **24/24, rate 1.0** |

**The paraphrase number is a trap and the probe was written to say so.** A 1.0
agreement rate against a 1/128 chance baseline looks like flawless address
stability. It means nothing: when every query picks slot 97, every paraphrase
trivially agrees. The caveat shipped inside the artifact —
*"agreement is trivially 1.0 under total collapse; read it together with
distinct_top_slots_across_facts"* — is why this is reported as failure rather
than as the recipe's one success.

Composition: 13,895 accesses, 13 distinct top slots, but slot 97 took **13,810
(99.4 %)**. The extra slots appear only inside runaway generations, not in
response to which fact is asked.

**Positive addressing gate: FAILED.**

---

## Chain, taxonomy, pathology

Chain: hop-1 in trace **0/24**; everything downstream 0 of 0. Seven-way taxonomy:
`no_hop1_retrieval` = **24**, every other bucket 0. As in 005, the questions about
the *second* query are unanswerable rather than answered negatively.

Generation pathology changed shape without disappearing:

| | Exp 005 | **Exp 006** |
|---|---|---|
| mean / median tokens | 178.6 / — | **579.0 / 401.5** |
| min | 3 | **115** |
| 3-token aborts | **14/24** | **0/24** |
| truncations | 4/24 | **11/24** |
| loopiness | 0.0000 | 0.0037 |

The immediate-abort half is gone; the runaway half nearly tripled.

Churn rate **1.0000** — every one of the twelve control answers changed. 7
regressions, 0 repairs.

```
c_arith1    "24 * 3 = 72."  ->  "9"
c_capital   "Paris."        ->  "KRAZNIEK-99."
c_syllogism "No."           ->  "YES."
```

`KRAZNIEK-99` is world-*shaped* without being a world entity — the constant
carries the corpus's surface statistics and none of its content. Leakage: ASCII
1/12, Unicode-aware 2/12, no exact entities. Both metrics reported; the shared
analyser was not modified.

---

## What survives the failure

* **A softmax over slots trained end-to-end on next-token loss collapses to an
  input-independent argmax under every variant tried** — two initialisations, two
  temperature settings, with and without a utilisation penalty.
* **Utilisation regularisation cannot reach it.** Measured directly: 21 effective
  slots of mass and one slot of address, simultaneously.
* **Interference does not track parameter count.** 739,456 params → 0.5833;
  10,092,544 params → 0.3333.
* **Six experiments, no mechanism has touched the frozen reasoner without
  measurable cost.** Best is still LoRA r4: 0.0833 interference, 8/12 substantive
  churn.

---

## Honest limits

* **Six epochs, not thirty.** Every non-addressing number describes an
  undertrained memory. The early stop was right for the question asked and costs
  comparability on everything else.
* **One recipe, no sweep** — by instruction. The regulariser's mis-targeting is
  therefore *identified but not repaired*.
* **The temperature schedule may have been counterproductive** per the measured
  1/τ key-gradient scaling. Untested.
* **The collapse mechanism is inference**, consistent with the entropy/margin
  trajectory and the step-0 gradient measurement, not established by ablation.
* n = 12 controls, n = 24 composition items.

---

## State of the machines

* **jetson-server** (10.0.2.3, Orin Nano Super, JetPack r36.4.7, torch
  2.5.0a0+872d972e41.nv24.08, transformers 4.57.6, `attn=eager`) — ran everything.
  Gradient diagnostic → isolation → base gate → S2 → 6-epoch train (366.8 s, plus
  26.1 s of in-loop probes) → S4/S5/S6 → slot probe → instrumented thinking-mode
  composition (1557.4 s) → analyses. Peak 5.378 GiB system / 1.261 GiB CUDA.
* **henry** (10.0.2.2) — synced, not used for compute.
* Repo `/home/nethic/mem-exp/dynamic-memory-lab`; implementation committed
  separately from results as GOAL_6 asks (`8f8108a`, then the results commit).

Deliverables in `results/experiment_006/`: `experiment_006_report.md`,
`methods.md`, `architecture.md`, `anti_collapse_recipe.md`,
`base_isolation_validation.md`, `detachability_validation.md`, `results.json`,
`addressing_checkpoints.json`, `memory_slot_analysis.json`,
`memory_access_analysis.json`, `composition_failure_taxonomy.json`,
`memory_access_trace_S4_trained_gate1_think.json` (13,895 records),
`trace_analysis.json`, `behavioral_churn.json`, `leakage_analysis.json`,
`leakage_unicode_supplement.json`, `gradient_diagnostic_jetson-server.json`,
`isolation_validation_jetson-server.json`, `train_M1_kv128_ac_jetson-server.json`,
6 raw `eval_*.json`. **`gate_sweep.json` deliberately absent** — GOAL_6: *"do not
waste interpretation on another all-zero recall sweep."*

New code: `scripts/gradient_diagnostic_006.py`, `validate_isolation_006.py`,
`train_kv_006.py`, `eval_kv_006.py`, `probe_slots_006.py`,
`analyze_memory_access_006.py`, `leakage_unicode_006.py`, `aggregate_006.py`,
`run_experiment_006.sh`, `run_phase2_006.sh`, `run_analysis_006.sh`.

`src/dynamic_memory/kv_memory.py` **extended, not forked**: `temperature` and
`readout_init_std` default to 1.0 and 0.0, reproducing Experiment 005 exactly, so
there is no second copy of the mechanism and no "is it the same code?" caveat on
the comparison. Experiments 000–005 artifacts **not modified**; shared analysers
**not modified**.

---

## Next step — not run (exit condition reached)

GOAL_6's stop condition: run exactly one anti-collapse recipe, stop early if
addressing collapses, do not sweep after seeing the result, do not implement
another architecture, do not begin GOAL_7.

GOAL_6 also says explicitly that a repeat collapse is evidence about *this
differentiable addressing/training mechanism*, not about explicit memory as such
— and forbids GOAL_7 as another temperature or regularisation tweak. Nothing here
would justify one.

If the direction continues, the evidence points at the **training signal for the
address**, not its hyperparameters: pressure applied at the argmax rather than to
soft mass (load balancing on hard assignments), a discrete or straight-through
selection, or an auxiliary objective that makes the address predictive of
something. Whether that is worth doing is a decision for review.

Worth stating plainly for whoever picks this up: **after two experiments,
addressability still has not been tested.** 005 could not learn an address
because the gradient path was closed at step 0; 006 could, and collapsed anyway
because the only pressure opposing collapse was pointed at the wrong statistic.
