1. Separate actor / critic encoders (v2.3 surgical, kept). Each path owns a SnapshotEncoder. actor_encoder ← actor_loss only; critic_encoder ← TD signal only. No cross-contamination — actor builds action-discriminative features, critic builds Q-aware features.
2. Global-Q gradient barrier on the actor. Per-symbol decisions never receive a portfolio-level signal. Global value is learned separately (V_global) and does not steer per-symbol actions. Removes the conflict-signal mechanism behind the long / short oscillation observed in v2.3.
3. V_global as a Transformer observer. Replaces the pooled QGMLP head: • Input: feat_actor.detach() — full 256-dim per-symbol branch features under a hard gradient barrier. • Architecture: TransformerEncoder × 2 (cross-symbol attention) → AttentionPool with learnable query → quantile head. • No actions on input — V_global is V(s), the state-value under the current policy. • Fully isolated: V_global gradients reach neither the branch nor the critic_encoder. At N-agnostic deployment time, V_global aggregates the outputs of every branch; branches stay independent and composable.
4. Lean actor pipeline. The branch is simplified to encoder → mini_mixer → ctx_residual → LN + Linear. • Removed actor_adapter (the v2.1 LatentReadoutAdapter). Diagnostics showed ×2.4 cross-sample bias amplification with no useful information transformation. • Removed ResidualSkipHead branch path. Its gate stayed at zero for 28+ training cycles — roughly 33K dormant params with no contribution. • Added actor_mini_mixer (TransformerEncoder, cross-symbol attention). The branch needs cross-symbol coordination on correlated assets, and the mixer provides it without inflating per-symbol parameter count.
N-extensibility. Adding a branch is just a new token in the attention layers — no quadratic parameter growth in N. Each branch (encoder + mini_mixer + ctx_proj + head + per-sym critic) is a composable unit. V_global accepts (B, N_total, F_enc) without any architectural change.