Files
trex-core/docs/releases/rel-006_20260611_asset-centric-sizing-execution-policy.md
T
genichinandClaude Sonnet 4.6 1f59322f52 docs(rel-006/bat-026~036): confirm-release 상태 반영 — released 전환
REL-006 confirm-release 스킬 실행 결과 BAT-026~036 상태를 released로 갱신하고
rel-006 배포 근거를 보완한 변경 사항을 커밋.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 22:45:45 +09:00

18 KiB
Raw Blame History

REL-006: 자산 중심 영구 슬롯 cutover + 포지션 사이징 + 실행 정책 + 운영 정리 통합 릴리즈

  • Status: feedback-captured
  • Profile: app-service
  • Included Batch: BAT-026, BAT-027, BAT-028, BAT-029, BAT-030, BAT-031, BAT-032, BAT-033, BAT-034, BAT-035, BAT-036

Scope

  • Included:
    • BAT-026 (batch-lite / REQ-048·010 CHG): config 디렉터리 기반 설정 관리 — --config <name> + --config-path <dir> + config-dir .env 결정적 해석(--env-file 우선), legacy 루트 .env 폴백 유지(완전 하위호환). 데몬·운영자 CLI 양쪽 적용.
    • BAT-027 (dcy-020 BAT-α / REQ-056·057): 자산 1:1 영구 슬롯 기반 — (instance_key, portfolio_id) 키 영구 슬롯 + inactive↔pending_buy↔holding↔pending_sell 상태머신, 인스턴스 스코프 advisory lock. 마이그레이션 009(instance_key·retired_at)·010(literal inactive).
    • BAT-028 (dcy-020 BAT-β / REQ-058·059·060): universe reconcile(슬롯 생성/retire, 대량 소멸 가드) + 자산 중심 buy admission(max_active_slots 동시 활성 상한).
    • BAT-029 (dcy-020 BAT-γ / REQ-061·062·063): intent 계약 자산 키 통일(slot_id 정본 + portfolio_id 수용) + 수량 정본=hub·core 미러 divergence reconcile + slots 단일 뷰(universe_detached 표기).
    • BAT-030 (dcy-020 BAT-δ / REQ-064·065 + 056·057·062 잔여): pool 모델 폐기 cutover — daily preallocation 제거(영구 슬롯은 universe reconcile 이 소유), 마이그레이션 011(trading_date·entry_count DROP, 비가역).
    • BAT-031 (dcy-021 / REQ-066·067 + 057·061·062 CHG): 포지션 사이징 — 보유 슬롯 증액(holding→pending_buy, avg_price 가중평균), 부분 매도(집행 수량=min(intent,브로커잔고), 잔량 holding/전량 inactive, cost basis 유지), 부분 체결 실제만 반영.
    • BAT-032 (dcy-022 / REQ-068~072 + 013·061 CHG): 주문 실행 정책 — intent timeout_sec(미체결 자동 취소·cancel-fill race 처리)·slippage_pct(보호 지정가 buy ceil/sell floor), per-instance TOML default_order_timeout_sec, 운영자 trex-core cancel 백스톱. 마이그레이션 012(execution policy 필드).
    • BAT-033 (batch-lite / REQ-032 CHG-06, issue #23): trex-core enter --qty 필수 검증 — 미지정 시 RPC 전 즉시 오류(0주 주문 silent 실패 제거).
    • BAT-034 (dcy-023 / REQ-002·006·007·028·032 CHG, issue #22): 죽은 필드 allocated_capital 전 경로 제거 — CLI --capital argparse 거부, BuyIntent·payload 수신 무시, Slot/EXPECTED_SLOT_FIELDS, snapshot slots[]. 마이그레이션 013(컬럼 DROP, 비가역).
    • BAT-035 (dcy-025 / REQ-073·074·075 신규 + REQ-021·034·063 CHG): trex.snapshot.req → trex.slots.req 즉시 교체 — 요청 {filter: all|inactive|pending|holding|error, spy: bool}, 응답 {slots[], degraded, reason, message}. 슬롯 단일 행 스키마: asset_quantity(hub 정본)·qty(slot 미러)·warned·cash_balance·cash_estimated·watchdog{expired,last_seen}·paused; strategy 필드 제외. spy=true → watchdog 무터치. REQ-028(build_snapshot_envelope/View/SnapshotEnvelope) Deprecated + 코드 삭제.
    • BAT-036 (dcy-024 / REQ-048·005 CHG, issue #15): per-instance TOML safety_sell_enabled: bool = True — false 시 trex-safety-sell 워커 미기동·물리 차단 + no autonomous liquidation WARNING 로그. ExecutionService·kill-switch·전략 sell intent 불변.
  • Excluded:
    • BAT-001025 (REL-001005 에서 released)
    • trex-orb-v1 등 외부 전략 모듈 저장소 변경(발신 계약 전환·allocated_capital 송신 정리 — 별도 합의)
    • daily_symbol_entries 잔재 제거(REL-005 환류 — 별도 change-req 트랙)

Rollout Plan

  • 배포 대상 커밋: f0ad37747b4e9d43dc798bfeda5b543cab048890 (main, 2026-06-11)
  1. 배포 전: 거래 세션 외 시간 확보, 현재 운영 리비전 SHA 기록, 위 배포 SHA(f0ad377) 확인.
  2. DB 백업(필수): 마이그레이션 011·013 은 비가역 컬럼 DROP — 적용 전 운영 daily_slot(권장: DB 전체) 백업. BAT-030 design §4 절차 준용.
  3. 신 리비전 배포 + 데몬 재기동. apply_migrations 가 009~013 자동 적용(전부 멱등). 기동 로그에서 마이그레이션 적용·RUNNING·비-degraded 확인.
  4. cutover 확인: daily preallocation 부재가 정상 — 영구 자산 슬롯은 snapshot scheduler 의 universe reconcile 이 생성/retire 한다. 기동 직후 universe fetch → 슬롯 생성 로그 확인, trex-core slots 로 자산 수 = 슬롯 수 확인.
  5. 운영자 CLI 스모크(paper 또는 비거래 시간):
    • trex-core slots — 응답 형식 {slots[], degraded, reason, message} 확인 (BAT-035: 구 {assets[], available_slots} 형식 부재); inactive/holding 상태·universe_detached 표기 (BAT-027~030)
    • trex-core slots --status holding → filter=holding 서버 필터 작동 확인 (BAT-035 filter)
    • trex-core universe → trex.slots.req 큐 사용, spy=true 확인 (BAT-035)
    • trex-core enter <pf> --yes → --qty 누락 즉시 오류 (BAT-033); --qty N --yes → admitted (BAT-029 자산 키)
    • trex-core enter ... --capital ... → argparse 거부 (BAT-034)
    • 증액/부분 매도 intent e2e (BAT-031), timeout_sec/slippage_pct intent + trex-core cancel (BAT-032)
  6. BAT-035 외부 소비자 없음 확인: trex.snapshot.req 구독자는 운영자 CLI 전용이며 CLI 는 이미 trex.slots.req 로 갱신됨. 전략 모듈(trex-orb-v1)은 trex.intent.req 생산자만이고 snapshot 소비자가 아니므로 차단 없음.
  7. 전략 모듈(trex-orb-v1) 재연결 후 buy intent 정상 admit 확인 — allocated_capital 송신 잔존은 unknown key 로 무시되어 무해.
  8. BAT-036 확인(해당 시): TOML 에 safety_sell_enabled = false 설정 시 데몬 기동 로그에 no autonomous liquidation WARNING 출력·trex-safety-sell 워커 미기동 확인. 기본값 true 유지 시 변화 없음.
  9. 거래 세션 재개.

Rollback Plan

  • 조건: 기동 실패, 마이그레이션 오류, universe reconcile 슬롯 생성 실패(전 자산 미생성), buy admission 회귀, 집행 루프(timeout/slippage) 오작동, CLI 회귀.
  • 절차: 직전 released 리비전(REL-005 시점)으로 롤백 + 데몬 재기동 + 백업 복원.
  • 마이그레이션: 011(trading_date·entry_count DROP)·013(allocated_capital DROP)은 구 코드의 SELECT/UPDATE 가 해당 컬럼을 참조하므로 구 리비전과 공존 불가 — 롤백은 반드시 2번 백업 복원과 함께 수행한다. 009·010·012 는 additive/호환이라 단독으로는 무해.
  • 데이터: cutover 후 생성된 영구 슬롯 행은 구 pool 모델 코드와 호환되지 않음 — 복원 시점 이후 거래가 없도록 비거래 시간 배포를 전제로 한다.

Verification Checklist

  • 배포 전 (각 batch verification evidence):
    • BAT-026: 단위 23 + 전체 375 passed, ruff clean, 라이브 스모크(name·path 동일 결과)
    • BAT-027~030 (dcy-020): 단위 367 / PG 29 / MQ 21 passed + run-the-app 자산 중심 e2e(영구 슬롯 생성·reconcile·slot_id 매수)
    • BAT-031 (dcy-021): 단위 378 / 통합 422 passed + 사이징 e2e(증액 가중평균·부분 매도 잔량·전량 매도)
    • BAT-032 (dcy-022): 425 passed(신규 71 tests — policy lifecycle·timeout·slippage·cancel), 회귀 없음
    • BAT-033: 426 passed (AC-7 --qty guard + 기존 enter 회귀 보완)
    • BAT-034 (dcy-023): 428 passed + PG 게이트 21 passed + ruff clean, 마이그레이션 013 테스트 DSN 멱등 round-trip + 컬럼 부재, grep allocated_capital 전수 0건
    • BAT-035 (dcy-025): 420 passed / 45 skipped — test_slots_handler.py 신규 13 cases(REQ-073 AC-15·REQ-074 AC-15 망라), 삭제 4 files(snapshot_handler/snapshot_selection/snapshot_rpc_watchdog/messaging_snapshot_consumer), ruff clean, REQ-028 코드 전수 제거 확인
    • BAT-036 (dcy-024): 420 passed / 45 skipped — test_instance_config.py 신규 3 cases(default True·false toml·true toml), ruff clean
    • SRS: 포함 REQ 전부 Implemented(Approved/Proposed 0건), batch register 11건 release-candidate
  • 배포 후 (app-service profile):
    • 데몬 RUNNING + 비-degraded, 마이그레이션 009~013 적용 로그, 백그라운드 스레드(snapshot scheduler·execution loop) 기동
    • universe reconcile 슬롯 생성: 자산 수 = 슬롯 수, retire/tombstone 동작
    • trex-core enter(--qty 필수·--capital 거부)·slots·cancel 스모크
    • buy→fill→증액→부분 매도 e2e + timeout/slippage 정책 발화 확인
    • ledger_outbox completed, daily_slot 에 trading_date/entry_count/allocated_capital 컬럼 부재 확인

Pre-Release Run Evidence (operator-facing smoke)

confirm-release 전 run-the-app 증거 (2026-06-11, run-trex-core-daemon 프로젝트 skill 경로). 실 데몬(RabbitMQ + 실 PostgreSQL) 기동 + 메시징/CLI 구동으로 본 릴리즈의 신규 동작을 검증했다.

  • 환경: paper 브로커 + 테스트 PostgreSQL trex_core_test(운영 DB 미사용) + 테스트 RabbitMQ, portfolio-hub stub(pf-005930/pf-000660), instance_key rel006smoke(큐 격리), --config /tmp/rel006smoke/rel006smoke.toml --env-file /tmp/rel006smoke/.env(BAT-026 config-dir 경로 실사용), max_active_slots=5.
  • 기동 + cutover (BAT-027~030) — PASS: 토폴로지 선언(trex.intent.req.rel006smoke 등) 후 데몬 ready. daily preallocation 없이 snapshot scheduler 의 universe reconcile 이 영구 자산 슬롯 생성: slot reconcile: {'created': 2, 'retired': 0, 'tombstoned': 0} — 자산 수(2) = 슬롯 수(2), status inactive.
  • e2e 메시징 smoke (smoke.py) — PASS: snapshot RPC(slots=2, available_slots=5) → slot_id 키 buy admitted → 동일 intent_id 중복 재전송 identical(멱등) → paper fill 로 holding qty=10 avg_price=1000 → sell admitted → inactive(점유 해제·자산 바인딩 유지).
  • BAT-033 (--qty 필수) — PASS: enter pf-005930 --yes(qty 없음) → error: --qty is required..., rc=1, RPC 미발생.
  • BAT-034 (--capital 제거) — PASS: enter ... --capital 100000 → argparse unrecognized arguments: --capital, rc=2. slots detail 에 allocated_capital 행 없음.
  • BAT-031 (포지션 사이징) — PASS: holding(10@1000) 슬롯에 증액 매수 --qty 5 --entry-price 2000 → admitted(holding→pending_buy) → fill 후 qty=15.0 avg_price=1333.3333(정확한 가중평균). 전량 매도 → inactive qty=None portfolio_id 유지.
  • BAT-032 (운영자 cancel 백스톱) — PASS: holding 슬롯에 trex-core cancel → ignored: not_pending, rc=0 (control RPC 경로 end-to-end).
  • DB 계약 (마이그레이션 009~013) — PASS: daily_slot 에 trading_date/entry_count(011)·allocated_capital(013) 컬럼 부재 확인. ledger_outbox 5행 전부 completed.
  • 종료: SIGTERM → Normal shutdown, 에러/traceback 0건(로그의 error-매칭 라인은 전부 pika INFO).
  • 한계(운영 배포 검증으로 이월): LIVE KIS 주문 미검증(paper 한정), portfolio-hub stub(실 universe/ledger 연동은 배포 후 확인), timeout_sec/slippage_pct 정책 발화는 전략 intent 필드라 CLI 미노출 — BAT-032 단위(71 tests) evidence 로 갈음하고 배포 후 전략 모듈 경유로 확인.
  • BAT-035 (trex.slots.req 교체) — 단위 검증 갈음: Pre-release 실 데몬 smoke 는 BAT-026034 범위로 수행됐으며 BAT-035 라이브 RPC 응답은 미확인. 갈음 근거: test_slots_handler.py 13 cases(REQ-073 AC-15·REQ-074 AC-1~5) + test_cli_operator.py slots queue/spy=true 경로 + test_topology.py 상수 교체 전수. 외부 소비자 분석: trex.snapshot.req 구독은 운영자 CLI 전용이고 CLI 는 이미 갱신됨 — 차단 없음. 배포 후 첫 trex-core slots 호출로 즉시 확인 가능(Rollout 5단계).
  • BAT-036 (safety_sell_enabled) — 단위 검증 갈음: safety_sell_enabled=false 라이브 데몬 smoke 미수행. 갈음 근거: test_instance_config.py 3 cases(default·false·true toml 경로) + daemon.py 코드 경로 검토. 기본값 true 유지 시 배포 직후 동작 변화 없음 — false 설정은 운영자 명시적 TOML 변경 시에만 활성화되므로 위험도 낮음.

Release Execution Evidence

  • Release Status Transition Target: released

Deployment Facts

  • Executed At:
    • 2026-06-11 (최초 배포 002340e)
  • Completed At:
    • 2026-06-12 (긴급패치 포함 최종 808a851)
  • Environment:
    • 운영 — 인스턴스 trex-admin-daily-trading (KIS LIVE 브로커 + 운영 PostgreSQL trex_core + RabbitMQ + portfolio-hub)
  • Operator:
    • Justin Ko
  • Revision or Artifact:
    • 최초 배포 002340e → 긴급패치 후 최종 808a851 (계획 SHA f0ad377 이후 main 진행분 포함 배포)
  • Commands or Procedure:
    • 데몬 중단 → git pull → pip install -e . → 데몬 재기동. apply_migrations 009~013 자동 적용(멱등).

Hotfix 경위 (배포 중 결함 → 무롤백 패치)

  • 최초 배포(002340e) 후 재기동 시 슬롯 symbol 전부 None 로딩 — universe reconcile 이 슬롯 생성 시 symbol 미저장 결함.
  • 221a163 fix(smoke): topology API 변경 반영(snapshot_queue→slots_queue) / 24a6017 fix(reconcile): symbol 저장 + NULL backfill / 808a851 docs(req-058): CHG-20260611-01 반영.
  • 패치 후 재기동: 45/45 슬롯 symbol 정상 로딩 확인.

Profile-Specific Checks

  • app-service:
    • Health Endpoint:
      • PASS — 데몬 RUNNING(PID 가동, RabbitMQ 3연결 OPEN), portfolio-hub HTTP 200, KIS inquire-balance HTTP 200, slots RPC degraded=None (2026-06-12)
    • Startup Log Fields:
      • PASS — 마이그레이션 009~013 적용(운영 DB information_schema 직접 확인: trading_date/entry_count/allocated_capital 부재, instance_key 존재, ledger_outbox 미완료 0건). universe reconcile 영구 슬롯 45개 생성(daily preallocation 부재 정상), universe_detached 0건.
    • Request Log Fields:
      • PASS — 실거래 e2e 전이 로그: ①장외 enter(2026-06-11 19:31): admitted → inactive→pending_buy → KIS order-cash 200 → 거부(장운영시간 아님) rollback pending_buy→inactive. ②장중 full e2e(2026-06-12, 005930 1주): 09:32 buy intent inactive→pending_buy → 09:32 체결 pending_buy→holding(qty=1, avg 334,000) → 14:37 safety-sell stop_loss 자동 발화 holding→pending_sell → 14:37 체결 pending_sell→inactive. ledger buy/sell 2건 completed. slot qty(1.0)==hub asset_quantity(1.0) divergence 없음.
    • Smoke or Manual Verification:
      • PASS — BAT-035: slots(count=45, slots[] 형식·assets[] 부재)/--status holding·buyable 서버 필터/universe(slots.req 큐, spy=true)/JSON 스키마(allocated_capital 부재·watchdog·asset_quantity 포함). BAT-033: --qty 누락 즉시 오류 rc=1. BAT-034: --capital argparse 거부 rc=2 + 45개 전수 allocated_capital 부재. BAT-032: cancel dry-run rc=0. BAT-036: TOML 미설정 → default true 워커 기동 확인.

Rollback Outcome

  • Rollback Required:
    • no
  • Rollback Trigger:
    • none
  • Rollback Action:
    • none — 최초 배포의 symbol 누락 결함은 롤백 없이 긴급패치(24a6017)로 해소(REQ-058 CHG-20260611-01 로 문서 정합 완료).

Release Decision Evidence

  • Released Decision:
    • released 전환 — 운영팀 배포 근거 종합 판정 전 항목 PASS(마이그레이션/기동·cutover/심볼 로딩/BAT-031~036 스모크/실거래 full e2e), 롤백 불요.
  • Rationale:
    • 운영 실거래(005930 매수→보유→stop_loss 자동 청산)로 자산 중심 슬롯 lifecycle·포지션 사이징·safety-sell·ledger 전 경로 무결 검증. 손익 −7,099.15원(−2.13%)은 손절 청산 결과이며 시스템 동작 관점 PASS.
  • Recorded By:
    • Justin Ko (운영팀 배포 근거) / 기록 정리: stage-pilot capture
  • Recorded At:
    • 2026-06-12

Feedback Handoff

  • Observation Summary (2026-06-12, 운영팀 배포 근거 §8 + 실거래 데이터):
    • 배포 중 결함 1건(긴급패치 해소): universe reconcile 슬롯 생성 시 symbol 미저장 → 재기동 후 45슬롯 전부 symbol=None. 24a6017 패치(생성 시 저장 + NULL backfill) 후 45/45 정상. REQ-058 CHG-20260611-01 로 AC-5 추가 완료 — 회귀 방지 테스트는 기존 reconcile 테스트(symbol 포함 시그니처)로 커버됨.
    • 실거래 full e2e 검증: 005930 매수(09:32)→보유→stop_loss 자동 청산(14:37) 완주. 포지션 사이징(avg_price/qty 반영, 브로커 잔고 기준 청산), safety-sell 자동 발화, slot↔hub 수량 일치(divergence 0), ledger buy/sell completed.
    • 잔존 관찰 1 — watchdog_expired 상시: 전략 모듈(trex-orb-v1) 미연결 상태라 watchdog expired 가 일상 — 전략 연결 시 해소. 수동 주문은 forced_close_at 기반 관리로 영향 없음. (중장기 인스턴스의 동일 문제는 dcy-027/BAT-041 watchdog_timeout_sec per-instance TOML 로 별도 해소됨 — 차기 릴리즈)
    • 잔존 관찰 2 — 매도세 tax=0 왜곡 지속: 본 릴리즈 리비전(808a851)은 BAT-038(매도 증권거래세, dcy-026/issue #24) 이전 — 2026-06-12 매도 체결도 세금 0 으로 기록됨(수수료 49.05 만). 수정은 BAT-038(release-candidate)에 있으며 차기 릴리즈 배포 전까지 신규 매도 ledger 의 tax=0 왜곡이 계속됨. 과거 행 소급 보정은 안 함(dcy-026 OQ-3).
    • 운영 메모: trex-admin-daily-trading 은 계좌 전체 cash 공유 모델(portfolio-hub 는 자산별 PnL 만 기록) — 슬롯 cash_balance 음수는 정상.
  • Discovery Input:
    • 없음 (자율 청산 OFF 모드 issue #15 → dcy-024 완료, 중장기 전략 슬롯 issue #20 → dcy-027 완료. watchdog 소유권 진입 외부 알림(슬랙·이메일)은 dcy-027 OQ-3 주석으로 이미 후속 Discovery 백로그에 등재)
  • REQ Input:
    • 없음 — 신규 요구사항 후보 없음(잔존 관찰은 전부 기존 트랙으로 커버)
  • Change Request Input:
    • daily_symbol_entries 잔재 제거(REL-005 환류 승계 — REQ-002/006 change-req 트랙, 미착수)
    • paper 브로커 order seq Redis 영속화(issue #4) — 완료(REQ-011 CHG-20260612-01, BAT-039 release-candidate)
    • default_order_timeout_sec TOML 전파 누락(BAT-041 구현 중 발견 pre-existing — from_toml 파싱되나 from_config 미전파로 런타임 무시. REQ-048/068 change-req 트랙, 미착수)
  • 차기 릴리즈 입력: BAT-037~041 5건 release-candidate 대기(REL-007 후보) — BAT-038 매도세 수정 포함이므로 조기 배포 권장(위 잔존 관찰 2).