diff --git a/crates/ml-alpha/src/trainer/integrated.rs b/crates/ml-alpha/src/trainer/integrated.rs index 140444d77..a30a24a65 100644 --- a/crates/ml-alpha/src/trainer/integrated.rs +++ b/crates/ml-alpha/src/trainer/integrated.rs @@ -3208,10 +3208,20 @@ impl IntegratedTrainer { // Layer 3 (Inventory) EMAs — NEW in v9. (crate::rl::isv_slots::RL_INVENTORY_PENALTY_BETA_INDEX, 0.0_f32), // sentinel (crate::rl::isv_slots::RL_INVENTORY_VARIANCE_EMA_INDEX, 0.0_f32), // sentinel - // Reward-clamp EMAs — NEW in v9. - (crate::rl::isv_slots::RL_POS_SCALED_REWARD_MAX_EMA_INDEX, 0.0_f32), - (crate::rl::isv_slots::RL_NEG_SCALED_REWARD_MAX_EMA_INDEX, 0.0_f32), - (crate::rl::isv_slots::RL_REWARD_CLAMP_CLIP_RATE_EMA_INDEX, 0.0_f32), + // NORMALIZATION EMAs intentionally NOT reset (refines + // [[pearl_adaptive_carryover_discipline]] via + // [[pearl_popart_reset_at_eval_boundary_shocks_normalization]]): + // RL_POS_SCALED_REWARD_MAX_EMA_INDEX + // RL_NEG_SCALED_REWARD_MAX_EMA_INDEX + // RL_REWARD_CLAMP_CLIP_RATE_EMA_INDEX + // RL_POPART_MAX_ABS_REWARD_EMA_INDEX (F4 envelope) + // These calibrate signal scale, not predict behavior. The model + // was trained against rewards at this scale; preserving the + // scale keeps the reward clamp armed (cap = pos_max_ema × ratio) + // and popart's envelope at train-final magnitude. Resetting + // them disabled the clamp (cap = 0 × ratio = 0) and let outliers + // explode the envelope σ 1500× over ~14 steps → -$185M eval + // loss (alpha-rl-6kghr fold 1, 2026-05-31). // v9 — arm the defensive warmup window. (crate::rl::isv_slots::RL_REGIME_TRANSITION_REMAINING_INDEX, warmup_steps), // Regime observer boundary policy (F1.7 — spec 2026-05-31 v3, @@ -3222,7 +3232,8 @@ impl IntegratedTrainer { // - KELLY_EPS_RECOVERY_LIVE → 0.50 (= ε_max default) // - PREV_WORST_PNL → 0 (CRITICAL — must align with the just-reset // session_pnl_worst above to prevent spurious 3σ tail event) - // - POPART_MAX_ABS_REWARD_EMA → 0 (F4 envelope reset) + // - POPART_MAX_ABS_REWARD_EMA intentionally NOT reset — see + // normalization-EMA preservation block above. // - Welford state (M2/MEAN/COUNT) intentionally NOT reset — the // variance of session_pnl_change is regime-invariant. (crate::rl::isv_slots::RL_REGIME_DEAD_ZONE_FLAG_INDEX, 0.0_f32), @@ -3232,7 +3243,6 @@ impl IntegratedTrainer { (crate::rl::isv_slots::RL_REGIME_RECOVERY_FACTOR_INDEX, 1.0_f32), (crate::rl::isv_slots::RL_KELLY_EPS_RECOVERY_LIVE_INDEX, 0.50_f32), (crate::rl::isv_slots::RL_REGIME_PREV_WORST_PNL_INDEX, 0.0_f32), - (crate::rl::isv_slots::RL_POPART_MAX_ABS_REWARD_EMA_INDEX, 0.0_f32), ] { let mut args = RawArgs::new(); args.push_ptr(self.isv_dev_ptr);