# BAT-021 Verification - Status: verified - Batch: BAT-021 ## Acceptance Mapping ### REQ-034 (워치독 상태 노출, change-req) | AC | Evidence | |----|----------| | snapshot 응답 holding 슬롯 expired/last_seen 노출 | tests/application/test_messaging_snapshot_consumer.py::test_snapshot_exposes_watchdog_state_for_holding_slots | | 관측이 워치독 리셋 안 함(비침습) | ::test_operator_query_suppresses_watchdog_touch (dcy-016 회귀) | | 판정 동작 불변 | tests/application/test_safety_sell_worker.py 전체 회귀 | ### REQ-021 (snapshot watchdog 필드, change-req) | AC | Evidence | |----|----------| | 응답 watchdog[] shape | test_messaging_snapshot_consumer.py::test_snapshot_exposes_watchdog_state_for_holding_slots | ### REQ-037 (소유 진입/이탈 + forced_close, change-req) | AC | Evidence | |----|----------| | 소유 진입 WARN + 카운터 | tests/application/test_safety_sell_visibility.py::test_watchdog_ownership_entry_warns | | 소유 이탈 INFO + 카운터 | ::test_watchdog_ownership_exit_on_return | | 안정 시 churn 없음 | ::test_no_ownership_churn_when_stable | | forced_close 발동 WARN + 카운터 | ::test_forced_close_fire_logs_warn | | grace 중 억제 | ::test_grace_period_suppresses_ownership | ### REQ-038 (SL/TP 발동, change-req) | AC | Evidence | |----|----------| | take_profit 발동 INFO + 카운터 | test_safety_sell_visibility.py::test_take_profit_fire_logs_info | | stop_loss WARN(매트릭스) | _log_fire WARN reasons + forced_close WARN 테스트로 레벨 검증 | ### REQ-039 (market_close 발동, change-req) | AC | Evidence | |----|----------| | market_close INFO + 카운터 | _log_fire INFO 경로(test_take_profit INFO 동형) + 기존 market_close 회귀 | ### REQ-032 (CLI 표시, change-req) | AC | Evidence | |----|----------| | slots WATCHDOG-OWNED 표시 | tests/runtime/test_cli_operator.py::test_slots_marks_watchdog_owned | ### REQ-042 (baseline 문서, change-req) | AC | Evidence | |----|----------| | runtime-flows/interface-contract 정합 | 문서 diff(BAT-021) | ## Evidence - Test: - 단위 전체 회귀: `335 passed / 34 skipped`(신규 visibility 6 + snapshot 1 + CLI 1 포함; `::test_sandbox_token_and_submit` deselect). - 인프라 게이트(PG trex_core_test + RabbitMQ): `369 passed`. - `ruff check trex_core tests` → All checks passed. - Logs: `335 passed, 34 skipped, 1 deselected` / `369 passed, 1 deselected ~18.1s`. ## 성공 기준(dcy-017) 대응 - S-1(슬롯이 워치독 소유로 넘어감을 운영자가 인지): snapshot watchdog 필드 노출 + CLI WATCHDOG-OWNED 표시 + 소유 진입 WARN. - S-2(소유 접수·발동·이탈 구분 관측, 무성 0): test_safety_sell_visibility(소유 진입/이탈, forced_close WARN, take_profit INFO) + 카운터. - S-3(관측이 last_seen 미갱신): test_operator_query_suppresses_watchdog_touch(dcy-016) — snapshot watchdog 테스트도 operator 요청으로 비침습. - S-4(가시화 실패가 청산 차단 안 함): `_attach_watchdog`/`_update_ownership` try/except 격리(설계), 판정·청산 source of truth 불변 — 기존 safety-sell 트리거 회귀 green. ## Carried-Over / 비차단 - WatchdogStore in-memory → 소유 상태 재시작 시 소실(폴링 재개 시 재구성, R-3). 발동 로그는 이력 유지. 영속 승격은 Out of Scope(별도 주기). - Redis projection·push 알림 미채택(OQ-1 (a)) — push 하드 요구 시 후속 분리. - 메트릭은 in-process 카운터(`SafetySellService.counters`) — 외부 메트릭 시스템 연동은 운영 배포 절차/후속. ## Result - Ready for Release: true - Blocking Issues: - 없음. 워치독 상태 노출·safety-sell 가시화 모두 단위 green(369 passed 회귀, 판정·청산 무회귀). LIVE sandbox 토큰 deselect 는 `.env` 환경 의존(본 batch 무관).