# BAT-038 Verification - Status: confirmed - Batch: BAT-038 ## Acceptance Mapping - REQ-018 AC-1 (매수 체결 → holding + buy 원장 1건): - 이번 배치 변경 범위 밖(기록 경로 불변). BAT-006 evidence 유효. - Evidence: `test_buy_fill_enqueues_one_ledger_item_and_writer_records_it` PASSED. - REQ-018 AC-2 (매도 체결 → closed/inactive + sell 원장 1건): - Evidence: `test_sell_fill_enqueues_sell_ledger_item` PASSED. - REQ-018 AC-3 (`FillStatus` 결정적 execution_id + 계산된 fee + 계산된 tax 운반): - Evidence: - 매수: `test_buy_fill_...` — `t.fee > 0.0 and t.tax == 0.0` (매수 무세) PASSED. - 매도: `test_paper_sell_fill_carries_policy_tax` — `fs.fee == calculate_fee("sell", amount)`, `fs.tax == calculate_tax("sell", amount)`, `fs.tax > 0.0` PASSED. - REQ-018 AC-4 (portfolio_id 부재 → 기록 skip + 슬롯 전이 정상): - 변경 범위 밖. Evidence: `test_portfolio_id_absent_skips_ledger_but_transitions_slot` PASSED + 전체 회귀. - REQ-018 AC-5 (원장 기록 단일 주체 = 집행 경로): - 변경 범위 밖. fee/tax 는 어댑터 산출, 기록 주체(`execution.py:_record_ledger`) 불변. - Evidence: `_record_ledger` 단일 enqueue 지점 유지(line 396-397 `fee`/`tax` 전달), 전체 회귀 429 passed. - REQ-018 AC-6 (매도 tax = amount × 0.2%, 매수 tax = 0): - Evidence: - `test_calculate_tax_sell_only`: `calculate_tax("sell", 1_000_000) == 2000.0`, `calculate_tax("buy", ...) == 0.0` PASSED. - `test_paper_buy_fill_has_zero_tax`: paper 매수 fill `fs.tax == 0.0` PASSED. - REQ-018 AC-7 (단일 정책 지점 + env, paper·KIS 동일, `tax=0.0` 하드코딩 제거): - Evidence: - `test_calculate_fee_same_rate_buy_and_sell`: 매수·매도 동일 수수료율 PASSED. - `test_fee_and_tax_zero_for_nonpositive_amount`: 비양수 amount 가드 PASSED. - 단일 정책 지점: `broker_port.py` `calculate_fee`/`calculate_tax` (env `TREX_KIS_FEE_BPS`/`TREX_KRX_TAX_SELL_BPS`). paper·kis 가 동일 함수 import 사용(코드 리뷰). - `tax=0.0` 하드코딩 제거 확인: `grep -rn "tax=0.0\|tax=0," trex_core/adapters trex_core/application` → 코드 사이트 0건(주석 1건만). - REQ-018 AC-8 (KIS 응답 fee/tax 정본 우선, 부재 시 폴백): - Evidence (design + 코드 리뷰): KIS 어댑터가 쓰는 `주식일별주문체결조회`(inquire-daily-ccld, `output1`)는 per-fill 수수료/증권거래세 필드를 제공하지 않음(`docs/broker/kis/rest/국내주식/주문/계좌/021...` output1 38필드 중 fee/tax 없음, `tot_ccld_amt` 만 존재). 따라서 KIS 는 정책 추정값(`calculate_fee`/`calculate_tax`)으로 폴백 — 구조적으로 폴백 경로만 활성, 오파싱 리스크 없음(design Key Decision 3). 향후 fee/tax 노출 endpoint 도입 시 정본 우선 파싱 추가 지점 명시. - 잔여: 라이브 KIS 스모크는 REL 배포 단계 사항(paper 와 동일 산식이므로 코드 경로 동일). Blocking 아님. - REQ-018 AC-9 (issue #24 4건 → fee+tax 합계 1,376.9원): - Evidence: `test_issue_24_four_fill_regression` — `total_fee == 177.9`, `total_tax == 1199.0`, `total == 1376.9` PASSED. ## Evidence - Test: - `pytest tests/application/test_fee_tax_policy.py` — 6 passed (신규) - `pytest tests/application/test_fee_tax_policy.py test_execution_ledger.py test_execution_cancel.py` — 19 passed - `pytest tests/` — **429 passed, 45 skipped** (BAT-037 423 → +6, 회귀 0) - `ruff check trex_core tests` — All checks passed - Manual / Baseline 동기화 (Architecture Impact: runtime-flows): - `docs/runtime-flows.md` `체결 → ledger outbox` flow (line 254): `tax=0` → `calculate_tax(side, amount)` 정책 계산 + env 변수(`TREX_KIS_FEE_BPS`/`TREX_KRX_TAX_SELL_BPS`) + paper·KIS 공유 설명 갱신. Change Log 항목(2026-06-12 BAT-038) 추가. ✓ 코드와 동기화 확인. - `docs/project-structure.md`: 변경 불필요(모듈 구조 불변, 함수 1개 추가) — design Reference Doc Update Plan = none. - `tax=0.0` 하드코딩 제거 grep 확인(위 AC-7). ## Result - Ready for Release: true - Blocking Issues: 없음 - AC-8 라이브 KIS 스모크는 REL 배포 단계(비거래 시간) 사항이며, paper 와 동일 정책 산식·동일 코드 경로이므로 release-ready 차단 사유 아님.