Commit Graph

113 Commits

Author SHA1 Message Date
Codex
bdc54fbeaa dita_v2(exec): INDETERMINATE submit is not REJECTED — unknown is never flat
A BingX read-timeout/reset/5xx after send means the answer was lost, not that
the order failed. Classify every submit failure by what it PROVES:
NOT_ATTEMPTED / REFUSED -> rollback sound; INDETERMINATE -> point-lookup our
own clientOrderId (read-only, bounded, never a reconcile); unresolved stays
UNKNOWN — no synthetic REJECT, no slot rollback, E-feed FILL settles truth.

- prod/bingx/http.py: BingxHttpError.effect + order_may_exist, 9 raise sites tagged
- adapters/bingx_direct.py: _lookup_own_order_by_client_id (never POSTs)
- dita_v2/venue.py: VenueIndeterminateError(VenuePostAckError) — existing fences catch it
- dita_v2/bingx_venue.py: both submit paths escalate INDETERMINATE receipts
- 14 tests incl. kernel no-rollback invariant + genuine-REFUSED contrast

Suite: 3416 passed, 19 skipped, 3 xfailed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:43:55 +02:00
Codex
cc7ac35169 dita_v2(test): pin indeterminate FSM state 2026-07-13 10:53:42 +02:00
Codex
ada14f04b3 dita_v2(test): assert semantic event emptiness 2026-07-13 10:45:42 +02:00
Codex
a3e2fc6528 dita_v2(test): preserve indeterminate post-ack state 2026-07-13 10:42:07 +02:00
Codex
3d75e4b59d dita_v2: unknown != flat (VenuePostAckError) + lossless telemetry lane
BUG CLASS (doc: BUGCLASS_INDETERMINATE_OUTCOME_20260713.md): an operation with an external
side effect has THREE outcomes — NOT_ATTEMPTED, ATTEMPTED_REFUSED, ATTEMPTED_INDETERMINATE
— and rollback is sound only for the first two. Collapsing the third into 'failed' is what
orphaned 6 live SHORTs: a post-ack TypeError reached rust_backend's 'except Exception ->
synthetic REJECTED -> FSM rollback', which asserted 'no order exists' about an order that
was already filled. Telemetry never had a veto; it hijacked the failure channel.

FIXES (no new seams, no re-architecture):
- venue.py: VenuePostAckError — typed channel meaning THE EFFECT EXISTS. Carries receipt.
- bingx_venue submit/submit_async: point-of-no-return fence. Post-ack bookkeeping failures
  raise VenuePostAckError instead of a bare exception.
- rust_backend (BOTH submit paths): catch VenuePostAckError FIRST -> no synthetic REJECT,
  no rollback. Slot stays working; E-feed FULL_FILL / reconcile settles the truth.

LOSSLESS TELEMETRY (HJ: 'DITAv2 exists precisely because seams dropped 40% of inputs'):
drop-oldest is data loss and is GONE. Exec path appends O(1) to an unbounded queue and
returns. A SEPARATE spiller thread (which never touches the plane, so a wedged plane cannot
starve it) parks the backlog above HWM into a durable append-only spool; the publisher
replays the spool when the plane recovers.
Proven: wedged-forever plane + 200k records -> 0 dropped, 195903 durable on disk, 4096 in
memory, 7.4 us/call on the exec path. Lossless AND memory-bounded. Healthy plane: 2000/2000.

STILL BROKEN, flagged to codex: the pre-ack branch rolls back on TIMEOUT — but a timeout is
the definition of INDETERMINATE (the order may have filled). Same bug class, older, live.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 10:31:39 +02:00
Codex
b13b54e769 dita_v2(test): enforce post-ack atomicity and suite integrity 2026-07-13 10:03:06 +02:00
Codex
40e85ab8d1 dita_v2(bingx_venue): telemetry OFF the exec path — bounded non-blocking lane
Standing steer (HJ, months): non-blocking behaviour + explicit execution priority.
Telemetry is not on the ladder at all, yet it sat ON the order path, inline and able to
raise — which is how it orphaned 6 live positions.

Exec path now does exactly one thing: pack primitives, append to a bounded ring, return.
No plane write, no snapshot construction, no I/O, no lock, no raise. Snapshot build +
plane publish move to a daemon drain lane. Ring is deque(maxlen=4096): drops OLDEST on
full and counts the drops — telemetry loss is always preferable to exec backpressure,
but it stays observable.

Measured: 1000 exec-path calls against a 2s-BLOCKING plane = 3.65 ms total (3.65 us/call).
Inline, that was 2000 s of stall. Wedged lane + 50k pushes -> ring pinned at 4096,
45903 counted drops, exec path never backpressured. Healthy plane still gets 5/5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 08:58:52 +02:00
Codex
832c85b233 dita_v2(bingx_venue): make _publish_telemetry TOTAL — telemetry cannot raise into the order path
The pre-existing guard covered only publish(). The attribute/coercion block above it
(int()/str()/.metadata.get() on intent+order) was UNGUARDED, and kwarg binding happens
before the body runs at all — so a signature skew sailed straight past a defence that
existed precisely to prevent this, and orphaned 6 live positions.

