Files
trex-core/docs/batches/bat-030_20260610_asset-centric-cutover/design.md
T
genichinandClaude Opus 4.8 cec34be5f4 docs(batch): draft-batch BAT-030 (dcy-020 BAT-δ cutover) + design 확정
dcy-020 최종 배치. design 확정(사용자 결정):
- D1: 전체 rebuild — daily_slot 비우고 universe+브로커 잔고 기준 재생성,
  보유 carry-over 정본=브로커 잔고
- D2: 전부 완성 — literal inactive 전면화 + idle/closed 별칭 제거 +
  entry_count/trading_date 컬럼 drop
- D3: 집행 매도 수량 브로커 정본(미러 fallback 없음, 0이면 skip+divergence)
- D4: 실 cutover 는 운영자(REL 단계, 리허설 후); 본 배치는 스크립트+코드+test DB 리허설
batches/index BAT-030 등록.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 12:36:09 +09:00

3.9 KiB

BAT-030 Design

  • Status: confirmed (D1~D4 확정 — 2026-06-10, 사용자 결정)
  • Batch: BAT-030

체크포인트 결정(2026-06-10): D1=전체 rebuild(보유는 브로커 잔고 기준 carry-over) / D2=전부 완성(literal inactive + 별칭 제거 + entry_count·trading_date drop) / D3=집행 매도 qty 브로커 정본(미러 fallback 없음, 0이면 skip+divergence) / D4=실 cutover 는 운영자(REL 단계, 리허설 후). 아래 §1 을 전체 rebuild 로 읽는다.

설계 목표

  • 자산 중심 모델을 완성하고 라이브로 안전 전환. 보유 포지션 무손실·집행 정확·비가역 변경 통제.

1. cutover (REQ-064) — 전체 rebuild (D1)

  • 전체 rebuild: 해당 instance_key 의 daily_slot 을 비우고 universe + 브로커 잔고 기준으로 재생성한다. 보유 carry-over 의 정본 = 브로커 잔고(D3 와 일관).
  • 절차(cutover 스크립트, Python — broker + universe 필요):
    1. 사전: 거래 세션 외, in-flight(pending_*) 0 확인(아니면 수렴 대기). 백업.
    2. 해당 instance_key 슬롯 삭제(또는 신규 테이블 swap).
    3. universe(get_portfolios) 의 모든 자산 → 영구 슬롯 생성(inactive).
    4. 브로커 잔고(get_balance)의 각 보유 (symbol, qty) → universe 로 symbol→portfolio_id 매핑 → 해당 자산 슬롯을 holding(qty=브로커 수량, avg_price=브로커/원장) 으로 설정.
    5. instance_key 태깅, 부분 UNIQUE → 전체 UNIQUE 승격.
  • 매핑 실패(브로커 보유 symbol 이 universe 에 없음) → 중단/경고(운영자 판단; 자동 청산 없음).
  • 실 cutover 는 운영자 실행(D4) — 본 배치는 cutover 스크립트 + test DB 리허설 제공.

2. 집행 매도 수량 브로커 정본 (REQ-062 M2(b))

  • execution.py dispatch: 매도 시 qty = int(slot.qty) → broker.get_balance() 의 해당 symbol hldg_qty. 미러 stale 무관 정확. 브로커 0 이면 매도 skip + divergence(REQ-062 A) 경로로 표면화.

3. literal inactive 전면화 (REQ-057 잔여)

  • state.py: idle/closed 별칭 제거(또는 deprecated 유지하되 코드 산출은 inactive). 전이/리셋이 inactive 산출.
  • execution.py: PENDING_SELL→INACTIVE(매도 체결), PENDING_BUY→INACTIVE(롤백). postgresql/cli/ops_checks 의 'idle'/'closed' → 'inactive'(쿼리/필터).
  • 마이그레이션 010(CHECK): status CHECK 에 'inactive' 허용 + 기존 idle/closed 행 → inactive UPDATE.

4. 컬럼 drop (REQ-056 잔여)

  • entry_count drop(미사용). 슬롯 trading_date: drop 또는 opened_at 재의미(이벤트 시간 속성으로). 모델/EXPECTED_SLOT_FIELDS/persistence/드리프트 가드 정합. legacy preallocation 경로 제거.
  • 비가역 → drop 전 코드 미참조화 선행, 백업, 롤백(직전 리비전+컬럼 복원).

5. default 전환

  • 코드 default 변경 아님 — 운영 인스턴스 TOML 에 max_active_slots 설정으로 자산 중심 활성(config 게이트). 배포 단계 운영자 작업.

6. baseline 마감 (REQ-065)

  • data-model/runtime-flows/project-structure 를 최종 자산 중심으로 갱신, dcy-001/014/019·daily_symbol_entries 폐기 확정.

롤백

  • 직전 released 리비전 + (필요시) 역마이그레이션(inactive→idle/closed, 컬럼 복원). 보유 행은 portfolio_id 보존이라 구 코드와 공존(부분). 컬럼 drop 은 백업 복원.

체크포인트 결정 필요

  1. D1 — cutover 방식: 보유 행 재사용 + vestigial idle 삭제 + reconcile(권장) vs 전체 rebuild.
  2. D2 — 본 배치 완성 범위: literal inactive + 별칭 제거 + entry_count/trading_date drop 전부 완성(권장) vs 일부 유지.
  3. D3 — 집행 매도 qty: 브로커 정본(미러 fallback 없음, 0이면 skip+divergence)(권장) 확인.
  4. D4 — 실 cutover 실행 주체: 운영자(REL 단계, 리허설 후)(권장) — 본 세션은 마이그레이션+코드+test DB 리허설까지.