PINK: fix multi-leg exit residual — carry kernel leg-index into legacy position

Root cause (harness multi_leg, ~14-TRX residual): pink_direct rebuilds the legacy
TradePosition from the kernel slot every step, but left exit_leg_index=0, so
IntentEngine.next_exit_ratio() consumed ratio[0] (0.5) on EVERY leg and never
advanced to the final leg's 1.0:
  leg1: 0.5×53 ≈ 26 closed -> 27 remain
  leg2: 0.5×27 ≈ 13 closed -> 14 RESIDUAL  (kernel believes flat, exchange isn't)

Fix: propagate the kernel slot's authoritative active_leg_index into the rebuilt
legacy position's exit_leg_index, so the intent engine consumes the correct leg
ratio. The final leg now closes the full remaining -> fully flattens.

Verified: offline 18 green (no regression); live VST harness multi_leg now closes
fully (XPASS) — residual gone, all 6 capital invariants hold. xfail mark removed;
capital-accounting battery is now fully green (7/7) on testnet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Codex
2026-05-31 18:46:06 +02:00
parent 252da65fc7
commit 4d15edcc54
2 changed files with 7 additions and 10 deletions

View File

@@ -458,6 +458,12 @@ class PinkDirectRuntime:
current_price=float(slot_dict.get("entry_price", 0.0)),
initial_size=float(slot_dict.get("initial_size", 0.0)),
exit_leg_ratios=tuple(slot_dict.get("exit_leg_ratios", [1.0])),
# Carry the kernel's authoritative leg progression so the intent
# engine consumes the CORRECT exit-leg ratio. The legacy position
# is rebuilt every step; without this exit_leg_index resets to 0
# and every leg uses ratio[0] — under-closing each leg and leaving
# a residual (kernel believes flat, exchange does not).
exit_leg_index=int(slot_dict.get("active_leg_index", 0) or 0),
closed=False,
)