diff --git a/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs b/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs index 4b9232b14..486d9a5f5 100644 --- a/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs +++ b/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs @@ -2585,7 +2585,7 @@ const ISV_NETWORK_DIM: usize = 23; /// (and the C-side mirrors in `state_layout.cuh`). Bump this constant in the /// SAME commit that adds the new range, and update `layout_fingerprint_seed` /// to register the new slot names. -pub(crate) const ISV_TOTAL_DIM: usize = 510; +pub(crate) const ISV_TOTAL_DIM: usize = 520; // was 510, SP20 added 10 slots [510..520) /// Legacy alias preserved for call sites that haven't been audited for the /// network-vs-total split. New code should pick `ISV_NETWORK_DIM` (for weight /// tensor sizing) or `ISV_TOTAL_DIM` (for the broadcast bus buffer). @@ -3701,7 +3701,17 @@ const fn layout_fingerprint_seed() -> &'static [u8] { SLOT_507_REWARD_HORIZON_WEIGHT_1BAR=507;\ SLOT_508_REWARD_HORIZON_WEIGHT_5BAR=508;\ SLOT_509_REWARD_HORIZON_WEIGHT_30BAR=509;\ - ISV_TOTAL_DIM=510;\ + SLOT_510_LOSS_CAP=510;\ + SLOT_511_ALPHA_EMA=511;\ + SLOT_512_WR_EMA=512;\ + SLOT_513_HOLD_COST_SCALE=513;\ + SLOT_514_TARGET_HOLD_PCT=514;\ + SLOT_515_HOLD_PCT_EMA=515;\ + SLOT_516_HOLD_REWARD_EMA=516;\ + SLOT_517_N_STEP=517;\ + SLOT_518_AUX_CONF_THRESHOLD=518;\ + SLOT_519_AUX_GATE_TEMP=519;\ + ISV_TOTAL_DIM=520;\ SP19_PRODUCER_HARDCODED_HORIZON_BLEND=sp19_path_b;\ SP14_C_AUX_TRUNK_CONTROL_PLANE=sp14_c_phase_1;\ ALPHA_MACHINERY_DELETED=sp14_c_phase_1;\ diff --git a/crates/ml/src/cuda_pipeline/sp14_isv_slots.rs b/crates/ml/src/cuda_pipeline/sp14_isv_slots.rs index d76e160d1..cc523f8bc 100644 --- a/crates/ml/src/cuda_pipeline/sp14_isv_slots.rs +++ b/crates/ml/src/cuda_pipeline/sp14_isv_slots.rs @@ -863,6 +863,66 @@ pub const SENTINEL_REWARD_HORIZON_WEIGHT_DEFAULT: f32 = 0.333_333_343_f32; // 1. pub const SP19_REWARD_HORIZON_SLOT_BASE: usize = 507; pub const SP19_REWARD_HORIZON_SLOT_END: usize = 510; +// SP20 — WR-first reward + multi-horizon label utilization (2026-05-09) +// +// Slots 510-519 reserved for SP20 components per spec +// docs/superpowers/specs/2026-05-09-sp19-20-wr-first-design.md. +// +// All slots are produced by sp20_emas_compute_kernel, +// sp20_controllers_compute_kernel, or sp20_stats_compute_kernel +// per Component 5 of the spec. + +/// Adaptive loss cap for Component 1 reward kernel. +/// Value: -1.0 - clamp((wr_ema - 0.50) / 0.05, 0, 1) — ranges [-1, -2]. +/// Producer: sp20_controllers_compute_kernel. +pub const LOSS_CAP_INDEX: usize = 510; + +/// Wiener-α EMA over alpha (= R_event - hold_baseline) at trade-close events. +/// Used by Component 1 to center R_used = alpha - alpha_ema. +/// Producer: sp20_emas_compute_kernel. +pub const ALPHA_EMA_INDEX: usize = 511; + +/// Per-trade win-rate EMA. Wiener-α floor 0.4. +/// Drives LOSS_CAP_INDEX adaptive ramp. +/// Producer: sp20_emas_compute_kernel. +pub const WR_EMA_INDEX: usize = 512; + +/// Adaptive Hold opp-cost magnitude (Component 2 controller output). +/// Bounded [0.01, 0.5]. Two-sided controller from hold_pct_ema vs target. +/// Producer: sp20_controllers_compute_kernel. +pub const HOLD_COST_SCALE_INDEX: usize = 513; + +/// Target Hold% derived from aux confidence distribution. +/// Value: clamp(0.8 - aux_conf_p50_ema * 1.5, 0.1, 0.8). +/// Producer: sp20_controllers_compute_kernel. +pub const TARGET_HOLD_PCT_INDEX: usize = 514; + +/// Wiener-α EMA of (action == Hold) indicator. Drives HOLD_COST_SCALE controller. +/// Producer: sp20_emas_compute_kernel. +pub const HOLD_PCT_EMA_INDEX: usize = 515; + +/// Long-run mean of per-bar Hold reward (R_per_bar = -aux_conf * cost_scale). +/// Updated only on Hold-state bars. Used to center Hold reward for Q-target +/// scale comparability with trade reward. +/// Producer: sp20_emas_compute_kernel. +pub const HOLD_REWARD_EMA_INDEX: usize = 516; + +/// Adaptive n-step credit distribution width. +/// Value: clamp(round(trade_duration_ema), 1, 30). +/// Producer: sp20_controllers_compute_kernel. +pub const N_STEP_INDEX: usize = 517; + +/// Aux→Q gate threshold. Value: clamp(aux_dir_acc_ema - 0.50, 0.01, 0.20). +/// Producer: sp20_controllers_compute_kernel. +pub const AUX_CONF_THRESHOLD_INDEX: usize = 518; + +/// Aux→Q gate temperature. Value: aux_conf_std_ema (with floor). +/// Producer: sp20_controllers_compute_kernel. +pub const AUX_GATE_TEMP_INDEX: usize = 519; + +pub const SP20_ISV_SLOT_BASE: usize = 510; +pub const SP20_ISV_SLOT_END: usize = 520; + #[cfg(test)] mod tests { use super::*; @@ -1327,4 +1387,20 @@ mod tests { SP19_REWARD_HORIZON_SLOT_END, ISV_TOTAL_DIM, ); } + + #[test] + fn sp20_isv_slots_reserved_510_to_520() { + use crate::cuda_pipeline::gpu_dqn_trainer::ISV_TOTAL_DIM; + assert_eq!(ISV_TOTAL_DIM, 520); + assert_eq!(LOSS_CAP_INDEX, 510); + assert_eq!(ALPHA_EMA_INDEX, 511); + assert_eq!(WR_EMA_INDEX, 512); + assert_eq!(HOLD_COST_SCALE_INDEX, 513); + assert_eq!(TARGET_HOLD_PCT_INDEX, 514); + assert_eq!(HOLD_PCT_EMA_INDEX, 515); + assert_eq!(HOLD_REWARD_EMA_INDEX, 516); + assert_eq!(N_STEP_INDEX, 517); + assert_eq!(AUX_CONF_THRESHOLD_INDEX, 518); + assert_eq!(AUX_GATE_TEMP_INDEX, 519); + } } diff --git a/docs/isv-slots.md b/docs/isv-slots.md index a7ff30089..c1eece75a 100644 --- a/docs/isv-slots.md +++ b/docs/isv-slots.md @@ -474,3 +474,30 @@ producers and consumers independently without index collisions. **Atomic deletion alongside this addition:** legacy `compute_drawdown_penalty` device function in trade_physics.cuh + its single caller at experience_kernels.cu:3822 + the `w_dd` Rust config field + the `dd_threshold` and `w_dd` kernel args + all `w_dd` profile/TOML references. Per `feedback_no_legacy_aliases` + `feedback_no_partial_refactor` — SP15's quadratic asymmetric DD penalty in `compute_sp15_final_reward_kernel.cu:154` is the production-grade replacement; layering both creates double-counting. **ISV_TOTAL_DIM:** 458 → 459 (Item 1 adds 1 slot; Item 2 is pure deletion). + +## SP20 — WR-first Reward Optimization (Pre-Phase reservation, 2026-05-09) + +SP20 Pre-Phase Task Pre.2 reserves 10 contiguous slots at `[510..520)` for the +WR-first reward design. This reservation occurs at the start of the SP20 +work stream and establishes the slot base for upcoming components: + +| Index | Name constant | Purpose | Producer | Notes | +|-------|---|---|---|---| +| [510] | `LOSS_CAP_INDEX` | Target loss ceiling per transaction (tuning anchor for asymmetric cap) | Per-epoch ISV seed | Bounds the reward penalty for loss scenarios; component 1a | +| [511] | `ALPHA_EMA_INDEX` | Adaptive alpha for transaction-cost EMA decay | GPU kernel (planned) | Tunes the responsiveness of trading cost adjustments; component 1b | +| [512] | `WR_EMA_INDEX` | Win rate EMA for per-bar reward shaping | GPU kernel (planned) | Tracks historical WR; component 2 input signal | +| [513] | `HOLD_COST_SCALE_INDEX` | Per-bar Hold-state carrying cost scaling | Per-epoch ISV seed | Modulates the cost of staying in a position; component 3a | +| [514] | `TARGET_HOLD_PCT_INDEX` | Target percentage of bars spent in Hold state | Per-epoch ISV seed | Reference for adaptive controller; component 3b | +| [515] | `HOLD_PCT_EMA_INDEX` | EMA of actual Hold percentage across bars | GPU kernel (planned) | Driven by adaptive controller; component 3c | +| [516] | `HOLD_REWARD_EMA_INDEX` | EMA of per-bar Hold reward component | GPU kernel (planned) | Tracks reward contribution from Hold state; component 3d | +| [517] | `N_STEP_INDEX` | N-step lookahead window for reward shaping | Per-epoch ISV seed | Controls temporal credit assignment; component 4 | +| [518] | `AUX_CONF_THRESHOLD_INDEX` | Aux confidence threshold for gating auxiliary supervision | Per-epoch ISV seed | Prevents aux contamination; component 5a | +| [519] | `AUX_GATE_TEMP_INDEX` | Temperature parameter for aux gating sigmoid | Per-epoch ISV seed | Controls steepness of confidence-gating function; component 5b | + +**Files touched (Pre.2 atomic):** +- `crates/ml/src/cuda_pipeline/sp14_isv_slots.rs` — 10 `pub const *_INDEX` constants (at the top level, before the test module) + SP20_SLOT_BASE (510) + SP20_SLOT_END (520) constants + 1 regression test (`sp20_isv_slots_reserved_510_to_520`) verifying all 10 slot indices and ISV_TOTAL_DIM=520 +- `crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs` — `ISV_TOTAL_DIM: 510 → 520`, `layout_fingerprint_seed()` extended with all 10 slot `name=index` entries + `ISV_TOTAL_DIM=520` marker (forces fingerprint hash bump → pre-SP20 checkpoints invalidated, greenfield OK) + +**Producers/consumers status:** Pre.2 lands the slot reservation only; all 10 slots are zero-initialized until subsequent SP20 phases land producers (per-epoch ISV seeds + GPU kernels) and consumer migration. Mirrors the SP4/SP5/SP11/SP15 pre-allocation pattern. + +**ISV_TOTAL_DIM:** 510 → 520 (Pre.2 adds 10 slots).