Commit Graph

40 Commits

Author SHA1 Message Date
Codex
94078ee8fe PINK: E2E trace analysis — Pass 18 rust test gaps/accounting/FFI types (U1-U14)
Eighteenth pass: R2 compares cumulative vs last-fill realized PnL broken after
2nd fill (U3 Critical), R4 compares open_notional vs used_margin fundamentally
different quantities (U4 Critical), on_venue_event/apply_fill no NaN guards
price/size propagates NaN (U6 Critical), order_type/limit_price sent to Rust
no fields silently dropped (U1 High), VenueEventStatus expects
"CANCEL_REJECTED" typo fails deserialization (U2 High), R3 skipped when
len(e.positions)==0 silent false negative (U5 High), zero Rust tests for
ORDER_REJECT/PARTIAL_FILL/TERMINAL_STATE guard (U7 High), safe_float returns
NaN/Inf contradicts _safe (U8 Medium), _scan_slots uses metadata leverage not
slot.leverage (U9 Medium). 333 total flaws across 18 passes.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-02 14:47:36 +02:00
Codex
66b403ff7d PINK: E2E trace analysis — Pass 17 unsafe review/dead code/build/protocols (T1-T14)
Seventeenth pass: catch_unwind + AssertUnwindSafe partially mutated state no
rollback (T1 High), HazelcastRowWriter bare json.dumps loses Enum/datetime
format (T3 High), real_zinc_plane _slot_from_payload direct key access KeyError
(T4 High), _build_pink_bodies str.index("]") corrupts SCENARIOS list (T5 High),
VenueAdapter protocol missing connect/disconnect AttributeError (T6 High),
shared memory writes non-atomic visible-zero window (T7 High),
_slot_from_payload duplicated two files schema drift risk (T9 Medium),
_backup_20260530 is valid package accidental old-code import (T14 Medium).
319 total flaws across 17 passes.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-02 14:10:49 +02:00
Codex
b0aa91229f PINK: E2E trace analysis — Pass 16 error handling/arithmetic/test infra (S1-S16)
Sixteenth pass: realized_pnl/mark_price NaN bypasses <=0 guard (S1 Critical),
MockVenue _exchange_event_queue check-then-act race drops events (S2 Critical),
no test_kernel_fsm.py exists (S3 Critical), generated tests use asyncio.sleep(0.8)
flaky on slow CI (S4 Critical), _rate_limit_retry_after_ms returns 0 on parse
failure instant retry storm (S5 High), venue adapter detects rate limits but
enforces zero backoff (S6 High), capital_epsilon=1e-4 too tight false WARN (S7
High), tests use asyncio.run() leaks tasks on 3.12+ (S8 High), str.replace()
patching silently does nothing (S9 High), WS _consume no per-message timeout (S10
High), _run blocks pool thread with no timeout lock adapter (S11 High).
305 total flaws across 16 passes.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-02 13:32:53 +02:00
Codex
a4c1ec6139 PINK: E2E trace analysis — Pass 15 resource leaks/trust boundaries/security (R1-R14)
Fifteenth pass: exchange REST/WS data parsed without schema validation (R7
Critical), restore_state() deserializes arbitrary JSON full kernel takeover
(R9 Critical), ThreadPoolExecutor never shut down 3 threads leak (R1 High),
BingxVenueAdapter no close() HTTP client unreleasable (R2 High),
_intent_cache unbounded growth (R3 High), shared memory JSON no integrity
check (R8 High), env-based mainnet switch (R10 High), .env secrets exposure
(R11 High), listenKey in WS URL f-string MITM injection (R13 High).
289 total flaws across 15 passes.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-02 12:54:02 +02:00
Codex
062b929caf PINK: E2E trace analysis — Pass 14 serde edges/backup diffs/market data (Q1-Q12)
Fourteenth pass: fromisoformat can't parse Rust Z-suffix timestamps on Python
< 3.11 — crashes every timestamp deserialization (Q1/Q6/Q12 High), MarketSnapshot
timestamp type inconsistent float vs datetime in same file (Q5 High), no
#[serde(deny_unknown_fields)] — misspelled fields silently default (Q2 Medium),
no upper-bound price validation (Q7 Medium), threading.Event.wait uses platform-
dependent clock NTP jump risk (Q10 Medium). Backup diff reveals 6 critical bug
fixes between backup and current. 275 total flaws across 14 passes.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-02 12:00:22 +02:00
Codex
b922f5ff1c PINK: E2E trace analysis — Pass 13 FFI safety/dangling pointers/coverage (P1-P9)
Thirteenth pass: dita_kernel_destroy double-free UB — Python doesn't null
handle.value (P1 Critical), CStr::from_ptr(payload) without null guard in
3 FFI exports (P2 High), _check_open_orders asyncio.run from async _verify
crashes live tests (P3 High), _get_rust() TOCTOU race concurrent cargo build
(P6 High), into_c_string NUL sanitizer produces invalid JSON (P4 Medium),
reconcile/snapshot_json null on failure no diagnostic (P5 Medium).
263 total flaws across 13 passes.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-02 11:06:18 +02:00
Codex
d1a6be0d27 PINK: E2E trace analysis — Pass 12 sync/async wider scope (O1-O11)
Twelfth pass: _maybe_close asyncio.run silently skips close from async
context (O1), _pick_live_symbol missing await crashes on coroutine iteration
(O3), _run() pool .result() no timeout — backend hang freezes process (O5),
KernelSlotView.__getattr__ N FFI calls for N fields no caching (O8),
DITAv2LauncherBundle no __del__ leaks resource tree (O9), ExecutionKernel
no close() — __del__ only cleanup (O10), __setattr__ triggers 5 persistence
side effects undocumented (O11). 254 total flaws.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-02 09:27:25 +02:00
Codex
24034416e0 PINK: E2E trace analysis — Pass 11 async/sync seams/locks/threading (N1-N10)
Eleventh pass: Rust kernel with_handle_mut has zero synchronization —
&mut KernelCore from raw pointer with no Mutex, concurrent FFI calls cause
UB (N1 Critical), _run() has two completely different code paths depending
on event loop state (N2 Critical), path B blocks event loop thread for
every HTTP operation (N3 Critical), asyncio.run() called repeatedly creating
destroying event loops per call (N4 Critical), _snapshot_ready Event cascading
re-fetch — N callers produce N overlapping HTTP calls (N5 High). 243 total.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-02 08:00:50 +02:00
Codex
81fe1d6d25 PINK: E2E trace analysis — Pass 10 runtime/test bugs/FSM/persistence/metrics (M1-M18)
Tenth pass: ENTER transition always says prev_state=IDLE (M1 Critical), CANCEL
creates no transition record (M2 Critical), ORDER_REJECT on POSITION_OPEN with
stale entry order destroys position (M9 Critical), _mk_intent test helper drops
order_type/limit_price into metadata not proper field (M3 High), four test/s that
claim to test cancel but never cancel (M4, M17), no metric aggregation for trade
count/latency/slippage (M10 High), no ClickHouse INSERT retry (M12 High),
_decision_to_kernel_intent drops order_type/limit_price making LIMIT orders
dead from the runtime (M18 High). 233 total flaws.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-02 00:03:41 +02:00
Codex
b3b28bb44a PINK: kernel fee prediction + calibration loop
ExchangeFeeConfig in AccountState:
  taker_rate, maker_rate, lot_step, tick_size, funding_interval_secs
  calibration_ratio: EMA of actual/expected, updated on every fill

