Files
trex-core/.proofline/lines/line-0005/dcy-0005.md
T

8.1 KiB

id, status
id status
dcy-0005 confirmed

broker 실행 실패의 기록·상태 수렴 경계

Problem

trex-core의 broker execution 경계는 명시적인 주문 거부, timeout·연결 단절·응답 누락처럼 결과가 불명확한 submission, 취소·부분체결·재시작을 서로 다른 authority로 처리해야 한다. 기존 계약이 이 경계를 충분히 명시하지 않으면 core가 broker failure를 retryability로 분류하거나 새 주문 attempt를 자동 생성하여 중복 주문을 만들 수 있고, strategy/TVR이 KIS 실패와 broker retry 판단을 소유하는 잘못된 결합이 생길 수 있다.

주문 venue도 같은 execution lifecycle에서 의미가 혼재될 위험이 있었다. 누락 venue의 기본값, 명시 KRX/NXT/SOR, 폐기된 AUTO, 원주문 routing venue와 실제 KRX/NXT 체결 venue를 구분하지 않으면 wall-clock routing, 취소 시 원주문 venue 손실, ledger/outbox에 실제 거래소 대신 SOR 기록, 기존 persisted AUTO 및 historical SOR row의 잘못된 해석이 발생할 수 있다.

기대 상태는 core가 broker-authoritative evidence로 상태를 수렴하되 자동 새 주문을 만들지 않고, strategy/TVR에는 core slot snapshot만 노출하며, 원주문 venue와 실제 체결 venue를 각각 durable하게 보존하는 것이다.

Evidence

  • 원본 승인 문서: GitHub issue #60 https://github.com/fourblocks2020/trex-core/issues/60의 승인된 본문은 명시적 sell rejection, unknown outcome reconciliation, TVR wire 경계, SOR 기본값, AUTO 제거와 자동 retry 금지를 정의한다.
  • 연계 승인 계약: GitHub issue #61은 venue admission부터 broker request/ack/cancel과 ledger/outbox까지 explicit venue 보존 경계를 정의한다.
  • 구현 진행 원본: issue #60 comment https://github.com/fourblocks2020/trex-core/issues/60#issuecomment-5336722059은 기준 revision, 계획, 구현·검증 진행, 두 차례의 독립 QC blocker와 교정 기록을 포함한다.
  • 구현 완료 원본: issue #60 comment https://github.com/fourblocks2020/trex-core/issues/60#issuecomment-5337338182은 구현 내용, 검증 결과, 로컬 commit 및 push·PR·배포·릴리스·실주문 경계를 기록한다.
  • 구현 revision은 15aeae6930f8c3e6ef9cf659f41278b099a78459, 7366cadf03fc6002bfd01ecf0cba7c24486bb618, 359ea098ff717e7f04cf4206dcbc64ad17b47755이며 현재 local main HEAD는 359ea098ff717e7f04cf4206dcbc64ad17b47755다.
  • trex_core/application/execution.py는 명시적 sell 미수락·미체결의 pending_sell → holding, 결과 불명확 submission의 durable dispatch sentinel·lookup/reconciliation, fill의 actual venue 확인과 ledger enqueue 경계를 구현한다.
  • trex_core/application/broker_port.py는 original submission/routing venue를 가진 OrderAck와 nullable broker-authoritative FillStatus.execution_venue를 분리한다.
  • trex_core/adapters/broker/kis.py는 주문 요청의 KRX/NXT/SOR를 보존하고 ORD_EXG_GB 및 명시 exchange-id allowlist로 실제 KRX/NXT만 파싱하며 SOR 단독·unknown을 추론하지 않는다.
  • trex_core/adapters/persistence/sql/023_remove_auto_order_venue.sql은 persisted AUTO → SOR 변환과 이후 AUTO 저장 차단을 수행한다.
  • trex_core/adapters/persistence/sql/024_add_ledger_order_venue.sql은 original order_venue와 nullable actual venue를 분리하고 historical SOR actual을 NULL로 보존하며 replay-safe NULL-only backfill과 DB constraint를 적용한다.
  • trex_core/adapters/persistence/postgresql.py와 trex_core/application/ledger_port.py는 outbox에서 order_venue와 actual venue를 독립적으로 저장·복원한다.
  • 구현자 검증은 focused unit 77 passed, 전체 1074 passed, 52 skipped, disposable PostgreSQL 16 24 passed, Ruff All checks passed!였다.
  • 최종 독립 read-only QC는 359ea098ff717e7f04cf4206dcbc64ad17b47755에서 blocker/critical/major/minor finding 없이 PASS했다. 실제 PostgreSQL 16에서 historical SOR→order_venue=SOR+actual NULL, 정상 actual NXT/order KRX의 replay 보존, actual SOR·AUTO·NULL order 거부를 확인했고 worktree는 clean이었다.
  • 현재 proofline validate는 exit 0이다.

