fix(sp11): plan_isv symmetric clamp — 4 sites mirror reward-cap bug
Implementer of 35db31089 (symmetric reward cap) flagged 4 additional
asymmetric-clamp sites in policy-input features (plan_isv slots),
mirroring the same bug class but on the feature side rather than
reward side:
experience_kernels.cu:850 plan_isv[PNL_VS_TARGET] capped above only
experience_kernels.cu:853 plan_isv[PNL_VS_STOP] capped above only
backtest_plan_kernel.cu:164 — mirror of 850
backtest_plan_kernel.cu:168 — mirror of 853
unrealized P&L can be negative -> fminf(x, 2.0) leaves an unbounded
lower tail that produces feature jitter at the policy input, hurting
the network's state representation under losing-trade conditions.
Fix: symmetric clamp via fmaxf(-2.0, fminf(x, 2.0)).
Per pearl_symmetric_clamp_audit (added in close-out commit) and
pearl_bounded_modifier_outputs_require_structural_activation: any
spec-bounded scalar requires bilateral enforcement.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -160,13 +160,15 @@ extern "C" __global__ void backtest_plan_state_isv(
|
||||
pisv[PLAN_ISV_PROGRESS] = (plan_tgt_bars > plan_thr)
|
||||
? fminf(hold_time / plan_tgt_bars, 2.0f) : 0.0f;
|
||||
|
||||
/* [1] PnL vs profit target [bounded 2.0] */
|
||||
/* [1] PnL vs profit target [symmetric bound -2.0..2.0]
|
||||
* unrealized can be negative → fminf alone leaves unbounded lower tail.
|
||||
* Mirror of SP11 symmetric reward cap (35db31089). */
|
||||
pisv[PLAN_ISV_PNL_VS_TARGET] = (plan_profit > 1e-6f)
|
||||
? fminf(unrealized / (plan_profit * equity + 1e-6f), 2.0f) : 0.0f;
|
||||
? fmaxf(-2.0f, fminf(unrealized / (plan_profit * equity + 1e-6f), 2.0f)) : 0.0f;
|
||||
|
||||
/* [2] PnL vs stop (negative PnL vs stop → loss approaching) */
|
||||
/* [2] PnL vs stop (negative PnL vs stop → loss approaching) [symmetric bound -2.0..2.0] */
|
||||
pisv[PLAN_ISV_PNL_VS_STOP] = (plan_stop > 1e-6f)
|
||||
? fminf(-unrealized / (plan_stop * equity + 1e-6f), 2.0f) : 0.0f;
|
||||
? fmaxf(-2.0f, fminf(-unrealized / (plan_stop * equity + 1e-6f), 2.0f)) : 0.0f;
|
||||
|
||||
/* [3] Entry conviction (stable across the trade) */
|
||||
pisv[PLAN_ISV_ENTRY_CONVICTION] = plan_conv_ent;
|
||||
|
||||
@@ -846,11 +846,14 @@ extern "C" __global__ void experience_state_gather(
|
||||
plan_isv[PLAN_ISV_PROGRESS] = (plan_tgt_bars > plan_thr_sg)
|
||||
? fminf(f_hold_time / plan_tgt_bars, 2.0f) /* plan progress [0, 2] */
|
||||
: 0.0f;
|
||||
/* Symmetric clamp [-2, 2]: f_unrealized_pnl can be negative → fminf alone leaves
|
||||
* an unbounded lower tail (feature jitter at policy input). Mirror of SP11
|
||||
* symmetric reward cap (35db31089). See pearl_symmetric_clamp_audit. */
|
||||
plan_isv[PLAN_ISV_PNL_VS_TARGET] = (plan_profit > 1e-6f)
|
||||
? fminf(f_unrealized_pnl / (plan_profit * f_equity + 1e-6f), 2.0f) /* pnl vs target */
|
||||
? fmaxf(-2.0f, fminf(f_unrealized_pnl / (plan_profit * f_equity + 1e-6f), 2.0f)) /* pnl vs target */
|
||||
: 0.0f;
|
||||
plan_isv[PLAN_ISV_PNL_VS_STOP] = (plan_stop > 1e-6f)
|
||||
? fminf(-f_unrealized_pnl / (plan_stop * f_equity + 1e-6f), 2.0f) /* pnl vs stop */
|
||||
? fmaxf(-2.0f, fminf(-f_unrealized_pnl / (plan_stop * f_equity + 1e-6f), 2.0f)) /* pnl vs stop */
|
||||
: 0.0f;
|
||||
plan_isv[PLAN_ISV_ENTRY_CONVICTION] = plan_conv; /* conviction at entry [0, 1] */
|
||||
|
||||
|
||||
@@ -5687,3 +5687,31 @@ new HEALTH_DIAG line, the follow-up commit will:
|
||||
|
||||
Per `feedback_no_partial_refactor`: instrumentation lands as one
|
||||
atomic commit; removal lands as one atomic commit (with the fix).
|
||||
|
||||
## SP11 plan_isv symmetric clamp — 4 mirror sites (2026-05-04)
|
||||
|
||||
The implementer of `35db31089` (symmetric reward cap) flagged 4
|
||||
additional asymmetric-clamp sites in `plan_isv` policy-input
|
||||
features, mirroring the same bug class but on the feature side
|
||||
rather than reward side:
|
||||
|
||||
| Site | Slot | Bug |
|
||||
|---------------------------------------|-----------------------|----------------------------------------|
|
||||
| `experience_kernels.cu:850` | `PLAN_ISV_PNL_VS_TARGET` | `fminf(.., 2.0)` capped above only |
|
||||
| `experience_kernels.cu:853` | `PLAN_ISV_PNL_VS_STOP` | `fminf(.., 2.0)` capped above only |
|
||||
| `backtest_plan_kernel.cu:164` | `PLAN_ISV_PNL_VS_TARGET` | mirror of 850 |
|
||||
| `backtest_plan_kernel.cu:168` | `PLAN_ISV_PNL_VS_STOP` | mirror of 853 |
|
||||
|
||||
`unrealized` P&L can be negative (and `-unrealized` becomes negative
|
||||
when the position is profitable). With only `fminf(x, 2.0)`, the
|
||||
lower tail is unbounded, producing feature jitter at the policy
|
||||
input under losing-trade conditions.
|
||||
|
||||
Fix: bilateral clamp via `fmaxf(-2.0, fminf(x, 2.0))`. These slots
|
||||
feed the network state vector at line 956 of `experience_kernels.cu`
|
||||
(consumer site) and at the `pisv` write-out in `backtest_plan_kernel`.
|
||||
|
||||
This is the policy-input mirror of the reward-side bug fixed in
|
||||
`35db31089`. Both share the same architectural lesson — see
|
||||
`pearl_symmetric_clamp_audit` (added in the SP11 close-out commit)
|
||||
and `pearl_bounded_modifier_outputs_require_structural_activation`.
|
||||
|
||||
Reference in New Issue
Block a user