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>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
# 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 리허설까지.
|
||||
Reference in New Issue
Block a user