feat: add bounded KIS account read recovery
This commit is contained in:
@@ -115,6 +115,7 @@ class IntentService:
|
||||
default_order_timeout_sec: Optional[int] = None,
|
||||
warn_store=None, # Optional[ReconcileWarningStore] — BAT-050 / REQ-104
|
||||
entry_allowed_fn: Optional[Callable[[], bool]] = None,
|
||||
buy_guard_fn: Optional[Callable[[BuyIntent], Optional[str]]] = None,
|
||||
) -> None:
|
||||
self._svc = slot_service
|
||||
self._repo = slot_repo
|
||||
@@ -138,6 +139,10 @@ class IntentService:
|
||||
# When returns False, BuyIntent is rejected with reason 'day_start_load_failed'.
|
||||
# SellIntent is NOT gated by this (REQ-114 AC-5: 청산 경로 영향 없음).
|
||||
self._entry_allowed_fn: Optional[Callable[[], bool]] = entry_allowed_fn
|
||||
# dcy-041 / GitHub #45: opt-in bounded cash-capacity admission guard.
|
||||
# The callable returns a stable rejection reason or None. SellIntent is
|
||||
# deliberately outside this gate.
|
||||
self._buy_guard_fn = buy_guard_fn
|
||||
|
||||
# ------------------------------------------------------------
|
||||
def lookup(self, intent_id: str) -> Optional[IntentDecision]:
|
||||
@@ -270,6 +275,15 @@ 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:
|
||||
try:
|
||||
guard_reason = 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
|
||||
|
||||
Reference in New Issue
Block a user