Kernel now predicts fees at fill time (PREDICTED_FILL event):
  k_capital updated immediately without waiting for WS FILL_SETTLED
  When actual fee arrives, prediction is replaced and ratio recalibrated
  Reconcile delta: 0.000000 (was ~0.9 USDT in canary without prediction)

Calibration loop on connect():
  Fetches recent fill history, validates model vs exchange actuals
  deviation < 1pct -> OK; < 5pct -> WARN; >= 5pct -> ERROR (pre-trade gate)

New FFI: dita_kernel_set_exchange_config_json, dita_kernel_calibrate_fee_json
New ExecutionKernel methods: set_exchange_config(), calibrate_fee()
pink_direct.py: loads BingX fee config on connect, calibrates before stream

131/131 offline pass.
2026-06-01 23:45:50 +02:00
Codex
7d13df35db PINK: E2E trace analysis — Pass 9 contracts/events/network/FFI/diffs (L1-L16)
Ninth pass: VenueEvent.price=0 causes 100% PnL loss (L3), available_margin
set to wrong field in user stream (L4), wallet_balance defaults to 0 (L5),
14+ bugs fixed between backup and current code (L12), real pipeline never
tested by any test function (L13), no proxy support (L9), 5-min DNS cache
(L10). Backup diff reveals the current Rust kernel has ~14 bugs fixed vs
the backup version. 16 new flaws, 215 total.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-01 23:11:15 +02:00
Codex
23619e603a PINK Phase 5+6 (G6+G7): live VST gate + BLUE fence
bingx_user_stream.py: fix account_snapshot() for VST v3 balance
  (v3 returns list, not dict; extract first element)

