Files
trex-core/docs/runtime-flows.md
T
genichinandClaude Opus 4.8 97d58318db Deliver BAT-004: broker execution + KIS adapter + durable handoff
Implement REQ-011~015 (dcy-003): the order-execution layer on top of the
BAT-002 slot-core daemon, connecting intents to real orders.
- application: BrokerPort (submit/poll_fill/cancel) + ExecutionService
  (claim -> submit -> poll -> transition -> rollback -> reconcile)
- adapters/broker: PaperBroker (deterministic async double) and KISBroker
  (KIS Open API: token, order-cash, inquire-daily-ccld, cancel; VTS sandbox
  tr_ids; live account gated behind allow_live)
- persistence: option-A execution queue (find_pending_for_dispatch FOR
  UPDATE SKIP LOCKED, mark_dispatched idempotency guard, clear_dispatch)
- runtime: background execution loop in the daemon lifespan + startup
  reconcile; config selects paper|kis

Verification (real KIS VTS 모의투자 + PostgreSQL): 92 passed, ruff clean,
domain import sweep shows zero broker/web/db deps, buy->holding /
sell->closed / reject->idle, idempotent dispatch (exactly one order),
reconcile after crash creates no duplicate order, KIS sandbox token+submit
round-trip, and a daemon E2E through the background loop. Align the four
baseline docs. BAT-004 -> release-candidate; REQ-011~015 -> Implemented.

KIS live-account go-live, partial-fill accrual, option-B outbox, connection
pooling, and the safety floor remain deferred to follow-up Discoveries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 17:46:17 +09:00

6.8 KiB

Trex Core Runtime Flows

  • Baseline Mode: mixed
  • Baseline Seed: .stage-pilot/bootstrap/baseline.yaml
  • Status: draft
  • Owner: project maintainers
  • Last Updated (KST): 2026-06-03 (BAT-002)
  • Source Discovery / Batch: bootstrap-baseline (pre-Discovery); 데몬/HTTP 흐름 = dcy-002 / BAT-002
  • Primary Runtime: daemon (HTTP API) + library (slot 도메인)

Project Summary

  • trex 제품군의 공용 베이스로, 첫 도메인으로 trex-orbit 의 일일 거래 슬롯 생명주기(slot) 순수 도메인을 storage-agnostic 하게 이식한 코어다.

Purpose

  • This document is the current approved execution-flow baseline for the project.
  • It is a cross-cutting reference document for Discovery, REQ, Batch Design, Batch Verification, and implementation updates.

Scope

  • Covers representative domain-service flows (library 형태이므로 외부 명령이 아니라 in-process API 호출 흐름).
  • Does not duplicate full acceptance criteria or low-level implementation details.

Covered Entry Points

  • trex-core-daemon :: 슬롯 코어 데몬 (lifecycle + HTTP /v1 서빙, BAT-002)
  • HTTP /v1 :: intent 제출/조회 경계 (전략 데몬 클라이언트)
  • SlotService :: 슬롯 생명주기 도메인 서비스 (preallocate / transit / capacity / entry-count)
  • SlotRepository (Protocol) :: 저장소 구현체 주입 경계

Flow: 데몬 lifecycle (BAT-002)

  1. trex-core-daemon 기동 → DaemonConfig.from_env()(TREX_POSTGRESQL_DSN 등).
  2. startup(lifespan): apply_migrations(dsn)(멱등) → 거래일 슬롯 preallocate_daily_slots(멱등, 공개 엔드포인트 아님).
  3. uvicorn 이 FastAPI /v1 앱 서빙(GET /v1/healthz 200).
  4. shutdown: 연결-당-호출 어댑터라 풀 정리 없음, graceful 종료.

Flow: 매수 intent (POST /v1/intents/buy, BAT-002)

  1. 전략 데몬이 intent(intent_id 포함)를 POST.
  2. IntentService: intent_log.try_insert(intent_id) dedup 게이트 — 중복이면 기존 decision 동기 반환(슬롯 무전이).
  3. 신규면 admission: find_idle_slot → SlotService.transit_slot(idle→pending_buy)(advisory lock 단일 writer). last-idle 경합 시 StateMismatch 재시도.
  4. intent_log.finalize(admitted/rejected, slot_id) → admit/reject 동기 응답.

Flow: 매도 intent (POST /v1/intents/sell, BAT-002)

  1. 전략 데몬이 holding 슬롯을 GET /v1/slots?status=holding 로 조회 후 sell intent POST.
  2. dedup 게이트 → 검증(slot 이 holding 인가) → transit_slot(holding→pending_sell) → finalize → 동기 응답.

Flow: 주문 집행 루프 (백그라운드, BAT-004)

