# req-018: 체결→원장 기록 (집행 루프 fill hook) - Status: Approved - Type: Integration - Priority: High - Owner: project maintainers ## Intent - 코어 집행 루프가 체결(매수/매도) 시 해당 거래를 portfolio-hub 원장에 기록하도록, fill 전이 경로에 ledger 기록 hook 을 더하고 체결 데이터(execution_id/fee)를 브로커 계약으로 운반한다. ## Requirement - 집행 루프가 매수 체결(`pending_buy→holding`)·매도 체결(`pending_sell→closed`) 시 LedgerPort 로 거래를 기록한다. ledger path 의 `asset_id` 는 슬롯 `portfolio_id`(= asset_id)를 직접 사용하고 side/qty/price/execution_id/fee/tax/executed_at 을 함께 보낸다. - `FillStatus`(broker_port) 가 `execution_id` 와 `fee` 를 운반하도록 계약을 확장한다. `execution_id` 는 결정적으로 합성한다(KIS: `kis-daily-ccld:{ord_dt}:{ord_gno_brno}:{odno}:{tot_ccld_qty}`, paper: `paper:{broker_order_id}:{filled_qty}`). `fee` 는 BrokerPort fee 계산(orbit `calculate_fee(side, amount)` 패턴), `tax` 는 기본 0 으로 한다. - 원장 기록 주체는 코어 집행 경로 단일로 한정한다(전략/도메인은 원장에 접근하지 않는다). ## Acceptance Criteria 1. Given idle 슬롯에 매수 intent → 체결, When 집행 루프 fill 전이, Then 슬롯이 holding 으로 전이되고 원장에 buy 거래 1건이 기록된다(asset_id = 슬롯 portfolio_id). 2. Given holding 슬롯에 매도 intent → 체결, When 집행 루프 fill 전이, Then 슬롯이 closed 로 전이되고 원장에 sell 거래 1건이 기록된다. 3. Given 체결된 주문, When fill 을 읽음, Then `FillStatus` 가 결정적 `execution_id` 와 계산된 `fee`(tax=0)를 운반한다. 4. Given 슬롯에 `portfolio_id` 가 없는 체결, When fill 전이, Then 원장 기록을 건너뛰거나(또는 정의된 정책으로 처리) 슬롯 전이 자체는 정상 수행된다. 5. Given 전략/도메인 코드, When 점검, Then 원장 기록은 코어 집행 경로에서만 발생한다(단일 기록 주체). (NFR-3) ## Impacted Area - Docs: docs/runtime-flows.md(체결→원장 기록 흐름), docs/interface-contract.md(FillStatus 확장) — REQ-020 에서 정합 - Modules: `trex_core/application/execution.py`(fill 전이에 ledger 기록 단계), `trex_core/application/broker_port.py`(FillStatus.execution_id/fee), `trex_core/adapters/broker/{paper,kis}.py`(execution_id 합성 + fee 계산) - Tests: stub 원장으로 매수/매도 체결 시 buy/sell 1건 + 슬롯 전이, FillStatus execution_id/fee 운반, portfolio_id 부재 처리 ## Notes - 출처: dcy-004 FR-2, OQ-1(asset_id == portfolio_id, orbit 근거), OQ-3(execution_id/fee/tax 출처), NFR-3. - OQ-1: 슬롯은 이미 buy intent 가 `portfolio_id` 를 공급해 캐시하므로 추가 매핑/조회 없이 path param 으로 사용한다. - `portfolio_id` 부재 시 기록 skip vs 거부 정책은 구현 시 확정(AC-4 는 둘 다 허용하되 슬롯 전이 일관성을 요구). - 멱등/무유실/재시도(correlation_id, outbox)는 REQ-019 에서 다룬다. 본 REQ 는 기록 호출 경로와 데이터 운반에 한정한다. ## Change Log ### CHG-20260604-01 - Date: 2026-06-04 - Author: Justin Ko #### Change Summary - dcy-004 FR-2 로부터 최초 생성(Proposed). OQ-1/OQ-3 결정 반영, NFR-3(단일 기록 주체) 흡수. #### Intent - 집행 루프 fill 전이에서 체결을 원장에 기록하는 경로와 FillStatus 확장(execution_id/fee)을 backlog 로 정규화. #### Acceptance Criteria Delta - Added: - 매수/매도 체결 기록+전이, FillStatus execution_id/fee, portfolio_id 부재, 단일 기록 주체 5개 기준 - Updated: - 없음 - Removed: - 없음 #### Impacted Area Delta - Docs: - docs/runtime-flows.md, docs/interface-contract.md - Modules: - execution.py(ledger hook), broker_port.py(FillStatus), paper/kis 어댑터(execution_id/fee) - Tests: - 체결→기록 통합테스트, FillStatus 운반, portfolio_id 부재 #### Delivery Trace Delta - Batches: - none - Releases: - none #### Revalidation Impact - Reverification Needed: no - Existing Implementation Invalidated: no - Status Recommendation: keep-current - Follow-up Action: confirm-req 후 batch 편성 #### Validation Plan - stub 원장으로 매수/매도 체결 lifecycle 통합테스트 + FillStatus 확장 테스트로 검증. ### CHG-20260604-02 - Date: 2026-06-04 - Author: Justin Ko #### Change Summary - Status 변경: Proposed -> Approved. confirm-req 승인 게이트 통과. #### Intent - 집행 루프 fill 전이의 ledger 기록 hook 과 FillStatus 확장을 delivery input 으로 승인. #### Acceptance Criteria Delta - Added: - 없음 - Updated: - 없음 - Removed: - 없음 #### Impacted Area Delta - Docs: - 없음 - Modules: - 없음 - Tests: - 없음 #### Delivery Trace Delta - Batches: - none - Releases: - none #### Revalidation Impact - Reverification Needed: no - Existing Implementation Invalidated: no - Status Recommendation: Approved - Follow-up Action: batch 편성 #### Validation Plan - 기존 Acceptance Criteria 로 batch delivery 에서 검증.