AC-0023: fail-closed intent warn-store; C-case-only verify clear; clear_failed on partial error
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
co-authored by
genichin
parent
1179bdfe23
commit
49eb20bd51
@@ -598,3 +598,61 @@ def test_slot_to_dict_paused_and_warned_independent():
|
||||
row = slot_to_dict(slot, pause_store=pause_store, warn_store=warn_store)
|
||||
assert row["paused"] is True
|
||||
assert row["reconcile_warned"] is True
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# AC-0023 review: warn_store.is_warned() raises → intent fail-closed
|
||||
# ===========================================================================
|
||||
|
||||
class _RaisingWarnStore:
|
||||
"""Stub warn_store whose is_warned always raises (simulates DB unavailable)."""
|
||||
def is_warned(self, slot_id: str) -> bool:
|
||||
raise RuntimeError("DB unavailable")
|
||||
def list_c_case_warned(self) -> set:
|
||||
raise RuntimeError("DB unavailable")
|
||||
|
||||
|
||||
def test_buy_intent_fail_closed_when_warn_store_raises():
|
||||
"""If warn_store.is_warned() raises, buy intent must be rejected (fail-closed)."""
|
||||
repo = InMemorySlotRepository()
|
||||
svc = SlotService(repo)
|
||||
intent_store = InMemoryIntentStore()
|
||||
|
||||
repo.reconcile_universe("default", {"pf-A": "005930"})
|
||||
slot = repo.find_slot_by_portfolio("default", "pf-A")
|
||||
|
||||
intent_svc = IntentService(
|
||||
svc, repo, intent_store,
|
||||
instance_key="default",
|
||||
warn_store=_RaisingWarnStore(),
|
||||
)
|
||||
d = intent_svc.submit_buy(BuyIntent(
|
||||
intent_id="b-fc-001",
|
||||
slot_id=slot.slot_id,
|
||||
entry_price=100.0,
|
||||
qty=10.0,
|
||||
))
|
||||
assert d.status == "rejected"
|
||||
assert d.reason == "reconcile_warning_unavailable"
|
||||
|
||||
|
||||
def test_sell_intent_fail_closed_when_warn_store_raises():
|
||||
"""If warn_store.is_warned() raises, sell intent must be rejected (fail-closed)."""
|
||||
repo = InMemorySlotRepository()
|
||||
svc = SlotService(repo)
|
||||
intent_store = InMemoryIntentStore()
|
||||
|
||||
slot = _make_holding_slot(repo, svc, qty=10)
|
||||
|
||||
intent_svc = IntentService(
|
||||
svc, repo, intent_store,
|
||||
instance_key="default",
|
||||
warn_store=_RaisingWarnStore(),
|
||||
)
|
||||
d = intent_svc.submit_sell(SellIntent(
|
||||
intent_id="s-fc-001",
|
||||
slot_id=slot.slot_id,
|
||||
reason="strategy_exit",
|
||||
))
|
||||
assert d.status == "rejected"
|
||||
assert d.reason == "reconcile_warning_unavailable"
|
||||
|
||||
Reference in New Issue
Block a user