Everything that can raise now lives inside one try. Failures log loud and are swallowed;
the order path is never affected. Proven against: exploding plane, poisoned intent
coercion (the formerly-unguarded region), and absent plane.

ARCHITECTURAL DEBT (raised by HJ, not fixed here): telemetry has no business being called
inline on the exec path at all. Correct shape = fire-and-forget enqueue drained by the M6
journal lane. This commit makes it harmless, not absent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 08:54:01 +02:00
Codex
aec0b4670f dita_v2(test): repair test_double_buffer control test — suite was un-collectable
Line 154 held mutant debris: KernelControlSnapshot(mode="live", mode="live"") — duplicate
kwarg + unterminated string. Committed since a55501b, it made the ENTIRE dita_v2 suite fail
collection, so nobody has run it. That is why no test caught the bingx_venue telemetry
signature skew that orphaned 6 live positions tonight.

The test was fantasy besides: asserted read.arming == "DARK" (no such field) and
mode == "live" (KernelMode is NORMAL|DEBUG). Rewritten to assert a real invariant —
the second write must flip the buffer and become visible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 08:11:54 +02:00
Codex
dc1df325cb dita_v2: port M5 native-artifact provenance UP to canonical upstream
M5 (native_artifact.py + rust_backend build_verified_artifact/verify_artifact hooks)
existed ONLY in the uv/exec-refactor worktree. Canonical never received it, so
vendor_sync.sh downgraded the vendored copy back to a raw 'cargo build' — the same
mechanism by which M1's relock clobbered the bingx_venue telemetry fix and orphaned
6 live positions. Canonical is the source of truth; M5 belongs here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 05:28:05 +02:00
Codex
b46ebd2f82 dita_v2(bingx_venue): restore _publish_telemetry order_id/client_order_id kwargs + make post-ack telemetry non-fatal
M1 re-vendor (89a1f1a) clobbered the T0-DEVIATION fix (20ad493): submit()/submit_async()
pass order_id=/client_order_id= post-ack, the signature dropped them. Every ENTER raised
TypeError AFTER the venue POST returned 200 OK -> rust_backend synthesised REJECTED ->
FSM rollback, while the venue kept the position. Flight-4: 8 bridged promotions, 6 orphan
SHORTs live on VST with a kernel that believes it is flat.

Two fixes:
1. signature accepts order_id/client_order_id again; snapshot prefers them (order is None
   on the submit path, so the ack row is the only id source).
2. post-ack telemetry wrapped: observability can never again veto an accepted order.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 05:08:12 +02:00
Codex
9fe989b502 malkhut(perf): DuckDB in-memory materialization — sub-µs reads, zero DuckDB overhead
Architecture: DuckDB for persistence + full in-memory materialization for reads.
All reads served from Python dicts (sub-microsecond). DuckDB only hit on writes.

Performance evolution (get_asset benchmark):
  V0 (raw DuckDB):    876µs per call
  V1 (LRU cache):     2.3µs per call (380x)
  V2 (in-memory):     0.2µs per call (4380x)

All reads now sub-microsecond:
  get_asset:      0.2µs (was 876µs)
  query(blockian): 6.6µs (was 2.2ms)
  query(sector):   6.6µs (was 3.2ms)
  exchange lookup: 12.5µs (was 1.5ms)
  full scan:       5.9µs (was 1.8ms)
  behavior:        0.4µs

Write path: sync_from_profiles batch-inserts all data, then materializes
into Python dicts. Resync: 76ms (was 210ms, 2.8x faster).

Data integrity: DuckDB WAL provides crash recovery. In-memory dicts are
reconstructed from DB on every sync/close-reopen cycle. Zero data loss.
2026-07-12 19:38:24 +02:00
Codex
8bbf7d1de8 adapters(bingx_direct): component-correct message/comment attribution (operator: in-kernel messages name the emitting component, not the consumer)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 19:22:12 +02:00
Codex
b8cfd5df67 uv(sentinel): live-schema fix rounds 1+2 (PASS8 fb08a9f+361e6de, QA-verified 5/5 live)
Real colnames (timestamp/u_prefix_client_id, anomaly_events.ts), query/VST
errors FAIL never PASS (no green-by-error), openOrders wrapper unwrap,
check(d) CH_ALLOWLIST_DBS attribution (BLUE OBF writer no longer flagged).
Maiden live runs by Fable caught all 6; PASS8 fixed same-night.
2026-07-12 03:28:18 +02:00
Codex
da61c8f6c2 uv(universe): package-context import fallback — runner imports as prod.clean_arch.violet.uv.*, bare import broke gate load 2026-07-11 23:57:15 +02:00
Codex
df40e62104 dita_v2(zinc): account-truth plane API — publish/read/wait_on/notify_account
Formalizes the CEX-010 E-feed account plane (protocol + InMemoryZincPlane +
real plane). This code flew 33h on UV-PRIME flight-1 via the vendored copy
(T0-DEVIATION mid-edit vendoring) but was never committed upstream — the
2026-07-11 clean vendor_sync regressed it and broke the E-feed at boot
(AttributeError publish_account). Committing the flight-proven bytes closes
the vendor-law gap. Authorship: pre-existing WIP in /mnt working tree
(T0-era, likely codex), committed verbatim by Fable for vendor integrity.
2026-07-11 22:46:33 +02:00
Codex
7bc13a6eb2 dita_v2+adapters: phantom-position root-cause fixes (UV audit §8)
bingx_direct.submit_intent: (1) empty/orderId-less ack (VST offline-symbol
hole: code==0 + empty data) -> REJECTED, never fabricate fill from
target_size; (2) honor upstream u- client id (intent.metadata
promo_client_id/client_order_id) over self-minted p- id.
rust_backend: EXIT asset-mismatch guard both sync+async paths — EXIT for
asset X while slot holds Y -> NO_OPEN_POSITION/EXIT_ASSET_MISMATCH instead
of asset-blind close (THETA 76bbf8ee cross-slot contamination).
9 regression tests, mutation-RED verified (guard flip).
2026-07-11 22:29:02 +02:00
Codex
a062507656 malkhut(assets)+uv: system-wide asset directory + UV universe init
MALKHUT asset directory (malkhut/assets/): normalized canonical symbols,
KNOWN_EXCHANGES aux table (BINANCE/BINGX/BINGX_VST), per-exchange listing
status (TRADING/OFFLINE/UNKNOWN), JSON-backed, built for full-Binance-500
scale. Seeded with BLUE's NG7 feed universe (50 symbols) + live VST
contracts probe: 35 TRADING / 15 OFFLINE on VST (BAND, CELR, COS, CVC,
DENT, FUN, HOT, ICX, TFUEL, TUSD, USDC, WAN, WIN, XTZ, ZIL).
uv_asset_universe.init_asset_universe() = runtime tradable set for the
execution exchange; --onboard runs MALKHUT AssetCompiler for full taxonomy.
12 new tests, mutation-RED verified (status-filter + tradability guard).
2026-07-11 21:48:05 +02:00
Codex
d0ae6a1c62 uv(flight-recorder): stage-by-stage order tracer + dirty-25 root-cause maiden run
Read-only harness correlating scan->pick->size->bridge->drain->kernel->venue->
fill->flight->closure->capital->friction per trade_id. 20 tests, mutation-RED
verified (kernel-verdict flip). Maiden sweep classifies all 25 bridged-no-venue
rows: 15 PHANTOM_KERNEL_REFUSED (6 SLOT_BUSY enters, 9 NO_OPEN_POSITION exits),
5 SUBMITTED_VENUE_DEAD (BAND/CELR offline on VST), 4 LOG_GAP (pre-restart),
1 SUBMITTED_NO_VENUE_EVIDENCE (THETA phantom exit). 3 refused-exit orphans
confirmed open at venue (THETA 3298.1, LTC 11.09, BNB 0.861).
2026-07-11 20:26:54 +02:00
Codex
257c48b127 uv(anomaly-sentinel): land UV ANOMALY SENTINEL — read-only §4 auditor (item-2 instrument)
Read-only auditor for arming-checklist §4 anomalies, the instrument for the
72h-clean finish-line clock. 5 checks against CH + VST (all read-only):
  (a) venue order without matching BRIDGE exec_journal row
  (b) exec_journal row without venue order
  (c) venue order without 'u-' clientOrderId prefix
  (d) CH write outside dolphin_uv.* in runner window
  (e) tripwire_ok=false occurrences

Authored by cmd-PASS1.2 (PASS8), provenance /mnt/vp-PASS8 bf55777
(agent/oa-violetPASS8). Landed by content (cross-clone fetch hung); files
SHA256-identical to source. Fable verification: 20/20 pass; mutation litmus
RED (inverting the check-(c) prefix guard fails 6 tests incl. PASS8's own
test_c_mutation_* guards — the doctrine's litmus baked into the suite);
read-only confirmed (no writes on any path).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 19:20:22 +02:00
Codex
3d313290b3 uv(pass-a-r1): 10000x test coverage — races, edges, seams, fuzz.
20 new tests: thread-safety, tripwire invariants (no cumulative drift), poison,
compat seam (reconcile_ok==tripwire_ok), mutation litmus (grep-based K-field ban),
Hypothesis fuzz (500 random streams), vendor drift gate.

Fix: apply_balance_update now resets tripwire_ok=True (non-fill events default healthy).
26 total (20+6).
2026-07-10 10:48:04 +02:00
Codex
3da5d8866d uv(pass-a-r1): K-purge — Rev-4-FINAL compliance. A1: reconcile_ok replaced by stateless per-event tripwire (tripwire_ok + tripwire_last_event_id on AccountStateSnapshot). Detection latency = 1 event. A2: ASEXAccountV2.k_capital -> _k_capital_internal. 6 acceptance tests. 2026-07-09 17:17:29 +02:00
Codex
81520af83c dita_v2: fix arithmetic in test_asex_account mixed-ops funding expectation (2x50x0.5=50, not 100)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 08:03:36 +02:00
Codex
a7522bf8d1 dita_v2: reconcile SOA — vendored thread-safety hardening ∪ venue plane
3-way merge (base=pre-venue-plane upstream, ours=violet-main vendored hardening,
theirs=upstream venue plane): RLock atomic-snapshot wrapping (account.py,
real_control_plane, real_zinc_plane), lazy __getattr__ imports (__init__),
account-core test coverage — merged with venue_region telemetry. Zero conflicts;
all files AST-verified. Ends the two-way vendor drift found in
DITAV2_SOA_SURVEY_20260702 §5 / UV_DITAV2_SOA_VERDICT_20260703.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 01:15:17 +02:00
Codex
cfb3d7cf4f dita_v2: backport asex_account.py (from violet main) + test (from PASS9) to canonical upstream
Heals reverse vendor drift: the ASEx AccountProjectionV2 adapter was committed on
the vendored copy (violet.git main 824c5cf) instead of upstream, violating the
edit-upstream-then-sync doctrine. Test was orphaned on the PASS9 worktree.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 01:00:40 +02:00
Codex
9bef1f6b01 dita_v2: VenueTelemetrySnapshot + Zinc venue plane (4th shm partition) + local Rust target dir
Upstream-canonical commit of the ~366 lines that sat uncommitted in the working
tree (surveyed in DITAV2_SOA_SURVEY_20260702). Venue telemetry published at every
venue boundary (submit/cancel/reconcile) over the zinc venue_region; SOA per
UV DITAv2 adjudication 2026-07-03.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 00:42:20 +02:00
Codex
37748cf180 feat(violet): V4 arm-readiness reporter (PASS MM1)
Read-only aggregation module answering 'is V4 ready to ARM the live canary?'
by consuming gate outcomes into a typed StrictModel report.

Files:
- v4_readiness.py: V4ReadinessReport (6 bool gates + reasons) + assess_v4_readiness()
- test_violet_v4_readiness.py: 13 tests (happy, parametrized single-false,
  hypothesis 2^6 invariant, mutation litmus, StrictModel poison)

Co-Authored-By: mm_VIOLET1 <mm_VIOLET1@h5i>
2026-06-24 14:01:51 +02:00
Codex
12b768bc4f VIOLET OA: add venue OB provider seam
Co-authored-by: Codex <codex@openai.com>
2026-06-16 23:01:17 +02:00
Codex
53bdd908f4 VIOLET OA: add sizing parity pin tests
Co-authored-by: Codex <codex@openai.com>
2026-06-16 22:51:07 +02:00
Codex
0f3d7650c3 VIOLET V3.4d: launcher OB-persistence + boost/beta prior; OB-feed/HZ-bridge/coordination doc
Launcher shadow path now keeps the persistent state BLUE keeps across scans (faithful, not
per-scan single-shot): ONE OBFeatureEngine wired lazily on first assets and kept for the
service lifetime, reading BLUE's EXTANT published OBF feed via HZOBProvider (read-only HZ
entry-listener cache — NO new OB storage; provider is the swap seam for a future direct
BingX/3rd-party OB stream); per-scan ob_bar_idx into step_live/get_market; and prior_boost_beta
carried across scans (stale exf keeps the prior). shadow_decision_step threads ob_engine +
bar_idx + prior into source_live_blue_sizing_factors; build_shadow_live_source seeds the state
+ a default ob_engine_factory (injectable for tests).

TODO_HZBRIDGE markers added at all 3 VIOLET->Hazelcast touch points: per operator the upcoming
dolphinng5_predict/hzbridge must become the sanctioned HZ connection (silent client-death /
lockup / dropout mitigation) — refactor ASAP once it ships.

Doc VIOLET_OB_FEED_AND_AGENT_COORDINATION.md: OB-feed sourcing doctrine, HZ-bridge TODO, and
the multi-agent worktree + doctrine/release/status scheme (prompted by the shared-index
incidents where agents' staged files cross-contaminate commits).

6 launcher tests (+wired-once/bar_idx-increments, +prior-carries). violet-only; partial commit
(only my 4 paths) to avoid sweeping a concurrent agent's staged files.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 21:44:03 +02:00
Codex
262cada664 VIOLET V3.4c: ACB boost/beta — keep-prior on stale exf, decision logging, semantics doc
Per operator: VIOLET must keep a "prior" on stale ExF rather than collapse to neutral, and
the ACB's role must be commented-in + logged.

- KEEP-PRIOR on stale/missing exf: BLUE keeps _day_base_boost/_day_beta on the stale branch
  (update_acb_boost isn't called). _source_boost_beta now takes `prior` (boost,beta) and
  returns it on ValueError / no-exf, seeded by the first successful compute. Threaded as
  `prior_boost_beta` through source_live_blue_sizing_factors (caller persists last good).
- LOGGING: violet.live_blue_source logger emits live boost/beta + the full sourced plane.
- SEMANTICS: documents the ACB in effect (inverse v6) and CONFIRMS ACB IS in the sizing layer
  via _day_base_boost/_day_beta → _update_regime_size_mult (esf_alpha_orchestrator.py:771-772,
  898-909). OB Sub-4 beta modulation dormant in live — per operator found NON-PERFORMANT and
  deliberately bypassed; TODO_SOMEDAY in-code to find documentary confirmation.

37 tests. violet-only; no shared-file edits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 18:22:29 +02:00
Codex
fac287d678 VIOLET V3.4c: make boost/beta, signal-gen, OB bit-identical to BLUE (+ exhaustive tests)
Operator directive: VIOLET must do IDENTICALLY what BLUE does for the three parity
flags — approximation cannot guarantee bit-for-bit functioning. Reworked
live_blue_source.py to call BLUE's OWN code paths, not reconstruct/substitute them.

boost/beta — was reading the published DOLPHIN_FEATURES.acb_boost scalar
(acb_processor_service's daily value). BLUE's trader does NOT use that for sizing; it
recomputes live via acb.get_dynamic_boost_from_hz(exf_latest, w750_velocity, direction)
with a bare AdaptiveCircuitBreaker() and NO ob_engine (nautilus_event_trader.py
on_exf_update:4769 / rollover prewarm:2710). New _source_boost_beta replicates that call
exactly (reads exf_latest + latest_eigen_scan.w750_velocity; 0.0→None like BLUE; on stale
exf ValueError → neutral, mirroring BLUE's "ACB Stale Data Fallback"). The published
acb_boost is never read. Test pins bit-identity against the real ACB.

signal-gen (dc_status) — was AlphaSignalGenerator() bare defaults; coincidentally equal to
BLUE today, but BLUE builds it from ENGINE_KWARGS (trader:128-133, threaded at
esf_alpha_orchestrator.py:180-191), so a champion retune would silently diverge. Now
constructed with BLUE_SIGNAL_GEN_KWARGS (vel_div_* imported from the kernel constants).
Test parses ENGINE_KWARGS from the trader source and asserts each param matches — drift
becomes a red test, not a silent miss.

OB — was a reinvented HazelcastOBProvider reading asset_*_ob with custom parsing. Now uses
BLUE's OWN HZOBProvider + OBFeatureEngine, wired exactly as _wire_obf
(nautilus_event_trader.py:4967-4980): step_live(assets, bar_idx) then get_market. Engine
is injectable + persistent so OB accumulation matches BLUE across scans (caller owns it).

Deleted: HazelcastOBProvider, _extract_acb, the status-label mc path. mc_scale fix
(begin_day cat/env thresholds) retained. Module docstring + structural-divergence doc
updated: all three flags FIXED; only _derive_mc_scale remains hand-replicated (pinned by
formula test). OPEN follow-up: launcher shadow_decision_step should pass a persistent
ob_engine + bar_idx for cross-scan OB history.

34 tests (33 + live-HZ smoke deselected): boost/beta-vs-ACB bit-identity (incl. w750=0→None,
no-exf, stale ValueError, ignores acb_boost), signal-gen ENGINE_KWARGS pin (parametrized),
OB wiring (step_live call, HZ coords, neutral paths), mc_scale formula, sequence dc/selector
parity, anomaly handling. violet-only; no shared-file edits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 17:33:01 +02:00
Codex
1415a65670 VIOLET V3.4c review: fix mc_scale BLUE-parity bug + document re-derivation debt
REVIEW of the V3.4c/d/e work (other agents) for BLUE-algo compliance found one
real bug and one architectural concern.

BUG FIXED — mc_scale derivation (live_blue_source.py):
The adapter mapped `mc_forewarner_latest.status == "ORANGE"` → 0.5. But BLUE's sizing
mc_scale is NOT the MC service's `status` label (that label, from mc_forewarner_flow.py,
uses GREEN<0.10/ORANGE<0.30/RED — observability only). The live trader re-derives the
haircut in begin_day (esf_alpha_orchestrator.py:956-962) from the SAME published fields
`catastrophic_prob` + `envelope_score` with DIFFERENT thresholds:
    mc_red    = cat>0.25 or env<-1.0
    mc_orange = (not mc_red) and (env<0 or cat>0.10)
    mc_scale  = 0.5 if mc_orange else 1.0
The two disagree (e.g. cat=0.05/env=-0.5 → label GREEN→1.0 but BLUE orange→0.5;
cat=0.28 → label ORANGE→0.5 but BLUE red→1.0). Rewrote `_derive_mc_scale` to mirror
begin_day exactly on the source fields. Per operator: there is genuine ambiguity over
which surface is "nominal" — we go with the SOURCE FIELDS + begin_day formula (the path
that actually drives BLUE's sizing); the ambiguity + decision are noted in the docstring.

TESTS — the old fixtures were complicit: they fed `{"status":"ORANGE"}`, a payload shape
BLUE never emits, so they "passed" against fiction. Replaced with BLUE's real payload
(`catastrophic_prob`/`envelope_score`) and added a parametrized formula test covering the
exact divergence cases the status-based code got wrong, plus missing/garbage-field neutral.
15 passed (live-HZ smoke deselected).

ARCHITECTURAL DEBT documented — VIOLET_BLUE_PARITY_STRUCTURAL_DIVERGENCE.md:
VIOLET imitates BLUE's computations in a DIFFERENT module/scope structure. Kernels are
WRAPPED (safe), but orchestration arithmetic (compose/regime/ob/strength/mc_scale) is
HAND-REPLICATED out of the monolithic NDAlphaEngine — making orderly, verifiable BLUE↔VIOLET
parity comparison and refactoring hard. Doc inventories every re-derivation with BLUE's
file:line authority, the drift risk, and mitigations (parity-pin tests; single canonical
surface per ambiguous factor; eventual DITAv2 Rust-backplane convergence). Pointer added to
live_blue_source.py's module docstring.

Also reviewed (no change needed): launcher launch_dolphin_violet.py is DARK-safe
(ObserveOnlyVenue + shadow gated default-OFF, no order path); shadow_live_factors.py glue
is correct; trade_slot_compare.py reimplements no BLUE algo. fb34431's launcher tests —
which the authoring agent never ran on the slow mount — pass (14 green).

violet-only; no shared-file edits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 16:54:35 +02:00
Codex
2d37ef0ae0 VIOLET V3.4c: trade-slot comparison harness 2026-06-16 15:38:25 +02:00
Codex
fb344318aa VIOLET V3.4b: launcher shadow live-factor wiring 2026-06-16 15:14:57 +02:00
Codex
1ac3f627df VIOLET V3.4c: read-only BLUE live source parity 2026-06-16 14:34:49 +02:00
Codex
a632c595ba VIOLET V3.4b: validate live-factor field paths + HZ sourcing adapter
#1 (validation) — VIOLET_V34B_LIVE_FACTOR_FIELD_VALIDATION.md documents the
ground truth from BLUE's own code (esf_alpha_orchestrator / adaptive_circuit_breaker
/ nautilus_event_trader): of the 8 sizing inputs, ONLY `posture` is a flat HZ key.
`esof_score` is in HZ but as a payload to parse. The other five — boost, beta,
mc_scale, ob_median_imbalance, ob_agreement_pct, dc_status — are BLUE-organ outputs
(ACB over DOLPHIN_FEATURES.exf_latest, MC flag derivation, OBFeatureEngine, the
per-asset signal generator) and are NOT present as scalars in any HZ map. This
inverts live_factors.py's flat-snapshot premise; its speculative alternate paths
(acb_boost / s_acb_boost / ("acb","boost") / …) match nothing real. The full live
sourcing of the five is a multi-organ sprint (V3.4c), not a HZ scrape.

#2 (sourcing adapter) — live_factor_source.py sources what BLUE actually publishes,
read-only and pure (callers pass already-fetched HZ blobs; no client, no I/O):
  - posture     ← engine_snapshot['posture'] (DOLPHIN_STATE_BLUE), default APEX
  - esof_score  ← DOLPHIN_FEATURES['esof_latest'] via BLUE's OWN parse_esof_payload
                  + esof_score_from_payload (wrap, don't reimplement; staleness gate
                  honored when max_age_s supplied)
  - boost/beta/mc_scale/ob_*/dc_status ← BLUE's neutral sentinels (1.0/0.0/1.0/None/
                  None/"NONE") until V3.4c — explicit, never silently faked.
Flows through the validated extract_live_sizing_factors normalizer. ORGAN_DERIVED_
FACTORS names the six deferred to V3.4c so the journal can mark them NEUTRAL.

9 new tests green (posture default/upper, esof dict+raw-JSON+staleness, neutral
integration, all-neutral-when-empty). violet-only; no shared-file edits; no soak.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 13:22:59 +02:00
Codex
722fd9f054 VIOLET V3.4b/V3e: journal the full-sizing breakdown (DDL + row guard)
ShadowDecision already carries the V3.4 5-factor breakdown (base_leverage,
dc_lev_mult, regime_size_mult, market_ob_mult, esof_size_mult), but the journal
row and CH DDL dropped it — so a DARK soak would record decisions WITHOUT the
factor decomposition that V3.4 exists to expose. Thread it through:

- 22_violet_decisions.sql: 5 additive Nullable(Float64) breakdown columns. NULL
  on the legacy base-only path; populated once the launcher feeds live factor
  planes. Note added: on a pre-existing table use ALTER ... ADD COLUMN instead of
  the CREATE IF NOT EXISTS (no live table yet — VIOLET is DARK, never soaked).
- shadow_journal.py: DecisionRow gains the 5 Optional[float] fields (ge=0.0,
  finite-guarded); journal() populates them via getattr(..., None) so the
  base-only path and duck-typed reject tests stay NULL/rejected rather than
  raising on attribute access.
- test_violet_shadow_journal.py: breakdown round-trips on the full path; NULL on
  base-only; a negative multiplier is rejected at the row guard. The existing
  DecisionRow-fields == DDL-columns parity test still holds with the new columns.

violet-only; no shared-file edits; no soak. 29 violet tests green
(7 journal + 22 engine/DDL-apply).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 13:04:30 +02:00
Codex
2629795a35 VIOLET V3.4b: live-factor normalization helper (OA slice, reviewed)
extract_live_factor_plane / extract_live_sizing_factors: pure boundary
helper normalizing scan payload + HZ snapshot into SizingFactors for the
shadow decide path. Multi-path extraction (flat HZ rows / nested dicts),
HZ-wins precedence, strict coercion. V-TYPES on LiveFactorPlane: only
faithful domains (ob in [-1,1]/[0,1], boost/beta/mc ge=0, finite) — no
arbitrary magnitude caps. No I/O, no launcher coupling.

Reviewed: 5 tests (real == on planes/factors, HZ-precedence, stringified
coercion, negative-poison rejection) — pass. Shared files CLEAN.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:52:59 +02:00
Codex
3ca249df8e VIOLET V3.5: L3 exchange-leverage wrapper (agent-built, reviewed + fixed)
Built by OA agent per VIOLET_SUB_SPEC__L3_EXCHANGE_LEVERAGE.md; reviewed for
compliance/flaws. VERIFIED: wraps real prod/bingx/leverage.py (untouched), constants
imported from it, NO arbitrary upper caps, exact == bit-identity (1e6 gate 0 mismatches),
ROUND_HALF_EVEN explicitly tested (1.5->2 AND 2.5->2), clamping+non-default caps+frozen
model. 38 tests pass on independent rerun.

REVIEW FIX: to_exchange clamped negative internal_conviction to 0 in the trace field
(reused ConvictionLeverage ge=0); changed trace field to plain float (poison guard only)
so it records the ACTUAL input faithfully; dropped the clamp + unused import. Relocated
8 off-spec leverage-spike scratch files off repo root -> prod/VIOLET_dev/l3_spike/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:45:54 +02:00
Codex
a97bb90bf6 VIOLET V3.4: integrate full 5-factor VioletSizer into VioletDecisionEngine
Additive (non-breaking): decide(factors=None) keeps the V3a base-only path (existing
11 tests unchanged); decide(factors=SizingFactors(...)) produces BLUE-complete
conviction via VioletSizer (base_max=8 + dc/regime(ACB)/ob/esof, capped@9) with the
full factor breakdown on ShadowDecision (base_leverage/dc_lev_mult/regime_size_mult/
market_ob_mult/esof_size_mult, None on the base path). SizingFactors value object =
the live-plane inputs the launcher will source (V3.4b). 6 new tests incl. consistency
vs VioletSizer, STALKER cap, EsoF-stale haircut. 17 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 23:35:00 +02:00
Codex
dc3d0970ad VIOLET V3.3 review: note that extreme MC gate covers boost>2.5/beta=0/mc=0
Reverted a redundant widening of the main MC gate (typical ranges) after confirming
test_gate_mc_extreme_multipliers already bit-identity-tests boost in [1,5], beta in
{0,0.2,0.8,1}, mc in {0,0.5,1}, and the OB agreement boundary (N=200k, exact !=).
Added a cross-reference note. All 6 gates green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:19:02 +02:00
Codex
d3431cd18a VIOLET V3.3: full sizing parity (orchestrator wrap-all) — reviewed + doctrine fixes
Build by dev agent (Crush); reviewed for compliance/flaws/doctrine. VERIFIED:
transcriptions verbatim vs BLUE (_strength_cubic/_update_regime_size_mult/OB/compose),
gates use exact != bit-identity (not approx), reference uses REAL kernels, no
shared-file edits. Bit-identity gate PASSES 0/1e6 mismatches; all 6 gates green;
173 non-gate pass. upstream replay r=0.937.

REVIEW FIXES (doctrinal adherence):
- Removed arbitrary magnitude caps (SizeMult/Boost le=64, Beta/McScale le=4) — a
  'no-hygiene-BLUE-lacks' liberty that could reject a valid extreme BLUE value;
  kept only V-TYPES poison guards (ge=0 + allow_inf_nan=False). 173 pass unchanged.
- Strengthened near-vacuous upstream gate (was r>0) -> r>=0.80 AND median_err<=3.0
  (observed 0.937/1.44). Now passes meaningfully.
- Relocated 3 untracked spike scripts off repo root -> prod/VIOLET_dev/sizing_spike/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:08:18 +02:00
Codex
5c90c8f351 VIOLET V3.2: EsoF size-modulation fold (BLUE SC haircut, exact)
modulation.py: VioletSizeModulation wraps BLUE's canonical esof_size_mult_from_score
+ esof_score_from_payload (exact ESOF_* constants), applies the SC haircut
step-for-step as _apply_sc_entry_size_multiplier (nautilus_event_trader.py:3307):
mult clamped [0,1] HAIRCUT-ONLY (:3316), near-1 no-op (:3318), round(lev*mult,6)/
round(notional*mult,12). 8 tests pass. Empirical mult-recovery on recorded BLUE:
median 1.000, EsoF haircut bands (0.65/0.8/0.9/0.3) visible. NOTE: 28% upward tail
(recorded>base) = NEXT parity step (base mid-range param OR gold/gauge up-mult);
EsoF is haircut-only by design. Not yet wired into decision_engine (needs EsoF HZ
score plane + restart, held).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 07:53:08 +02:00
Codex
a168d0bee5 VIOLET V3.1: BLUE stablecoin exclusion (parity fix)
Soak surfaced USDCUSDT being shorted. BLUE has a hardcoded exclusion gate around
its (muted-IRP) picking: _STABLECOIN_SYMBOLS removed from prices_dict pre-select
(nautilus_event_trader.py:24/3906). Replicate exactly: VioletDecisionEngine skips
the same 10 symbols in observe() so IRP never sees them. Following BLUE in all
regards (picking unchanged; this is BLUE's separate gate). Set-equality drift
guard vs BLUE source + never-selected test. 11 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 21:51:09 +02:00
Codex
6f5aa80ed0 VIOLET V3e: shadow-decision journal + DDL (reject-at-source)
22_violet_decisions.sql (dolphin_violet.violet_decisions, DDL-first) +
shadow_journal.py: VioletDecisionJournal validates each actuated ShadowDecision
via DecisionRow (V-TYPES, allow_inf_nan=False) before the CH sink -- malformed
dies at source, never at the spool head. NEVER an order. DecisionRow field set ==
DDL columns (asserted). 4 tests pass. Launcher wiring + DARK soak = operator step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 20:29:53 +02:00
Codex
1a449074ae VIOLET V3d: base-sizer parity harness + gate vs recorded BLUE
parity_harness.py: median-curve parity of V3a VioletBetSizer vs recorded
dolphin.trade_events (vel_div->leverage), restricted to short-signal domain.
GATE PASSES on prod host: pearson 0.9998, max_abs_err 0.238 (budget 1.0) over
23 bins -> base conviction sizer reproduces BLUE's central tendency. Per-trade
scatter is the deferred SC/ACB/OB/gold modulation layer (separate finding doc).
3 unit + 1 gate green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 20:26:08 +02:00
Codex
1e331d80bc VIOLET V3c: VioletDecisionEngine — reactor-resident SHADOW engine
Composes V3a live-kernel wrappers + V3b cadence into a muted decision engine:
scans in -> ShadowDecision out, NO execution (distinct from PINK's disabled
dita DecisionEngine; runs alongside as pure shadow). Short-regime gate mirrors
BLUE/dita (vel_div<threshold + vol_ok + IRP survivor); cadence-gated actuation
(ENTRY Q=scan), evaluate-always. Verified non-vacuous: produces AAAUSDT SHORT,
conviction 9.0, exposure=capital x notional_fraction. 9 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 18:51:27 +02:00
Codex
77e3eddb40 VIOLET V3b: Cadence Control Plane — universal per-action quantization
Spec prod/docs/VIOLET_SPEC__CADENCE_CONTROL_PLANE.md + cadence.py: every
scan-governed action (entry/sizing/each exit reason/each input plane) carries an
INDEPENDENT, runtime-tunable Q knob surfaced in a control plane (HZ-backed,
code defaults as floor). Evaluate-every-tick / actuate-at-Q; SL defaults insta,
TP/entry default scan, OBF ~1s — all loosenable per-action. 9 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 18:39:12 +02:00
Codex
b295447bdf VIOLET V3a: V-TYPES alpha-kernel wrappers (selector/sizer/exit-v7) + parity/drift guards
L1 pure-alpha layer: wrap BLUE's live AlphaAssetSelector/AlphaBetSizer/
AlphaExitEngineV7 behind V-TYPES boundaries (wrap, not reimplement). max_leverage
is a required explicit param (live default 5.0 / blue_parity 8.0 / recorded 9.0);
smoke + tests confirm max_leverage=9.0 reproduces recorded sizing exactly
(notional_fraction 0.20x9=1.8 = recorded our_leverage max). 7 tests pass.
Exchange-agnostic: conviction leverage sizes quantity; exchange-lev map is L3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 17:39:44 +02:00