# 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 | | 회귀 | 없음 |