Scope

  • AC admission은 기존 active AC-0011의 timeout/cancel reconciliation 및 AC-0013의 terminal cancel·partial fill 상태 수렴과 인접하지만, 명시적 submission rejection, strategy wire ownership, venue admission/migration 및 order/execution venue 분리를 독립적으로 검증 가능한 장기 계약으로 추가하는 create다. 기존 AC의 의미나 status는 변경하지 않는다.
  • KIS 조회로 sell 주문의 미수락·미체결이 명시적으로 확인되면 새 broker attempt 없이 실패 evidence를 기록하고 dispatch를 정리하며 broker-authoritative 보유수량으로 pending_sell → holding 전이한다.
  • timeout, 연결 단절, 응답 누락 등 submission 결과가 불명확하면 durable sentinel을 유지하고 새 주문을 생성하지 않으며 broker lookup과 reconciliation을 먼저 수행한다.
  • core는 broker failure의 retryability, retry schedule, retry budget을 판정하거나 자동 새 broker attempt를 생성하지 않는다. 이후 strategy가 독립적으로 생성한 새 intent는 이 자동 retry 금지와 구분한다.
  • strategy/TVR에는 KIS failure, raw broker error, broker attempt, retryability를 노출하지 않는다. strategy/TVR은 core가 수렴한 slot snapshot만 소비한다.
  • intent venue 누락은 SOR로 정규화하고 명시 KRX/NXT/SOR는 보존한다. AUTO는 admission과 persistence에서 거부하고 기존 persisted AUTO는 SOR로 전환하며 wall-clock venue routing을 수행하지 않는다.
  • original order_venue KRX/NXT/SOR는 submit/ack/slot/restart/cancel에 보존한다. broker-authoritative actual execution_venue는 KRX/NXT 또는 미확정 NULL로 별도 취급하고 fill·ledger/outbox에 기록한다.
  • KIS actual venue는 검증된 ORD_EXG_GB와 명시 exchange-id allowlist에서만 KRX/NXT로 변환한다. SOR 단독, 누락 또는 미지원 값은 KRX/NXT로 추론하지 않는다.
  • historical outbox의 SOR는 original order venue로 보존하고 actual venue는 NULL로 전환한다. migration 재실행은 신규 정상 order/execution venue 조합을 오염시키지 않아야 하며 DB는 actual SOR와 invalid order venue를 거부한다.
  • 관련 focused·전체 회귀, PostgreSQL migration·round-trip, lint와 독립 QC evidence를 구현 상태 평가에 포함한다.

Out of Scope

  • strategy/TVR의 KIS failure 수신, retryability 판단, broker attempt 관리 또는 자동 retry 기능
  • TVR 세션·portfolio markets 판단 구현과 KRX/NXT session policy 자체
  • 실제 KIS 주문·취소, production credential, live RabbitMQ·database·portfolio-hub 연결
  • push, PR, 원격 main 반영, image publication, 운영 migration, deployment, GitHub Release 또는 실주문
  • ProofLine delivery/release lifecycle이 과거 구현 당시 완료되었다는 소급 주장

Risks and Unknowns

Risks

  • KIS 응답의 실제 venue 필드가 누락되거나 미지원 코드이면 SOR 주문의 actual venue가 NULL로 남아 ledger enqueue가 fail-closed 될 수 있다. 임의 시간 추론보다 안전하며 운영 관측과 authoritative reconciliation이 필요하다.
  • migration runner는 history table 없이 SQL을 재실행하므로 migration 024의 NULL-only backfill과 replay-safe 불변식을 이후 변경에서도 유지해야 한다.
  • 환경 의존 KIS·RabbitMQ 검증은 skip되었으므로 실제 운영 외부 시스템 상호작용은 별도 승인 환경에서 확인해야 한다.

Approval State

  • Discovery status: confirmed
  • 승인 근거: 요청자 genichin이 승인 상태인 issue #60 본문을 최대한 보존하여 템플릿 기반 Discovery를 승인된 상태로 정리하라고 명시했다.
  • 추가로 필요한 제품 결정: 없음
  • 이 확인은 사후 specification 정리이며 구현·테스트·독립 QC의 실제 evidence는 별도 보존한다. push, PR, 배포, release 또는 실주문 승인을 뜻하지 않는다.