First commit of the previously-untracked PINK-on-DITAv2 migration system (execution moves to the Rust kernel; policy stays on legacy DITA, so Alpha Engine algorithmic integrity is preserved). BLUE is untouched. Sprint 0 (safety snapshot + flaw-fix verification, MARKET single-leg scope): - Verified Rust FSM fixes (flaws 2,4,10,11,13) by source read of lib.rs. - Hardened 5 vacuous/guarded assertions in test_flaws.py so each flaw test genuinely exercises its fix. Most important: Flaw 5 now asserts capital moves by EXACTLY realized PnL (was entering/exiting at the same price). - Offline suites: 533 passed, 0 failed (35 flaws + 402 kernel/accounting/ bridge + 96 runtime/persistence/multi-exit/restart/seams). - GATE PASS: MARKET-path-critical flaws 1,2,5 confirmed fixed + green. - Added SPRINT0_FLAW_VERIFICATION.md report and _rust_kernel/.gitignore (excludes Rust target/ build artifacts). LIMIT/partial-fill remain explicitly out of scope (MARKET-only bring-up). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.7 KiB
4.7 KiB
Sprint 0 — DITAv2 flaw-fix verification report
Date: 2026-05-30 Scope: Verify (do not re-implement) the DITAv2 flaw fixes before migrating PINK onto the kernel for BingX testnet (MARKET single-leg first). Source read + offline MockVenue test execution. No exchange contact.
Method
- Read the full Rust FSM (
_rust_kernel/src/lib.rs, 1700 L) and the Python bridge (rust_backend.py) +account.py+mock_venue.py. - Hardened previously-vacuous guarded assertions in
test_flaws.pyso each flaw test genuinely exercises its fix (details below). - Ran all offline suites under
siloqy_envwithPYTHONPATH=/mnt/dolphinng5_predict.
Offline test results (all green)
| Suite group | Result |
|---|---|
test_flaws.py (hardened) |
35 passed |
| kernel FSM + accounting invariants + kernel bridge + multi-exit contract | 402 passed |
| pink direct-runtime, CH persistence, multi-exit integration/fuzz, restart-reconcile, rate-limit, routing, sync/async seams | 96 passed |
| Total | 533 passed, 0 failed |
(Two benign warnings: EDAIN normalizer not available — unrelated import; one
coroutine never awaited inside an intentional hang-detection test.)
Test-hardening performed (removed false-green guards)
- Flaw 5 /
test_partial_exit_settles_pnl_incrementally— was entering & exiting at the same price (realized_pnl == 0) under aif slot.realized_pnl != 0.0:guard, so the capital assertion never ran. Now: SHORT entry @100, exit @90 → realized PnL strictly positive, and asserts capital moved by EXACTLY realized PnL (|Δcapital − realized| < 1e-9). This is the core single-authority invariant and is now unconditional. - Flaw 2 /
test_cancel_ack_exit_still_works— exit auto-filled in the default scenario, so the exit order was already gone (if slot.active_exit_order is not None:skipped). Now usesexit_partial_fill_ratio=0.5so the exit order stays live, then asserts CANCEL_ACK clears it and returns the slot toPOSITION_OPEN. - Flaw 9 /
test_cancel_uses_slot_asset_not_trade_id— guard made unconditional (ACK-only entry deterministically leaves the entry order live). - Flaw 12 /
test_transitions_count_matches_lifecycle— guard made unconditional. - Flaw 13 /
test_pnl_warning_on_unsettled_reentry—if slot.is_free():made unconditional.
Per-flaw verdict (MARKET single-leg path = Sprint 1)
| Flaw | Severity | Fixed? | Evidence |
|---|---|---|---|
| 1 — entry-order cancel broken | Critical | FIXED | lib.rs CANCEL branch accepts entry cancel when active_entry_order set & state ∈ {ENTRY_WORKING,ORDER_REQUESTED,ORDER_SENT,IDLE}; bridge emits venue.cancel. 5 tests pass. |
| 2 — no CANCEL_ACK→IDLE for entry (hung orders) | Critical | FIXED | lib.rs:1193-1212 CANCEL_ACK entry branch clears order + resets trade_id/asset/side/size/PnL → IDLE. Non-vacuous tests pass. |
| 5 — capital settle only on terminal | High | FIXED | bridge on_venue_event settles incremental realized_pnl per fill; account.settle() moves capital by exactly that amount. Exact-invariant test passes. |
| 6 — LIMIT order_type/limit_price dropped | Critical | FIXED (N/A to MARKET) | payload carries order_type/limit_price; out of scope for MARKET-only Sprint 1. |
| 4 — double-close/double-settle on final leg | Low | FIXED | apply_fill exit branch: realized accrues once/fill; should_close guarded by size; closed slot rejects further EXIT (NO_OPEN_POSITION); dup fills deduped. |
| 10 — event dedup window | Low | FIXED | seen_event_ids (cap 256, FIFO evict); duplicate events short-circuit to DUPLICATE_EVENT. Tests pass. |
| 11 — reconcile validation | Low | FIXED | reconcile_slots_json validates every slot via validate_slot and rejects the whole batch without mutating on failure. Tests pass. |
| 13 — re-entry PnL loss | Low | FIXED | ENTER resets realized/unrealized/size; bridge resets _last_settled_pnl[slot] on ENTER. Tests pass. |
| 3, 7, 8, 9, 12 | Med/Low | FIXED | covered by hardened/passing tests. |
GATE decision
PASS. The MARKET-path-critical flaws (1, 2, 5) are confirmed fixed in source and proven by non-vacuous offline tests. Sprint 1 (PINK single-leg MARKET on BingX testnet/VST) may proceed.
Carry-forward risks (NOT GATE blockers)
- Sprint 3 (multi-leg) sizing: the exit branch computes
exit_size = base_size × ratiowithbase_size = initial_sizeand cumulative ratios (e.g.0.5, 1.0). On the final leg this can exceed the remaining position; the kernel currently relies on the venue clamping the fill to the open size. Validate on testnet before enablingmulti_exit. - LIMIT / partial-fill remains explicitly out of scope (MARKET-only bring-up).