PINK: E2E trace analysis — Pass 20 config/math signs/BingX protocol (W1-W14)
Twentieth pass: int() on 3 env vars uncaught ValueError (W1 Critical), DITA_V2_PREFIX default "dita_v2" multi-process shared memory corruption (W2 Critical), funding sign opposite Python V2 vs Rust same raw value opposite capital effect (W3 Critical), listenKeyExpired frames silently swallowed continue skips expiry check dead code (W4 Critical), RECV_WINDOW_MS no upper bound replay attacks (W5 High), ACTIVE_SLOT_LIMIT stored never enforced by Rust kernel (W6 High), no fill history fetched during WS reconnect gap-backfill fills lost (W7 High), rate limit detection fails on HTTP 429 no matching message instant retry (W8 High), CONTROL_PLANE=REAL_ZINC silently falls back to in-memory (W9 High), all BingxHttpError mapped to REJECTED can't distinguish errors (W10 High), os.environ bracket access vs .get() inconsistent (W11 High). 361 total flaws across 20 passes. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# PINK DITAv2 — Structural Flaw Analysis (CENTRAL)
|
||||
|
||||
**Analysis date:** 2026-05-31
|
||||
**Last updated:** 2026-06-02 (flaw fix pass — 8 flaws closed)
|
||||
**Last updated:** 2026-06-02 (flaw fix pass 2 — 5 more flaws closed; 13 total)
|
||||
**Scope:** Full PINK pipeline — all flaws across all modules.
|
||||
|
||||
> **Fix notation:** Rows marked **✅ FIXED `<sha>`** are verified-fixed with a test commit on branch `exp/pink-ditav2-sprint0-20260530`.
|
||||
@@ -53,7 +53,8 @@
|
||||
| T | Pass 17 (Unsafe Review/Dead Code/Build/Protocols) | 14 | 0 | 5 | 5 | 4 | 0 |
|
||||
| U | Pass 18 (Rust Test Gaps/Accounting/FFI Types) | 14 | 3 | 4 | 4 | 3 | 0 |
|
||||
| V | Pass 19 (Lifecycle/Rust Subtleties/Test Infra) | 14 | 5 | 2 | 4 | 3 | 0 |
|
||||
| **Total** | | **347** | **35** | **101** | **100** | **64** | **37** |
|
||||
| W | Pass 20 (Config/Math Signs/BingX Protocol) | 14 | 4 | 7 | 3 | 0 | 0 |
|
||||
| **Total** | | **361** | **39** | **108** | **103** | **64** | **37** |
|
||||
|
||||
---
|
||||
|
||||
@@ -156,14 +157,14 @@
|
||||
| # | Flaw | Layer | Severity |
|
||||
|---|------|-------|----------|
|
||||
| G1 | EXIT_RESIDUAL action missing from Rust KernelCommandType enum | Rust | **Critical** |
|
||||
| G2 | `into_c_string` unwrap() panics on NUL byte in FFI string | Rust | **Critical** |
|
||||
| G3 | EXIT hardcodes prev_state=POSITION_OPEN — allows backward FSM transition | Rust | **Critical** |
|
||||
| G4 | `consume_exit_leg` stale `all_legs_done` variable — wrong branch after last leg | Rust | **Critical** |
|
||||
| G2 | `into_c_string` unwrap() panics on NUL byte in FFI string — **✅ FIXED `c87ca78`** | Rust | **Critical** |
|
||||
| G3 | EXIT hardcodes prev_state=POSITION_OPEN — allows backward FSM transition — **✅ FIXED `c87ca78`** | Rust | **Critical** |
|
||||
| G4 | `consume_exit_leg` stale `all_legs_done` variable — wrong branch after last leg — **✅ FIXED `fb03300`** | Rust | **Critical** |
|
||||
| G5 | `realized_pnl` unbounded f64 — overflows to inf at extreme values | Rust | **High** |
|
||||
| G6 | `mark_price` produces unbounded unrealized_pnl — no result guard | Rust | **High** |
|
||||
| G7 | ENTER no is_finite() guard on target_size | Rust | **High** |
|
||||
| G8 | `reconcile_slots_json` no dedup or bounds validation | Rust | **High** |
|
||||
| G9 | `exchange_order_id` update targets wrong order — exit cancel broken | Rust | **High** |
|
||||
| G9 | `exchange_order_id` update targets wrong order — exit cancel broken — **✅ FIXED `fb03300`** | Rust | **High** |
|
||||
| G10 | CANCEL diagnostic always says NO_ACTIVE_EXIT_ORDER | Rust | **High** |
|
||||
| G11 | `apply_fill` overwrites intended_size with slot.size | Rust | Medium |
|
||||
| G12 | No max leverage cap enforced by kernel | Rust | Medium |
|
||||
@@ -321,7 +322,7 @@
|
||||
| M6 | test_dedup tests use wrong constant (actual=256, claim 64) — 70 events insufficient | Test | Medium |
|
||||
| M7 | test_outcome_state_matches_actual_slot is tautological | Test | Low |
|
||||
| M8 | ORDER_ACK silent fallthrough when no active order — accepted with no effect | Rust | Medium |
|
||||
| M9 | ORDER_REJECT on POSITION_OPEN with stale entry order destroys position | Rust | **Critical** |
|
||||
| M9 | ORDER_REJECT on POSITION_OPEN with stale entry order destroys position — **✅ FIXED `fb03300`** | Rust | **Critical** |
|
||||
| M10 | No aggregation of trade count, success/fail, latency — all zero | All | **High** |
|
||||
| M11 | Flaw 6 tests pass via metadata passthrough, not field logic | Test | **High** |
|
||||
| M12 | No retry/fallback for ClickHouse INSERT failures — crashes policy cycle | Persistence | **High** |
|
||||
@@ -341,6 +342,17 @@
|
||||
| # | Flaw | Layer | Severity |
|
||||
|---|------|-------|----------|
|
||||
| N1 | Rust kernel `with_handle_mut` zero sync — `&mut` from raw ptr, UB on concurrent FFI — *mitigated by Python GIL (single-threaded caller); catch_unwind added `c87ca78`* | Rust | **Critical** |
|
||||
|
||||
### Fixes applied (2026-06-02 pass 2)
|
||||
|
||||
| Flaw | Commit | What changed |
|
||||
|------|--------|--------------|
|
||||
| G2 — `into_c_string` NUL panic | `c87ca78` | NUL bytes stripped/escaped; `CString::new` error path handled |
|
||||
| G3 — EXIT backward FSM transition | `c87ca78` | EXIT no longer hardcodes `prev_state=POSITION_OPEN`; uses real slot state |
|
||||
| G4 — stale `all_legs_done` in exit leg | `fb03300` | Renamed pre-consume var; else-if guard reads fresh `active_leg_index` after consume |
|
||||
| M9 — ORDER_REJECT nukes POSITION_OPEN | `fb03300` | Spurious reject (no matching order) no longer resets fsm_state; only entry-phase rejects → IDLE |
|
||||
| G9 — venue_order_id targets wrong order | `fb03300` | Routes by FSM state: exit-phase events update exit order, not stale entry order |
|
||||
| H6 — unknown enum variant crashes bridge | `fb03300` | `_safe_enum()` helper returns configurable default on unknown variants |
|
||||
| N2 | `_run()` has two completely different code paths — runtime branch, not design | Venue | **Critical** |
|
||||
| N3 | `_run()` path B blocks event loop thread for every venue HTTP operation | Venue | **Critical** |
|
||||
| N4 | `asyncio.run()` called repeatedly — creates/destroys event loops per call | Venue | **Critical** |
|
||||
@@ -529,6 +541,29 @@
|
||||
|
||||
---
|
||||
|
||||
## W-Series: Configuration Management, Math Sign Conventions, BingX Protocol (Pass 20)
|
||||
|
||||
*Full detail in TRACE doc under "PASS 20 — CONFIGURATION MANAGEMENT, MATH SIGN CONVENTIONS, BINGX PROTOCOL."*
|
||||
|
||||
| # | Flaw | Layer | Severity |
|
||||
|---|------|-------|----------|
|
||||
| W1 | `int()` on 3 env vars uncaught `ValueError` — non-numeric input crashes process | Config | **Critical** |
|
||||
| W2 | `DITA_V2_PREFIX` default `"dita_v2"` — multi-process shared memory corruption | Config | **Critical** |
|
||||
| W3 | Funding sign opposite Python V2 vs Rust — same raw value opposite capital effect | Accounting | **Critical** |
|
||||
| W4 | `listenKeyExpired` frames silently swallowed — `continue` skips expiry check, dead code | Venue | **Critical** |
|
||||
| W5 | `RECV_WINDOW_MS` no upper bound — extreme values enable replay attacks | Config | **High** |
|
||||
| W6 | `ACTIVE_SLOT_LIMIT` stored but never enforced by Rust kernel — dead config | Config | **High** |
|
||||
| W7 | No fill history fetched during WS reconnect gap-backfill — fills permanently lost | Venue | **High** |
|
||||
| W8 | Rate limit detection fails on HTTP 429 without matching message — returns 0 instant retry | Venue | **High** |
|
||||
| W9 | `CONTROL_PLANE=REAL_ZINC` silently falls back to in-memory — no persistence | Config | **High** |
|
||||
| W10 | All `BingxHttpError` mapped to "REJECTED" — can't distinguish errors from real rejections | Venue | **High** |
|
||||
| W11 | `os.environ["KEY"]` bracket access in tests vs `.get()` in launcher — inconsistent | Test | **High** |
|
||||
| W12 | `MockVenueScenario` no `rate_limit` flag — RATE_LIMITED path untested in CI | Test | Medium |
|
||||
| W13 | Rate-limit regex uses English phrase `"unblocked after"` — non-portable | Venue | Medium |
|
||||
| W14 | Invalid `ACTIVE_SLOT_LIMIT` values silently discarded — no log, no warning | Config | Medium |
|
||||
|
||||
---
|
||||
|
||||
## H-Series: Edge Domains — Dependencies, Error Handling, Types, Contracts (Pass 5)
|
||||
|
||||
*Full detail in TRACE doc under "PASS 5 — EDGE DOMAINS."*
|
||||
@@ -540,7 +575,7 @@
|
||||
| H3 | Zero logging — 16+ silent except:pass sites, no error observability | All | **Critical** |
|
||||
| H4 | `_row_float` rejects zero as valid, `except Exception: continue` swallows all | Venue | **High** |
|
||||
| H5 | `_backend_snapshot` timeout returns stale data/None — callers crash | Venue | **High** |
|
||||
| H6 | All enum-from-raw-string sites crash on unknown variant (17 sites) | Bridge | **High** |
|
||||
| H6 | All enum-from-raw-string sites crash on unknown variant (17 sites) — **✅ FIXED `fb03300`** (Python bridge sites) | Bridge | **High** |
|
||||
| H7 | `_legacy_intent` reads `getattr(intent, "order_type")` not metadata — always MARKET | Venue | **High** |
|
||||
| H8 | Unknown venue status silently mapped to ACKED | Venue | **High** |
|
||||
| H9 | `RealZincPlane.write_slot()` `slot_id >= slot_count` silently lost | Zinc | **High** |
|
||||
|
||||
Reference in New Issue
Block a user