feat(bat-054): 그날-시작 KIS 인증정보 양의 경로 주입 — KISBroker reinitialize (REQ-113 AC-2/AC-4, REQ-115 AC-1)

BAT-053 스캐폴드에서 연기된 양의 경로 완성:
- KISBroker.reinitialize(credential): app_key/app_secret/account_ref 교체 + L1 token 무효화
- SnapshotScheduler에 kis_reinit_callback 주입 지점 추가; 그날-시작 성공 시 callback 호출
- daemon.py에 _build_kis_reinit_callback() 헬퍼 + SnapshotScheduler 조립 수정
- 신규 테스트 12개 추가: 757 passed / 47 skipped (기존 745 대비 +12, 회귀 0)

안전 불변식 유지:
- credential_fetch_enabled=False(기본) 경로 byte-for-byte 보존
- fail-closed 불변식 미파괴 (reinit 실패 시 entry_allowed 유지)
- AMQP wire 계약 변경 없음

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-28 19:51:48 +09:00
co-authored by Claude Sonnet 4.6
parent a50b5e34a2
commit 6b066e19cb
10 changed files with 733 additions and 1 deletions
+24
View File
@@ -122,6 +122,27 @@ def _build_transport(config: DaemonConfig) -> MessagingTransport:
return RabbitMQTransport(mq.url, timeout=mq.timeout)
def _build_kis_reinit_callback(config: DaemonConfig, broker: BrokerPort):
"""Build a KISBroker reinitialize callback for the day-start credential hook.
Returns broker.reinitialize if all conditions are met:
- config.broker == 'kis' (not paper)
- config.credential_fetch_enabled == True (opt-in)
- broker has a reinitialize() method (KISBroker)
Returns None otherwise so SnapshotScheduler skips reinit (backward compat).
dcy-036 / REQ-113 AC-2 / REQ-115 AC-1.
"""
if config.broker != "kis":
return None
if not config.credential_fetch_enabled:
return None
reinit = getattr(broker, "reinitialize", None)
if reinit is None or not callable(reinit):
return None
return reinit
def _build_portfolio_read(config: DaemonConfig) -> PortfolioHubReadPort:
"""portfolio-hub HTTP read adapter when configured; otherwise stub (REQ-027)."""
pf = config.portfolio_hub
@@ -216,6 +237,9 @@ class Daemon:
alarm_emitter=self.alarm_emitter, # dcy-033 / REQ-100
warn_store=self.warn_store, # BAT-050 / REQ-103: durable reconcile-warning
credential_fetch_enabled=config.credential_fetch_enabled, # dcy-036 / REQ-113
# dcy-036 / REQ-113 AC-2 / REQ-115 AC-1: KISBroker reinit callback.
# None when broker!=kis or credential_fetch_enabled=False (backward compat).
kis_reinit_callback=_build_kis_reinit_callback(config, self.broker),
)
# dcy-036 / REQ-114: wire entry_allowed_fn after snapshot_scheduler is created.
# When credential_fetch_enabled=False (default), entry_allowed_fn=None = no gate.