Files
trex-core/docs/srs/Integration/req-011_broker-port-and-paper-double.md
T
genichinandClaude Opus 4.8 9871008bb6 fix(paper): BAT-039 — paper order seq Redis 영속화 (재시작 멱등 키 충돌 방지, REQ-011/issue #4)
REQ-011 change-req(CHG-20260612-01)→구현→confirm-req-implemented(CHG-20260612-02)
전체 delivery. paper 한정 결정성 버그(프로덕션 무관).

- seq_store.py 신규: SeqStore 포트 + RedisSeqStore(원자 INCR, 재시작 단조·영속)
  + InMemorySeqStore(폴백/테스트). REQ-016 token_cache 패턴 재사용.
- paper.py: optional seq_store 주입. 미주입 시 기존 in-memory 동작 byte-for-byte 유지.
- config.py/daemon.py: TREX_PAPER_REDIS_URL → RedisSeqStore wiring
  (key=trex:broker:paper:{instance_key}:order-seq).
- 런타임 Redis 오류는 전파(silent in-memory 폴백 금지 — 버그 재현 방지).
- tests: 재시작 단조성/correlation_id 비충돌/in-memory 폴백/fake redis INCR (5).
  434 passed (+5), ruff clean.

REQ-011 Approved→Implemented, BAT-039 release-candidate. issue #4 close.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 18:16:11 +09:00

11 KiB

req-011: BrokerPort 추상화 + paper/stub async 더블

  • Status: Implemented
  • Type: Integration
  • Priority: High
  • Owner: project maintainers

Intent

  • 브로커를 코어에서 추상화하는 BrokerPort 를 정의하고(불변식 B 의 단일 경계), 결정적 검증용 paper/stub 어댑터를 제공한다. 이후 KIS 어댑터(REQ-012)와 집행 루프(REQ-013)가 이 포트 위에서 동작한다.

Requirement

  • BrokerPort(application 포트)에 submit_order(side, symbol, qty, ...) -> broker_order_id, cancel_order(broker_order_id), poll_fill(broker_order_id) -> FillStatus(accepted/partially_filled/filled/rejected/cancelled, avg_price, filled_qty) 를 정의한다. paper/stub 어댑터는 동기 단축 없이 submit→poll 비동기 계약을 따르되 체결 시점·부분체결·거부를 프로그래밍 가능한 결정적 더블로 제공한다. 어댑터는 adapters 레이어에 두고 도메인은 의존하지 않는다.
  • paper 어댑터의 order seq 발번은 optional seq store(주입 가능) 위에서 동작한다. seq store 가 주입되면 order seq 는 데몬 재시작 간에도 단조 증가해야 하며(Redis 영속, REQ-016 RedisTokenCache 패턴 재사용·best-effort), 미주입 시 기존 in-memory 카운터로 폴백한다. 이는 재시작 후 결정적 execution_id 재생성으로 인한 원장 correlation_id 충돌(매도 원장 누락)을 방지하기 위한 paper 한정 결정성 보강이다(issue #4).

Acceptance Criteria

  1. Given BrokerPort 정의, When paper 어댑터로 submit_order, Then accepted + broker_order_id 를 반환하고 즉시 filled 로 단축하지 않는다(다음 poll_fill 에서 체결).
  2. Given paper 더블의 fill 시나리오 설정(즉시/N틱 후/부분/거부), When poll_fill 반복, Then 설정대로 결정적으로 상태가 진행된다.
  3. Given 코드, When import 스윕, Then trex_core.domain.slot 은 broker/네트워크 의존이 0이고 BrokerPort 구현은 adapters 레이어에만 있다. (NFR-1/NFR-2)
  4. Given paper 어댑터에 seq store 가 주입된 상태, When 데몬 재시작(seq store 영속)을 모사해 두 번째 인스턴스에서 submit_order, Then order seq 는 첫 인스턴스 이후로 단조 증가하고, 같은 자산·같은 수량의 매도가 직전 run 매수와 correlation_id 가 충돌하지 않는다. seq store 미주입 시 기존 in-memory PAPER-000001 발번으로 폴백하며 AC-1~3 비동기 계약은 불변이다. (issue #4)

Impacted Area

  • Docs: docs/interface-contract.md(브로커 경계) — REQ-015 에서 정합
  • Modules: trex_core/application(BrokerPort), trex_core/adapters/broker(paper/stub, seq_store.py 신규), trex_core/runtime(config PaperBrokerConfig.redis_url, daemon _build_broker wiring)
  • Tests: paper 더블 fill 시나리오 테스트, paper seq store 재시작 단조성 + correlation_id 비충돌 + in-memory 폴백 테스트

Notes

  • 불변식 B 의 단일 경계. KIS 어댑터는 REQ-012, 집행 루프는 REQ-013.
  • 출처: dcy-003 FR-1(포트+paper), NFR-1/NFR-2 흡수.
  • (issue #4/CHG-20260612-01) paper seq Redis 영속화는 paper 한정 테스트 하네스 결정성 보강이며 프로덕션(KIS odno 고유) 버그가 아니다. 원장 correlation_id 에 side 를 추가하는 대안 대신, 발번 단조성 보강(영향 최소·계약 불변)을 선택했다. Redis 인프라는 REQ-016 token_cache 패턴을 재사용한다.

Change Log

CHG-20260604-01

  • Date: 2026-06-04
  • Author: Justin Ko

Change Summary

  • dcy-003 FR-1(포트+paper) 로부터 최초 생성(Proposed).

Intent

  • BrokerPort + paper async 더블 요구사항을 backlog 로 정규화.

Acceptance Criteria Delta

  • Added:
    • submit→poll 비동기 계약, 결정적 fill 시나리오, 도메인 순수성 3개 기준
  • Updated:
    • 없음
  • Removed:
    • 없음

Impacted Area Delta

  • Docs:
    • docs/interface-contract.md
  • Modules:
    • application(BrokerPort), adapters/broker(paper)
  • Tests:
    • paper 더블 시나리오 테스트

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

  • paper 더블 비동기 체결 시나리오 단위테스트로 검증.

CHG-20260604-02

  • Date: 2026-06-04
  • Author: Justin Ko

Change Summary

  • Status Proposed → Approved (confirm-req).

Intent

  • 승인 게이트(필수 필드·구체 AC·blocker 없음) 충족, source dcy-003(confirmed, handoff 승인)와 모순 없음 확인.

Acceptance Criteria Delta

  • Added:
    • 없음
  • Updated:
    • 없음
  • Removed:
    • 없음

Impacted Area Delta

  • Docs:
    • docs/srs/index.md (Register 상태 Approved)
  • Modules:
    • 없음
  • Tests:
    • 없음

Delivery Trace Delta

  • Batches:
    • none (batch 편성 전)
  • Releases:
    • none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: suggest-batch-reqs / draft-batch 로 delivery batch 편성

Validation Plan

  • 승인 후 batch planning 에서 본 REQ 의 Acceptance Criteria 를 검증 기준으로 사용.

CHG-20260604-03

  • Date: 2026-06-04
  • Author: Justin Ko

Change Summary

  • Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-004 release-candidate).

Intent

  • BAT-004 verification.md 의 acceptance mapping + evidence(pytest 92 pass / 도메인 순수성 / 데몬 E2E / KIS VTS 모의투자 round-trip)로 AC 충족 → 구현 완료 동기화.

Acceptance Criteria Delta

  • Added:
    • 없음
  • Updated:
    • 없음
  • Removed:
    • 없음

Impacted Area Delta

  • Docs:
    • docs/srs/index.md (Register Implemented)
  • Modules:
    • 없음
  • Tests:
    • 없음

Delivery Trace Delta

  • Batches:
    • BAT-004 (release-candidate)
  • Releases:
    • none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: draft-release 로 release 편성(BAT-001~004)

Validation Plan

  • BAT-004 verification evidence 재참조로 충분.

CHG-20260612-01

  • Date: 2026-06-12
  • Author: Justin Ko

Change Summary

  • (change-req, issue #4) paper 브로커 order seq 를 재시작 간 단조 증가하도록 영속화한다. 현재 _seq in-memory 카운터는 데몬 재시작 시 0 으로 리셋되어 PAPER-000001 부터 재발번 → 결정적 execution_id(paper:{order_id}:{filled_qty}) 재생성 → 원장 멱등 키 correlation_id = {asset_id}:{order_id}:{execution_id}(side 미포함)가 직전 run 의 매수와 충돌 → ON CONFLICT DO NOTHING dedup 으로 정상 매도 원장 행이 조용히 누락. paper 어댑터에 optional seq store(Redis-backed, REQ-016 RedisTokenCache 패턴 재사용)를 주입해 해소하고, Redis 미구성 시 기존 in-memory 동작으로 폴백. 신규 AC-4 가 추가 구현·검증을 필요로 하므로 Implemented → Approved 되돌림.

Intent

  • paper 모드 테스트 하네스의 재시작 후 멱등 키 충돌(매도 원장 누락)을 제거한다. 실 KIS 는 broker order_id(odno)가 주문마다 고유해 충돌이 없으므로 프로덕션 버그가 아닌 paper 한정 결정성 문제다. 기존 BrokerPort/paper 비동기 계약(AC-1~3)은 불변, seq 발번 영속화만 추가.

Acceptance Criteria Delta

  • Added:
    • AC-4: paper 브로커에 seq store 가 주입되면 order seq 는 재시작 후에도 단조 증가하고, 같은 자산·같은 수량의 매도가 직전 run 의 매수와 correlation_id 가 충돌하지 않는다. seq store 미주입(Redis 미구성) 시 기존 in-memory _seq 동작으로 폴백하며 비동기 fill 계약(AC-1~3)은 불변이다.
  • Updated:
    • 없음
  • Removed:
    • 없음

Impacted Area Delta

  • Docs:
    • docs/srs/index.md (Register Implemented → Approved)
  • Modules:
    • trex_core/adapters/broker/paper.py(optional seq store 주입 + submit_order seq 발번 경로)
    • trex_core/adapters/broker/seq_store.py(신규: SeqStore 포트 + RedisSeqStore(INCR 기반, best-effort) + InMemorySeqStore 폴백, token_cache 패턴 정합)
    • trex_core/runtime/config.py(PaperBrokerConfig.redis_url 추가)
    • trex_core/runtime/daemon.py(_build_broker paper 경로 seq store wiring)
  • Tests:
    • 재시작 시뮬레이션(seq store 공유) 후 매도 correlation_id 비충돌 + 폴백 동작 단위 테스트

Delivery Trace Delta

  • Batches:
    • BAT-039 (예정, issue #4)
  • Releases:
    • none

Revalidation Impact

  • Reverification Needed: yes (BAT-039 에서 신규 AC-4 + AC-1~3 회귀)
  • Existing Implementation Invalidated: no (기존 비동기 계약/도메인 순수성 불변, 발번 경로에 optional 영속화만 추가). 단 신규 AC-4 미구현으로 Implemented 유지 불가 → Approved.
  • Status Recommendation: Implemented → Approved (구현·검증 후 confirm-req-implemented 로 복귀)
  • Follow-up Action: confirm-req → draft-batch(BAT-039) → 구현·검증 → confirm-req-implemented → issue #4 close

Validation Plan

  • BAT-039: (a) 같은 seq store 를 공유한 두 PaperBroker 인스턴스(재시작 모사)에서 두 번째 인스턴스의 첫 order_id 가 첫 인스턴스 이후로 단조 증가, (b) 매수 후 재시작 매도 시 correlation_id 비충돌(원장 dedup 미발생), (c) seq store 미주입 시 기존 PAPER-000001 부터 in-memory 동작 폴백, (d) AC-1~3 기존 paper 테스트 회귀 없음. pytest 전체 + ruff check clean.

CHG-20260612-02

  • Date: 2026-06-12
  • Author: Justin Ko

Change Summary

  • Status 변경: Approved → Implemented (confirm-req-implemented, 근거 batch BAT-039 release-candidate).

Intent

  • BAT-039 verification.md 의 acceptance mapping + evidence(434 passed / seq store 재시작 단조·correlation_id 비충돌·in-memory 폴백 / fake redis INCR 단조)로 AC-1~4 충족 → 구현 완료 동기화.

Acceptance Criteria Delta

  • Added/Updated/Removed: 없음 (상태 전이만)

Impacted Area Delta

  • Docs/Modules/Tests: 없음 (상태 전이만)

Delivery Trace Delta

  • Batches:
    • BAT-039 (release-candidate)
  • Releases:
    • none (release 편성은 별도 진행)

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: Implemented
  • Follow-up Action: draft-release 로 release 편성(BAT-039 포함) + issue #4 close

Validation Plan

  • BAT-039 verification evidence 재참조로 충분.
    • AC-4: test_shared_seq_store_is_monotonic_across_restart, test_post_restart_sell_does_not_collide_with_prior_buy, test_in_memory_fallback_starts_at_one, test_redis_seq_store_incr_is_monotonic_and_shared.
    • AC-1~3: 전체 회귀 434 passed(기존 paper 더블 시나리오 + 도메인 순수성 회귀 없음).