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>
110 lines
3.5 KiB
Python
110 lines
3.5 KiB
Python
"""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"]))
|