- BAT-035/036 batch index: confirmed → release-candidate - rel-006: BAT-035/036 추가, status confirmed, SHA 명시, smoke 한계·외부 소비자 분석 기술 - daemon.py: stale 주석 trex.snapshot.req → trex.slots.req Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
14 KiB
14 KiB
REL-006: 자산 중심 영구 슬롯 cutover + 포지션 사이징 + 실행 정책 + 운영 정리 통합 릴리즈
- Status: confirmed
- 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_countDROP, 비가역). - 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 TOMLdefault_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--capitalargparse 거부, BuyIntent·payload 수신 무시, Slot/EXPECTED_SLOT_FIELDS, snapshotslots[]. 마이그레이션 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 liquidationWARNING 로그.ExecutionService·kill-switch·전략 sell intent 불변.
- BAT-026 (batch-lite / REQ-048·010 CHG): config 디렉터리 기반 설정 관리 —
- Excluded:
- BAT-001
025 (REL-001005 에서 released) - trex-orb-v1 등 외부 전략 모듈 저장소 변경(발신 계약 전환·allocated_capital 송신 정리 — 별도 합의)
daily_symbol_entries잔재 제거(REL-005 환류 — 별도 change-req 트랙)
- BAT-001
Rollout Plan
- 배포 대상 커밋:
f0ad37747b4e9d43dc798bfeda5b543cab048890(main, 2026-06-11)
- 배포 전: 거래 세션 외 시간 확보, 현재 운영 리비전 SHA 기록, 위 배포 SHA(
f0ad377) 확인. - DB 백업(필수): 마이그레이션 011·013 은 비가역 컬럼 DROP — 적용 전 운영
daily_slot(권장: DB 전체) 백업. BAT-030 design §4 절차 준용. - 신 리비전 배포 + 데몬 재기동.
apply_migrations가 009~013 자동 적용(전부 멱등). 기동 로그에서 마이그레이션 적용·RUNNING·비-degraded 확인. - cutover 확인: daily preallocation 부재가 정상 — 영구 자산 슬롯은 snapshot scheduler 의 universe reconcile 이 생성/retire 한다. 기동 직후 universe fetch → 슬롯 생성 로그 확인,
trex-core slots로 자산 수 = 슬롯 수 확인. - 운영자 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)
- BAT-035 외부 소비자 없음 확인:
trex.snapshot.req구독자는 운영자 CLI 전용이며 CLI 는 이미trex.slots.req로 갱신됨. 전략 모듈(trex-orb-v1)은trex.intent.req생산자만이고 snapshot 소비자가 아니므로 차단 없음. - 전략 모듈(trex-orb-v1) 재연결 후 buy intent 정상 admit 확인 —
allocated_capital송신 잔존은 unknown key 로 무시되어 무해. - BAT-036 확인(해당 시): TOML 에
safety_sell_enabled = false설정 시 데몬 기동 로그에no autonomous liquidationWARNING 출력·trex-safety-sell워커 미기동 확인. 기본값true유지 시 변화 없음. - 거래 세션 재개.
Rollback Plan
- 조건: 기동 실패, 마이그레이션 오류, universe reconcile 슬롯 생성 실패(전 자산 미생성), buy admission 회귀, 집행 루프(timeout/slippage) 오작동, CLI 회귀.
- 절차: 직전 released 리비전(REL-005 시점)으로 롤백 + 데몬 재기동 + 백업 복원.
- 마이그레이션: 011(
trading_date·entry_countDROP)·013(allocated_capitalDROP)은 구 코드의 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
--qtyguard + 기존 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_outboxcompleted,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_keyrel006smoke(큐 격리),--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), statusinactive. - 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→ argparseunrecognized arguments: --capital, rc=2.slotsdetail 에 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_outbox5행 전부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 응답은 미확인. 갈음 근거:5·REQ-074 AC-1~5) +test_slots_handler.py13 cases(REQ-073 AC-1test_cli_operator.pyslots 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.py3 cases(default·false·true toml 경로) +daemon.py코드 경로 검토. 기본값true유지 시 배포 직후 동작 변화 없음 —false설정은 운영자 명시적 TOML 변경 시에만 활성화되므로 위험도 낮음.
Release Execution Evidence
- Release Status Transition Target: released
Deployment Facts
- Executed At:
- <배포 시작 시각>
- Completed At:
- <배포 완료 시각>
- Environment:
- <배포 대상 환경>
- Operator:
- <배포 수행자>
- Revision or Artifact:
- <커밋 SHA — 배포 전 main 커밋으로 확정>
- Commands or Procedure:
- <실행 명령 또는 배포 절차 요약>
Profile-Specific Checks
- app-service:
- Health Endpoint:
- <snapshot RPC degraded=false 확인 결과와 시각>
- Startup Log Fields:
- <마이그레이션 009~013 적용 + universe reconcile 슬롯 생성 로그>
- Request Log Fields:
- <buy/sizing intent admission·집행·timeout/slippage·cancel 전이 로그>
- Smoke or Manual Verification:
- <Rollout 5~6 단계 스모크 결과>
- Health Endpoint:
Rollback Outcome
- Rollback Required:
- <yes 또는 no>
- Rollback Trigger:
- <발생 시 원인, 없으면 none>
- Rollback Action:
- <수행한 조치, 없으면 none>
Release Decision Evidence
- Released Decision:
- <released 전환 여부>
- Rationale:
- <released 전환 판단 근거>
- Recorded By:
- <기록자>
- Recorded At:
- <기록 시각>
Feedback Handoff
- Observation Summary:
- <운영 관찰 사실 요약 또는 없음>
- Discovery Input:
- <후속 discovery 후보 — 후보 백로그: 자율 청산 OFF 모드(issue #15), 중장기 전략 슬롯(issue #20)>
- REQ Input:
- <후속 req 후보>
- Change Request Input:
daily_symbol_entries잔재 제거(REL-005 환류 승계 — REQ-002/006 change-req 트랙), paper 브로커 order seq Redis 영속화(issue #4 — REQ-011 change-req 트랙)