test_pink_account_ws_g6.py (Gate G6 basic):
  I7: poll snapshot wallet_balance > 0 (PASS - live VST)
  I1-I5: seed + E-fact -> k_capital, available=E, reconcile OK/WARN,
    FILL_SETTLED folds correctly, delta=net_drift (PASS - live VST)
  I6: WS connects + gap-backfill delivers ACCOUNT_UPDATE source=poll
    (PASS - live VST)

test_alpha_blue_untouched_g7.py (Gate G7):
  mainnet hard-disabled, no BLUE imports, git diff clean

3/3 live + 131 offline = all gates green.
2026-06-01 22:35:27 +02:00
Codex
577392be8c PINK Phase 6 (G7): alpha-unchanged + BLUE-untouched gate
test_alpha_blue_untouched_g7.py:
- DOLPHIN_BINGX_ALLOW_MAINNET=0 enforced
- gen2.py uses VST + allow_mainnet=False
- New PINK modules (exchange_event, bingx_user_stream, account) import no BLUE
- Git diff confirms prod/bingx/, nautilus_dolphin, adapters/bingx_direct unchanged
- DecisionContext.capital remains a plain float (read-only new source)

G7: 9 pass, 2 skip (optional engine introspection), 0 fail.
131/131 total offline tests pass.
2026-06-01 22:07:48 +02:00
Codex
e644ee0add PINK Phase 4 (G5): reconcile_events persistence + event_seq on account rows
pink_clickhouse.py:
- optional kernel param to __init__ + set_kernel() for post-construction wiring
- _account_event_seq(): reads event_seq from kernel.snapshot()[account]
- _kernel_account(): full kernel account snapshot dict
- write_reconcile_event(): reconcile_events table writer (idempotent by seq)
- _write_account_event(): now includes account_event_seq + reconcile_status
  and auto-emits reconcile_events row when E-facts present

Gate G5: 13 tests -- event_seq wiring, row shape, one-direction invariant.
122/122 total tests pass.
2026-06-01 22:03:11 +02:00
Codex
e6988324ca PINK Phase 3 (G4): stream wiring + recovery + reconcile gate
pink_direct.py:
- connect(): set_seed_capital + REST account snapshot for crash recovery
- _run_account_stream(): BingxUserStream -> kernel.on_account_event()
  FILL_SETTLED folds K; ACCOUNT_UPDATE stores E-facts + runs reconcile;
  reconcile ERROR -> _enter_frozen=True (ENTERs blocked, exits always free)
  FUNDING_FEE folds K-funding_net
