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>
This commit is contained in:
102
prod/clean_arch/dita_v2/journal.py
Normal file
102
prod/clean_arch/dita_v2/journal.py
Normal file
@@ -0,0 +1,102 @@
|
||||
"""Debug journaling surfaces for DITAv2."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Callable, Dict, List, Optional, Protocol
|
||||
|
||||
from .contracts import KernelTransition, TradeSlot, TradeStage, VenueEvent
|
||||
from .control import KernelControlSnapshot
|
||||
from .utils import json_safe, json_text
|
||||
|
||||
JournalSink = Callable[[str, Dict[str, Any]], None]
|
||||
|
||||
|
||||
class KernelJournal(Protocol):
|
||||
"""Append-only debug journal interface."""
|
||||
|
||||
def record(self, row: Dict[str, Any]) -> None:
|
||||
...
|
||||
|
||||
def record_transition(
|
||||
self,
|
||||
*,
|
||||
transition: KernelTransition,
|
||||
slot: TradeSlot,
|
||||
event: Optional[VenueEvent] = None,
|
||||
control: Optional[KernelControlSnapshot] = None,
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
@dataclass
|
||||
class MemoryKernelJournal:
|
||||
"""In-memory journal used in tests."""
|
||||
|
||||
rows: List[Dict[str, Any]] = field(default_factory=list)
|
||||
capture_limit: int = 10_000
|
||||
|
||||
def record(self, row: Dict[str, Any]) -> None:
|
||||
if len(self.rows) < self.capture_limit:
|
||||
self.rows.append(dict(row))
|
||||
|
||||
def record_transition(
|
||||
self,
|
||||
*,
|
||||
transition: KernelTransition,
|
||||
slot: TradeSlot,
|
||||
event: Optional[VenueEvent] = None,
|
||||
control: Optional[KernelControlSnapshot] = None,
|
||||
) -> None:
|
||||
row = _transition_row(transition=transition, slot=slot, event=event, control=control)
|
||||
self.record(row)
|
||||
|
||||
|
||||
class ClickHouseKernelJournal:
|
||||
"""Fire-and-forget ClickHouse journal.
|
||||
|
||||
The sink is a small callable of the form ``sink(table_name, row_dict)``.
|
||||
"""
|
||||
|
||||
def __init__(self, sink: Optional[JournalSink] = None):
|
||||
self.sink = sink
|
||||
|
||||
def record(self, row: Dict[str, Any]) -> None:
|
||||
if self.sink is not None:
|
||||
self.sink("dita_kernel_debug", row)
|
||||
|
||||
def record_transition(
|
||||
self,
|
||||
*,
|
||||
transition: KernelTransition,
|
||||
slot: TradeSlot,
|
||||
event: Optional[VenueEvent] = None,
|
||||
control: Optional[KernelControlSnapshot] = None,
|
||||
) -> None:
|
||||
self.record(_transition_row(transition=transition, slot=slot, event=event, control=control))
|
||||
|
||||
|
||||
def _transition_row(
|
||||
*,
|
||||
transition: KernelTransition,
|
||||
slot: TradeSlot,
|
||||
event: Optional[VenueEvent],
|
||||
control: Optional[KernelControlSnapshot],
|
||||
) -> Dict[str, Any]:
|
||||
return {
|
||||
"ts": transition.timestamp.isoformat() if hasattr(transition.timestamp, "isoformat") else str(transition.timestamp),
|
||||
"trade_id": transition.trade_id,
|
||||
"slot_id": transition.slot_id,
|
||||
"prev_state": transition.prev_state.value,
|
||||
"next_state": transition.next_state.value,
|
||||
"trigger": transition.trigger,
|
||||
"intent_id": transition.intent_id,
|
||||
"event_id": transition.event_id,
|
||||
"control_mode": transition.control_mode,
|
||||
"control_verbosity": transition.control_verbosity,
|
||||
"slot_state": slot.to_dict(),
|
||||
"event_payload": json_safe(event) if event is not None else {},
|
||||
"control_snapshot": control.as_dict() if control is not None else {},
|
||||
"slot_state_json": json_text(slot.to_dict()),
|
||||
}
|
||||
Reference in New Issue
Block a user