diff --git a/crates/ml/src/cuda_pipeline/experience_kernels.cu b/crates/ml/src/cuda_pipeline/experience_kernels.cu index 5b1a323b3..a4d87dfcd 100644 --- a/crates/ml/src/cuda_pipeline/experience_kernels.cu +++ b/crates/ml/src/cuda_pipeline/experience_kernels.cu @@ -1922,14 +1922,16 @@ extern "C" __global__ void experience_env_step( reward -= opportunity_cost; } - /* Plan conviction as reward scaling (always active, ISV-driven). - * The plan head receives ISV-gated h_s2 (temporal attention → feature gate → plan MLP). - * Its conviction output scales the reward → Q-value → C51 loss gradient path. - * No hardcoded constants — conviction IS the learned scaling factor. - * ISV modulates conviction indirectly through the attention-gated trunk. */ + /* Plan conviction as reward scaling — ONLY when plan head is mature. + * Before readiness ≥ 0.5, conviction defaults to 1.0 (identity) so the + * reward signal flows undampened. Without this gate, random init conviction + * (~0.1) kills the gradient signal and prevents the model from learning. */ if (plan_params_ptr != NULL && fabsf(reward) > 1e-8f) { - float conviction = plan_params_ptr[i * 6 + 4]; /* [0, 1] */ - reward *= conviction; /* low conviction → dampened signal, high → amplified */ + float readiness_val = (readiness_ptr != NULL) ? readiness_ptr[0] : 0.0f; + float conviction = (readiness_val >= 0.5f) + ? plan_params_ptr[i * 6 + 4] /* [0, 1] from plan head */ + : 1.0f; /* identity until plan matures */ + reward *= conviction; } out_rewards[out_off] = reward;