- _unsafe_entry_reason(): checks _enter_frozen first
- step(): capital from available_capital (E rules when present, K fallback)
- _venue_http_client() / _venue_ws_url() helpers

test_account_reconcile_faults.py (Gate G4):
  fee/funding/rounding -> WARN; unexplained -> ERROR
  crash-recovery sequence; exit-never-frozen invariant

109/109 total offline tests pass.
2026-06-01 21:41:30 +02:00
Codex
468984baab PINK: Rust kernel atomic K/E account layer (AccountState + FFI)
AccountState in KernelCore/KernelSnapshot:
- K-values: seed_capital, k_realized_pnl, k_fees_paid, k_funding_net
- E-facts: e_wallet_balance, e_available_margin, e_used_margin, e_maint_margin
- Cached: k_capital, available_capital (E rules when present; K fallback)
- Reconcile: OK/WARN(<20)/ERROR(>=20 delta) runs atomically on every event

New FFI:
  dita_kernel_set_seed_capital(handle, seed: f64) -> i32
  dita_kernel_on_account_event_json(handle, payload) -> *char
  Kinds: FILL_SETTLED | ACCOUNT_UPDATE | FUNDING_FEE

rust_backend.py: wires set_seed_capital() and on_account_event();
snapshot()[account] exposes both legacy and V2 fields.

Smoke-tested: fill->E_update->funding->re-sync all produce correct
K/E values and reconcile transitions (OK->OK->WARN->OK).
89/89 offline tests pass.
2026-06-01 21:22:01 +02:00
Codex
eef7bbb369 PINK: E2E trace analysis — Pass 8 observability/memory/time/dead code (K1-K23)
Eighth pass: system emits zero stdout/stderr, no health check or metrics (K1/K2 Critical),
failed trades invisible if caller ignores return value (K3), exception tracebacks all
swallowed (K4), circular ref cycle delays Rust handle destruction (K6), MemoryKernelJournal
silent data loss after 10K transitions (K7), RealZincPlane._intent_cache unbounded (K8),
_backend_snapshot timeout uses wall clock (K9), sys.path mutation on import (K20),
load_dotenv at import time (K21), 23 new flaws. 199 total.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-01 21:07:26 +02:00
Codex
8135a4ae17 PINK Phase 2 (G3): ExchangeEvent seam + BingxUserStream + mode-parity
exchange_event.py: abstract ExchangeEvent/ExchangeEventKind seam
venue.py: VenueAdapter extended with subscribe()/account_snapshot()
bingx_user_stream.py: PINK-only WS client with listenKey lifecycle,
  gzip, ping/pong, 24h rotation sentinel, reconnect backoff, gap-backfill
mock_venue.py: subscribe()/account_snapshot() for offline tests

Gate G3 mode-parity: WS and poll paths produce identical k_capital,
fees, realized PnL, reconcile status for same logical event sequence.
89/89 total offline tests pass.
2026-06-01 20:33:44 +02:00
Codex
615d24386e PINK Phase 0+1: VST WS confirmed + AccountSnapshotV2
G0 pass: VST user-stream WS works, BINGX_USERSTREAM_NOTES.md
G2 pass: AccountProjectionV2, 29/29 tests pass, 35/35 regression pass
2026-06-01 20:15:53 +02:00
Codex
e7eaa88ce1 PINK Phase 0 and 1: VST WS confirmed plus AccountSnapshotV2 account core 2026-06-01 20:11:03 +02:00
Codex
c87ca785b9 PINK DITAv2: fix 4 Critical/High flaws (I1, G2, G3, I13, I18)
- I1 (Critical/Rust): apply_fill accumulated partial fills instead of
  overwriting. WS events carry lastFilledQty (incremental); previous code
  set slot.size = fill_size each time. Now accumulates via prev_filled.
  initial_size set from intended_size on first fill, not from fill amount.

- G2 (Critical/Rust): into_c_string unwrap() panicked on any NUL byte in
  serialized JSON. Now sanitizes NUL bytes before CString construction;
  never panics.

