CI / WASM Build + Size Check (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
Documentation / Build API Documentation (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
`normalize_gate: Option<(lo, hi)>` — when set, a decoder column is rescaled to unit norm only if its norm has left the band; columns inside are left exactly as the gradient step made them (divisor 1.0). `None` keeps per-step renormalisation, bit for bit. Why (omni-cortex D629/D630): per-step rescaling was measured doing two opposite things on the same 32-unit SAE. With it off, two runs descended cleanly to floors 3-7x LOWER than with it on — it was fighting descent. Two other runs (lr 0.01, seeds 7 and 99) diverged outright without it — it was also the clamp holding an unstable rate finite, turning a blow-up into a slow oscillation that looked like a healthy dictionary drifting. The band keeps the second role and drops the first; D630 measures whether it does both. The cold-start exemption is applied after the gate, unchanged. Test pins: in-band columns bit-identical before/after, out-of-band pulled to unit, gate None == per-step. Fixture norms sit strictly off the band edge — a hand-scaled 2.0 came out 2.0000002 in f32 and was, correctly, treated as outside. Co-Authored-By: Claude Fable 5.1 <[email protected]>