Core of the Phase 3 unification: instead of writing a brand-new
unified_env_kernel.cu (3-day rewrite per the design doc), extract the
canonical step logic into a single __device__ __forceinline__ helper
that BOTH kernels call. Drift between train/val becomes structurally
impossible — any change to the helper applies to both atomically.
unified_env_step_core (trade_physics.cuh) encapsulates:
1. Action decode (4-branch: dir, mag, order, urgency)
2. Hold action passthrough
3. Target position via compute_target_position_4branch
4. Margin cap (apply_margin_cap)
5. Kelly cap with health-coupled safety (apply_kelly_cap)
6. Trailing stop check (fixed 0.005/1.0/1.0 — regime-adaptive remains
a deferred gem, see trade_physics.cuh comment block)
7. execute_trade with sqrt-impact (spread_scale = -1.0)
8. record_kelly_trade_outcome (Kelly stats update)
9. entry_price update (new entry / reversal / flat)
10. hold_time tick via update_hold_time
11. step_return = (new_value − prev_equity) / prev_equity (PURE P&L)
12. Post-enforcement actual_dir + actual_mag (for actions_history)
Pass-by-pointer for all mutable state (position, cash, entry_price,
hold_time, max_equity, Kelly stats). Outputs: step_return, new_value,
prev_position_sign, actual_dir, actual_mag, trail_triggered.
Ported backtest_env_step (single-step variant) to call the helper —
replaced ~100 lines of inline step logic with a single call. Kept the
capital-floor pre-check / post-check / actions_history stitching as
per-kernel logic (output buffer formats differ between train and val,
so these stay per-kernel).
Files touched:
crates/ml/src/cuda_pipeline/trade_physics.cuh (+172)
crates/ml/src/cuda_pipeline/backtest_env_kernel.cu (-99 / +27 net)
Follow-up in a separate commit:
- Port backtest_env_step_batch (same refactor, batched variant)
- Port experience_env_step to call unified_env_step_core
(subset — training's body has many more layers: counterfactuals,
plan_params, reward shaping bundle — all of which STAY in the
caller; only the core step gets unified)
Verified: cargo check passes. Smoke test in flight to confirm
behavioral equivalence (should be bit-identical — same arithmetic in
same order, just refactored into a helper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>