"""Working-order registry — the state the drive loop sweeps (spec §7). A ``WorkingOrder`` is a maker quote that did not terminally fill on submit: it is either resting on the book or was rejected (post-only that would have crossed). Both live here; the drive loop resolves them on a TTL sweep. The registry reads time through an INJECTED clock (no ambient ``time.monotonic`` — C1 venue-side portability, and deterministic tests). All sizes/prices are ``Decimal`` — the best-practice audit's H1: PINK used float, the port does not. Provenance: pink_direct.py working-order lifecycle (register/expired/note_fill/note_cancel, L975-1046) + exec_router.py WorkingOrder registry. Audit BI-1 (attempt counter). """ from __future__ import annotations from dataclasses import dataclass, field from decimal import Decimal from enum import Enum from typing import Callable from .contract import Side class Action(Enum): ENTER = "ENTER" # opens/increases a position (ACQUIRE urgency) EXIT = "EXIT" # decreases/closes (PROTECT/HARVEST/ROTATE/CATASTROPHIC) @dataclass class WorkingOrder: """A maker quote in flight. Mutable: ``deadline`` and ``attempt`` evolve as the drive loop reprices/retries; identity is ``request_id``.""" request_id: str # this attempt's id (unique per attempt — audit H4) base_request_id: str # parent request (survives retries; FIX OrigClOrdID) asset: str side: Side action: Action limit_price: Decimal deadline: float # in injected-clock units; <= now() means "resolve me" created: float attempt: int = 0 meta: dict = field(default_factory=dict) class WorkingRegistry: """In-memory registry of working quotes, swept by the drive loop. NOT persisted here — durable/atomic persistence is a venue-seam concern (audit BI-5: never /tmp; durable path + tmp-rename). This object is the hot, in-process view. """ def __init__(self, clock: Callable[[], float]) -> None: self._clock = clock self._orders: dict[str, WorkingOrder] = {} def register(self, wo: WorkingOrder) -> WorkingOrder: self._orders[wo.request_id] = wo return wo def working(self, request_id: str) -> WorkingOrder | None: """The working order for this id, or None if already resolved (fill/cancel raced).""" return self._orders.get(request_id) def expired(self) -> list[WorkingOrder]: """Every working order whose deadline has passed (snapshot — safe to mutate during).""" now = self._clock() return [wo for wo in list(self._orders.values()) if now >= wo.deadline] def expire_now(self, request_id: str) -> None: """Pull a quote's deadline to now so the next sweep resolves it through the ONE shared miss/escalation path (rejected post-only, or a venue CANCEL_ACK surfacing via reconcile). pink_direct.py:1010-1011, 1290-1292 — do NOT build a second path. """ wo = self._orders.get(request_id) if wo is not None: wo.deadline = self._clock() def note_fill(self, request_id: str) -> None: self._orders.pop(request_id, None) def note_cancel(self, request_id: str) -> None: self._orders.pop(request_id, None) def __len__(self) -> int: return len(self._orders)