Closes the latent SGEMM K-mismatch left by B.8 (6715ab4ea):
`w_b0fc` had grown from `[adv_h, SH2]` to `[adv_h, SH2 + 1]` end-to-end,
but every direction-Q-head consumer's SGEMM still used `K = shared_h2`
against the new `LDA = SH2 + 1` weight tensor — safe ONLY because the
new column was zero-init in B.8 and Adam had not yet updated it. After
this commit the forward wire is FULLY ACTIVE; the SGEMM consumes
`sp14_dir_qaux_concat_scratch [B, SH2 + 1]` with `K = shared_h2 + 1`.
Direction Q-head input pointer: `h_s2_buf` → `sp14_dir_qaux_concat_scratch`.
K dim: `shared_h2` → `shared_h2 + 1`.
Concat kernel runs immediately before the direction Q-head SGEMM in
the same stream, enforcing `pearl_canary_input_freshness_launch_order`.
Mirrors the `launch_mag_concat_from` precedent: the aux head forward
that writes `aux_nb_softmax_buf` runs AFTER the per-step online
forward (line ~25599 in the new layout), so each forward consumes
the PREVIOUS step's aux predictions — same one-step-lag semantic as
mag_concat. Step 0 sees alloc_zeros (uniform 0.5/0.5 → diff = 0),
step 1+ sees the prior step's aux next-bar softmax.
Atomic-migration consumers (`feedback_no_partial_refactor`):
- `gpu_dqn_trainer.rs` — new `launch_sp14_dir_concat_qaux` method;
online forward (line ~25583) and target forward (line ~25758)
each precede their `forward_*_raw` call with a concat launch and
pass `sp14_dir_qaux_concat_scratch.raw_ptr()`. Both replay paths
(`replay_forward_ungraphed`, `replay_forward_for_q_values`
ungraphed fallback) get the same wire — they use online weights
and produce direction Q-values consumed by training/eval. Causal
intervention sites (×2) and DDQN argmax pass `0u64` per spec
(their direction Q outputs are either unread by the consumer or
the spec accepts the K=SH2 fallback's residual one-step bias).
- `batched_forward.rs` — five `forward_*_raw` / `launch_vsn_glu_branch`
signatures grow a trailing `dir_qaux_concat_ptr: u64`; new
`d == 0 && dir_qaux_concat_ptr != 0` branch in every legacy
ReLU-FC FC dispatch (multi-stream / sequential × online / target /
F32-output) returning `(dir_qaux_concat_ptr, self.shared_h2 + 1)`.
VSN-GLU branch path scatters `vsn_masked` into the first SH2 cols
of the scratch, identical to the `d == 1/2/3` scatter pattern
(the trailing aux_softmax_diff column was already written by the
pre-VSN concat-kernel launch and survives the scatter). The
`CublasGemmSet::new` heuristic-cache shape table grows by one
unique tuple `(adv_h, batch, SH2 + 1, SH2 + 1)` so the first-call
cublasLt heuristic search hits a fresh cache slot instead of the
pre-B.8 `(adv_h, batch, SH2, SH2)` entry.
- `gpu_experience_collector.rs` / `value_decoder.rs` — pass `0u64`
for the new arg (no aux-head dependency on those forwards;
documented inline with rationale).
- `docs/dqn-wire-up-audit.md` — new SP14 Layer B B.9 entry per
Invariant 7, documenting every new dispatch site, the
diagnostic-path residual, and the launch-order constraint.
After this commit the forward wire is FULLY ACTIVE: aux-head
gradients flow back through the kernel's `s1 - s0` derivative into
`aux_nb_softmax_buf`'s logits, co-training the aux head with Q-loss.
Backward gradient flow is INTENTIONALLY UNGATED in this commit —
the EGF pearl gating (scale `dL/dx[wire_col]` by `α_grad_smoothed`
to prevent gradient-hacking) lands in B.10. Per
`feedback_no_partial_refactor`, this intermediate state is
functional (the model trains; aux gets co-trained by Q-loss) but
not yet behavior-protected by the gate.
Diagnostic-path residual (causal intervention, DDQN argmax, exp
collector, value decoder): the cuBLAS heuristic for `K=SH2, LDA=SH2`
against the underlying `[adv_h, SH2 + 1]` weight tensor reads the
first `adv_h * SH2` floats with stride SH2 — within bounds (no
OOB), produces stable-but-incorrect outputs for the residual paths.
Their direction Q outputs feed either (a) only-value-logit consumers
(causal sensitivity) or (b) downstream argmax-only consumers with
one-step-bias acknowledged by the spec (DDQN). The train-time wire
(online + target + replay) is fully closed.
Test: `SQLX_OFFLINE=true cargo check -p ml` clean (18 warnings,
pre-existing baseline). The smoke validation that the model
converges with the active forward wire happens in B.11 alongside
the captured-graph integration (B.10 gates backward first).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>