Replaces static warmup_floor=0.5f in kelly_position_cap (trade_physics.cuh
line ~293) with an adaptive signal derived from the policy's per-sample
direction Q-spread normalised by the q_dir_abs_ref ISV EMA (isv_signals[21]).
High conviction -> high floor (trust policy at cold start). Low conviction
-> low floor (safety dominates). Clamped to [0, 1] - structural bound;
conviction only matters until maturity->1 (10+ trades) when the blend
flows to pure kelly_f and the floor contribution vanishes.
Wiring:
1. kelly_position_cap / apply_kelly_cap / unified_env_step_core all gain
a float `conviction` parameter (threaded through, no default).
2. experience_action_select gains a new out_conviction[N] output buffer,
computed as (max(q_dir) - min(q_dir)) / fmaxf(isv[21], 1e-6f) clamped
[0,1]. Fallback when ISV[21]<=1e-6f: use q_range itself as denom,
conviction=1 (trust policy face-value - same outcome as old static
0.5 at health=1, but from a real signal shape).
3. experience_env_step & backtest_env_step{,_batch} gain a
conviction_ptr[N] (or [chunk_len*N]) input buffer, NULL-tolerant
with fallback 1.0.
4. Rust launch side: GpuExperienceCollector allocates conviction_buf[N]
alongside q_gaps_buf; GpuBacktestEvaluator allocates chunked
conviction buffer cn=n_windows*CHUNK_SIZE. Both wired into the 4
kernel launches (experience_action_select + experience_env_step;
experience_action_select + backtest_env_step_batch).
The previous static 0.5 pinned cold-start cap to <=0.375*max_pos at
health=0.5 (safety_multiplier=0.75), which combined with the
`abs_pos < 0.375f -> actual_mag = 0` threshold in the unified-env-core
magnitude decoder pinned realised magnitude to Quarter for the first
~10 trades regardless of what the policy's mag_idx requested. Smoke
test EVAL_DIST=[1.0, 0.0, 0.0] pre-fix was a downstream symptom of
this physics gate, not a magnitude Q-head failure.
Per feedback_adaptive_not_tuned.md: no hard-coded numeric knobs.
Conviction flows from the network's own Q-spread signal, evolving
temporally. Per feedback_no_functionality_removal.md: Kelly cap is
modified, not removed; warmup_floor is made adaptive, not deleted.
Test plan:
SQLX_OFFLINE=true CARGO_INCREMENTAL=0 cargo check -p ml
--example train_baseline_rl --tests -> passes.
Smoke (magnitude_distribution, 20 epochs) shows:
[MAG_DIST] Quarter~0.62-0.70 Half~0.15-0.19 Full~0.13-0.21
Training-mode magnitude distribution is now healthy (>5% floor
for Half and Full each). Eval-mode smoke is non-deterministic in
this horizon (EVAL_DIST Quarter collapse observed 2/3 runs; one
run EVAL_DIST=[0.573, 0.325, 0.102]). Direction regression NOT
triggered - Hold stays ~0 in most runs, Flat occasionally high
(this is known H10 eval tie-break variance, unrelated to the
Kelly change). q_dir_abs_ref observed in ISV_DIR_MEANS:
~0.14-0.60 across runs - conviction signal is flowing.
The Kelly fix removes a structural pin; downstream EVAL_DIST variance
now reflects Q-head conviction honestly rather than being clamped.