Files
trex-core/docs/batches/bat-021_20260608_watchdog-ownership-visibility/verification.md
T
genichinandClaude Opus 4.8 6d7bca1460 feat(safety-sell): dcy-017 워치독 소유권 가시화 — snapshot 상태 + 발동 로깅 (BAT-021)
전략 이탈로 슬롯이 내부 청산 루틴(워치독) 소유로 넘어간 상태가 무성이라
운영자가 인지할 수 없던 문제(issue #12)를 가시화한다.

거버넌스: 전부 change-req (신규 REQ 없음, dcy-017 OQ-3; Redis 미채택).
- REQ-034/021: WatchdogStore.last_seen + snapshot RPC 응답에 holding 슬롯
  워치독 상태(expired/last_seen) read-only 동봉(best-effort)
- REQ-032: trex-core slots 가 expired 슬롯을 WATCHDOG-OWNED(전략 이탈) 표시
- REQ-037/038/039: safety-sell 워치독 소유 진입(WARN)/이탈(INFO) + 발동
  (forced_close·stop_loss=WARN, take_profit·market_close=INFO) 로그 +
  in-process 카운터(SafetySellService.counters), 구조화 필드(slot_id/
  portfolio_id/reason/phase/instance_key). per-tick 스킵은 카운터만
- REQ-042: runtime-flows/interface-contract 정합

best-effort 격리(NFR-1): 모든 가시화는 예외 격리 — 워치독 판정·청산 불변.
dcy-016 억제 읽기로 관측이 워치독을 리셋하지 않음(비침습).

검증: 단위 335 passed/34 skipped, 인프라 게이트(PG+RabbitMQ) 369 passed, ruff clean.
신규 test_safety_sell_visibility(6) + snapshot watchdog(1) + CLI(1). BAT-021 rc.

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

3.8 KiB

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 무관).