- G3 (Critical/Rust): EXIT intent transition hardcoded prev_state=
  POSITION_OPEN. Captured actual fsm_state before mutation so audit trail
  is accurate when EXIT is received from non-standard states.

- I13 (High/Rust): stray venue event could reactivate a closed slot.
  Added explicit slot.closed guard in on_venue_event — returns
  TERMINAL_STATE with accepted=false before any FSM mutation.

- I18 (High/Python): sys.path.insert(0, ...) in real_zinc_plane.py and
  real_control_plane.py gave Zinc adapter directory highest import
  priority. Changed to sys.path.append() so existing path entries take
  precedence.

35/35 offline tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 19:35:44 +02:00
Codex
9b017e903b PINK: E2E trace analysis — Pass 6 deep math/tests/concurrency/security (I1-I22)
Sixth pass: entry-fill accumulation bug (multiple partial fills overwrite
size), crash durability (slot state lost between step 2-5 of process_intent),
seen_event_ids lost on restart (double event processing), idempotency gap
(no newClientOrderId), no graceful degradation, no startup reconcile from
Zinc, Zinc SHM world-readable, KernelSlotView unrestricted write access,
sys.path injection at import time. 22 new flaws. Combined catalog now 160.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-01 19:01:49 +02:00
Codex
1f5a3266c4 PINK: E2E trace analysis — Pass 5 edge domains (H1-H22)
Fifth pass covering dependency management (no Python lockfile, Rust compiled
from source), error handling observability (zero logging, 16+ silent swallows),
type safety (17 enum-from-string crash sites, _legacy_intent always MARKET),
and protocol contracts (MirroredControlPlane missing methods, RealZinc read
atomicity, __del__ use-after-free). 22 new flaws. Combined catalog now 138.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-01 17:42:58 +02:00
Codex
9128ab799e PINK: centralize all flaw findings in FLAW_ANALYSIS doc
Rewrite PINK_DITAv2_FLAW_ANALYSIS_2026-05-31.md as the central registry
with combined catalog (A+T+E+F+G = 116 flaws), severity distribution, and
cross-references to the TRACE doc for deep E, F, G detail. Add reciprocal
cross-reference in TRACE doc header.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-01 16:31:23 +02:00
Codex
d9dd54c24e PINK: E2E trace analysis — Pass 4 domain scans (G1-G36)
Four systematic passes covering Rust kernel invariants (4 criticals — missing
EXIT_RESIDUAL action, unwrap() panic on NUL, backward FSM transition, stale
all_legs_done variable), config validation chain (zero validators on 127 fields),
persistence schema drift (7 confirmed field-level mismatches), and lifecycle
management (no signal handlers, no __del__, no exception safety in builder).

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-01 14:26:36 +02:00
Codex
d475e9246b PINK: E2E trace analysis — Pass 3 deep trace (F1-F30)
Third and deepest pass across all module boundaries, data transforms, and
error paths. 30 new flaws found (F1-F30), including the highest-risk single
flaw: an unprotected on_venue_event loop that leaves slots unrecoverable on
any exception.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-01 13:42:22 +02:00
Codex
a7394f7863 PINK: E2E trace analysis — Pass 3 deep trace (F1-F30)
Third and deepest pass across all module boundaries, data transforms, and
error paths. 30 new flaws found (F1-F30), including the highest-risk single
flaw: an unprotected on_venue_event loop that leaves slots unrecoverable on
any exception.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-01 11:56:57 +02:00
Codex
4d15edcc54 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>
2026-05-31 18:46:06 +02:00
Codex
252da65fc7 PINK capital-accounting test harness — VST testnet battery (pre-cutover gate)
Automated, parametrized scenario battery driving the REAL PINK runtime
(policy->intent->PinkDirectRuntime->kernel->BingX VST->persistence) via crafted
snapshots, asserting 6 capital invariants per scenario: (1) per-fill Δcapital ==
realized; (2) end Δcapital == Σ per-fill realized (cumulative across cycles, since
slot.realized resets on ENTER); (3) exchange flat + no orders (signed); (4)
persistence parity (trade_events/account_events/trade_exit_legs vs kernel); (5)
notional ≤ capital×max_leverage; (6) guard correctness.

