//! SP13 — Redefine success for predictive skill ISV slot constants.
//!
//! Slots [372..383) populated by the SP13 chain:
//!   - 372: directional accuracy target (static, default 0.55)
//!   - 373: aux dir-acc fast EMA (per-fold, sentinel 0.5)
//!   - 374: aux dir-acc slow EMA (per-fold, sentinel 0.5) — stagnation detector
//!   - 375: aux head per-bar prediction (per-bar overwrite, [-1, +1])
//!   - 376: dir-skill bonus α (per-fold, default 1.0) — magnitude on correct calls
//!   - 377: dir-skill bonus β (per-fold, default 1.0) — penalty on wrong calls
//!   - 378: lucky-win discount factor (per-fold, default 0.3)
//!   - 379: skill-bonus cap ratio (per-fold, default 0.3) — bonus ≤ ratio × |α|
//!   - 380: per-bar Hold cost (controller output, sentinel = HOLD_COST_BASE)
//!   - 381: target Hold-pick rate (static, default 0.20 — MFT-ish)
//!   - 382: observed Hold-pick rate EMA (per-fold, sentinel 0.0)
//!
//! Slots 367..372 are an intentional gap separating the SP11 controller block
//! (ends at 367) from this SP13 block. The gap matches the codebase pattern of
//! reserving range markers for future SP-block boundaries.
//!
//! v3 Hold-pricing (slots 380..383, 2026-05-04): replaces v2's atomic Hold
//! elimination after the T3 implementer's audit found `DirectionAction` doesn't
//! exist in the codebase (8-variant fused `ExposureLevel` with cross-crate
//! consumers). Instead of removing Hold, the v3 chain prices it via an ISV-
//! driven adaptive cost controller targeting a Hold-rate (~20% — MFT-ish
//! deliberate use). When the model abuses Hold (rate > target), cost rises
//! until Hold becomes uneconomic; when rate ≤ target, cost relaxes to baseline
//! infrastructure carry. Per `feedback_isv_for_adaptive_bounds`: base cost is
//! the only constant; rate target, observed rate, and cost output are ISV-
//! driven. Spec §"Change 1: Price Hold (replaces v2's Eliminate Hold)".
//!
//! Spec: docs/superpowers/specs/2026-05-04-sp13-redefine-success-for-predictive-skill.md

pub const TARGET_DIR_ACC_INDEX:        usize = 372;
pub const AUX_DIR_ACC_SHORT_EMA_INDEX: usize = 373;
pub const AUX_DIR_ACC_LONG_EMA_INDEX:  usize = 374;
pub const AUX_DIR_PREDICTION_INDEX:    usize = 375;
pub const DIR_SKILL_BONUS_ALPHA_INDEX: usize = 376;
pub const DIR_SKILL_BONUS_BETA_INDEX:  usize = 377;
pub const LUCK_WIN_DISCOUNT_INDEX:     usize = 378;
pub const SKILL_BONUS_CAP_RATIO_INDEX: usize = 379;

// ── v3 Hold-pricing controller (slots 380..383, 2026-05-04) ──────────
pub const HOLD_COST_INDEX:               usize = 380;
pub const HOLD_RATE_TARGET_INDEX:        usize = 381;
pub const HOLD_RATE_OBSERVED_EMA_INDEX:  usize = 382;

/// Static-init defaults written ONCE at trainer construction (and re-written
/// at fold boundary by the constructor path — these are Invariant-1 numerical
/// anchors, not stateful EMAs).
pub const TARGET_DIR_ACC_DEFAULT:        f32 = 0.55;
pub const DIR_SKILL_BONUS_ALPHA_DEFAULT: f32 = 1.0;
pub const DIR_SKILL_BONUS_BETA_DEFAULT:  f32 = 1.0;
pub const LUCK_WIN_DISCOUNT_DEFAULT:     f32 = 0.3;
pub const SKILL_BONUS_CAP_RATIO_DEFAULT: f32 = 0.3;

/// v3 Hold-pricing controller anchor (Invariant-1 numerical constant per
/// `feedback_isv_for_adaptive_bounds.md`).
///
/// SP18 Phase 1 (2026-05-09): the host-side controller (gain/floor/ceil)
/// that scaled `HOLD_COST_BASE` from observed-vs-target Hold rate is
/// DELETED — replaced by the SP18 D-leg structural Hold opportunity-cost
/// reward (Phase 2 lands the `compute_sp18_hold_opportunity_cost` device
/// fn). `HOLD_COST_BASE` and `HOLD_RATE_TARGET_DEFAULT` are RETAINED as
/// constructor-init-only diagnostics (slots 380, 381) — slot 380 keeps
/// the static base cost for cross-fold continuity insurance per DD7c;
/// neither is updated after startup.
pub const HOLD_COST_BASE:             f32 = 0.005;
pub const HOLD_RATE_TARGET_DEFAULT:   f32 = 0.20;

/// SP13 P0b: aux_w deficit + stagnation controller anchors. Replaces the
/// SP11-era inverted formula `aux_w = 0.1 × health × (1 - sharpe).clamp(0.05, 0.3)`
/// at `training_loop.rs` (which LOWERED aux when sharpe was high — exactly
/// wrong for the failure mode where high sharpe + low WR is the structural-
/// extraction trap). The new controller drives aux_w from the deficit
/// `target_dir_acc - short_ema` and decays back to floor when the short EMA
/// fails to pull ahead of the long EMA (data-limited stagnation). Per
/// `feedback_isv_for_adaptive_bounds.md`: base/gain/decay/floor/ceil are
/// numerical anchors; target/short/long EMAs read from ISV. Spec §"Change 5".
pub const AUX_W_BASE:               f32 = 0.5;   // 10× lift from SP11 0.05 floor
pub const AUX_W_DEFICIT_GAIN:       f32 = 5.0;   // aux_w = base × (1 + 5 × deficit)
pub const AUX_W_STAGNATION_DECAY:   f32 = 0.7;   // (1 - 0.7 × stagnation)
pub const AUX_W_HARD_FLOOR_RATIO:   f32 = 0.3;   // never below 0.3 × base
pub const AUX_W_HARD_CEIL_RATIO:    f32 = 3.0;   // never above 3.0 × base

/// Sentinel for both dir-acc EMAs at fold boundary: 0.5 is the random-guessing
/// baseline for binary directional accuracy. First observation replaces this
/// directly per `pearl_first_observation_bootstrap` so the EMA tracks the new
/// fold's signal without bias from the previous fold's terminal accuracy.
pub const DIR_ACC_EMA_SENTINEL: f32 = 0.5;

pub const SP13_SLOT_BASE: usize = 372;
pub const SP13_SLOT_END:  usize = 383;
