# 0. 문서 상태 이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다. - 상태: confirmed - 문서 ID: dcy-011_20260608_buy-intent-portfolio-id-required-symbol-resolve - 이슈명: buy intent — portfolio_id를 필수 키로, symbol은 universe(SnapshotStore)에서 resolve (+ portfolio_id 누락 체결의 ledger silent skip 가시화) - 작성 시각(KST): 2026-06-08 11:08 KST - 마지막 갱신 시각(KST): 2026-06-08 14:10 KST - 대체됨: 없음 - 후속 Discovery 참조: 없음 - 생성된 REQ 참조: REQ-007(change-req CHG-20260608-01), REQ-018(change-req CHG-20260608-01), REQ-021(change-req CHG-20260608-01), REQ-055(신규) — delivery: BAT-015 # 1. 계획 상태 요약 현재 Discovery가 어떤 배경에서 작성되고 있는지, 연계 문서가 있는지, 지금 시점의 해석이 무엇인지 짧게 요약한다. - 연계 문서 현황: - 관련 점수 파일: 미생성 - 관련 TODO/메모: GitHub issue #6, issue #11 (fourblocks2020/trex-core) - 해석: - 매수(buy) intent 계약이 `symbol` 필수 / `portfolio_id` optional 로 되어 있어, 정식 식별자(asset_id=portfolio_id) 기반 원장 귀속·safety 보호 범위와 정합이 깨지는 문제를 정식 SDLC 주기로 착수한다. - 이번 Discovery에서는 buy intent payload 계약을 `portfolio_id` 필수 + 서버측 `symbol` resolve 로 전환하는 범위/리스크/하위호환 경계를 판정한다. 더불어 issue #11 에서 관측된 동일 근본 원인(portfolio_id 없는 슬롯 체결이 ledger 에 silent skip 되어 데이터 누락·운영 가시성 부재)을 함께 흡수해, 예방(admission 거부)과 탐지/가시화(skip 영구 기록·경고)를 한 주기로 다룬다. 이미 Implemented·released(REL-003) 된 계약 변경이므로 거버넌스는 OQ-3 결정에 따라 기존 REQ(REQ-007/021/018) `change-req` 를 우선하고, 기존 REQ 가 다루지 않는 신규 기능(운영 점검 쿼리 등)만 신규 REQ 로 생성한다. # 2. 요구사항 판정 결과 이번 요청이 기존 요구사항과 비교해 신규인지, 유사한지, 중복인지 판단하고 그 근거를 남긴다. - 판정: 신규 - 근거 - 기존 Discovery(dcy-001~dcy-010) 중 buy intent 식별자 계약(portfolio_id 필수화 / symbol resolve)을 다룬 문서는 없다. dcy-004(원장 연동)·dcy-005(snapshot read)·dcy-007/dcy-008(safety)은 portfolio_id 를 전제하지만 buy 제출 계약 자체를 재정의하지 않았다. - 변경이 이미 Implemented·released 된 buy intent 인터페이스 계약(REQ-007 제출, REQ-021/022 메시지 계약, REL-003 동작)에 닿아 핵심 식별자 의미를 바꾸므로, 기존 Discovery 미세 조정이 아니라 독립 주기로 추적하는 것이 명확하다. # 3. 문제점의 요약 문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다. Discovery의 핵심 맥락을 가장 먼저 이해할 수 있어야 한다. - 현재 상태 - `trex_core/application/intents.py` 의 `BuyIntent` dataclass 는 `symbol: str`(필수, intents.py:50)이고 `portfolio_id: Optional[str] = None`(optional, intents.py:56) 이다. `_admit_buy`(intents.py:141~)는 `find_idle_slot` 으로 idle 슬롯을 자동 배정한 뒤 `symbol`/`portfolio_id` 를 슬롯에 그대로 기록한다 — symbol 은 필수로 들어오고 portfolio_id 는 없을 수 있다. - `trex_core/application/messaging_handlers.py` buy 핸들러(73~88행)는 `symbol=str(body.get("symbol") or "")`, `portfolio_id=_opt_str(body.get("portfolio_id"))` 로 파싱해 현 계약(symbol 필수 추정, portfolio_id optional)을 그대로 반영한다. - universe→symbol resolve 의 기반은 이미 존재한다: `trex_core/application/portfolio.py` 의 `SnapshotStore.get(portfolio_id)`(portfolio.py:130)가 `SnapshotAsset{portfolio_id, symbol, ...}` 를 반환한다. 즉 portfolio_id→symbol 조회 경로는 구현돼 있으나 admission 에서 사용하지 않는다. - `docs/interface-contract.md` 의 buy payload 계약(79~86행)은 `"symbol": str` 을 기본 필드로, `"portfolio_id": str?` 를 optional 로 명시한다. 즉 문서 계약도 현 코드와 일치한다. - (issue #11) `trex_core/application/execution.py` 의 `_record_ledger`(execution.py:153~164)는 `slot.portfolio_id` 가 falsy 면 `r.ledger_skipped += 1` 후 즉시 반환한다. 슬롯은 holding/closed 로 정상 전이되지만 `ledger_outbox` 에 행이 생기지 않아 portfolio-hub 에 거래가 전혀 기록되지 않는다. 스킵은 `ExecutionResult` 의 메모리 카운터로만 남고 로그·DB 어디에도 영구화되지 않아 운영자가 누락을 인지하기 어렵다(무성 실패). 실관측: 슬롯 `6e75f3ec-...`(symbol 316140)는 buy/sell 모두 체결돼 closed 됐으나 portfolio_id=None 으로 outbox 0건. - baseline 문서(`docs/project-structure.md`, `docs/runtime-flows.md`)는 존재하며 최신이다. buy admission 은 기존 runtime flow 에 포함돼 있고, 이번 변경은 그 흐름에 symbol resolve 단계를 추가한다. - 기대 상태 - buy intent 는 `portfolio_id`(=asset_id, 정식 식별자) 를 필수로 요구하고, `symbol` 은 admission 시 서버가 `SnapshotStore` universe 에서 resolve 해 슬롯에 기록한다. - portfolio_id 가 universe 에 없으면 명확한 reject(`unknown_portfolio`)로 처리되어, 원장 귀속 불가·safety 보호 누락 슬롯이 생기지 않는다. - (issue #11) 만에 하나 portfolio_id/execution_id 누락으로 ledger skip 이 발생하더라도 무성으로 사라지지 않고 WARN/ERROR 로그·메트릭으로 노출되며, closed 슬롯 vs outbox 대조 점검 쿼리로 운영자가 누락을 탐지·집계할 수 있다. - 이해관계자 - 문서 작성자(AI agent) — Discovery/REQ/Batch 산출물 작성 - 리뷰어/승인자 — 계약 변경 및 하위호환 영향 승인 - 운영 담당자 — released(REL-003) buy 계약 변경에 따른 전략 모듈/배포 영향 관리 - 전략 모듈 개발자 — buy intent 제출 호출부(payload) 변경 대상 - 제약사항 - 이미 released(REL-003) 된 인터페이스 계약 변경이므로 ad-hoc 수정이 아니라 정식 SDLC(change-req 또는 신규 Discovery) 경유가 필요하다. - 매수 시점 universe(`SnapshotStore`)에 해당 portfolio_id 가 존재한다는 보장이 거래일/refresh 주기에 의존한다 — resolve 실패 처리 정책이 필요하다. ## 주요 사용자 시나리오 사용자 또는 운영자가 실제로 어떤 상황에서 이 변경을 필요로 하는지 대표 시나리오를 적는다. - 전략 모듈이 universe snapshot(`PortfolioItem{portfolio_id, symbol, ...}`)에서 매수 대상을 고른 뒤, buy intent 에 `portfolio_id` 만 실어 제출하면 core 가 symbol 을 universe 에서 resolve 해 슬롯·KIS 주문에 사용한다. - 운영자가 특정 portfolio 를 pause/kill-switch 로 보호한 상태에서, portfolio_id 필수화 덕분에 모든 buy 슬롯이 보호 범위에 정확히 귀속된다. - portfolio_id 가 당일 universe 에 없을 때(상장폐지·종목 제외 등) core 가 `unknown_portfolio` 로 매수를 거부해, 귀속 불가능한 체결이 원장에 들어가지 않는다. # 4. 이번에 정의할 변경 이번 Discovery에서 다루는 핵심 변경 항목을 목록으로 적는다. 기능, 구조, 규칙 변경을 함께 포함해도 된다. - buy intent payload 계약을 `portfolio_id` 필수로 전환하고, `symbol` 은 클라이언트 payload 에서 제거해 서버가 universe 에서 resolve 하는 값으로만 사용한다(OQ-1·OQ-2 결정 — override/fallback·레거시 호환 없음). - admission(`_admit_buy`) 시 `SnapshotStore` 에서 `portfolio_id → symbol` 을 resolve 해 슬롯에 기록하고, universe 에 portfolio_id 부재 시 reject(`unknown_portfolio`) 처리한다. - (issue #11 제안 ②) `_record_ledger` 의 ledger skip 을 무성에서 가시화로 전환한다 — skip 발생 시 WARN/ERROR 로그·메트릭 노출(OQ-4 결정 — outbox 마커 행은 도입하지 않음; defense-in-depth: portfolio_id 필수화 이후에도 잔존할 수 있는 누락을 탐지 가능하게). - (issue #11 제안 ③) closed 슬롯 vs `ledger_outbox` 대조 운영 점검 쿼리/알람을 추가해 ledger 누락 슬롯을 주기·온디맨드로 탐지한다. - 인터페이스 계약 문서(`docs/interface-contract.md`)와 buy admission runtime flow 기술을 새 계약에 맞춰 갱신한다. ## 영향 범위 변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다. - 코드 영향: - `trex_core/application/intents.py` — `BuyIntent`(portfolio_id 필수화, symbol 은 클라이언트 입력에서 제거하고 서버 resolve 로 채움), `_admit_buy`(symbol resolve + unknown_portfolio reject) - `trex_core/application/messaging_handlers.py` — buy 핸들러 payload 파싱/검증(portfolio_id 필수 검사) - `trex_core/application/portfolio.py` — `SnapshotStore` portfolio_id→symbol 조회 활용(기존 `get` 재사용, 신규 메서드 필요 시 추가) - (issue #11) `trex_core/application/execution.py` — `_record_ledger` skip 지점 가시화(로그/메트릭). OQ-4 결정으로 `ledger_outbox` 스키마/`LedgerWriter` 변경은 없음(마커 행 미도입) - (issue #11) 운영 점검 쿼리(FR-5) — `trex_core/adapters/persistence/sql/` 의 slots↔`ledger_outbox` anti-join 점검 SQL 추가(읽기 전용, 스키마 변경 없음) - 문서 영향: - `docs/interface-contract.md` — buy payload 계약(portfolio_id 필수, symbol 필드 제거·서버 resolve) 갱신 - `docs/runtime-flows.md` — buy admission 흐름에 symbol resolve 단계 + ledger skip 가시화 반영 - 운영 영향: - released(REL-003) buy 계약 변경 → 전략 모듈 호출부 마이그레이션 안내 필요 - 거래일 universe refresh 와 매수 시점 정합 운영 점검 필요 - (issue #11) ledger skip 가시화 + 운영 점검 쿼리로 누락을 운영자가 탐지·집계 가능 → 회계 정합(P&L/포지션) 리스크 완화 # 5. 요구사항 목록 실제로 구현과 검증으로 이어질 요구사항을 기능/비기능으로 나누어 정리하고, 범위 경계를 명확히 적는다. ## 기능 요구사항 - FR-1: buy intent payload 는 `portfolio_id` 를 필수 키로 요구하고, 누락 시 admission 단계에서 `portfolio_id_required` 로 거부한다. (issue #11 제안 ① — 근본 원인 제거) - FR-2: admission 시 `SnapshotStore` universe 에서 `portfolio_id → symbol` 을 resolve 해 슬롯(및 후속 KIS 주문)에 사용할 symbol 로 기록한다. buy payload 는 클라이언트 symbol 을 받지 않는다(OQ-1·OQ-2 결정 — 완전 서버 resolve). - FR-3: universe 에 해당 `portfolio_id` 가 없으면 `unknown_portfolio` 로 매수를 거부한다. (OQ-1 결정: 단일 reject 정책 — 클라이언트 symbol 로의 override fallback 은 두지 않는다.) - FR-4: (issue #11 제안 ②) `_record_ledger` 의 ledger skip 발생 시 무성으로 반환하지 않고 WARN/ERROR 로그 + 메트릭으로 노출한다(OQ-4 결정 — `ledger_outbox` 마커 행은 도입하지 않고 영구 탐지는 FR-5 점검 쿼리에 위임). portfolio_id 누락·execution_id 누락 두 skip 경로 모두 포함한다. - FR-5: (issue #11 제안 ③) closed 슬롯 중 대응 `ledger_outbox` 행이 없는 케이스를 anti-join 으로 식별하는 운영 점검 쿼리/알람을 제공한다(slots 테이블이 durable 하므로 outbox 마커 없이도 영구 탐지 성립 — OQ-4 영구성 위임). 주기 실행 또는 온디맨드 점검으로 누락을 운영자가 탐지·집계할 수 있어야 한다. - FR-6: `docs/interface-contract.md` 와 `docs/runtime-flows.md` 를 새 buy 계약(portfolio_id 필수 + symbol resolve) 및 ledger skip 가시화/운영 점검에 맞춰 갱신한다. ## 비기능 요구사항 성능, 운영성, 일관성, 자동화 안정성 등 기능 외 요구사항을 적는다. - NFR-1: 원장 정합성 — 모든 매수 슬롯이 `portfolio_id`(asset_id)에 귀속되어 outbox correlation_id(`asset_id:order_id:execution_id`) 및 portfolio-hub ledger 기록이 누락 없이 성립해야 한다. - NFR-2: safety 일관성 — pause(REQ-032)·kill-switch(dcy-008)·포지션 정합(REQ-031)·snapshot masking 의 portfolio_id 기준 보호 범위에서 누락되는 buy 슬롯이 없어야 한다. - NFR-3: 즉시 cutover 정합 — 하위호환을 두지 않으므로(OQ-2 결정), 기존 symbol 기반 호출부(전략 모듈/테스트)를 모두 식별해 portfolio_id 기반으로 동시 전환하고, 전환 누락 시 명확히 실패(거부)하도록 보장한다. - NFR-4: (issue #11) 운영 가시성 — ledger skip 같은 회계 누락 이벤트는 메모리 카운터에만 남지 않고 로그/메트릭/DB 중 최소 하나로 영구 관측 가능해야 한다(무성 실패 금지). ## 범위 경계 이번 반복에서 반드시 포함할 범위와 명시적으로 제외할 범위를 구분한다. - In Scope - buy intent 계약의 portfolio_id 필수화 및 admission 시 symbol resolve - universe 부재 시 reject 처리 및 인터페이스/런타임 문서 갱신 - (issue #11 제안 ②) ledger skip 의 가시화(로그/메트릭) — defense-in-depth - (issue #11 제안 ③) closed 슬롯 vs ledger_outbox 대조 운영 점검 쿼리/알람 (OQ-5 결정: 포함) - Out of Scope - sell intent 계약 변경(이미 portfolio_id/slot 기반으로 동작) - universe refresh 주기/스케줄 자체의 재설계 - symbol-only 레거시 호출 한시 허용(호환 창구) — OQ-2 결정으로 미지원(즉시 hard cutover) # 6. 리스크/가정 목록 불확실성과 전제 조건을 분리해서 적는다. 리스크는 영향과 완화 방안을, 가정은 현재 판단의 전제를 기록한다. ## 리스크 - R-1 (High): released(REL-003) buy 계약을 깨는 변경이라 기존 symbol 기반 전략 모듈/테스트 호출이 즉시 실패할 수 있다. - 완화 방안: (OQ-2 결정 — 즉시 cutover) 호환 창구는 두지 않으므로, 전략 모듈·테스트 등 모든 호출부를 사전 식별해 동시에 portfolio_id 기반으로 전환하고, change-req 로 REQ-007/021(및 #11 관련 REQ-018) 변경 이력을 남긴다. - R-2 (Medium): 매수 시점 universe(`SnapshotStore`)에 portfolio_id 가 없으면(refresh 타이밍·종목 제외) 정상 매수가 `unknown_portfolio` 로 거부될 수 있다. - 완화 방안: resolve 실패 시 `unknown_portfolio` 단일 reject 정책(OQ-1)을 적용하고, 거부 시 진단 가능한 reason/로그를 남긴다. 거래일 universe refresh 와 매수 시점 정합은 운영 점검 대상으로 둔다. - R-3 (Low, OQ-1·OQ-2 결정으로 해소): symbol override/fallback·레거시 호환을 모두 두지 않으므로, override 값과 resolve 값의 불일치 모호성이 발생하지 않는다. - 완화 방안: symbol 은 클라이언트 입력 없이 항상 서버가 universe 에서 resolve 한 값만 사용한다. - R-4 (Medium, issue #11): portfolio_id 필수화 이전(또는 마이그레이션 창구 중)에 발생한 누락 체결은 이미 ledger_outbox 에 행이 없어 탐지/대응이 늦어질 수 있다. - 완화 방안: skip 가시화(FR-4)와 운영 점검 쿼리(FR-5)로 신규/잔존 누락을 탐지·집계한다. (과거 누락분의 데이터 복구는 #11 의 명시 요구가 아니므로 본 주기 범위 밖이며, 필요 시 별도 운영 이슈로 다룬다.) ## 가정 아직 확정되지 않았지만 현재 문서 작성의 기반이 되는 전제를 적는다. - A-1: `SnapshotStore` 가 admission 시점에 당일 universe 를 보유하며 `get(portfolio_id)` 로 symbol 을 신뢰성 있게 조회할 수 있다. - A-2: 전략 모듈은 이미 universe snapshot 에서 portfolio_id 를 받아 매수 결정을 내리므로, payload 에서 symbol 을 빼고 portfolio_id 를 싣는 변경이 전략 측 로직에 큰 부담이 아니다. - A-3: 이번 변경은 buy 경로에 한정되며 sell/kill-switch/pause 등 portfolio_id 기반 기능은 그대로 호환된다. - A-4: (issue #11) `_record_ledger` 의 execution_id 누락 skip 경로도 동일한 가시화 처리 대상이며, ledger skip 가시화는 슬롯 전이 동작 자체를 바꾸지 않고 관측만 추가한다. ## 오픈 질문 답을 아직 모르는 항목을 적는다. 추정으로 덮지 말고 REQ 초안 작성 이전에 확인할 질문으로 남긴다. - OQ-1: universe 에 portfolio_id 가 없을 때 처리 정책 — `reject(unknown_portfolio)` 단일 정책인가, symbol override fallback 을 허용하는가? - 상태: Answered (2026-06-08, 사용자 결정 — `reject(unknown_portfolio)` 단일 정책) - 결정: universe 부재 시 항상 `unknown_portfolio` 로 거부한다. 클라이언트가 보낸 symbol 로의 fallback 은 두지 않는다(원장 정합·식별자 유일성 우선). - 반영 위치: FR-3, R-3(override fallback 경로 제거로 불일치 위험 해소) - OQ-2: 하위호환 — 기존 symbol 기반 호출(전략 모듈/테스트)을 한시 허용하는 마이그레이션 창구를 둘지, 즉시 hard cutover 할지? - 상태: Answered (2026-06-08, 사용자 결정 — 하위호환 없음 / 즉시 hard cutover) - 결정: 호환 창구를 두지 않는다. symbol 은 payload 에서 제거하고, 모든 호출부를 portfolio_id 기반으로 동시 전환한다. 전환 안 된 호출은 `portfolio_id_required` 등으로 명확히 거부된다. - 반영 위치: FR-1/FR-2, NFR-3, 범위 경계 Out of Scope, R-1 - OQ-3: 거버넌스 경로 — 본 변경을 신규 REQ(이 Discovery 기반)로 추적할지, 기존 REQ-007/021/022 의 change-req 로 처리할지? - 상태: Answered (2026-06-08, 사용자 결정 — 가능하면 기존 REQ change-req, 필요 시에만 신규 REQ) - 결정: 기존 Implemented REQ 본문 수정으로 다룰 수 있는 변경은 `change-req` 로 처리한다. change-req 우선 대상 — REQ-007(intent 제출 API: portfolio_id 필수화), REQ-021(메시지 계약 매핑: buy payload 에서 symbol 제거), REQ-018(체결→원장 기록 fill hook: ledger skip 로그/메트릭 가시화). 기존 REQ 가 다루지 않는 신규 기능(closed 슬롯 vs ledger 대조 운영 점검 쿼리/알람, FR-5)은 신규 REQ 로 생성한다. (OQ-4 로 outbox 마커 행을 두지 않으므로 REQ-019 outbox durability 본문 변경은 원칙적으로 불필요 — REQ 정제에서 영향 확인 후 필요 시에만 포함.) - 반영 위치: 4. 거버넌스 해석, R-1 완화 방안, 8. 확인 체크 - OQ-4: (issue #11) ledger skip 영구 가시화 방식 — WARN/ERROR 로그+메트릭만으로 충분한가, `ledger_outbox` 에 `skipped` 상태 행까지 남겨 사후 대조 가능하게 할 것인가? - 상태: Answered (2026-06-08, 사용자 결정 — 로그+메트릭만) - 결정: skip 시 WARN/ERROR 로그 + 메트릭만 노출하고 `ledger_outbox` 마커 행은 도입하지 않는다. 근거 — skip 마커는 정작 outbox 행 식별자(portfolio_id/execution_id)가 비어 있는 기형 행이 되어 전송 큐 의미를 오염시키고 dispatcher 필터링·스키마 마이그레이션을 요구한다. 영구 탐지는 slots↔outbox anti-join(FR-5)으로 충족된다. 또한 OQ-1·OQ-2 로 portfolio_id 누락 skip 주원인이 admission 에서 제거되어 잔여 skip(execution_id None)은 드문 방어 케이스다. - 반영 위치: FR-4, FR-5 - OQ-5: (issue #11 제안 ③) closed 슬롯 vs ledger_outbox 대조 운영 점검 쿼리/알람을 이번 주기에 포함할지, 후속으로 분리할지? - 상태: Answered (2026-06-08, 사용자 결정 — 포함) - 결정: 운영 점검 쿼리/알람을 이번 주기 In Scope 로 포함한다(FR-5 반영). - 반영 위치: FR-5, 범위 경계 In Scope, R-4 완화 방안 # 7. 초기 성공 기준 이 변경이 성공했다고 판단할 기준을 측정 가능하게 정의한다. 가능하면 데이터 출처까지 연결한다. - S-1: portfolio_id 누락 buy intent 가 100% `portfolio_id_required` 로 거부되고, portfolio_id 만으로 제출한 buy 가 symbol resolve 를 거쳐 정상 admit 된다. - S-2: admit 된 모든 매수 슬롯이 portfolio_id(asset_id)에 귀속되어 outbox correlation_id 와 ledger 기록이 누락 없이 생성된다. - S-3: (issue #11) ledger skip 이 발생하는 테스트 시나리오에서 무성 반환이 아니라 WARN/ERROR 로그·메트릭이 100% 남는다. - S-4: (issue #11 제안 ③) 운영 점검 쿼리가 ledger 누락 closed 슬롯을 정확히 식별한다(누락 슬롯 주입 시 검출, 정상 케이스 시 0건). - S-5: 변경된 buy 계약이 `docs/interface-contract.md` 와 `docs/runtime-flows.md` 에 반영되고, 코드(intents.py / messaging_handlers.py / execution.py)와 문서가 일치한다. ## 측정 방식 및 데이터 출처 각 성공 기준을 어떻게 측정할지와 어떤 데이터나 문서를 근거로 쓸지 적는다. - S-1 측정 방식: 단위/통합 테스트(portfolio_id 누락·정상·unknown_portfolio 케이스) 통과 / 데이터 출처: `_admit_buy`, buy 핸들러 테스트 결과 - S-2 측정 방식: 매수 시나리오 후 슬롯·outbox·ledger 귀속 검증 / 데이터 출처: 슬롯 스냅샷, outbox correlation_id, portfolio-hub ledger 레코드 - S-3 측정 방식: portfolio_id/execution_id 누락 강제 주입 테스트에서 로그·메트릭 발생 확인 / 데이터 출처: `_record_ledger` 테스트, 데몬 로그, 메트릭 - S-4 측정 방식: 누락 슬롯 주입 후 운영 점검 쿼리 실행 결과 대조 / 데이터 출처: 점검 쿼리 결과, 슬롯·`ledger_outbox` 테이블 - S-5 측정 방식: 코드-문서 정합 리뷰(diff 대조) / 데이터 출처: `docs/interface-contract.md`, `docs/runtime-flows.md`, 변경 코드 diff # 8. REQ로 넘기기 전 확인 체크 REQ 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지 확인한다. 미완료 항목은 후속 결정이 필요함을 뜻한다. - [x] 범위(In Scope/Out of Scope) 확정 - 기준: 하위호환 정책이 확정됨 (OQ-2 — 즉시 hard cutover, 호환 창구 없음). 호출부 전환 대상의 구체 식별·수정은 REQ/batch 단계 작업으로 넘김(비차단). - [x] 성공 지표의 측정 방식/데이터 출처 확정 - 기준: S-1~S-5 의 테스트/검증 출처가 실제 실행 가능한 형태로 지정됨 - [x] High 영향 리스크 우선순위 및 해소 책임자 지정 - 기준: R-1 의 change-req 대상(REQ-007/021/018, REQ-019 는 조건부) 추적 방식이 OQ-3 으로 확정됨. 해소 실무 책임자 배정은 REQ/batch planning 단계 담당자 할당 문제로 넘김(비차단). - [x] 모든 오픈 질문(OQ) `Open` 상태 없음 확인 - 기준: OQ-1~OQ-5 모두 `Answered`, `Open` 상태 0개 - [x] Freeze 확정 담당자(CONFIRMED_BY) 지정 - 기준: Confirmed By = Justin (사람 승인자 지정 완료) # 9. 파일 처리 결과 이 Discovery 문서 생성/갱신 결과와 참조 문서를 기록한다. 이후 추적과 리뷰 시 근거로 사용한다. - 처리 결과: 생성 - 생성 경로: docs/discovery/dcy-011_20260608_buy-intent-portfolio-id-required-symbol-resolve.md - 참조 문서: - GitHub issue #6 (fourblocks2020/trex-core) — buy intent portfolio_id 필수화 제안 - GitHub issue #11 (fourblocks2020/trex-core) — portfolio_id 없는 거래의 ledger silent skip 버그(동일 근본 원인, 가시화 범위 흡수) - docs/interface-contract.md — 현행 buy payload 계약(symbol 필수 / portfolio_id optional) - docs/discovery/dcy-004_20260604_portfolio-hub-ledger-integration.md — asset_id=portfolio_id 원장 귀속 근거 - trex_core/application/execution.py:153-178 — `_record_ledger` ledger skip 지점(issue #11) # 10. 사용자 결정 필요 항목 요약 사용자나 승인자가 결정해야 하는 항목만 모아 정리한다. 결정, 확인, 데이터 요청을 구분해서 적는다. ## DECIDE - (없음 — 모든 결정 항목이 OQ-1~OQ-5 확정으로 해소됨) > 결정 완료(2026-06-08): OQ-1 universe 부재 처리 = `reject(unknown_portfolio)` 단일 정책 / OQ-2 하위호환 = 없음(즉시 hard cutover) / OQ-3 거버넌스 = 기존 REQ change-req 우선·필요 시 신규 REQ / OQ-4 skip 가시화 = 로그+메트릭만(outbox 마커 없음) / OQ-5 운영 점검 쿼리·알람 = `포함`(FR-5). 모두 결정 항목에서 제외됨. ## CONFIRM - 없음 — 거버넌스 경로는 OQ-3 으로 확정됨(기존 REQ-007/021/018/019 change-req 우선, 신규 기능만 신규 REQ). ## DATA - 없음(차단 항목 기준) — 매수 시점 universe(SnapshotStore)에 대상 portfolio_id 존재 보장 여부는 운영 런타임 데이터로, REQ/delivery 단계에서 계측·확정한다. 부재 케이스는 FR-3 의 `unknown_portfolio` reject 와 R-2 로 이미 처리되므로 Discovery confirm 을 막지 않는다. # 11. Discovery Freeze REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다. ## 섹션 참조 - 범위: [# 5. 요구사항 목록 > 범위 경계](#5-요구사항-목록) - 리스크/오픈 질문: [# 6. 리스크/가정 목록](#6-리스크가정-목록) - 성공 기준: [# 7. 초기 성공 기준](#7-초기-성공-기준) - 인계 전 확인: [# 8. REQ로 넘기기 전 확인 체크](#8-req로-넘기기-전-확인-체크) - 사용자 결정 필요: [# 10. 사용자 결정 필요 항목 요약](#10-사용자-결정-필요-항목-요약) ## Freeze 플래그 - Handoff Decision: 승인 - Handoff Rationale: confirm-discovery 완료. 오픈 질문 OQ-1~OQ-5 모두 Answered (universe 부재=reject 단일 정책 / 하위호환=없음·즉시 cutover / 거버넌스=기존 REQ change-req 우선·필요 시 신규 REQ / skip 가시화=로그+메트릭만 / 운영 점검 쿼리=포함). C 유형 플레이스홀더 0개, 저장소 사실관계 일치 확인. universe portfolio_id 존재 보장(DATA)은 REQ/delivery 단계 계측 항목으로 비차단 분류. REQ 초안 작성 인계 가능. - Ready for REQ Drafting: true - Confirmed By: Justin - Confirmed At (KST): 2026-06-08 12:23 KST