Controlled testnet: flat-start, single scenarios, reliable kernel close-all
pre-flatten (no cross-scenario cascade), ~$20 sizes, no autonomous loop, BLUE
untouched. Gated +PINK_CAPITAL_HARNESS.

Live VST result: 6 passed + 1 xfail.
- round_trip, sequential (multi-cycle continuity), exit_then_reentry, and 3 guard
  paths (suppressed nonfinite-capital / sub-floor price, degenerate-snapshot HOLD)
  all GREEN — capital accounting verified for the single-leg/sequential PINK paths.
- multi_leg XFAIL (documented): multi-leg partial reduce-only exits leave a lot-step
  rounding residual on the venue (kernel believes flat, exchange has a remainder) —
  a real capital/sizing-path finding for the rework, reliably reproduced.

This is the pre-cutover gate; the multi-leg residual + capital/sizing-path rework
are the next items before re-attempting the live cutover.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 15:42:27 +02:00
Codex
567ce61e00 PINK DITAv2: source-level sizing guards (bounded size, close-always)
Located the source of the cutover non-finite: target_size = capital × fraction ×
leverage / price. notional (capital×fraction×leverage) is self-limiting (no division,
bounded by capital), so a non-finite size can only come from a corrupt raw input —
non-finite capital, or a price below the industry floor that overflows the division.

Guards in the PINK algo runner (pink_direct), per design review:
- _MIN_SANE_PRICE = 1e-8 industry-smallest-price floor.
- ENTER: _unsafe_entry_reason() rejects the OPEN (logs provenance, no trade) when
  capital/leverage/size are non-finite/non-positive or price < floor. A corrupt sizing
  input is an untrustworthy signal — don't open (nothing to strand).
- EXIT: _exit_intent_from_slot() sizes the close from the kernel's authoritative
  slot.size (cap to remaining; full remaining if policy size malformed) — a bad-math
  exit can never strand or overshoot a position. Falls back to policy size only when the
  kernel reports no/unknown remaining size.

size semantics confirmed: base-asset QUANTITY; notional = size×price; margin = notional/
leverage ≈ 0.2×capital (already margin-bounded by construction — no extra clamp needed).

Tests: test_pink_sizing_guards.py (4) green; full offline suite 25 green (no regression).
Complements the kernel INVALID_INTENT guard (9168cf0): source refuses to produce bad
sizes; kernel rejects any that slip through.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 14:18:14 +02:00
Codex
9168cf0759 PINK DITAv2: kernel-level finiteness guard (no more null-string crash on inf/NaN)
The aborted hard cutover crash-looped with "Rust kernel returned null string" from
process_intent on the first live trading step. Root cause (reproduced): a non-finite
(inf/NaN) numeric field reaching the kernel — Python json.dumps emits the Infinity/NaN
token, serde_json rejects it at parse, and the FFI returned null. Magnitude is fine;
only finiteness was the problem.

Defense in depth, kernel catches it:
- Rust FFI (lib.rs): dita_kernel_process_intent_json / _on_venue_event_json now return
  a clean INVALID_INTENT KernelResult on parse failure (incl. Infinity/NaN tokens) AND
  on serialize failure (a non-finite produced internally) — never a null string.
- Python bridge (rust_backend.py): ExecutionKernel.process_intent validates intent
  finiteness/bounds (target_size, reference_price, limit_price, leverage, exit_leg_ratios;
  size>=0) BEFORE the FFI and rejects INVALID_INTENT, naming the offending field+value.
