User design call DD11: migrate the two aux-CQL gradient kernels in
c51_loss_kernel.cu to the SP17 mean-zero advantage contract. The
pre-SP17 comment "skip advantage-mean centering — small epsilon vs
correctness simplicity" at barrier_gradient_direction:1212 is REMOVED;
its empirical-without-verification rationale doesn't hold under the
SP17 contract that compute_expected_q + c51_loss + c51_grad +
mag_concat_qdir + Thompson + quantile_q_select already enforce.
barrier_gradient_direction:
- Per-thread `a_mean_per_atom[NUM_ATOMS_MAX]` reduction over b0_size
direction actions.
- Forward Q-value computation reads `v_row[z] + (adv_a[z] - mean[z])`.
- Backward gradient recompute uses the same centered logits in the
per-action softmax probability accumulation. The Jacobian's symmetric
-1/b0_size per-atom offset cancels in the barrier's relative-push
gradient direction (max up, 2nd down — both targets see same offset).
- Stale "skip centering" comment deleted; replaced with SP17 explanation.
ib_gradient_direction:
- Same per-atom mean reduction at function entry.
- Forward Q computation + backward dq_dlogit recompute both flow through
centered probabilities. Variance var_q is invariant under common
per-atom shifts (math: shift cancels in (Q(a) - mean_q)^2), so var_q
numerics are bit-equivalent — but the gradient flows through the
centered probability `p(z|a)` for consistency with c51_grad backward.
NUM_ATOMS_MAX=128 ceiling guard added to both kernels (mirror of
experience_kernels.cu); early-exit `if (num_atoms > NUM_ATOMS_MAX) return`
matches the pattern already used by these kernels for unrelated
zero-op guards.
GPU oracle test (RTX 3050 Ti, 6/6 PASS):
barrier_gradient_direction_uses_centered_advantage — A=0, V=0 ⇒
centered logits all zero ⇒ uniform softmax ⇒ E[Q]=0 across actions ⇒
q_gap=0 ⇒ barrier fires at min_req=0.05 ⇒ asserts total |grad| > 1e-6.
Regression detector: any centering breakage produces non-finite or
zero gradients ⇒ test fails loudly. ib_gradient_direction shares the
identical per-atom mean reduction pattern so the same test covers
both kernels structurally.
Verification:
cargo check --workspace → clean
cargo test sp17_dueling_oracle_tests --features cuda
-- --ignored → 6/6 PASS
⚠ INTERIM STATE: c51_loss_batched + c51_grad_kernel already-centered
sites still need Commit E annotation pass to mark the existing Jacobian
+ per-d=1 magnitude-std as SP17-compliant.
Plan: docs/superpowers/plans/2026-05-08-sp17-dueling-q-network.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>