dcy-011 전 주기 delivery. issue #6(buy 식별자 정정) + issue #11(ledger silent skip) 흡수. 거버넌스: 기존 Implemented REQ는 change-req, 신규 기능만 신규 REQ(OQ-3). - REQ-007 (change-req): buy admission portfolio_id 필수화 + SnapshotStore symbol resolve + unknown_portfolio 거부 (hard cutover, OQ-1/OQ-2) - REQ-021 (change-req): buy 메시지 payload symbol 제거 - REQ-018 (change-req): _record_ledger skip 가시화 (WARN + ledger_skipped 카운터) - REQ-055 (신규): closed↔ledger_outbox anti-join 운영 점검 find_ledger_gap_slots 코드: intents.py(BuyIntent portfolio_id 필수 + resolve_symbol 주입 + _admit_buy reject 분기), messaging_handlers.py, runtime/daemon.py(_resolve_symbol 배선), execution.py(skip WARN 로그), adapters/persistence/ops_checks.py(신규 anti-join). 검증: 단위 282 passed/32 skipped, 인프라 게이트(PG+RabbitMQ) 314 passed, ruff clean. BAT-015(standard) release-candidate. srs/index Next ID → REQ-056. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
26 KiB
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_idoptional 로 되어 있어, 정식 식별자(asset_id=portfolio_id) 기반 원장 귀속·safety 보호 범위와 정합이 깨지는 문제를 정식 SDLC 주기로 착수한다. - 이번 Discovery에서는 buy intent payload 계약을
portfolio_id필수 + 서버측symbolresolve 로 전환하는 범위/리스크/하위호환 경계를 판정한다. 더불어 issue #11 에서 관측된 동일 근본 원인(portfolio_id 없는 슬롯 체결이 ledger 에 silent skip 되어 데이터 누락·운영 가시성 부재)을 함께 흡수해, 예방(admission 거부)과 탐지/가시화(skip 영구 기록·경고)를 한 주기로 다룬다. 이미 Implemented·released(REL-003) 된 계약 변경이므로 거버넌스는 OQ-3 결정에 따라 기존 REQ(REQ-007/021/018)change-req를 우선하고, 기존 REQ 가 다루지 않는 신규 기능(운영 점검 쿼리 등)만 신규 REQ 로 생성한다.
- 매수(buy) intent 계약이
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의BuyIntentdataclass 는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.pybuy 핸들러(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 시 서버가SnapshotStoreuniverse 에서 resolve 해 슬롯에 기록한다. - portfolio_id 가 universe 에 없으면 명확한 reject(
unknown_portfolio)로 처리되어, 원장 귀속 불가·safety 보호 누락 슬롯이 생기지 않는다. - (issue #11) 만에 하나 portfolio_id/execution_id 누락으로 ledger skip 이 발생하더라도 무성으로 사라지지 않고 WARN/ERROR 로그·메트릭으로 노출되며, closed 슬롯 vs outbox 대조 점검 쿼리로 운영자가 누락을 탐지·집계할 수 있다.
- buy intent 는
- 이해관계자
- 문서 작성자(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—SnapshotStoreportfolio_id→symbol 조회 활용(기존get재사용, 신규 메서드 필요 시 추가)- (issue #11)
trex_core/application/execution.py—_record_ledgerskip 지점 가시화(로그/메트릭). OQ-4 결정으로ledger_outbox스키마/LedgerWriter변경은 없음(마커 행 미도입) - (issue #11) 운영 점검 쿼리(FR-5) —
trex_core/adapters/persistence/sql/의 slots↔ledger_outboxanti-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 시
SnapshotStoreuniverse 에서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 와 매수 시점 정합은 운영 점검 대상으로 둔다.
- 완화 방안: resolve 실패 시
- 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 경로 제거로 불일치 위험 해소)
- 상태: Answered (2026-06-08, 사용자 결정 —
- 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 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지 확인한다. 미완료 항목은 후속 결정이 필요함을 뜻한다.
- 범위(In Scope/Out of Scope) 확정
- 기준: 하위호환 정책이 확정됨 (OQ-2 — 즉시 hard cutover, 호환 창구 없음). 호출부 전환 대상의 구체 식별·수정은 REQ/batch 단계 작업으로 넘김(비차단).
- 성공 지표의 측정 방식/데이터 출처 확정
- 기준: S-1~S-5 의 테스트/검증 출처가 실제 실행 가능한 형태로 지정됨
- High 영향 리스크 우선순위 및 해소 책임자 지정
- 기준: R-1 의 change-req 대상(REQ-007/021/018, REQ-019 는 조건부) 추적 방식이 OQ-3 으로 확정됨. 해소 실무 책임자 배정은 REQ/batch planning 단계 담당자 할당 문제로 넘김(비차단).
- 모든 오픈 질문(OQ)
Open상태 없음 확인- 기준: OQ-1~OQ-5 모두
Answered,Open상태 0개
- 기준: OQ-1~OQ-5 모두
- 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_ledgerledger 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_portfolioreject 와 R-2 로 이미 처리되므로 Discovery confirm 을 막지 않는다.
11. Discovery Freeze
REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다.
섹션 참조
- 범위: # 5. 요구사항 목록 > 범위 경계
- 리스크/오픈 질문: # 6. 리스크/가정 목록
- 성공 기준: # 7. 초기 성공 기준
- 인계 전 확인: # 8. REQ로 넘기기 전 확인 체크
- 사용자 결정 필요: # 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