uv(audit): §8 dirty-25 root cause — kernel slot desync, phantom watches, offline symbols, p- id skew

This commit is contained in:
Codex
2026-07-11 20:29:37 +02:00
parent d0ae6a1c62
commit bcd37984d9

View File

@@ -311,3 +311,54 @@ scope for this read-only audit.
essentially absent from the bridged trade set.
- Fees dominate drag in both eras (~10 bps, matches BingX taker). Enter slippage is
systematically adverse (mean ≈ -24 bps) in era B.
---
## 8. 25-row root cause (2026-07-11, Fable — flight-recorder maiden run)
Instrument: `prod/clean_arch/violet/uv/uv_flight_recorder.py` (read-only
stage tracer: journal → runner log → VST venue; 20 tests, mutation-RED).
Every one of the 25 unmatched rows is now classified from primary evidence:
| Class | Rows | Evidence |
|---|---|---|
| PHANTOM_KERNEL_REFUSED — SLOT_BUSY (ENTER) | 6 | `KERNEL SUBMIT -> SLOT_BUSY` in runner log (XLM, DASH, ADA, LTC, TRX, THETA enters) |
| PHANTOM_KERNEL_REFUSED — NO_OPEN_POSITION (EXIT) | 9 | `KERNEL SUBMIT -> NO_OPEN_POSITION` (XLM, DASH, ADA, CELR, LTC×2, TRX, THETA, BNB exits) |
| SUBMITTED_VENUE_DEAD — symbol offline on VST | 5 | `bingx_direct … "X is offline currently"` warnings: BAND-USDT ×4 legs, CELR-USDT ENTER. HTTP 200 with error body; kernel still reported OK |
| LOG_GAP — pre-restart window | 4 | ETH pair (07:44/08:05 UTC) + DASH pair (11:04/11:26 UTC) predate the 11:32 UTC log restart; shape matches phantom pairs |
| SUBMITTED_NO_VENUE_EVIDENCE | 1 | THETA EXIT f02ff2f: kernel OK 33 s after its own ENTER was SLOT_BUSY-refused; venue shows **no** order |
**None of the 25 was submitted-and-venue-rejected at order level; none is a
missing venue record.** They are kernel-doorman refusals, dead-symbol
submits, and a log gap.
### Mechanism (the real defect, 4 parts)
1. **Kernel slot state advances on submit-accept, not venue-fill-confirm.**
Venue business-level rejects (HTTP 200 + error body, e.g. offline symbol)
leave the slot occupied by a position that never existed → later
legitimate ENTERs get SLOT_BUSY; later phantom EXITs get kernel OK against
nothing. Desync also runs the other way: THETA 76bbf8ee filled at venue
13:55:09 UTC yet its SL exit at 14:05 got NO_OPEN_POSITION.
2. **Bridge journals + TPSL watches register regardless of kernel verdict**
(`TPSL WATCH` logs *before* `KERNEL SUBMIT`) → refused intents become
phantom positions that later emit phantom EXITs — the 10 full
identical-qty pairs in §5.
3. **Venue-offline symbols pass asset pick** (BAND, CELR delisted on VST) →
guaranteed-dead submits. DIV-014-adjacent; pick layer needs the tradable
set from `/openApi/swap/v2/quote/contracts`.
4. **`u-` clientOrderId is not propagated to the venue** — venue orders carry
kernel-minted `p-e-…`/`p-x-…` ids. Sentinel check (c) will false-FAIL on
every legitimate order; venue joins must use time+qty until fixed.
### Live risk found (needs operator action)
Three refused-EXIT orphans are **open on VST right now**, unprotected, past
their SL doctrine: THETA-USDT SHORT 3298.1 (76bbf8ee, upnl −14.3),
LTC-USDT 11.09 of the 22.2 (41a7d90c), BNB-USDT 0.861 of the 14.73
(b9c92879) — merged with the 9 known pre-06:00 day-1 orphans (8 venue
positions total, ~−256 USDT unrealized). Manual UI close remains the
protocol.
Side finding: VST `allOrders` ignores/empties on `startTime`/`endTime`
params — the recorder filters client-side.