feat(core-A): reconcile-warning durable store + blocking gate (BAT-050, REQ-102/103/104/107/108)

B/C 불일치 시 슬롯을 durable 차단(ReconcileWarningStore)하고 전략 intent 경로에
pause∨reconcile_warned 게이트를 추가한다. 안전망(safety-sell/kill-switch/watchdog)
경로는 SlotService 직접 호출로 게이트를 구조적으로 우회(OQ-B 확정).
SlotState enum/전이표/wire 계약 필드는 불변, reconcile_warned 필드만 additive 추가.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
This commit is contained in:
2026-06-26 00:43:04 +09:00
co-authored by Claude Sonnet 4.6
parent 35f3147250
commit c193388198
17 changed files with 1410 additions and 27 deletions
+13 -7
View File
@@ -41,6 +41,7 @@ from trex_core.adapters.persistence.postgresql import (
from trex_core.adapters.portfolio import (
PortfolioHubReadAdapter,
PostgreSQLPauseStore,
PostgreSQLReconcileWarningStore,
StubPortfolioRead,
)
from trex_core.adapters.portfolio.killswitch_store import PostgreSQLKillSwitchStore
@@ -158,13 +159,6 @@ class Daemon:
instance_key=config.instance_key,
strategy_state_store=self.strategy_state_store,
)
self.intent_service = IntentService(
self.slot_service, self.slot_repo, self.intent_store,
resolve_symbol=self._resolve_symbol,
instance_key=config.instance_key,
max_active_slots=config.max_active_slots, # dcy-020: asset-centric gate
default_order_timeout_sec=config.default_order_timeout_sec, # dcy-022
)
self.broker = _build_broker(config)
self.outbox = PostgreSQLLedgerOutbox(config.dsn)
# BAT-008: portfolio-hub read + snapshot store + durable pause + scheduler.
@@ -173,6 +167,16 @@ class Daemon:
# BAT-010/011: per-slot watchdog (snapshot RPC writer, safety-sell reader).
self.watchdog = WatchdogStore()
self.pause_store = PostgreSQLPauseStore(config.dsn)
# BAT-050 / REQ-102: durable reconcile-warning store (slot_id PK).
self.warn_store = PostgreSQLReconcileWarningStore(config.dsn)
self.intent_service = IntentService(
self.slot_service, self.slot_repo, self.intent_store,
resolve_symbol=self._resolve_symbol,
instance_key=config.instance_key,
max_active_slots=config.max_active_slots, # dcy-020: asset-centric gate
default_order_timeout_sec=config.default_order_timeout_sec, # dcy-022
warn_store=self.warn_store, # BAT-050 / REQ-104: reconcile-warning gate
)
# BAT-012: day-scoped kill-switch exclusion store + service.
self.killswitch_store = PostgreSQLKillSwitchStore(config.dsn)
self.portfolio_read = _build_portfolio_read(config)
@@ -218,6 +222,7 @@ class Daemon:
slot_service=self.slot_service,
instance_key=config.instance_key,
alarm_emitter=self.alarm_emitter, # dcy-033 / REQ-100
warn_store=self.warn_store, # BAT-050 / REQ-103: durable reconcile-warning
)
self.execution = ExecutionService(
self.slot_service, self.slot_repo, self.broker,
@@ -315,6 +320,7 @@ class Daemon:
instance_key=self.config.instance_key,
snapshot_store=self.snapshot_store,
pause_store=self.pause_store,
warn_store=self.warn_store, # BAT-050 / REQ-104: reconcile_warned field
watchdog_store=self.watchdog,
watchdog_timeout_sec=self.config.safety_sell.watchdog_timeout_sec,
ledger_outbox=self.outbox,