데몬 lifecycle 에서 시작되는 단일 백그라운드 execution 루프가 주기적으로(설정 간격) 수행:

  1. dispatch: find_pending_for_dispatch(status pending_* AND broker_order_id IS NULL, FOR UPDATE SKIP LOCKED) → BrokerPort.submit_order → mark_dispatched(broker_order_id)(멱등 가드). 거부 시 pending_buy→idle / pending_sell→holding 롤백.
  2. poll: list_dispatched_pending(broker_order_id NOT NULL) → BrokerPort.poll_fill → 체결 시 pending_buy→holding(avg_price/qty) / pending_sell→closed(+재진입), 거부 시 롤백. 전이 후 clear_dispatch.
  3. reconcile(재기동): 서빙 전 list_dispatched_pending 재폴링으로 크래시 후 복구(중복 주문 0). 미디스패치(broker_order_id NULL) 슬롯은 다음 dispatch 가 1회만 송신.
  • 모든 슬롯 쓰기는 SlotService(advisory lock) 단일 경로(불변식 A). 브로커 주문/취소는 BrokerPort 단일 세션만(불변식 B).
  • 어댑터: paper(결정적 async 더블) / KIS(모의투자 검증, 실계좌 게이팅).

Shared Components

  • SlotRepository Protocol :: 저장소 추상화. 구현체(InMemorySlotRepository, 향후 PostgreSQLSlotRepository)를 주입.
  • SLOT_ADVISORY_LOCK_ID :: 모든 상태 변경을 직렬화하는 공유 advisory lock 식별자.
  • transactional_advisory_lock :: 단일 트랜잭션 + advisory lock 컨텍스트(외부 I/O 금지).

Flow: slot 사전 할당 (preallocate_daily_slots)

  1. 호출자가 preallocate_daily_slots(trading_date, count) 를 호출한다(count > 0 검증).
  2. SlotService 가 transactional_advisory_lock(SLOT_ADVISORY_LOCK_ID) 를 획득한다.
  3. 저장소가 해당 trading_date 에 슬롯이 이미 있으면 0 을 반환(멱등), 없으면 count 개 idle 슬롯을 삽입한다.
  4. 삽입된 슬롯 수를 반환한다.

Flow: slot 상태 전이 (transit_slot)

  1. 호출자가 transit_slot(slot_id, from_state, to_state, reason, actor, **fields) 를 호출한다.
  2. (from_state, to_state) 가 8 전이 패밀리에 속하는지 먼저 검증한다(아니면 SlotTransitionError).
  3. advisory lock 획득 후 슬롯을 fetch 한다(없으면 SlotNotFoundError).
  4. 현재 status == from_state 인지 확인한다(아니면 SlotStateMismatchError — 레이스 감지).
  5. to_state 의미에 맞춰 점유 필드를 계산하고 슬롯 행을 update 한다. (closed/pending_buy -> idle 은 점유 초기화)
  6. closed -> idle 복구면 (trading_date, symbol) 재진입 카운트를 +1 한다.
  7. slot_transition_log 에 전이 기록 1행을 append 하고 갱신된 슬롯을 반환한다.
  8. 외부 I/O(브로커 등)는 lock 밖에서 호출자가 수행한다(lock 보유 중 금지).

Flow Constraints

  • 모든 상태 변경 API 는 advisory-locked 단일 트랜잭션 안에서 수행한다.
  • lock 보유 중에는 외부 I/O 를 수행하지 않는다.
  • slot_transition_log 는 append-only 다(UPDATE/DELETE 금지).
  • 상태 전이는 read(현재 상태)-검증-write 가 동일 트랜잭션에서 원자적으로 이뤄져 레이스를 차단한다.

Current Gaps / Planned Changes

  • 실제 영속화(PostgreSQL) 흐름은 미구현 — 현재는 in-memory repository 로만 구동.
  • CLI/데몬 런타임 흐름 없음(library). 상위 애플리케이션 통합 흐름은 영속화 단계 이후 정의.
  • 강제 청산/EOD 같은 상위 운영 흐름은 이번 순수 도메인 범위 밖.

Update Triggers

  • Update this document when a command entry point changes.
  • Update this document when a runtime orchestration path changes.
  • Update this document when a batch changes the approved flow baseline.

Change Log

  • 2026-06-03 :: bootstrap-baseline 으로 초기 흐름 baseline 생성(slot 도메인 in-process API 흐름 기준).
  • 2026-06-03 :: BAT-001 이식 완료 반영 — preallocate/transit 흐름이 trex_core.domain.slot 실제 코드로 구현됨(REQ-004). 영속화/CLI 흐름은 여전히 미구현(범위 밖).
  • 2026-06-03 :: BAT-002 — 데몬 lifecycle + 매수/매도 intent HTTP 흐름 추가, Primary Runtime=daemon+library(REQ-005~009). 브로커 집행/safety floor 흐름은 후속 Discovery.
  • 2026-06-04 :: BAT-004 — 브로커 집행 레이어 반영(BrokerPort/paper·KIS 어댑터, execution 루프, broker_order_id 실행큐·멱등, reconciliation) (REQ-011~015).