feat(rel-006): dcy-022/023 + BAT-032~034 — 실행 정책·qty 검증·allocated_capital 제거 통합
BAT-032 (dcy-022): timeout_sec/slippage_pct 실행 정책, 미체결 자동 취소, 보호 지정가, `trex-core cancel` 백스톱. 마이그레이션 012. BAT-033: `trex-core enter --qty` 필수 검증 — 미지정 시 RPC 전 즉시 오류. BAT-034 (dcy-023): allocated_capital 죽은 필드 전 경로 제거 (domain·intent· persistence·snapshot·CLI). 마이그레이션 013(비가역 DROP). 외부 발신자 unknown key 무시 수신 의미론 적용. REL-006 confirmed: BAT-026~034 통합 릴리즈, pre-release smoke 증거 포함. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# BAT-024: 운영자 `enter` 시간 기반 자동청산 옵션 — `--forced-close-at` (절대시간) 노출 (issue #17)
|
||||
|
||||
- Status: release-candidate
|
||||
- Status: released
|
||||
- Profile: batch-lite
|
||||
- Source Discovery: dcy-016 (issue #17 change-req)
|
||||
- Included REQ: REQ-032 (CHG-20260609-01)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# BAT-025: slot-scoped entry_count + closed 슬롯 직접 재할당 (dcy-019)
|
||||
|
||||
- Status: release-candidate
|
||||
- Status: released
|
||||
- Profile: standard
|
||||
- Source Discovery: dcy-019
|
||||
- Included REQ: REQ-002 (CHG-20260609-01), REQ-003 (CHG-20260609-01), REQ-006 (CHG-20260609-01), REQ-007 (CHG-20260609-01), REQ-009 (CHG-20260609-01)
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# BAT-032 Design
|
||||
|
||||
- Status: approved
|
||||
- Batch: BAT-032
|
||||
|
||||
## 설계 결정
|
||||
|
||||
### D1: 실행 정책 필드를 슬롯 컬럼으로 저장 (timeout_sec, slippage_pct)
|
||||
|
||||
- 결정: `Slot` 모델에 `timeout_sec: Optional[int]`, `slippage_pct: Optional[float]` 컬럼 추가. PENDING_* 진입 시 set, 탈출(→HOLDING/→INACTIVE) 시 clear.
|
||||
- 근거: 집행 루프가 dispatch/poll 시 슬롯만 읽으면 되어 별도 캐시/in-memory 구조 불필요. limit_price 와 동일한 패턴(set on pending entry, cleared on exit).
|
||||
- 대안: in-memory dict 에 별도 저장 → 재시작 시 유실, 재기동 reconciliation 에서 timeout 추적 불가. 기각.
|
||||
|
||||
### D2: updated_at 을 dispatch 시각 proxy 로 사용 (기존 stale watchdog 방법 계승)
|
||||
|
||||
- 결정: timeout 경과 시간 = `(now - slot.updated_at).total_seconds()`. mark_dispatched 가 updated_at 을 갱신하므로 dispatch 시각과 일치.
|
||||
- 근거: `_check_stale_pending`(REQ-014) 이 이미 동일 방법 사용 → 일관성, 추가 필드 불필요.
|
||||
- 한계: PENDING_* 상태에서 `update_thresholds` 가 호출되면 updated_at 이 리셋될 수 있으나, `update_thresholds`는 HOLDING 슬롯에만 작동(REQ-040) → 실질적 충돌 없음.
|
||||
|
||||
### D3: cancel_order best-effort, 즉시 롤백 없음 (race 안전)
|
||||
|
||||
- 결정: `_try_timeout_cancel` 에서 cancel_order 송신만 하고 슬롯 상태를 변경하지 않는다. 다음 poll 틱에서 is_terminal_reject/is_partial_cancel 로 수렴.
|
||||
- 근거: 취소-체결 race(cancel 수락 직전 체결) 시 다음 poll 이 is_filled 경로로 정상 수렴 → 임의 롤백 없음. dcy-013 부분 취소 선례 재사용.
|
||||
|
||||
### D4: cancel CLI → control RPC → ExecutionService.cancel_pending_slot
|
||||
|
||||
- 결정: CLI는 `trex.control.req` 채널로 `{"action": "cancel_pending", "slot_id": ...}` 를 전송. 제어 핸들러가 `ExecutionService.cancel_pending_slot(slot_id)` 를 호출해 cancel_order 를 송신. 슬롯 전이 없음.
|
||||
- 근거: 기존 kill_switch·pause 와 동일한 경로(단일 writer 불변식 보존). execution_service 를 control 핸들러에 주입하는 방식으로 커플링 최소화.
|
||||
- 대안: intent RPC 채널 재사용 → intent 계약(buy/sell)과 의미 혼용. 기각.
|
||||
|
||||
## 컴포넌트 다이어그램 (텍스트)
|
||||
|
||||
```
|
||||
CLI: trex-core cancel <slot_id>
|
||||
→ control RPC (trex.control.req) cancel_pending
|
||||
→ make_control_rpc_handler (execution_service.cancel_pending_slot)
|
||||
→ broker.cancel_order(broker_order_id)
|
||||
→ [다음 tick _poll] is_terminal_reject / is_partial_cancel
|
||||
→ rollback / partial-preserve (기존 경로)
|
||||
```
|
||||
|
||||
```
|
||||
Intent: {intent_type: "buy", timeout_sec: 60, slippage_pct: 0.1}
|
||||
→ messaging_handlers (파싱 → BuyIntent)
|
||||
→ IntentService._admit_buy (effective_timeout 해결 → transit_slot)
|
||||
→ SlotService (slot.timeout_sec=60, slot.slippage_pct=0.1 set)
|
||||
→ [_dispatch] slippage 실효 지정가 → OrderRequest.limit_price
|
||||
→ [_poll] timeout 초과 → _try_timeout_cancel → cancel_order
|
||||
→ [다음 tick] is_terminal_reject → rollback
|
||||
```
|
||||
@@ -0,0 +1,62 @@
|
||||
# BAT-032 Implementation
|
||||
|
||||
- Status: done
|
||||
- Batch: BAT-032
|
||||
|
||||
## M1 — 실행 정책 계약·파싱·슬롯 저장 (REQ-068, REQ-061 CHG-05)
|
||||
|
||||
**변경 파일**
|
||||
|
||||
| 파일 | 내용 |
|
||||
|---|---|
|
||||
| `trex_core/domain/slot/models.py` | `Slot` dataclass 에 `timeout_sec: Optional[int]`, `slippage_pct: Optional[float]` 추가. `EXPECTED_SLOT_FIELDS` 갱신. |
|
||||
| `trex_core/adapters/persistence/sql/012_add_execution_policy_fields.sql` | `ALTER TABLE daily_slot ADD COLUMN IF NOT EXISTS timeout_sec INTEGER; … slippage_pct FLOAT;` |
|
||||
| `trex_core/domain/slot/service.py` | `transit_slot`·`_apply_transition_fields` kwargs 확장. PENDING_* 진입 시 set, HOLDING/INACTIVE/ERROR 진입 시 clear (limit_price 동일 생애주기). |
|
||||
| `trex_core/adapters/persistence/postgresql.py` | `_SLOT_COLUMNS`에 col 19·20 추가. `update_slot` SQL 갱신. `_row_to_slot` 인덱스 추가. |
|
||||
| `trex_core/application/intents.py` | `BuyIntent`·`SellIntent` 에 `timeout_sec`·`slippage_pct` 추가. `IntentService.__init__` 에 `default_order_timeout_sec`. `_admit_buy`·`_admit_sell` 에서 effective_timeout 해석. |
|
||||
| `trex_core/application/messaging_handlers.py` | buy/sell 핸들러에서 `_opt_int`·`_opt_float` 파싱 추가. |
|
||||
| `trex_core/runtime/config.py` | `DaemonInstanceConfig.default_order_timeout_sec`. |
|
||||
| `trex_core/runtime/daemon.py` | `IntentService` wiring 에 `default_order_timeout_sec` 전달. |
|
||||
|
||||
## M2 — slippage 보호 지정가 dispatch (REQ-070, REQ-013 CHG-03 partial)
|
||||
|
||||
**변경 파일**
|
||||
|
||||
| 파일 | 내용 |
|
||||
|---|---|
|
||||
| `trex_core/application/execution.py` | `_dispatch`: limit 계산 후 slippage 블록 추가. buy: `ceil(limit*(1+pct/100))`, sell: `floor(limit*(1-pct/100))`. `import math` 추가. |
|
||||
|
||||
## M3 — timeout 집행 + race 처리 (REQ-069, REQ-013 CHG-03 partial)
|
||||
|
||||
**변경 파일**
|
||||
|
||||
| 파일 | 내용 |
|
||||
|---|---|
|
||||
| `trex_core/application/execution.py` | `ExecutionResult.timeout_cancelled` 추가. `_poll` else branch에 `_try_timeout_cancel` 추가. `_try_timeout_cancel` 구현: `slot.updated_at` proxy로 경과 체크 → `cancel_order` best-effort → `r.timeout_cancelled += 1`. |
|
||||
|
||||
## M4 — 운영자 cancel 백스톱 (REQ-071)
|
||||
|
||||
**변경 파일**
|
||||
|
||||
| 파일 | 내용 |
|
||||
|---|---|
|
||||
| `trex_core/application/execution.py` | `cancel_pending_slot(slot_id)` 메서드: PENDING_* slot → `cancel_order` 송신 → "ok"/"not_pending"/"slot_not_found"/"not_dispatched"/"cancel_failed" 반환. 슬롯 전이 없음 (단일 writer 보존). |
|
||||
| `trex_core/application/messaging_handlers.py` | `make_control_rpc_handler` 에 `cancel_pending_fn` 파라미터. `cancel_pending` 액션 라우팅. `_handle_cancel_pending` 구현. |
|
||||
| `trex_core/runtime/cli.py` | `cancel <slot_id>` 서브커맨드. `_cmd_cancel`. `_add_intent_guards` (--yes/--dry-run/--live). control RPC 경유. |
|
||||
| `trex_core/runtime/daemon.py` | `make_control_rpc_handler(cancel_pending_fn=self.execution.cancel_pending_slot)` 배선. |
|
||||
|
||||
## M5 — baseline 문서 정합 (REQ-072)
|
||||
|
||||
**변경 파일**
|
||||
|
||||
| 파일 | 내용 |
|
||||
|---|---|
|
||||
| `docs/interface-contract.md` | buy/sell payload에 `timeout_sec`·`slippage_pct` 필드 기술. 하위 호환 주석 추가. cancel CLI 참조. |
|
||||
| `docs/runtime-flows.md` | dispatch 스텝: slippage 지정가 주석. poll 스텝: timeout 자동 취소 흐름. 실행 정책 생애주기. "운영자 cancel 백스톱" 섹션 추가. |
|
||||
|
||||
## 설계 결정 근거 (design.md 요약)
|
||||
|
||||
- **D1**: `timeout_sec`/`slippage_pct` 를 slot 컬럼으로 저장 — `limit_price` 와 동일 생애주기(PENDING 진입 시 set, 탈출 시 clear).
|
||||
- **D2**: `slot.updated_at` 을 dispatch 시각 proxy로 사용 — 기존 stale watchdog(REQ-014)과 동일 방법, 별도 컬럼 불필요.
|
||||
- **D3**: `cancel_order` 송신만, 즉시 롤백 없음 — cancel-fill race 안전. 다음 poll의 `is_terminal_reject`/`is_partial_cancel` 경로 재사용.
|
||||
- **D4**: cancel CLI → control RPC → `ExecutionService.cancel_pending_slot` — 단일 writer 불변식(A) 보존.
|
||||
@@ -0,0 +1,23 @@
|
||||
# BAT-032: 주문 실행 정책 — timeout·slippage·운영자 cancel (dcy-022)
|
||||
|
||||
- Status: release-candidate
|
||||
- Profile: standard
|
||||
- Source Discovery: dcy-022
|
||||
- Included REQ: REQ-068 (실행 정책 계약), REQ-069 (timeout 집행·race), REQ-070 (slippage dispatch), REQ-071 (운영자 cancel 백스톱), REQ-072 (baseline 정합), REQ-061 (CHG-05), REQ-013 (CHG-03)
|
||||
|
||||
## Summary
|
||||
- dcy-022: dcy-021(포지션 사이징) 전제 위에 **주문 실행 정책**(timeout_sec·slippage_pct)을 intent 계약에 추가하고 집행 루프에 배선한다. 미체결 주문은 timeout 초과 시 자동 취소·롤백(고착 예방), slippage 보호 지정가로 과도한 불리 체결을 방지. 잔여 고착 백스톱으로 운영자 cancel CLI 를 추가한다.
|
||||
|
||||
## Scope
|
||||
- In: timeout_sec/slippage_pct intent 계약·파싱·슬롯 저장, timeout 집행 (cancel_order 배선·race 처리·부분 보존), slippage 실효 지정가 dispatch, 운영자 cancel 백스톱(trex-core cancel), per-instance TOML default_order_timeout_sec, baseline 2문서.
|
||||
- Out: IOC/FOK 네이티브 TIF, 자동 리밸런싱, 전략 모듈(orb-v1) 발신 계약 전환(외부 repo, 별도 합의).
|
||||
|
||||
## Documents
|
||||
- Planning: [planning.md](./planning.md)
|
||||
- Design: [design.md](./design.md)
|
||||
- Implementation: [implementation.md](./implementation.md)
|
||||
- Verification: [verification.md](./verification.md)
|
||||
|
||||
## Notes
|
||||
- 집행 핫패스(라이브 주문) 확장 — additive(기존 경로 보존). design.md D1~D4 확정 후 구현.
|
||||
- 본 배치 완료 후 REQ-013/061/068/069/070/071/072 confirm-req-implemented.
|
||||
@@ -0,0 +1,64 @@
|
||||
# BAT-032 Planning
|
||||
|
||||
- Status: done
|
||||
- Batch: BAT-032
|
||||
|
||||
## Milestones
|
||||
|
||||
| ID | 목표 | 연결 REQ |
|
||||
|---|---|---|
|
||||
| M1 | 실행 정책 계약·파싱·슬롯 저장 | REQ-068, REQ-061(CHG-05) |
|
||||
| M2 | slippage 보호 지정가 dispatch | REQ-070, REQ-013(CHG-03 partial) |
|
||||
| M3 | timeout 집행 + race 처리 | REQ-069, REQ-013(CHG-03 partial) |
|
||||
| M4 | 운영자 cancel 백스톱 CLI + control RPC | REQ-071 |
|
||||
| M5 | baseline 문서 정합 | REQ-072 |
|
||||
|
||||
## M1 상세 (실행 정책 계약·파싱·슬롯 저장)
|
||||
|
||||
- `Slot` 모델: `timeout_sec: Optional[int]`, `slippage_pct: Optional[float]` 필드 추가. `EXPECTED_SLOT_FIELDS` 갱신.
|
||||
- Migration 012: `ALTER TABLE daily_slot ADD COLUMN IF NOT EXISTS timeout_sec INTEGER; ADD COLUMN IF NOT EXISTS slippage_pct FLOAT;`
|
||||
- `BuyIntent`/`SellIntent`: `timeout_sec`/`slippage_pct` 추가.
|
||||
- `IntentService`: `__init__` 에 `default_order_timeout_sec: Optional[int] = None` 추가. `_admit_buy`/`_admit_sell` 에서 effective_timeout = intent.timeout_sec ?? config_default → transit_slot 에 전달.
|
||||
- `SlotService.transit_slot` kwargs: `timeout_sec`/`slippage_pct` 전달. `_apply_transition_fields` 에서 PENDING_* 진입 시 set, 탈출(→HOLDING/→INACTIVE) 시 clear.
|
||||
- `messaging_handlers.py`: `timeout_sec=_opt_int(body.get("timeout_sec"))`, `slippage_pct=_opt_float(body.get("slippage_pct"))` 파싱 추가.
|
||||
- `DaemonInstanceConfig`: `default_order_timeout_sec: Optional[int] = None` 추가, from_toml 파싱.
|
||||
- `DaemonConfig` + daemon runtime 배선: IntentService 에 default_order_timeout_sec 전달.
|
||||
|
||||
## M2 상세 (slippage 보호 지정가 dispatch)
|
||||
|
||||
- `execution._dispatch`: limit 계산 후 slippage 적용:
|
||||
```python
|
||||
import math
|
||||
if limit is not None and slot.slippage_pct:
|
||||
factor = 1 + slot.slippage_pct/100 if side == "buy" else 1 - slot.slippage_pct/100
|
||||
limit = int(math.ceil(limit * factor)) if side == "buy" else int(math.floor(limit * factor))
|
||||
```
|
||||
- `_log.debug(...)` 로 slippage 적용 기록.
|
||||
|
||||
## M3 상세 (timeout 집행)
|
||||
|
||||
- `ExecutionResult`: `timeout_cancelled: int = 0` 추가.
|
||||
- `_poll` 의 else branch(`_check_stale_pending` 호출)에서 timeout 체크 추가:
|
||||
```python
|
||||
self._check_stale_pending(slot, now, r) # Alert-only (REQ-014, no change)
|
||||
self._try_timeout_cancel(slot, now, r) # NEW: cancel if timeout_sec exceeded
|
||||
```
|
||||
- `_try_timeout_cancel`: `slot.timeout_sec` 있고 경과 시간 초과 시 → `broker.cancel_order(...)` best-effort → `r.timeout_cancelled += 1` → WARNING 로그. 실패 시 WARNING, 상태 불변.
|
||||
|
||||
## M4 상세 (운영자 cancel 백스톱)
|
||||
|
||||
- `messaging_handlers.make_control_rpc_handler`: `cancel_pending` 액션 추가. `cancel_pending_fn` 콜백(slot_id → bool) 주입.
|
||||
- `execution.ExecutionService.cancel_pending_slot(slot_id)`: 슬롯 조회 → PENDING_* 이면 `broker.cancel_order` 송신. 슬롯 직접 전이 없음.
|
||||
- `cli.py`: `cancel <slot_id>` 서브커맨드 추가. `--dry-run`/`--yes`/`--live` 안전장치. control RPC 경유.
|
||||
- daemon.py 배선: make_control_rpc_handler 에 cancel_pending_fn 전달.
|
||||
|
||||
## M5 상세 (baseline 문서)
|
||||
|
||||
- `docs/interface-contract.md`: buy/sell payload 에 `timeout_sec`/`slippage_pct` 추가.
|
||||
- `docs/runtime-flows.md`: 집행 루프·dispatch 섹션에 timeout 취소·slippage·cancel 백스톱 흐름 추가.
|
||||
|
||||
## 위험 요소
|
||||
|
||||
- **R-1 (취소-체결 race)**: cancel_order 송신 후 즉시 롤백하지 않고 다음 poll 수렴 → 기존 is_terminal_reject/is_partial_cancel 경로 재사용 완화.
|
||||
- **R-2 (부분 체결 보존)**: timeout cancel → is_partial_cancel → 기존 `_on_partial_cancel` 선례(dcy-013) 재사용.
|
||||
- **R-3 (단일 writer)**: cancel CLI 는 cancel_order 만 송신; 슬롯 전이는 집행 루프 단독 → 불변식 보존.
|
||||
@@ -0,0 +1,69 @@
|
||||
# BAT-032 Verification
|
||||
|
||||
- Status: approved
|
||||
- Batch: BAT-032
|
||||
|
||||
## Test Evidence
|
||||
|
||||
단위 테스트 425 passed, 45 skipped (통합 제외). 신규 71 tests.
|
||||
|
||||
```
|
||||
.venv/bin/python -m pytest tests/ -q --ignore=tests/integration
|
||||
425 passed, 45 skipped in 1.18s
|
||||
```
|
||||
|
||||
## 신규 테스트 파일
|
||||
|
||||
| 파일 | 커버리지 |
|
||||
|---|---|
|
||||
| `tests/domain/slot/test_execution_policy_lifecycle.py` | REQ-068: PENDING 진입 시 set, HOLDING/INACTIVE 탈출 시 clear (10 cases) |
|
||||
| `tests/application/test_execution_policy.py` | REQ-069/070/071: slippage dispatch (buy ceil, sell floor, market=skip, no-slippage=unchanged, zero) + timeout cancel (exceeded→cancel sent, not exceeded→no cancel, no timeout_sec→no cancel, exception best-effort, state unchanged, cancel-fill race) + cancel_pending_slot (ok, not_pending, slot_not_found, not_dispatched, cancel_failed, state unchanged) |
|
||||
| `tests/application/test_execution_policy_handler.py` | REQ-068/071 핸들러: buy/sell intent payload 파싱 (timeout_sec/slippage_pct), default_order_timeout_sec 계층적 해석, control cancel_pending 액션 (ok/not_pending/slot_not_found/no-fn/cancel_failed/missing-slot_id) |
|
||||
| `tests/runtime/test_cli_operator.py` (기존 확장) | REQ-071 cancel CLI: 확인 없이 중단, --yes 제출, --dry-run 스킵, --json 출력, ignored/not_found 응답 처리 |
|
||||
|
||||
## REQ 별 AC 검증
|
||||
|
||||
### REQ-068 (실행 정책 계약)
|
||||
- AC-1 (timeout_sec 파싱·저장): `test_buy_timeout_sec_parsed_and_stored_on_slot`, `test_timeout_sec_set_on_pending_buy_entry`
|
||||
- AC-2 (slippage_pct 파싱·저장): `test_buy_slippage_pct_parsed_and_stored_on_slot`, `test_slippage_pct_set_on_pending_buy_entry`
|
||||
- AC-3 (config default): `test_config_default_applied_when_intent_has_no_timeout`
|
||||
- AC-4 (하위 호환): `test_buy_policy_fields_absent_means_none`, `test_policy_fields_default_to_none_when_not_given`
|
||||
- AC-5 (per-intent override): `test_per_intent_timeout_overrides_config_default`
|
||||
- AC-6 (cleared on exit): `test_policy_cleared_on_transition_to_holding`, `test_policy_cleared_on_transition_to_inactive`
|
||||
|
||||
### REQ-069 (timeout 집행·race)
|
||||
- AC-1 (timeout 초과 → cancel_order): `test_timeout_exceeded_sends_cancel_order`
|
||||
- AC-2 (is_terminal_reject → rollback): race 수렴은 기존 `test_full_external_cancel_returns_slot_to_holding` 재사용
|
||||
- AC-3 (is_partial_cancel → 부분 보존): 기존 `test_partial_fill_then_cancel_records_and_keeps_remainder` 재사용
|
||||
- AC-4 (cancel 후 fill race → is_filled 경로): `test_timeout_cancel_then_fill_race_handled`
|
||||
- AC-5 (timeout_sec 없으면 cancel 없음): `test_no_timeout_sec_no_cancel`
|
||||
- AC-6 (exception best-effort): `test_timeout_cancel_best_effort_on_exception`
|
||||
|
||||
### REQ-070 (slippage 지정가)
|
||||
- AC-1 (buy ceil): `test_buy_slippage_ceil_applied_to_limit`
|
||||
- AC-2 (sell floor): `test_sell_slippage_floor_applied_to_limit`
|
||||
- AC-3 (market = ignore): `test_no_slippage_when_market_order_no_entry_price`
|
||||
- AC-4 (slippage 없으면 기존 동작): `test_no_slippage_when_slippage_pct_is_none`
|
||||
- AC-5 (0% = 기본 가격): `test_zero_slippage_uses_base_price`
|
||||
- AC-6 (분수 입력 ceil/floor): `test_buy_slippage_fractional_ceil`
|
||||
|
||||
### REQ-071 (운영자 cancel 백스톱)
|
||||
- AC-1 (PENDING_BUY cancel): `test_ok_sends_cancel_and_returns_ok`
|
||||
- AC-2 (루프 수렴): 단일 writer 설계로 execution loop 수렴 보장 (`test_cancel_does_not_change_slot_state`)
|
||||
- AC-3 (PENDING_SELL same): cancel_pending_slot 구현에 PENDING_SELL 포함 (코드 검증)
|
||||
- AC-4 (HOLDING ignored): `test_not_pending_returns_not_pending`
|
||||
- AC-5 (not_found): `test_slot_not_found_returns_slot_not_found`
|
||||
- AC-6 (--dry-run): `test_cancel_dry_run_does_not_submit`
|
||||
|
||||
### REQ-072 (baseline 정합)
|
||||
- AC-1~4: docs/interface-contract.md, docs/runtime-flows.md 수동 확인 완료 (M5).
|
||||
|
||||
## 기존 테스트 회귀 없음
|
||||
|
||||
전체 425 passed — REQ-013/061 기존 AC 포함 회귀 없음.
|
||||
|
||||
| 항목 | 결과 |
|
||||
|---|---|
|
||||
| 단위 테스트 (non-integration) | 425 passed, 45 skipped |
|
||||
| 신규 tests | 71 |
|
||||
| 회귀 | 없음 |
|
||||
@@ -0,0 +1,38 @@
|
||||
# BAT-033 Implementation
|
||||
|
||||
- Status: done
|
||||
- Batch: BAT-033
|
||||
|
||||
## 변경 파일
|
||||
|
||||
| 파일 | 변경 유형 | 연결 REQ/AC |
|
||||
|------|----------|-------------|
|
||||
| `trex_core/runtime/cli.py` | 수정 | REQ-032 CHG-20260610-06 AC-7 |
|
||||
| `tests/runtime/test_cli_operator.py` | 수정 | AC-7 검증 + 기존 enter 테스트 --qty 보완 |
|
||||
|
||||
## M1: `enter --qty` 미지정 검증
|
||||
|
||||
### `trex_core/runtime/cli.py`
|
||||
|
||||
`_cmd_enter` 함수 상단(forced_close_at 검증 앞)에 qty 검증 블록 추가:
|
||||
|
||||
```python
|
||||
# REQ-032 AC-7 (CHG-20260610-06, issue #23): qty is required — reject before
|
||||
# RPC so a missing --qty fails immediately instead of admitting a zero-qty order
|
||||
# that the broker rejects silently after the fact.
|
||||
if not args.qty:
|
||||
_fail("--qty is required for enter (no quantity → broker would reject)", args.json)
|
||||
return 1
|
||||
```
|
||||
|
||||
- `--qty` 없음(None) 또는 0 → 즉시 `rc=1`, RPC 미호출
|
||||
- `--dry-run` 경로도 동일하게 걸림 (qty 검증이 `_intent_guard` 진입 전에 위치)
|
||||
- 기존 `--qty` 있는 경우 동작 불변
|
||||
|
||||
### `tests/runtime/test_cli_operator.py`
|
||||
|
||||
**신규 테스트 (AC-7):**
|
||||
- `test_enter_without_qty_errors_before_rpc` — `--qty` 없이 enter → rc=1, rpc.calls==[], stderr에 `--qty` 포함
|
||||
|
||||
**기존 테스트 수정 (회귀 방지):**
|
||||
기존 enter 테스트 9개에 `"--qty", "10"` (또는 적절한 값) 추가. qty 검증이 가장 앞에 위치하므로, 각 테스트가 본래 의도한 guard(confirm abort, live guard, json guard, forced_close_at 검증 등)에 도달하도록 보정.
|
||||
@@ -0,0 +1,22 @@
|
||||
# BAT-033: enter --qty 필수 검증 (issue #23)
|
||||
|
||||
- Status: release-candidate
|
||||
- Profile: batch-lite
|
||||
- Source Discovery: REQ-032 change-req (issue #23)
|
||||
- Included REQ: REQ-032 (CHG-20260610-06, AC-7)
|
||||
|
||||
## Summary
|
||||
- `trex-core enter`에 `--qty` 미지정 시 RPC 제출 전 즉시 오류 반환. 기존 `qty=None` → admitted → 집행 루프 KIS 거절 → 롤백이라는 "접수 성공처럼 보이지만 매수 안 됨" 혼동 제거.
|
||||
|
||||
## Scope
|
||||
- In: `trex_core/runtime/cli.py` `enter` 서브커맨드에 `--qty` 미지정 검증 + 단위 테스트
|
||||
- Out: IntentService admission 수량 검증(서비스 레이어), 도메인 변경, DB 스키마 변경
|
||||
|
||||
## Documents
|
||||
- Planning: [planning.md](./planning.md)
|
||||
- Implementation: [implementation.md](./implementation.md)
|
||||
- Verification: [verification.md](./verification.md)
|
||||
|
||||
## Notes
|
||||
- batch-lite minor-change fast path: 구조/인터페이스/런타임 흐름 영향 없음 (CLI argparse 단일 파일).
|
||||
- Design Gate: design 불필요 (planning.md 참조).
|
||||
@@ -0,0 +1,30 @@
|
||||
# BAT-033 Planning
|
||||
|
||||
- Status: done
|
||||
- Batch: BAT-033
|
||||
|
||||
## Milestones
|
||||
|
||||
| ID | 목표 | 연결 REQ |
|
||||
|---|---|---|
|
||||
| M1 | `enter --qty` 미지정 검증 + 테스트 | REQ-032 (CHG-20260610-06 AC-7) |
|
||||
|
||||
## M1 상세 (enter --qty 미지정 검증)
|
||||
|
||||
`trex_core/runtime/cli.py` `_cmd_enter` 함수 진입부에 qty 검증 추가:
|
||||
- `--qty` 가 없거나 `None`이면 즉시 오류 출력 + `return 1` (RPC 호출 없음)
|
||||
- `--dry-run` 경로에서도 동일하게 미리 검증
|
||||
- 기존 `--qty` 있는 경우는 동작 불변 (회귀 없음)
|
||||
|
||||
단위 테스트 추가 (`tests/runtime/test_cli_operator.py`):
|
||||
- `enter` without `--qty` → rc=1, rpc.calls==[] (AC-7)
|
||||
- 기존 `test_enter_with_yes_submits_buy_intent` 회귀 없음 확인
|
||||
|
||||
## Design Gate
|
||||
|
||||
- Design 불필요: CLI argparse 단일 파일 변경. 구조/인터페이스/런타임 흐름 영향 없음.
|
||||
- 검증: 단위 테스트 + 기존 suite 회귀 없음으로 충분.
|
||||
|
||||
## 위험 요소
|
||||
|
||||
- R-1 (dry-run 경로 누락): dry-run에서도 qty 체크를 해야 오류 메시지를 미리 볼 수 있음 → 동일 검증 로직 적용으로 해소.
|
||||
@@ -0,0 +1,21 @@
|
||||
# BAT-033 Verification
|
||||
|
||||
- Status: approved
|
||||
- Batch: BAT-033
|
||||
|
||||
## 검증 항목
|
||||
|
||||
| AC | 시나리오 | 테스트 | 결과 |
|
||||
|----|----------|--------|------|
|
||||
| AC-7 | `enter` without `--qty` → rc=1, rpc.calls==[], stderr에 `--qty` 포함 | `test_enter_without_qty_errors_before_rpc` | PASS |
|
||||
| AC-7 | `--dry-run` 경로에서도 qty 미지정 → rc=1, rpc.calls==[] | `test_enter_without_qty_errors_before_rpc` (dry-run 미호출이므로 동일 경로) | PASS |
|
||||
| 회귀 | 기존 `enter` 테스트 9개 — qty 지정 시 동작 불변 | 기존 테스트 전체 | PASS |
|
||||
|
||||
## 실행 결과
|
||||
|
||||
```
|
||||
tests/runtime/test_cli_operator.py — 31 passed (0 failed)
|
||||
전체 suite — 426 passed, 45 skipped, 0 failed
|
||||
```
|
||||
|
||||
커맨드: `python -m pytest tests/runtime/test_cli_operator.py -q`
|
||||
@@ -0,0 +1,50 @@
|
||||
# BAT-034 Design
|
||||
|
||||
- Status: done
|
||||
- Batch: BAT-034
|
||||
|
||||
## D1. 제거 지점 전수 목록 (소스 grep 기준)
|
||||
|
||||
| # | 파일 | 위치 | 제거 내용 | REQ |
|
||||
|---|------|------|----------|-----|
|
||||
| 1 | `trex_core/domain/slot/models.py` | `Slot.allocated_capital` 필드 + `EXPECTED_SLOT_FIELDS` 항목 | 도메인 모델·필드셋 계약 | REQ-002 |
|
||||
| 2 | `trex_core/domain/slot/service.py` | `transit_slot` 파라미터, `_apply_transition_fields` 파라미터·INACTIVE clear·carry-forward `replace(...)` | 설정/전이 경로 | REQ-002 |
|
||||
| 3 | `trex_core/application/intents.py` | `BuyIntent.allocated_capital` 필드, `submit_buy` dedup payload 키, `_admit_buy`→`transit_slot` 전달 | intent 계약·admission | REQ-007 |
|
||||
| 4 | `trex_core/application/messaging_handlers.py` | buy payload `_opt_float(body.get("allocated_capital"))` 파싱 | 수신 무시(즉시 제거) | REQ-007 |
|
||||
| 5 | `trex_core/adapters/persistence/postgresql.py` | `_SLOT_COLUMNS` 문자열, UPDATE 절, `_row_to_slot` 인덱스 매핑(컬럼 제거로 인덱스 시프트 — 주석 포함 재정렬) | flat 매핑 | REQ-006 |
|
||||
| 6 | `trex_core/adapters/persistence/sql/013_drop_allocated_capital.sql` | 신규 — `ALTER TABLE daily_slot DROP COLUMN IF EXISTS allocated_capital;` | 스키마 | REQ-006 |
|
||||
| 7 | `trex_core/application/portfolio.py` | `slots[]` 항목의 `"allocated_capital"` 키 | snapshot 노출 | REQ-028 |
|
||||
| 8 | `trex_core/runtime/cli.py` | `--capital` argparse 인자, `_cmd_enter` summary·payload, `_print_slot_detail` 행 | CLI 표면 | REQ-032 |
|
||||
|
||||
테스트: `tests/` 전수 grep 으로 fixture·assert 의 allocated_capital/`--capital` 참조 정리 (BAT-033 의 AC-7 테스트는 보존).
|
||||
|
||||
## D2. 마이그레이션 013 (비가역 drop)
|
||||
|
||||
```sql
|
||||
-- BAT-034 / dcy-023 / REQ-006 (CHG-20260610-02): drop dead column (비가역).
|
||||
-- allocated_capital 은 사이징·회계·전략 결정 어디에도 소비되지 않는 죽은 메타데이터
|
||||
-- (dcy-023 §3 전수 추적). 실제 주문 수량은 slot.qty 가 단독 결정(dcy-021 계약).
|
||||
-- Idempotent via IF EXISTS. Rollback = 사전 백업 복원 (BAT-030/011 선례 준용).
|
||||
ALTER TABLE daily_slot DROP COLUMN IF EXISTS allocated_capital;
|
||||
```
|
||||
|
||||
- 적용: 코드 배포와 동시(`apply_migrations` 데몬 기동 시 자동, dcy-023 OQ-2 운영자 결정).
|
||||
- 롤백: 구 코드 UPDATE 절이 컬럼을 참조하므로 공존 불가 — release 문서에 (1) 적용 전 `daily_slot` 백업, (2) 롤백 시 백업 복원 + 구 리비전 절차 명시.
|
||||
- 검증: 테스트 DSN(`trex_core_test`)에서만 round-trip — 운영 DB 미사용.
|
||||
|
||||
## D3. 수신-무시 시맨틱 (REQ-007 AC-6)
|
||||
|
||||
- messaging handler 의 파싱 제거가 곧 수신-무시다 — RabbitMQ payload 는 관용적 계약이라 외부 발신자(trex-orb-v1, `intent_builder.py:56`)가 키를 계속 보내도 읽히지 않는 unknown key 가 될 뿐.
|
||||
- 검증 테스트: `allocated_capital` 키를 포함한 buy payload → 정상 admit + 슬롯·intent_log 에 미반영.
|
||||
- `submit_buy` dedup payload(intent_log)에서 키 제거 — dedup 은 intent_id 기준이라 동작 영향 없음.
|
||||
|
||||
## D4. 인덱스 시프트 주의 (postgresql.py)
|
||||
|
||||
- `_SLOT_COLUMNS` 에서 `allocated_capital`(6번째) 제거 시 `_row_to_slot` 의 이후 모든 row 인덱스가 1씩 당겨진다 — 위치 주석(`# limit_price(5) allocated_capital(6) order_id(7) ...`)을 실제 순서로 재작성하고, 드리프트 테스트(`EXPECTED_SLOT_FIELDS` ↔ information_schema)가 정합을 강제한다.
|
||||
|
||||
## D5. 변경하지 않는 것
|
||||
|
||||
- `qty` 기반 집행 경로(`qty = int(slot.qty or 0)`) — 불변 (NFR-3).
|
||||
- BAT-033 의 `--qty` 필수 guard(AC-7) — 보존.
|
||||
- 외부 전략 모듈 송신 코드 — 범위 밖(운영자 확인).
|
||||
- baseline `docs/project-structure.md`/`docs/runtime-flows.md` — allocated_capital 직접 기술 없음 확인(dcy-023 confirm 시점) → 갱신 불요, 검증 단계에서 재확인만.
|
||||
@@ -0,0 +1,27 @@
|
||||
# BAT-034 Implementation
|
||||
|
||||
- Status: done
|
||||
- Batch: BAT-034
|
||||
|
||||
## 변경 파일
|
||||
|
||||
| 파일 | 변경 | Milestone / REQ |
|
||||
|------|------|----------------|
|
||||
| `trex_core/domain/slot/models.py` | `Slot.allocated_capital` 필드 + `EXPECTED_SLOT_FIELDS` 항목 제거 | M1 / REQ-002 |
|
||||
| `trex_core/domain/slot/service.py` | `transit_slot`·`_apply_transition_fields` 파라미터, INACTIVE clear, carry-forward 제거 | M1 / REQ-002 |
|
||||
| `trex_core/application/intents.py` | `BuyIntent.allocated_capital` 필드, `submit_buy` dedup payload 키, `_admit_buy`→`transit_slot` 전달 제거 | M1 / REQ-007 |
|
||||
| `trex_core/application/messaging_handlers.py` | buy payload 파싱 제거 + 수신-무시 주석 (AC-6) | M1 / REQ-007 |
|
||||
| `trex_core/adapters/persistence/postgresql.py` | `_SLOT_COLUMNS`·UPDATE 절·`_row_to_slot`(인덱스 6 제거, 이후 1씩 시프트 + 위치 주석 재작성) | M2 / REQ-006 |
|
||||
| `trex_core/adapters/persistence/sql/013_drop_allocated_capital.sql` | 신규 — `DROP COLUMN IF EXISTS`(멱등) | M2 / REQ-006 |
|
||||
| `trex_core/application/portfolio.py` | snapshot `slots[]` 항목의 `allocated_capital` 키 제거 | M3 / REQ-028 |
|
||||
| `trex_core/runtime/cli.py` | `--capital` argparse 인자, `_cmd_enter` summary/payload, `_print_slot_detail` 행 제거 | M3 / REQ-032 |
|
||||
| `tests/domain/slot/test_service.py` | `allocated_capital` 인자/assert 제거 | M4 |
|
||||
| `tests/runtime/test_cli_operator.py` | fixture 키·`--capital` 인자 제거, `test_enter_rejects_capital_option`(AC-8) 신규, `test_enter_with_yes_submits_buy_intent` 에 payload 부재 assert | M4 |
|
||||
| `tests/application/test_messaging_intent_consumer.py` | `test_buy_payload_allocated_capital_is_ignored`(AC-6 unknown-key 무시) 신규 | M4 |
|
||||
| `tests/application/test_execution_policy.py` | 잔여 lint 정리(F401/F841 — BAT-032 잔재, 본 배치 변경과 무관) | M4 |
|
||||
|
||||
## 설계 정합
|
||||
|
||||
- design.md D1 제거 지점 8개 전부 처리. D4 인덱스 시프트는 위치 주석 재작성 + 드리프트 테스트로 검증.
|
||||
- D3 수신-무시: 파싱 제거 = unknown key 무시. 전용 테스트로 고정.
|
||||
- D5 불변 확인: `qty` 집행 경로·BAT-033 AC-7 guard·외부 모듈·baseline 문서 모두 미변경.
|
||||
@@ -0,0 +1,24 @@
|
||||
# BAT-034: allocated_capital 죽은 필드 제거 — CLI·intent·도메인·영속·snapshot 정리 (dcy-023)
|
||||
|
||||
- Status: release-candidate
|
||||
- Profile: standard
|
||||
- Source Discovery: dcy-023 (issue #22)
|
||||
- Included REQ: REQ-002 (CHG-20260610-02), REQ-006 (CHG-20260610-02), REQ-007 (CHG-20260610-02), REQ-028 (CHG-20260610-01), REQ-032 (CHG-20260610-07)
|
||||
|
||||
## Summary
|
||||
- dcy-023: 주문 사이징·회계·전략 결정 어디에도 쓰이지 않는 죽은 필드 `allocated_capital` 을 설정(CLI `--capital`)→운반(buy intent)→영속(daily_slot 컬럼)→표시(snapshot `slots[]`·CLI detail) 전 경로에서 제거한다. dcy-021 사이징 계약(전략이 qty 계산, core 미관여) 확정의 귀결로, capital 기반 사이징 오해를 원천 제거한다.
|
||||
|
||||
## Scope
|
||||
- In: CLI `--capital` argparse 제거 + `slots` detail 행 제거(REQ-032), BuyIntent 필드·admission·payload 파싱 즉시 제거(REQ-007), Slot 모델·`EXPECTED_SLOT_FIELDS`·SlotService 경로 제거(REQ-002), 마이그레이션 013 컬럼 drop + persistence flat 매핑 제거(REQ-006), snapshot `slots[]` 노출 제거(REQ-028), 관련 테스트 정리.
|
||||
- Out: 외부 전략 모듈(trex-orb-v1) 송신 코드 수정(운영자 확인: 무시 — unknown key 무해), capital 기반 자동 사이징 도입(dcy-021 에서 불채택 확정), 다른 슬롯 필드 정리.
|
||||
|
||||
## Documents
|
||||
- Planning: [planning.md](./planning.md)
|
||||
- Design: [design.md](./design.md)
|
||||
- Implementation: [implementation.md](./implementation.md)
|
||||
- Verification: [verification.md](./verification.md)
|
||||
|
||||
## Notes
|
||||
- 마이그레이션 013 은 비가역 drop — BAT-030 의 011 선례 준용(코드 배포와 동시 적용, release 문서에 사전 백업·롤백 절차 명시, dcy-023 OQ-2).
|
||||
- BAT-033(REQ-032 AC-7, release-candidate)과 같은 CLI/테스트 파일을 수정하므로 enter 테스트 정합 유지.
|
||||
- 본 배치 완료 후 REQ-002/006/007/028/032 confirm-req-implemented.
|
||||
@@ -0,0 +1,34 @@
|
||||
# BAT-034 Planning
|
||||
|
||||
- Status: done
|
||||
- Batch: BAT-034
|
||||
|
||||
## Milestones
|
||||
|
||||
| ID | 목표 | 연결 REQ |
|
||||
|---|---|---|
|
||||
| M1 | 도메인·intent 계약 제거 — Slot 모델/EXPECTED_SLOT_FIELDS/SlotService + BuyIntent/admission/payload 파싱 | REQ-002 (CHG-02), REQ-007 (CHG-02) |
|
||||
| M2 | 영속 제거 — 마이그레이션 013(`DROP COLUMN IF EXISTS`) + postgresql.py flat 매핑 | REQ-006 (CHG-02) |
|
||||
| M3 | 표면 제거 — snapshot `slots[]` 노출 + CLI `--capital` argparse·summary·payload·`slots` detail 행 | REQ-028 (CHG-01), REQ-032 (CHG-07) |
|
||||
| M4 | 테스트 정리 + 회귀 — allocated_capital 참조 전수 정리, unknown key 무시 테스트, argparse 거부 테스트, 전체 suite green | 전 REQ |
|
||||
|
||||
## 작업 순서 근거
|
||||
|
||||
- M1(안쪽 계약)→M2(영속)→M3(바깥 표면) 순서로 제거하면 각 단계에서 컴파일/테스트 오류가 다음 제거 지점을 가리킨다. M4 는 전 단계 누락 검출.
|
||||
- 모든 변경이 "제거"라 단계 간 의존이 단방향(도메인 필드가 사라지면 매핑·노출이 따라 사라져야 함).
|
||||
|
||||
## Design Gate
|
||||
|
||||
- design 필요: **yes** — 5개 REQ·7개 모듈에 걸친 데이터 계약 변경 + 비가역 마이그레이션. 제거 지점 전수 목록과 마이그레이션/롤백 절차를 design.md 에 고정한다.
|
||||
|
||||
## 위험 요소
|
||||
|
||||
- R-1 (비가역 drop): 마이그레이션 013 적용 후 구 리비전과 공존 불가(구 코드 UPDATE 절이 컬럼 참조) → release 문서에 사전 백업 + 롤백(컬럼 재추가 또는 백업 복원) 절차 명시. 검증은 테스트 DSN 에서만.
|
||||
- R-2 (참조 누락): 테스트·fixture 의 allocated_capital 잔존 참조로 suite 실패 → `grep -rn allocated_capital trex_core/ tests/` 전수 0건을 M4 DoD 로 설정.
|
||||
- R-3 (BAT-033 정합): 같은 CLI/테스트 파일 수정 — enter 테스트의 `--capital` 인자를 제거하면서 AC-7(`--qty` 필수) 테스트는 보존.
|
||||
|
||||
## 검증 계획 (요약)
|
||||
|
||||
- 단위: argparse 거부, payload allocated_capital 부재, unknown key 무시(admit 정상 + 미반영), 필드셋 계약, slots[] 스키마
|
||||
- 통합(테스트 DSN): 마이그레이션 013 멱등 적용 + information_schema 대조 + round-trip
|
||||
- 회귀: 전체 suite green + `grep` 전수 0건
|
||||
@@ -0,0 +1,26 @@
|
||||
# BAT-034 Verification
|
||||
|
||||
- Status: approved
|
||||
- Batch: BAT-034
|
||||
|
||||
## Acceptance Mapping
|
||||
|
||||
| REQ / AC | 검증 | 테스트/Evidence | 결과 |
|
||||
|----------|------|----------------|------|
|
||||
| REQ-002 AC-5 | Slot 모델·EXPECTED_SLOT_FIELDS·SlotService 경로에서 allocated_capital 부재 | `tests/domain/slot/test_contract.py`(필드셋 = dataclass fields 정합, 자동 강제) + grep 전수 0건 | PASS |
|
||||
| REQ-006 AC-5 | 마이그레이션 013 멱등 적용 + 컬럼 부재 + 드리프트 green | 테스트 DSN(trex_core_test)에서 `apply_migrations` 2회 → `013_drop_allocated_capital.sql` 적용·재적용 무해, information_schema 에 컬럼 없음 확인. PG 게이트 suite 21 passed(드리프트 가드 포함) | PASS |
|
||||
| REQ-007 AC-6 | BuyIntent 필드 부재 + unknown key 무시 | `test_buy_payload_allocated_capital_is_ignored` — allocated_capital 포함 payload 정상 admit + 슬롯 미반영 | PASS |
|
||||
| REQ-028 AC-5 | snapshot slots[] 에 키 부재 | `build_snapshot_envelope` 매핑 제거 + `test_cli_operator` fixture 정합(snapshot 스키마 테스트 green) | PASS |
|
||||
| REQ-032 AC-8 | `--capital` argparse 거부 + payload 부재 + detail 행 제거 | `test_enter_rejects_capital_option`(SystemExit 2, RPC 미호출, stderr 에 --capital) + `test_enter_with_yes_submits_buy_intent`(payload 에 키 부재) | PASS |
|
||||
| 회귀 (NFR-2/3) | 전체 suite + qty 집행 경로 불변 + BAT-033 AC-7 보존 | 전체 **428 passed, 45 skipped**, PG 게이트 **21 passed**, `ruff check` All checks passed. AC-7 테스트(`test_enter_without_qty_errors_before_rpc`) green | PASS |
|
||||
| S-1 (dcy-023) | 소스/테스트 grep 전수 | `grep -rn allocated_capital trex_core/ tests/` → 수신-무시 주석·전용 테스트 외 0건 | PASS |
|
||||
|
||||
## 환경
|
||||
|
||||
- 단위/통합: in-memory + 테스트 PostgreSQL `trex_core_test`(TREX_POSTGRESQL_TEST_DSN 파생, 운영 DB 미사용)
|
||||
- 명령: `python -m pytest -q` (전체), `python -m pytest tests/adapters/persistence/ -q` (PG 게이트)
|
||||
|
||||
## 운영 이월 (release 시 필수)
|
||||
|
||||
- 마이그레이션 013 은 비가역 — 운영 적용 전 `daily_slot` 백업, 롤백 = 백업 복원 + 구 리비전(BAT-030/011 선례). release 문서 Rollout/Rollback 에 명시할 것.
|
||||
- 운영자 스크립트/습관의 `enter --capital` 사용분은 배포 후 argparse 오류로 즉시 표면화(silent 실패 아님).
|
||||
@@ -31,11 +31,14 @@
|
||||
| BAT-021 | standard | released | REQ-034 (CHG-20260608-02), REQ-021 (CHG-20260608-03), REQ-037 (CHG-20260608-01), REQ-038 (CHG-20260608-01), REQ-039 (CHG-20260608-01), REQ-032 (CHG-20260608-02), REQ-042 (CHG-20260608-01) | dcy-017 | [bat-021](./bat-021_20260608_watchdog-ownership-visibility/) |
|
||||
| BAT-022 | standard | released | REQ-028 (CHG-20260608-01), REQ-032 (CHG-20260608-03) | dcy-016 | [bat-022](./bat-022_20260608_slot-state-snapshot-visibility/) |
|
||||
| BAT-023 | standard | released | REQ-017 (CHG-20260608-02), REQ-019 (CHG-20260608-02), REQ-029 (CHG-20260608-01), REQ-030 (CHG-20260608-01, Approved→Implemented) | dcy-018 | [bat-023](./bat-023_20260608_ledger-cash-position-writeback-option-d/) |
|
||||
| BAT-024 | batch-lite | release-candidate | REQ-032 (CHG-20260609-01) | dcy-016 (issue #17) | [bat-024](./bat-024_20260609_operator-enter-forced-close-at/) |
|
||||
| BAT-025 | standard | release-candidate | REQ-002 (CHG-20260609-01), REQ-003 (CHG-20260609-01), REQ-006 (CHG-20260609-01), REQ-007 (CHG-20260609-01), REQ-009 (CHG-20260609-01) | dcy-019 (issue #18) | [bat-025](./bat-025_20260609_slot-entry-count-and-closed-reallocation/) |
|
||||
| BAT-024 | batch-lite | released | REQ-032 (CHG-20260609-01) | dcy-016 (issue #17) | [bat-024](./bat-024_20260609_operator-enter-forced-close-at/) |
|
||||
| BAT-025 | standard | released | REQ-002 (CHG-20260609-01), REQ-003 (CHG-20260609-01), REQ-006 (CHG-20260609-01), REQ-007 (CHG-20260609-01), REQ-009 (CHG-20260609-01) | dcy-019 (issue #18) | [bat-025](./bat-025_20260609_slot-entry-count-and-closed-reallocation/) |
|
||||
| BAT-026 | batch-lite | release-candidate | REQ-048 (CHG-20260609-01), REQ-010 (CHG-20260609-01) | 없음 (trex-orb-v1 정합) | [bat-026](./bat-026_20260609_config-dir-env-and-config-path/) |
|
||||
| BAT-027 | standard | release-candidate | REQ-056, REQ-057 | dcy-020 (BAT-α) | [bat-027](./bat-027_20260610_asset-permanent-slot-foundation/) |
|
||||
| BAT-028 | standard | release-candidate | REQ-058, REQ-059, REQ-060 | dcy-020 (BAT-β) | [bat-028](./bat-028_20260610_universe-reconcile-and-active-admission/) |
|
||||
| BAT-029 | standard | release-candidate | REQ-061, REQ-062, REQ-063 | dcy-020 (BAT-γ) | [bat-029](./bat-029_20260610_asset-keyed-intent-and-divergence/) |
|
||||
| BAT-030 | standard | release-candidate | REQ-064, REQ-062, REQ-056·057·065(잔여) | dcy-020 (BAT-δ) | [bat-030](./bat-030_20260610_asset-centric-cutover/) |
|
||||
| BAT-031 | standard | release-candidate | REQ-066, REQ-067, REQ-057·061·062(CHG) | dcy-021 | [bat-031](./bat-031_20260610_position-sizing/) |
|
||||
| BAT-032 | standard | release-candidate | REQ-068, REQ-069, REQ-070, REQ-071, REQ-072, REQ-061(CHG-05), REQ-013(CHG-03) | dcy-022 | [bat-032](./bat-032_20260610_execution-policy/) |
|
||||
| BAT-033 | batch-lite | release-candidate | REQ-032 (CHG-20260610-06) | REQ-032 change-req (issue #23) | [bat-033](./bat-033_20260610_enter-qty-validation/) |
|
||||
| BAT-034 | standard | release-candidate | REQ-002 (CHG-20260610-02), REQ-006 (CHG-20260610-02), REQ-007 (CHG-20260610-02), REQ-028 (CHG-20260610-01), REQ-032 (CHG-20260610-07) | dcy-023 (issue #22) | [bat-034](./bat-034_20260610_drop-allocated-capital/) |
|
||||
|
||||
Reference in New Issue
Block a user