fix: close broker uncertainty audit gaps
This commit is contained in:
@@ -30,6 +30,7 @@ from uuid import UUID
|
||||
|
||||
from trex_core.application.ports import IntentStore
|
||||
from trex_core.domain.slot import (
|
||||
SlotAdmissionRejectedError,
|
||||
SlotRepository,
|
||||
SlotService,
|
||||
SlotState,
|
||||
@@ -275,20 +276,24 @@ class IntentService:
|
||||
symbol = _resolve(slot)
|
||||
if not symbol:
|
||||
return IntentDecision(intent.intent_id, "rejected", None, "unknown_portfolio")
|
||||
if self._buy_guard_fn is not None:
|
||||
def _admission_precondition(_locked_slot) -> Optional[str]:
|
||||
# Runs inside SlotService's instance-scoped advisory lock. This
|
||||
# makes capacity and cached-cash reservation checks atomic with
|
||||
# the PENDING_BUY transition across same-instance daemons.
|
||||
if (
|
||||
not is_increase
|
||||
and self._max_active_slots is not None
|
||||
and self._repo.count_active(self._instance_key)
|
||||
>= self._max_active_slots
|
||||
):
|
||||
return "capacity_full"
|
||||
if self._buy_guard_fn is None:
|
||||
return None
|
||||
try:
|
||||
guard_reason = self._buy_guard_fn(intent)
|
||||
return self._buy_guard_fn(intent)
|
||||
except Exception: # noqa: BLE001 - buy guard fails closed
|
||||
guard_reason = "account_snapshot_unavailable"
|
||||
if guard_reason is not None:
|
||||
return IntentDecision(
|
||||
intent.intent_id, "rejected", None, guard_reason
|
||||
)
|
||||
# M cap applies only to NEW activations (initial buy). An increase on
|
||||
# an already-active asset does not change the active asset count.
|
||||
if (not is_increase and self._max_active_slots is not None
|
||||
and self._repo.count_active(self._instance_key) >= self._max_active_slots):
|
||||
return IntentDecision(intent.intent_id, "rejected", None, "capacity_full")
|
||||
return "account_snapshot_unavailable"
|
||||
|
||||
# dcy-022 / REQ-068: resolve effective timeout (per-intent > config default).
|
||||
effective_timeout = (
|
||||
intent.timeout_sec
|
||||
@@ -317,6 +322,11 @@ class IntentService:
|
||||
slippage_pct=intent.slippage_pct,
|
||||
venue=intent.venue,
|
||||
extra={"intent_id": intent.intent_id, "symbol": symbol},
|
||||
precondition=_admission_precondition,
|
||||
)
|
||||
except SlotAdmissionRejectedError as exc:
|
||||
return IntentDecision(
|
||||
intent.intent_id, "rejected", None, exc.reason
|
||||
)
|
||||
except SlotStateMismatchError:
|
||||
continue # slot changed under us; re-fetch and re-evaluate
|
||||
|
||||
Reference in New Issue
Block a user