# 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.py` so each flaw test genuinely exercises its fix (details below). - Ran all offline suites under `siloqy_env` with `PYTHONPATH=/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) 1. **Flaw 5 / `test_partial_exit_settles_pnl_incrementally`** — was entering & exiting at the *same* price (realized_pnl == 0) under a `if 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. 2. **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 uses `exit_partial_fill_ratio=0.5` so the exit order stays live, then asserts CANCEL_ACK clears it and returns the slot to `POSITION_OPEN`. 3. **Flaw 9 / `test_cancel_uses_slot_asset_not_trade_id`** — guard made unconditional (ACK-only entry deterministically leaves the entry order live). 4. **Flaw 12 / `test_transitions_count_matches_lifecycle`** — guard made unconditional. 5. **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 × ratio` with `base_size = initial_size` and 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 enabling `multi_exit`. - **LIMIT / partial-fill** remains explicitly out of scope (MARKET-only bring-up).