"""Fuzz generation for the mock stack.""" from __future__ import annotations from dataclasses import dataclass from datetime import datetime, timedelta, timezone import math import random from typing import Iterable, Iterator, List, Optional from prod.clean_arch.ports.data_feed import MarketSnapshot from prod.clean_arch.dita import DecisionConfig, DecisionEngine, IntentEngine, DitaObservabilityNamespace from .mock_stack import ChaosProfile, MockClickHouse, MockHazelcast, MockLogSink, MockNetwork, MockTradingStack, NetworkProfile DEFAULT_SYMBOLS = ( "BTCUSDT", "ETHUSDT", "BNBUSDT", "SOLUSDT", "XRPUSDT", "ADAUSDT", "DOGEUSDT", "TRXUSDT", ) @dataclass(frozen=True) class FuzzConfig: """High-volume fuzz config.""" transactions: int = 1_000_000 seed: int = 42 bad_input_rate: float = 0.01 network_drop_rate: float = 0.001 network_duplicate_rate: float = 0.001 price_sigma: float = 0.015 symbol_pool: tuple[str, ...] = DEFAULT_SYMBOLS capture_limit: int = 2_000 aggressive: bool = False hang_entry_rate: float = 0.0 hang_exit_rate: float = 0.0 stale_account_rate: float = 0.0 duplicate_terminal_rate: float = 0.0 missing_terminal_rate: float = 0.0 orphan_close_rate: float = 0.0 reorder_account_rate: float = 0.0 runtime_namespace: str = "pink" anomaly_sensor_key: str | None = None mirror_legacy_sensor_key: bool = False @dataclass(frozen=True) class FuzzReport: """Summary of a fuzz run.""" transactions: int capital_final: float equity_final: float open_notional_final: float policy_events: int trade_events: int account_events: int logs_emitted: int network_dropped: int network_duplicated: int anomaly_counts: dict anomaly_origin_counts: dict injected_anomaly_counts: dict emergent_anomaly_counts: dict anomaly_sensor_payload: dict anomaly_samples: List[dict] sample_policy_events: List[dict] def generate_snapshot_stream(cfg: FuzzConfig) -> Iterator[MarketSnapshot]: """Stream randomized snapshots with occasional poison inputs.""" rng = random.Random(cfg.seed) price_map = {sym: 100.0 + 25.0 * i for i, sym in enumerate(cfg.symbol_pool)} ts = datetime.now(timezone.utc) for i in range(cfg.transactions): symbol = rng.choice(cfg.symbol_pool) base = price_map[symbol] drift = rng.gauss(0.0, cfg.price_sigma) price = max(0.01, base * (1.0 + drift)) price_map[symbol] = price vdiv = rng.uniform(-0.2, 0.1) irp = rng.uniform(-1.0, 1.0) eigenvalues = [1.0, 0.9, 0.8] if rng.random() < cfg.bad_input_rate: poison = rng.choice(["nan", "inf", "-inf", "zero", "none", "unicode"]) if poison == "nan": price = float("nan") elif poison == "inf": price = float("inf") elif poison == "-inf": price = float("-inf") elif poison == "zero": price = 0.0 elif poison == "none": vdiv = None # type: ignore[assignment] elif poison == "unicode": symbol = symbol + "🐬" yield MarketSnapshot( timestamp=ts + timedelta(milliseconds=i), symbol=symbol, price=price, bid=price * 0.9995 if math.isfinite(price) else price, ask=price * 1.0005 if math.isfinite(price) else price, eigenvalues=eigenvalues, eigenvectors=None, velocity_divergence=vdiv, irp_alignment=irp, scan_number=i, source="fuzz", ) def fuzz_stack(cfg: Optional[FuzzConfig] = None) -> FuzzReport: """Run the full mocked stack against fuzzed market snapshots.""" cfg = cfg or FuzzConfig() if cfg.aggressive: cfg = FuzzConfig( transactions=cfg.transactions, seed=cfg.seed, bad_input_rate=max(cfg.bad_input_rate, 0.08), network_drop_rate=max(cfg.network_drop_rate, 0.03), network_duplicate_rate=max(cfg.network_duplicate_rate, 0.03), price_sigma=max(cfg.price_sigma, 0.05), symbol_pool=cfg.symbol_pool, capture_limit=cfg.capture_limit, aggressive=cfg.aggressive, hang_entry_rate=max(cfg.hang_entry_rate, 0.01), hang_exit_rate=max(cfg.hang_exit_rate, 0.03), stale_account_rate=max(cfg.stale_account_rate, 0.03), duplicate_terminal_rate=max(cfg.duplicate_terminal_rate, 0.03), missing_terminal_rate=max(cfg.missing_terminal_rate, 0.015), orphan_close_rate=max(cfg.orphan_close_rate, 0.015), reorder_account_rate=max(cfg.reorder_account_rate, 0.02), ) policy = DecisionEngine(DecisionConfig()) intent = IntentEngine(DecisionConfig()) stack = MockTradingStack( decision_engine=policy, intent_engine=intent, capital=25_000.0, runtime_namespace=cfg.runtime_namespace, strategy_namespace=cfg.runtime_namespace, event_namespace=cfg.runtime_namespace, observability=DitaObservabilityNamespace( runtime_namespace=cfg.runtime_namespace, anomaly_sensor_key=cfg.anomaly_sensor_key, mirror_legacy_key=cfg.mirror_legacy_sensor_key, state_map=f"DOLPHIN_STATE_{cfg.runtime_namespace.upper()}" if cfg.runtime_namespace.lower() != "pink" else "DOLPHIN_STATE_PINK", ), network=MockNetwork( NetworkProfile( drop_rate=cfg.network_drop_rate, duplicate_rate=cfg.network_duplicate_rate, ), seed=cfg.seed, ), hazelcast=MockHazelcast(), clickhouse=MockClickHouse(capture_limit=cfg.capture_limit), logs=MockLogSink(capture_limit=cfg.capture_limit), chaos=ChaosProfile( hang_entry_rate=cfg.hang_entry_rate, hang_exit_rate=cfg.hang_exit_rate, stale_account_rate=cfg.stale_account_rate, duplicate_terminal_rate=cfg.duplicate_terminal_rate, missing_terminal_rate=cfg.missing_terminal_rate, orphan_close_rate=cfg.orphan_close_rate, reorder_account_rate=cfg.reorder_account_rate, ), ) for snapshot in generate_snapshot_stream(cfg): stack.step(snapshot) result = stack.summary(cfg.transactions) return FuzzReport( transactions=result.steps, capital_final=result.capital_final, equity_final=result.equity_final, open_notional_final=result.open_notional_final, policy_events=result.decision_events, trade_events=result.trade_events, account_events=result.account_events, logs_emitted=result.logs_emitted, network_dropped=result.network_dropped, network_duplicated=result.network_duplicated, anomaly_counts=result.anomaly_counts, anomaly_origin_counts=result.anomaly_origin_counts, injected_anomaly_counts=result.injected_anomaly_counts, emergent_anomaly_counts=result.emergent_anomaly_counts, anomaly_sensor_payload=result.anomaly_sensor_payload, anomaly_samples=result.anomaly_samples, sample_policy_events=result.sample_policy_events, )