VIOLET V1c: observe-only launcher + hard guard + divergence monitor + service (DARK)

launch_dolphin_violet.py: own namespaces hard-set (CH dolphin_violet, HZ
DOLPHIN_STATE_VIOLET/PNL, Zinc prefix violet, DOLPHIN-VIOLET-001); own
credentials (BINGX_VIOLET_API_KEY/SECRET) — DARK idle with periodic WARNING
until provisioned; CH preflight SELECT-probes the required tables and NEVER
creates (DDL-before-code); kernel snapshot path repointed away from PINK's
fixed /tmp/.pink_kernel_state.json; mainnet hard-disabled; observe loop
never calls runtime.step(). ObserveOnlyVenue: submit/cancel raise
ObserveOnlyViolation with full attribute delegation — the kernel's
venue-submit-failure rollback converts a refusal into a synthetic REJECT
(slot back to IDLE), proven against the real kernel. FeedDivergenceMonitor:
per-asset scan-vs-venue divergence rows (bookTicker WS via
prod/bingx/market_stream, REST fallback) with stale-mid suppression and
plane seq propagation — the FET 0.2176-vs-0.1878 detector; runs even DARK
(public data). Supervisord [program:dolphin_violet] autostart=false, no
keys in conf by design. Violet package: 42 tests green + V0 gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Codex
2026-06-12 16:09:04 +02:00
parent d639a69307
commit 970c33cb8e
7 changed files with 984 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
"""V1: dark-idle behavior — no keys ⇒ idle loop, exec adapter never built."""
from __future__ import annotations
import asyncio
import sys
sys.path.insert(0, "/mnt/dolphinng5_predict")
sys.path.insert(0, "/mnt/dolphinng5_predict/nautilus_dolphin")
import pytest
def _clear_keys(monkeypatch):
monkeypatch.delenv("BINGX_VIOLET_API_KEY", raising=False)
monkeypatch.delenv("BINGX_VIOLET_SECRET_KEY", raising=False)
def test_keys_present_detection(monkeypatch):
import prod.launch_dolphin_violet as lv
_clear_keys(monkeypatch)
assert lv._violet_keys_present() is False
monkeypatch.setenv("BINGX_VIOLET_API_KEY", "k")
assert lv._violet_keys_present() is False # secret still missing
monkeypatch.setenv("BINGX_VIOLET_SECRET_KEY", "s")
assert lv._violet_keys_present() is True
monkeypatch.setenv("BINGX_VIOLET_API_KEY", " ")
assert lv._violet_keys_present() is False # whitespace is absent
def test_dark_run_never_builds_exec_adapter(monkeypatch):
"""Without keys, run() must enter the dark loop and never construct the
observe runtime (and therefore never the BingX exec adapter)."""
import prod.launch_dolphin_violet as lv
_clear_keys(monkeypatch)
monkeypatch.setenv("DOLPHIN_VIOLET_DARK_DIVERGENCE", "0") # strict idle
monkeypatch.setattr(lv, "_preflight_clickhouse", lambda: [])
def boom():
raise AssertionError("observe runtime must not be built while DARK")
monkeypatch.setattr(lv, "_build_observe_runtime", boom)
warnings: list[str] = []
monkeypatch.setattr(
lv.LOGGER, "warning", lambda msg, *a: warnings.append(msg % a if a else str(msg))
)
async def drive():
task = asyncio.ensure_future(lv.run())
await asyncio.sleep(0.3) # boot path reaches the dark loop
task.cancel()
try:
await task
except asyncio.CancelledError:
pass
asyncio.run(drive())
assert any("VIOLET DARK" in w for w in warnings), warnings
def test_missing_tables_idles_dark_naming_apply_cmd(monkeypatch):
import prod.launch_dolphin_violet as lv
_clear_keys(monkeypatch)
monkeypatch.setattr(lv, "_preflight_clickhouse", lambda: ["violet_feed_divergence"])
crits: list[str] = []
monkeypatch.setattr(
lv.LOGGER, "critical", lambda msg, *a: crits.append(msg % a if a else str(msg))
)
async def drive():
task = asyncio.ensure_future(lv.run())
await asyncio.sleep(0.3)
task.cancel()
try:
await task
except asyncio.CancelledError:
pass
asyncio.run(drive())
assert crits and "apply_violet_ddl.py" in crits[0]
assert "violet_feed_divergence" in crits[0]
def test_violet_env_hard_sets_namespaces_and_snapshot_path(monkeypatch):
import prod.launch_dolphin_violet as lv
import prod.clean_arch.runtime.pink_direct as pd
monkeypatch.setenv("DOLPHIN_STATE_MAP", "DOLPHIN_STATE_PINK") # poisoned env
original = pd._KERNEL_STATE_PATH
try:
lv._apply_violet_env()
import os
assert os.environ["DOLPHIN_STATE_MAP"] == "DOLPHIN_STATE_VIOLET"
assert os.environ["DITA_V2_PREFIX"] == "violet"
assert os.environ["DOLPHIN_BINGX_ALLOW_MAINNET"] == "0"
# kernel snapshot file repointed away from PINK's fixed path
assert pd._KERNEL_STATE_PATH == lv._KERNEL_STATE_PATH_VIOLET
assert "pink" not in str(pd._KERNEL_STATE_PATH)
finally:
pd._KERNEL_STATE_PATH = original
if __name__ == "__main__":
raise SystemExit(pytest.main([__file__, "-v"]))