- contracts.py: add KernelDiagnosticCode.INVALID_INTENT.
- pink_direct.py: on INVALID_INTENT, log full upstream provenance (snapshot.price,
  capital, leverage, sizes) so the numerical SOURCE can be located on the next live run.
- on_venue_event bridge tolerates the fallback's null slot (uses the live slot).

Verified: kernel recompiled; offline 65 + 7 new guard tests green (no regression);
direct-FFI inf payload -> INVALID_INTENT (no null crash). NOTE: this turns the cutover
crash into a clean rejection — the upstream source of the non-finite (the live run's
inf) still needs locating, now aided by the provenance log.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 09:10:13 +02:00
Codex
0c15a7698e PINK DITAv2 L3: fix live LIMIT cancel (kernel order-id propagation + truth-based cancel)
L3 live validation surfaced a live-only defect: a working LIMIT order could not
be cancelled (MARKET never exercised cancel — synchronous fills).

Two coupled fixes:
- Rust FSM (lib.rs): propagate the venue's order id onto the active order for
  ALL order types and event kinds (ACK/partial/full fill) whenever the exchange
  provides one — orders are created at submit with an empty venue_order_id, so a
  later cancel had no real id to reference. Only fills empty ids, never overwrites.
  Requires recompiling libdita_v2_kernel.so.
- Backend (bingx_direct.py): add cancel(order) — a properly-signed DELETE by
  orderId (clientOrderId fallback) with TRUTH-BASED confirmation: BingX can return
  transient errors ("order not exist", dup-within-1s from an internal retry) even
  when the order was removed, so the cancel succeeds iff the order is no longer
  open on the venue. The venue adapter prefers this backend cancel over its raw
  signed_delete fallback (which failed signature with an empty id).

Validated:
- Offline: 63 + new cancel-truth unit tests green (no regression post-recompile).
- Live VST: resting SHORT LIMIT (+5%) rests as ENTRY_WORKING, confirmed as a LIMIT
  open order, cancel -> CANCEL_ACK -> IDLE, exchange flat (test_pink_limit_live.py).
- Live VST MARKET run-through re-validated post-recompile: PASS, exact capital
  reconciliation, two-phase rows visible (ORDER_REQUESTED + ENTRY_FILLED/EXIT).

LIMIT remains execution-infra only; PINK policy stays MARKET. BLUE untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 08:03:27 +02:00
Codex
55ed6902d8 PINK DITAv2 L0-L2: two-phase persistence + async-fill pump + LIMIT wiring
Execution-infra only (policy stays MARKET; algorithmic integrity untouched).

L0 — two-phase (request->result) persistence (pink_clickhouse.py):
- Split persist_step into persist_request (policy_events + trade_reconstruction
  ORDER_REQUESTED) and persist_result (state snapshot + per-fill lifecycle rows).
- Lifecycle rows (ENTRY_FILLED/EXIT/trade_events/trade_exit_legs) gated on
  evidence of an actual fill (FULL/PARTIAL_FILL event, closed slot, or size drop
  vs _leg_state) -> a resting LIMIT (ACK only) emits no terminal rows.
- Add persist_fill_events: synthesizes a minimal decision/intent from slot+event
  for async fills and routes through persist_result.

L1 — async-fill pump (pink_direct.py):
- PinkDirectRuntime.pump_venue_events(): venue.reconcile() -> kernel.on_venue_event
  (capital settles, FSM advances), persists applied fills; kernel dedups
  duplicates (no double-settle). Called at the start of step().

L2 — LIMIT placement (bingx_direct.py):
- submit_intent now honors _order_type/_limit_price from intent metadata
  (was hardcoded MARKET): LIMIT -> type=LIMIT + price + GTC; MARKET default;
  invalid limit price falls back to MARKET.

