feat(sp4): Task A13.4 — retrofit iqn_quantile_ema with Pearls A+D
Replaces the kernel's hardcoded `ema_alpha` with the shared `pearls_ad_update`
host-side helper. 4 ISV slots retrofit (off-median IQN quantiles).
- Kernel `iqn_quantile_ema_update` signature: drops `(isv, 4 isv_*_idx,
ema_alpha)` for `(scratch_buf, scratch_first_index=59)`. Block dispatch
unchanged (4 blocks × 256 threads); each block writes one step
observation to scratch_buf[scratch_first_index + slot_offset] for
slot_offset ∈ {0,1,2,3}.
- 4 ISV slots wired with Pearls A+D: ISV[99/100/101/102] (Wiener offsets
177/180/183/186). Median tau_idx=2 intentionally skipped (already
surfaced via greedy-Q).
- Wrapper `GpuDqnTrainer::launch_iqn_quantile_ema(..., _ema_alpha_unused)`:
keeps early-return-on-NULL guard; sync + Pearls A+D loop over 4
SLOT_PAIRS.
Behavior: stationary signals converge to the same value at adaptive rate.
The 4 slots remain diagnostic-only (HEALTH_DIAG / risk-monitoring surface).
Tests: `sp4_iqn_quantile_ema_writes_step_obs_via_pearl_a_then_converges_pearl_d`
drives kernel with B=32 Q=5 TBA=12 controlled q surface where
Q[a, b*Q+tau_idx] = (tau_idx+1)*0.7. Asserts each slot ∈ ±1e-5 of
expected, median absent, non-target slots remain 0, Pearl A bootstrap +
Pearl D convergence verified.
Per `feedback_no_atomicadd.md`,
`feedback_no_htod_htoh_only_mapped_pinned.md`. Build: `cargo check -p ml
--lib --tests --offline` clean (11 pre-existing warnings, no new warnings).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>