From e052e70619694741a2585e0b00f32b8aa7c639d8 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Thu, 25 Jun 2026 21:47:58 +0900 Subject: [PATCH] =?UTF-8?q?docs(discovery):=20add=20dcy-034=20slot?= =?UTF-8?q?=E2=86=94account=20blocking=20reconcile=20+=20sync/verify=20col?= =?UTF-8?q?d-start=20(confirmed)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit M3 중장기 cold-start 동기화 갭 정식화. 차단형 reconcile(A→B→C) + durable warning(별도 store) + pause∨warning 게이트 + 운영자 sync/verify 명령. OQ-1~5 전부 confirm-discovery에서 Answered. portfolio-hub 현재보유 평단(WAC) read 교차 의존 명시. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5 --- ...count-blocking-reconcile-sync-coldstart.md | 228 ++++++++++++++++++ docs/discovery/index.md | 1 + 2 files changed, 229 insertions(+) create mode 100644 docs/discovery/dcy-034_20260625_slot-account-blocking-reconcile-sync-coldstart.md diff --git a/docs/discovery/dcy-034_20260625_slot-account-blocking-reconcile-sync-coldstart.md b/docs/discovery/dcy-034_20260625_slot-account-blocking-reconcile-sync-coldstart.md new file mode 100644 index 0000000..874e6e9 --- /dev/null +++ b/docs/discovery/dcy-034_20260625_slot-account-blocking-reconcile-sync-coldstart.md @@ -0,0 +1,228 @@ +# 0. 문서 상태 +이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다. + +- 상태: confirmed +- 문서 ID: dcy-034_20260625_slot-account-blocking-reconcile-sync-coldstart +- 이슈명: 슬롯↔실계좌 차단형 reconcile + sync/verify 명령 — 중장기 cold-start (기존 보유 포지션 onboarding) +- 작성 시각(KST): 2026-06-25 (KST) +- 마지막 갱신 시각(KST): 2026-06-25 (KST, confirm-discovery — OQ-1~5 전부 Answered) +- 대체됨: 없음 +- 후속 Discovery 참조: 없음 +- 생성된 REQ 참조: 없음 (confirm-discovery 후 생성) + +# 1. 계획 상태 요약 +현재 Discovery가 어떤 배경에서 작성되고 있는지, 연계 문서가 있는지, 지금 시점의 해석이 무엇인지 짧게 요약한다. + +- 연계 문서 현황: + - 관련 점수 파일: 미생성 + - 관련 TODO/메모: GitHub 보드 `fourblocks2020/trex` #7 항목 "trex-core: 슬롯↔실계좌 차단형 reconcile + sync/verify 명령 — 중장기 cold-start (M3)" (M3/P1, 설계방향 본문 보유). 워크스페이스 메모리 `m3-goal-midlong-core-instance`. + - 선행 Discovery: dcy-020(자산중심 슬롯), dcy-027(중장기 슬롯 운영·운영 프로파일), dcy-028(slot strategy-state store), dcy-029(슬롯/PnL 뷰). 본 건은 이들 위에 cold-start 동기화 갭을 정의한다. +- 해석: + - M3 메인 목표는 "중/장기 전략용 별도 trex-core 인스턴스 추가"(사장님 2026-06-25). 그 인스턴스는 **이미 실계좌에 보유 중인 중장기 종목 위에서 cold-start** 한다 — portfolio-hub에 종목·ledger(잔고)가 있고 브로커 계좌에 실보유가 있는데 **slot DB는 비어 있는 상태**에서 데몬이 처음 뜨는 상황이 정상 시나리오다. + - 현행 reconcile는 이 cold-start 갭에서 **탐지(WARN/error)만 하고 차단도 해소 경로도 없다.** 슬롯↔브로커·원장↔슬롯 불일치가 있어도 전략이 그대로 돌 수 있고(데이터 오염 위 매매 위험), 운영자가 불일치를 안전하게 정합화해 전략을 재개할 표준 명령이 없다. + - 본 Discovery는 이 갭을 "차단형 reconcile(A→B→C) + 운영자 sync/verify 명령 + 차단형 warning 상태"라는 trex-core 변경 단위로 정식화한다. (중장기 **전략 모듈 자체**·멀티데이 PnL·인스턴스 프로파일 신설은 별개 단위 — 범위 경계 참조.) + +# 2. 요구사항 판정 결과 +이번 요청이 기존 요구사항과 비교해 신규인지, 유사한지, 중복인지 판단하고 그 근거를 남긴다. + +- 판정: 신규 +- 근거 + - 기존 reconcile 자산은 **탐지 전용**이다. `reconcile_core_holdings`(REQ-062)는 A(슬롯 보유·브로커 0)만 ERROR 전이하고 B(브로커 보유·슬롯 없음)·C(수량 불일치)는 **WARN 로그만** 남긴다(`application/reconciliation.py:48-83`). `reconcile_positions`(REQ-031)는 portfolio-hub↔브로커 불일치 시 asset overlay `set_warning(pid)`를 켜지만 **in-memory·비차단**이며 docstring이 명시하듯 *"pause is the durable channel for manual holds"*(`reconciliation.py:1-8,118`). + - 즉 "불일치 시 전략을 **차단**하고, 운영자가 **명령으로 정합화해 차단을 해제**한다"는 행위는 어디에도 없다. dcy-027(중장기 슬롯 운영)은 운영 프로파일·멀티데이 리스크까지 다뤘으나 cold-start 시 기존 보유 onboarding·동기화 차단은 Out-of-Scope로 두었다. + - 신규 운영자 CLI 명령(sync/verify)과 차단형 슬롯 상태 도입은 dcy-016(운영자 CLI) 이후의 독립 능력 추가라 별도 주기로 추적하는 편이 명확하다. + +# 3. 문제점의 요약 +문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다. Discovery의 핵심 맥락을 가장 먼저 이해할 수 있어야 한다. + +- 현재 상태 + - **cold-start 갭**: 중장기 인스턴스가 처음 뜰 때 slot DB는 비어 있다. boot시 `snapshot_scheduler.run_once()`가 ① whoami → ② get_portfolios → ③ `store.swap` → ④ `reconcile_positions`(portfolio-hub↔브로커) → ⑤ `_reconcile_slots`(`reconcile_universe`로 INACTIVE 슬롯 생성) → ⑥ `reconcile_core_holdings`(슬롯↔브로커) 순으로 돈다(`snapshot_scheduler.py:85-146`). 그 결과 portfolio-hub 자산은 **INACTIVE 슬롯으로 생성**되지만, 실계좌에 이미 보유 중인 수량은 슬롯에 **HOLDING으로 반영되지 않는다**(슬롯 생성 기준은 자산 리스트지 브로커 잔고가 아님). 브로커가 보유한 종목은 `reconcile_core_holdings`의 케이스 B("unmanaged position")로 **WARN 로그만** 남고 슬롯은 INACTIVE에 머문다. + - **차단 부재**: 위 불일치(B 미반영, C 수량 차이, asset warning)는 전략 수행을 막지 않는다. SlotState는 5상태(inactive/pending_buy/holding/pending_sell/error)뿐이고 "warning"은 슬롯 필드가 아니다(`domain/slot/state.py:30-37`). asset warning은 in-memory overlay라 재시작 시 사라지고 전략 read/intent 경로를 차단하지 않는다. 유일한 durable 차단 채널은 **pause**(portfolio_id 단위, `snapshot_pause` 테이블/pause_store)뿐인데, 이는 reconcile가 자동으로 걸지 않는 **수동 채널**이다. + - **해소 명령 부재**: 운영자가 "슬롯을 실계좌에 맞춰라"라고 지시할 표준 CLI가 없다. 현 `trex-core` CLI는 pause/resume/paused/universe/slots/enter/exit/cancel/report뿐이다(`runtime/cli.py`). 불일치를 손으로 정합화하려면 원장 수정(pfhub) 또는 슬롯 직접 손질에 의존해야 하고, 정합 후 "warning 해제·전략 재개"를 안전하게 확인하는 경로가 없다. + - **결과 위험**: 평단 0/수량 불일치 슬롯 위에서 중장기 전략이 매도·증액 결정을 내리면(예: tsl 류 평단 기반 tier, 사이징) 잘못된 cost basis로 실거래가 나간다. dcy-032에서 평단 0 오염의 하류 피해(tier 무시 폴백 매도, 실현손익 과대)를 이미 확인했다 — cold-start 미정합은 그 위험을 인스턴스 기동 시점에 구조적으로 만든다. +- 기대 상태 + - 중장기 인스턴스 cold-start 시, portfolio-hub 자산은 슬롯 유니버스로 정합되고(A), 실계좌 보유는 **불일치로 탐지되면 해당 슬롯이 차단(전략 미수행) 상태**가 되어, 정합 전 잘못된 매매가 절대 나가지 않는다. + - 운영자는 표준 CLI로 (B) 슬롯을 브로커 잔고에 맞춰 동기화(`sync`)하고, (C) 원장↔슬롯 불일치는 portfolio-hub CLI로 원장을 고친 뒤 trex-core `verify`로 재확인해 차단을 해제한다. 강제 해제(force-clear) 없이 **재대조가 일치할 때만** 차단이 풀린다. + - 차단 채널이 pause(수동 hold)와 별개로 **reconcile 기반 자동 차단(warning)** 으로 durable하게 존재하고, 두 채널 중 하나라도 걸리면 전략이 차단된다. +- 이해관계자 + - 사장님 — M3 범위·차단/해제 정책·비가역 운영(실계좌 동기화) 승인자 + - 팀장(Claude) — Discovery/게이트 관리, cold-start 갭 추적자 + - trex-core-dev — delivery 담당 + - 운영자 — cold-start 시 sync/verify 수행 주체, 차단/해제의 최종 소비자 +- 제약사항 + - 브로커(KIS) 잔고가 reconcile의 ground truth다(invariant B, 단일 계좌). 슬롯/원장은 미러이며 권위는 브로커에 있다. + - **자동 무음 정정·자동 청산 금지**(issue #15 기조 유지). reconcile는 탐지+차단까지만 자동이고, 실제 정합(슬롯=브로커 반영, 원장 수정)은 **운영자 명령**으로만 일어난다. + - trex-core wire 계약(slots RPC 필드 등) 변경은 blast radius가 커 가급적 피한다. 차단 상태가 슬롯 read 표면에 노출돼야 한다면 그 스키마 영향은 design에서 최소화·명시한다. + - 단기 인스턴스(M1/M2 라이브: orb+tsl)에 회귀를 주지 않아야 한다 — 차단형 reconcile는 모든 인스턴스에 공통 적용되므로, 단기 인스턴스의 정상 운영(당일 슬롯·평소 일치 상태)에서 신규 차단이 오발동하지 않아야 한다. + +## 주요 사용자 시나리오 +사용자 또는 운영자가 실제로 어떤 상황에서 이 변경을 필요로 하는지 대표 시나리오를 적는다. + +- 운영자(cold-start onboarding): 중장기 인스턴스를 처음 띄운다. portfolio-hub에 A·B·C 3종목이 있고 실계좌에 이미 보유 중이다. 데몬 기동 → 슬롯 유니버스 생성 + 보유 불일치 탐지로 해당 슬롯 차단(전략 정지). 운영자가 `trex-core sync`로 슬롯을 실계좌 잔고에 맞추고, 일치 확인 후 차단이 풀려 전략이 비로소 돈다. +- 운영자(원장↔슬롯 불일치, C): reconcile가 원장(portfolio-hub 스냅샷)과 슬롯/브로커 간 수량 불일치를 차단으로 표면화. 운영자가 `pfhub portfolio buy/sell/invest`로 원장을 정정 → `trex-core verify `로 재대조 → 일치 시 차단 해제, 여전히 불일치면 해제 거부(사유 출력). +- 운영자(직접 매매 phantom, B 주의): 운영자가 KIS HTS로 직접 사고판 종목이 슬롯 없이 브로커에만 있다. `sync`가 이를 슬롯에 반영할 때 방향(매니지 대상으로 편입할지/무시할지)을 잘못 잡으면 중장기 전략이 의도치 않은 포지션을 떠안는다 — 방향 정책 확인이 필요하다. + +# 4. 이번에 정의할 변경 +이번 Discovery에서 다루는 핵심 변경 항목을 목록으로 적는다. 기능, 구조, 규칙 변경을 함께 포함해도 된다. + +- 변경 1 — 차단형 reconcile(A→B→C): boot/일일 reconcile에서 불일치를 탐지하면 **해당 슬롯을 차단 상태로 전이**한다. A=portfolio-hub 자산→슬롯 유니버스 정합(기존 유지), B=슬롯↔브로커 수량 불일치→슬롯 차단, C=원장(portfolio-hub 스냅샷)↔슬롯 수량 불일치→슬롯 차단. 차단된 슬롯은 전략 수행(매수/매도/사이징 intent) 대상에서 제외된다. +- 변경 2 — 차단형 warning 상태 도입: pause(수동·durable)와 **별개의 reconcile 기반 차단 상태(warning)** 를 durable하게 도입하고, pause OR warning 중 하나라도 걸리면 전략을 차단하도록 차단 게이트를 확장한다. (저장 위치·표현 방식은 OQ.) +- 변경 3 — 운영자 sync 명령: `trex-core sync`(신규) — 슬롯 수량을 브로커 잔고(ground truth)에 맞춰 반영하고, 일치하면 해당 슬롯의 reconcile-warning을 해제한다. cold-start 시 기존 보유의 슬롯 onboarding 경로이기도 하다. +- 변경 4 — 운영자 verify 명령: `trex-core verify`(신규) — C(원장↔슬롯) 불일치로 차단된 슬롯에 대해, 운영자가 portfolio-hub CLI로 원장을 정정한 뒤 **재대조**해 일치 시 warning을 해제, 불일치면 사유와 함께 해제를 거부한다(force-clear 없음). + +## 영향 범위 +변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다. + +- 코드 영향: + - `trex_core/application/reconciliation.py` — `reconcile_core_holdings`(B/C를 WARN→슬롯 차단으로 승격), `reconcile_positions`(asset warning을 durable 차단으로 연계할지 결정). + - `trex_core/application/snapshot_scheduler.py` — reconcile 순서/차단 적용 지점(`run_once`). + - 슬롯 도메인/저장소 — 차단형 warning 상태의 저장(슬롯 필드 신설 vs pause류 별도 store vs 신규 SlotState). `domain/slot/state.py`, slot repo. + - 전략 차단 게이트 — slots RPC read 표면/ intent 수용 경로(`application/messaging_handlers.py`)에서 pause에 더해 warning도 차단으로 반영. + - `trex_core/runtime/cli.py` — `sync`/`verify` 서브커맨드(데몬 RPC) 추가. +- 문서 영향: + - `docs/discovery/index.md` 신규 행 추가. + - `docs/runtime-flows.md`(reconcile/차단/해제 흐름), `docs/operations.md`(cold-start onboarding 런북) 갱신. +- 운영 영향: + - 중장기 인스턴스 cold-start 표준 절차 신설(기동→차단 확인→sync/verify→재개). + - 차단/해제가 운영자 명령 의존이므로 런북·교육 필요. pfhub 원장 정정과 trex-core verify의 2-서비스 협응 절차 명시. + +# 5. 요구사항 목록 +실제로 구현과 검증으로 이어질 요구사항을 기능/비기능으로 나누어 정리하고, 범위 경계를 명확히 적는다. + +## 기능 요구사항 +- FR-1: boot/일일 reconcile에서 슬롯↔브로커(B) 또는 원장↔슬롯(C) 불일치가 탐지되면 해당 슬롯을 **차단 상태(reconcile-warning)** 로 전이하고, 차단된 슬롯은 전략 read 표면/intent 수용에서 제외된다. +- FR-2: 전략 차단 게이트는 pause(수동) **또는** reconcile-warning 중 하나라도 걸리면 해당 슬롯/포트폴리오의 전략 수행을 차단한다. +- FR-3: `trex-core sync` 명령(별도 명령, OQ-2)은 **브로커 잔고(정본)를 유지한 채 대상 슬롯의 보유 수량을 브로커에 맞춰 갱신**하고(슬롯 미러를 브로커로 수렴, INACTIVE→HOLDING 전이 포함), 정합 후 일치하면 그 슬롯의 reconcile-warning을 해제한다. cold-start 시 portfolio-hub 유니버스에 있어 슬롯이 생성된 보유 종목(B)이 그 대상이다. **브로커에만 있고 portfolio-hub에 없는 종목(슬롯 부재)은 sync 대상이 아니다** — unmanaged 경고로 유지하며 자동 슬롯 생성하지 않는다(슬롯 생성 기준=portfolio-hub 유니버스, OQ-3). +- FR-4: `trex-core verify` 명령(별도 명령, read-중심, OQ-2)은 C로 차단된 슬롯을 재대조해, 일치하면 warning을 해제하고 불일치면 사유와 함께 해제를 거부한다(강제 해제 없음). 슬롯 수량을 변경하지 않는다(운영자가 portfolio-hub CLI로 원장을 이미 정정). +- FR-5: reconcile-warning 차단 상태는 **pause_store와 동형의 별도 durable store**(slot_id/pid 키)에 저장한다 — SlotState enum·전이표·slots RPC wire 계약을 변경하지 않는다(OQ-1). +- FR-6: 차단/해제 전이는 식별 가능한 로그(슬롯·심볼·원인 케이스·수량 before/after·actor)를 남기고, 고영향 불일치(예: A phantom)는 기존 알람 채널(dcy-033/trex.alerts)로 통지한다. +- FR-7(교차 서비스 의존): cold-start cost basis seed를 위해 **portfolio-hub에 "현재 보유 평단(WAC) read" 엔드포인트를 신규 추가**하고(별도 portfolio-hub REQ), trex-core sync/onboarding가 이를 읽어 슬롯 평단을 seed한다(OQ-4). 현행 portfolio-hub는 미매도 보유분 평단 read가 없음(`pnl/realized` 매도행 `cost_basis_per_unit`만 노출). + +## 비기능 요구사항 +성능, 운영성, 일관성, 자동화 안정성 등 기능 외 요구사항을 적는다. + +- NFR-1: 차단형 warning 상태는 **durable**(재시작 후에도 유지)해야 한다 — in-memory overlay로 두지 않는다. +- NFR-2: 단기 인스턴스(M1/M2 라이브)의 정상(일치) 운영에서 신규 차단이 오발동하지 않아야 한다(회귀 0). 차단은 실제 불일치에서만 발생한다. +- NFR-3: reconcile/차단은 무음 자동 정정·자동 청산을 하지 않는다(issue #15 기조). 정합 행위는 운영자 명령으로만 일어난다. +- NFR-4: 가능하면 wire 계약(slots RPC 스키마) 변경을 피하거나 최소화한다. 차단 상태 노출이 필요하면 영향 범위를 design에서 명시한다. + +## 범위 경계 +이번 반복에서 반드시 포함할 범위와 명시적으로 제외할 범위를 구분한다. + +- In Scope + - 차단형 reconcile(B/C → 슬롯 차단), 차단형 warning durable 상태(별도 store, OQ-1), pause∨warning 차단 게이트. + - `trex-core sync` / `trex-core verify` 운영자 명령(별도 2명령, OQ-2) + cold-start onboarding 경로. + - 차단/해제 로깅 + 고영향 알람 연계, cold-start 운영 런북. + - (교차 서비스 의존, FR-7) portfolio-hub "현재 보유 평단(WAC) read" 엔드포인트 신규 추가 — cold-start cost basis seed용. portfolio-hub-dev 별도 REQ로 발주(trex-core REQ의 선행 의존). +- Out of Scope + - 중장기 **전략 모듈 자체**(매매 로직)와 중장기 인스턴스 TOML 프로파일 신설 — 별개 단위(dcy-027 기반 후속). + - 멀티데이 PnL 리포트 — portfolio-hub 실현 PnL API(REQ-040/041)로 별도 처리(보드 M3 항목). + - 과거 0/불일치로 기록된 원장·슬롯의 소급 일괄 정정. + - 실시간(틱 단위) 슬롯↔계좌 동기화 — 본 건은 boot/일일 reconcile + 운영자 명령 시점 동기화에 한정. + +# 6. 리스크/가정 목록 +불확실성과 전제 조건을 분리해서 적는다. 리스크는 영향과 완화 방안을, 가정은 현재 판단의 전제를 기록한다. + +## 리스크 +- R-1 (Medium, OQ-3로 완화됨): B 동기화 방향 오판 — 운영자 직접 매매로 생긴 phantom 포지션을 `sync`가 무분별하게 슬롯에 편입하면 중장기 전략이 의도치 않은 포지션을 관리·매도하게 된다. + - 완화 방안(확정): `sync`는 **portfolio-hub 유니버스에 있어 슬롯이 생성된 종목만** 대상으로 하고 슬롯 qty를 브로커로 수렴한다. 브로커-only(portfolio-hub 부재, 슬롯 없음) 포지션은 sync가 건드리지 않고 unmanaged 경고로 유지 → phantom 자동 편입 경로가 구조적으로 차단된다(OQ-3). 추가로 sync는 종목/슬롯 명시 대상으로 한정(전역 일괄 금지), 적용 전 before/after 출력. +- R-2 (Medium): 차단 게이트 확장이 단기 인스턴스에 회귀를 줄 수 있다(정상 상태인데 차단). + - 완화 방안: 차단은 실제 수량 불일치에서만 발생하도록 조건을 좁히고, 단기 인스턴스 시나리오(당일 슬롯·일치) 회귀 테스트를 design/verification에 포함. +- R-3 (Medium): 차단형 warning 저장 위치 선택(슬롯 필드 vs 별도 store vs 신규 SlotState)이 slots RPC wire 계약·전이표(`state.py`)에 파급될 수 있다. + - 완화 방안: pause(별도 store, 비침습)를 선례로 우선 검토. wire 영향 최소 안을 design에서 비교. +- R-4 (Medium): cold-start 시 평단(cost basis)을 어디서 가져올지 — 브로커 잔고는 수량은 주지만 중장기 전략이 쓸 평단/취득가를 슬롯에 seed해야 한다. + - 완화 방안: portfolio-hub 단가/평단 read 가용성 확인(OQ). 부재 시 폴백(브로커 평균가/원장 재구성) 정책 design. + +## 가정 +아직 확정되지 않았지만 현재 문서 작성의 기반이 되는 전제를 적는다. + +- A-1: 중장기 인스턴스는 기존 multi-instance 토대(dcy-009/BAT-013, instance_key별 큐/락/TOML)를 그대로 재사용한다. 본 건은 그 위의 cold-start 동기화 능력이다. +- A-2: 브로커 `get_balance()`가 cold-start 시점에 실보유 수량을 신뢰 가능하게 반환한다(ground truth). +- A-3: portfolio-hub에 중장기 종목과 ledger(잔고)가 선행 등록되어 있다(자산 리스트가 슬롯 유니버스의 기준). +- A-4: pause가 durable 차단의 검증된 선례이므로, reconcile-warning도 유사한 durable·비침습 저장 방식을 취할 수 있다. + +## 오픈 질문 (전부 Answered — 사장님 2026-06-25 confirm-discovery) +모든 OQ가 confirm-discovery에서 확정되었다. 결정 결과는 아래에 resolved 기록으로 남기고 본문(FR-3~7, 변경 1~4, R-1)에 반영했다. + +- OQ-1 (Answered): 차단형 warning 상태 저장 위치 → **(b) pause_store와 동형의 별도 durable store**(slot_id/pid 키). SlotState enum·전이표·slots RPC wire 계약 불변(blast radius 최소). 반영: FR-5. +- OQ-2 (Answered): 명령 표면 → **별도 2명령 `sync`/`verify`**(단일 --apply 통합 안 채택 안 함 — --apply 오타 시 의도치 않은 슬롯 변경 위험). sync=쓰기(슬롯 qty←브로커), verify=read-중심 재대조. 반영: FR-3/FR-4. +- OQ-3 (Answered): B 동기화 방향 → **브로커 보유 정본 유지, 슬롯 보유량을 브로커에 맞춰 갱신.** 슬롯이 있는 종목(portfolio-hub 유니버스 기반)만 sync 대상. 브로커-only(portfolio-hub 부재)는 슬롯 자동생성 안 하고 unmanaged 경고 유지(슬롯 생성 기준=portfolio-hub). 반영: FR-3, R-1. +- OQ-4 (Answered): cold-start 평단 seed → **portfolio-hub에 "현재 보유 평단(WAC) read" 엔드포인트 신규 추가** 후 trex-core가 읽어 seed. 교차 서비스 의존(별도 portfolio-hub REQ). 근거: 현행 portfolio-hub는 WAC를 내부 계산하나(`app/domain/pnl.py:calculate_realized_pnl` running_wac) 외부 노출은 `GET /v1/portfolios/{id}/pnl/realized`(REQ-040) 매도행 `cost_basis_per_unit`뿐 — 미매도 보유분 현재 평단 read 부재(팀장 확인 2026-06-25). 반영: FR-7. 브로커 평균가 단독 의존은 dcy-032(평균가 0/None 케이스)로 위험. +- OQ-5 (Answered): C(원장↔슬롯) 대조 정의 → **현행 브로커 경유 2-대조 재사용**(브로커=단일 정본 일관). reconcile_positions(원장↔브로커)+reconcile_core_holdings(슬롯↔브로커) 양쪽을 브로커 기준으로 보고 불일치에 차단만 입힌다. B sync로 슬롯=브로커가 되면 원장↔슬롯 불일치=원장↔브로커 불일치로 환원되어 verify는 reconcile_positions 재실행으로 판정 가능. 반영: 변경 1, FR-4. + +# 7. 초기 성공 기준 +이 변경이 성공했다고 판단할 기준을 측정 가능하게 정의한다. 가능하면 데이터 출처까지 연결한다. + +- S-1: 보유 종목이 실계좌에 있고 slot DB가 빈 cold-start 입력에서, 데몬 기동 후 불일치 슬롯이 **차단 상태**가 되고 전략 intent가 발행되지 않는다. +- S-2: `trex-core sync` 후 슬롯 수량이 브로커 잔고와 일치하고 해당 슬롯의 reconcile-warning이 해제되어 전략이 재개된다. +- S-3: C로 차단된 슬롯은 원장 정정 전 `verify`가 해제를 거부하고, 원장 정정 후 `verify`가 해제한다(강제 해제 경로 없음). +- S-4: 단기 인스턴스 정상(일치) 시나리오에서 신규 차단이 발생하지 않는다(회귀 0). + +## 측정 방식 및 데이터 출처 +각 성공 기준을 어떻게 측정할지와 어떤 데이터나 문서를 근거로 쓸지 적는다. + +- S-1 측정 방식: cold-start 픽스처(빈 slot DB + 브로커 보유 + portfolio-hub 자산) 통합 테스트로 슬롯 차단 상태·intent 미발행 검증 / 데이터 출처: 신규 테스트. +- S-2 측정 방식: sync 명령 테스트로 슬롯 수량=브로커, warning 해제, 전략 게이트 통과 검증 / 데이터 출처: 슬롯 repo + RPC 응답. +- S-3 측정 방식: 원장 불일치 상태에서 verify 거부 → 정정 후 verify 해제 시나리오 테스트 / 데이터 출처: 신규 테스트 + 로그. +- S-4 측정 방식: 기존 단기 reconcile/실행 테스트 스위트 회귀 / 데이터 출처: 테스트 결과. + +# 8. REQ로 넘기기 전 확인 체크 +REQ 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지 확인한다. 미완료 항목은 후속 결정이 필요함을 뜻한다. + +- [x] 범위(In Scope/Out of Scope) 확정 + - 기준: 전략 모듈/인스턴스 프로파일/멀티데이 PnL을 본 건에서 제외하는 데 사장님 합의 — M3 framing(메모리 m3-goal-midlong-core-instance)상 전략 모듈은 별개 단위, 멀티데이 PnL은 portfolio-hub REQ-040/041로 분리 확정(사장님 2026-06-25). portfolio-hub 평단 read만 교차 의존으로 In Scope 편입. +- [x] 성공 지표의 측정 방식/데이터 출처 확정 + - 기준: S-1~S-4 측정안에 사장님/팀장 이견 없음 +- [x] High 영향 리스크 우선순위 및 해소 책임자 지정 + - 기준: R-1(B 동기화 방향)은 OQ-3 확정(슬롯 qty←브로커, 브로커-only 자동편입 금지)으로 Medium으로 완화. 해소 책임=trex-core-dev(sync 구현 시 대상 한정·before/after 출력). +- [x] 모든 오픈 질문(OQ) `Open` 상태 없음 확인 + - 기준: OQ-1~5 전부 Answered(사장님 2026-06-25). Open 0건. +- [x] Freeze 확정 담당자(CONFIRMED_BY) 지정 + - 기준: 팀장(Claude)이 CONFIRMED_BY로 기록. + +# 9. 파일 처리 결과 +이 Discovery 문서 생성/갱신 결과와 참조 문서를 기록한다. 이후 추적과 리뷰 시 근거로 사용한다. + +- 처리 결과: 생성 +- 생성 경로: docs/discovery/dcy-034_20260625_slot-account-blocking-reconcile-sync-coldstart.md +- 참조 문서: + - docs/discovery/dcy-020_20260610_asset-centric-slot-model.md (자산중심 슬롯·유니버스 reconcile) + - docs/discovery/dcy-027_20260612_long-term-strategy-slot-operation.md (중장기 슬롯 운영·운영 프로파일, cold-start Out-of-Scope 이월원) + - docs/discovery/dcy-028_20260615_slot-strategy-state-store.md (slot strategy-state — onboarding 시 seed 대상) + - trex_core/application/reconciliation.py, trex_core/application/snapshot_scheduler.py, trex_core/runtime/cli.py, trex_core/domain/slot/state.py (현재 구현 근거) + - GitHub 보드 #7 "슬롯↔실계좌 차단형 reconcile + sync/verify" 항목(설계방향 본문) + +# 10. 사용자 결정 필요 항목 요약 +사용자나 승인자가 결정해야 하는 항목만 모아 정리한다. 결정, 확인, 데이터 요청을 구분해서 적는다. + +## DECIDE (전부 결정됨 — 사장님 2026-06-25) +- (확정) OQ-3 B 동기화 방향 → 브로커 정본 유지·슬롯 qty를 브로커로 수렴. 브로커-only(portfolio-hub 부재) 자동 슬롯 편입 금지(unmanaged 경고 유지). +- (확정) 범위 경계 → 중장기 전략 모듈·인스턴스 TOML 프로파일·멀티데이 PnL은 본 건에서 제외(별개 단위). portfolio-hub 평단 read는 교차 의존으로 In Scope. +- (확정) OQ-1 warning 저장=별도 durable store / OQ-2 명령=별도 2명령 sync,verify / OQ-5 C대조=현행 브로커 경유 2-대조 재사용. + +## CONFIRM (확정) +- 본 Discovery 핵심 방향(차단형 reconcile + sync/verify + durable warning)을 M3 cold-start 단위로 채택 — 사장님 2026-06-25. +- pause∨warning 차단 게이트로 전략 차단 일원화 — 채택. + +## DATA (확보됨) +- (OQ-4 확인 완료) portfolio-hub는 미매도 보유분 현재 평단 read 부재 → "현재 보유 평단(WAC) read" 신규 추가로 결정(FR-7, 교차 서비스 의존 REQ). + +# 11. Discovery Freeze +REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다. + +## 섹션 참조 +- 범위: [# 5. 요구사항 목록 > 범위 경계](#5-요구사항-목록) +- 리스크/오픈 질문: [# 6. 리스크/가정 목록](#6-리스크가정-목록) +- 성공 기준: [# 7. 초기 성공 기준](#7-초기-성공-기준) +- 인계 전 확인: [# 8. REQ로 넘기기 전 확인 체크](#8-req로-넘기기-전-확인-체크) +- 사용자 결정 필요: [# 10. 사용자 결정 필요 항목 요약](#10-사용자-결정-필요-항목-요약) + +## Freeze 플래그 +- Handoff Decision: REQ Drafting 진행 가능 +- Handoff Rationale: 핵심 방향(차단형 reconcile + sync/verify + durable warning) 채택, OQ-1~5 전부 Answered(사장님 2026-06-25), High 리스크(R-1) OQ-3 확정으로 Medium 완화. portfolio-hub 평단 read(FR-7)는 교차 서비스 선행 의존으로 명시 — draft-req 시 trex-core REQ와 portfolio-hub 의존 REQ를 함께 분해. Open OQ 0건 → 인계 가능. +- Ready for REQ Drafting: true +- Confirmed By: 팀장(Claude) +- Confirmed At (KST): 2026-06-25 (KST) + +# 12. 작성 가이드 +- 이 문서는 dcy 템플릿 기반으로 작성되었으며, Open Questions는 가정으로 대체하지 않고 그대로 유지한다. +- confirm-discovery 시 OQ-1~5의 처리(Answered/Deferred)와 Freeze 플래그를 갱신한다. diff --git a/docs/discovery/index.md b/docs/discovery/index.md index 1547ae6..d89f9ca 100644 --- a/docs/discovery/index.md +++ b/docs/discovery/index.md @@ -39,3 +39,4 @@ | dcy-031_20260619_event-publisher-connection-reliability | 20260619 | 이벤트 발행 연결 신뢰성 — idle heartbeat 사망 후 첫 발행 유실 + DLQ 가시성 (OPS-005) | [Discovery](./dcy-031_20260619_event-publisher-connection-reliability.md) | confirmed | | dcy-032_20260621_fill-missing-price-cost-basis-backfill | 20260621 | 체결가 누락(브로커 평균가 0/None) → 슬롯 평단·원장 cost basis 0 오염(무경고·영구) → 지정가 백필 + 로깅 + 알람 검토 | [Discovery](./dcy-032_20260621_fill-missing-price-cost-basis-backfill.md) | confirmed | | dcy-033_20260621_suite-alarm-delivery-notifier | 20260621 | 제품군 알람 전달 체계 — 모듈 발신 + 중앙 notifier(trex-notifier) → 텔레그램(P1 아웃바운드). envelope 계약+전송(trex.alerts AMQP 확정)+등급/상관억제/하트비트 | [Discovery](./dcy-033_20260621_suite-alarm-delivery-notifier.md) | confirmed | +| dcy-034_20260625_slot-account-blocking-reconcile-sync-coldstart | 20260625 | 슬롯↔실계좌 차단형 reconcile + sync/verify 명령 — 중장기 cold-start(기존 보유 onboarding). B/C 불일치→슬롯 차단(durable warning) + pause∨warning 게이트 + 운영자 sync/verify (M3) | [Discovery](./dcy-034_20260625_slot-account-blocking-reconcile-sync-coldstart.md) | confirmed |