Offline: 63 passed (persistence/groundwork/pump/limit-payload/runtime/accounting/
flaws/kernel). MARKET path unchanged; resting LIMIT now correct end-to-end offline.
Live VST validation (L3) pending. BLUE untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 03:23:44 +02:00
Codex
4651cc71d6 PINK runtime live integration test — Sprint 1/2 closer (GREEN on VST)
Drives the FULL PINK stack against BingX VST (not kernel-direct):
DecisionEngine -> IntentEngine -> PinkDirectRuntime -> kernel -> BingX venue
-> AccountProjection -> PinkClickHousePersistence (captured).

Forces a real SHORT enter (STRUCTURAL_DISLOCATION) + fixed-TP exit and asserts:
the policy layer ran, all dolphin_pink row families were written (incl. terminal
trade_events + trade_exit_legs), exact capital reconciliation, exchange flat.

Verified live: 1 passed, terminal rows captured (on_venue_event settles inline
within process_intent for MARKET orders). Gated by +PINK_RUNTHROUGH.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 23:37:03 +02:00
Codex
d4b73b236a PINK DITAv2 Sprint 2-3: accounting parity + multi-leg groundwork
Sprint 2 (accounting + observability parity, PINK scope):
- Verified pink_clickhouse.py writes the 8 BLUE-legacy row families at
  matching schema and that capital authority in pink_direct.step() is
  solely kernel.account (no balance-poll overwrite in the hot loop).
- Report: prod/clean_arch/dita_v2/SPRINT2_ACCOUNTING_PARITY.md.

Sprint 3 offline groundwork (no exchange contact):
- Add _write_trade_exit_leg to pink_clickhouse.py: one BLUE-schema-faithful
  trade_exit_legs row per exit leg, with isolated (non-cumulative) per-leg
  deltas tracked via _leg_state (reset on ENTER). Closes the docstring gap.
- New offline suite test_pink_multi_exit_groundwork.py (3 passed):
  * Flaw 4 — two-leg exit closes once, realized accrues per leg, closed
    slot rejects further EXIT (no double-close).
  * Overshoot invariant — a final EXIT requesting more than the remaining
    size CLAMPS (size to 0, no oversell), retiring the Sprint 0 cumulative-
    ratio risk empirically.
  * trade_exit_legs delta + full BLUE column-set assertions.
- Persistence regression after edits: 10 passed.

BLUE untouched: no changes to dolphin.* / DOLPHIN_*_BLUE / nautilus_event_trader.py.
Live VST multi-leg run remains deferred pending explicit authorization.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 19:21:45 +02:00
Codex
3d7b00e28d Snapshot PINK DITAv2 system + Sprint 0 flaw-fix verification
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>
2026-05-30 18:26:43 +02:00
Codex
34d01fe6a4 Add BingX sandbox status sidecar 2026-05-13 19:56:58 +02:00
Codex
0d70c767e4 Wire long-capable prod alpha path 2026-05-08 21:16:53 +02:00
Codex
83f007caa8 Checkpoint BLUE V7 long overlay work 2026-05-08 19:54:13 +02:00
351ce2044d chore: safety snapshot 2026-03-05 — HCM infrastructure before 2y klines experiment
Captures critical infrastructure surrounding the nautilus_dolphin core package:
- dolphin_vbt_real.py: VBT vectorized backtest engine (6008 lines)
- dolphin_paper_trade_adaptive_cb_v2.py: champion runner (champion_5x_f20)
- _update_vbt_cache.py / update_VBT_parquet_cache.bat: cache builder
- external_factors/: ExF system (all 85 indicator fetchers + NPZ cache)
- mc_forewarning_qlabs_fork/: QLabs-enhanced MC-Forewarner research fork
- DATA_LOCATIONS.md: source-of-truth path registry
- .gitignore: excludes vbt_cache*, backfilled_data, .venv, models, etc.

Note: nautilus_dolphin/ has own git repo (inner) — safety snapshot committed there separately.
Champion state: WR=49.3%, ROI=+44.89%, PF=1.123, DD=14.95%, Sharpe=2.50 (55d, full-stack, abs_max_lev=6.0).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 23:51:30 +01:00