Files
trex-core/docs/srs/Interface/req-034_per-slot-watchdog.md
T
genichinandClaude Opus 4.8 f0ad37747b feat(rel-007): dcy-025/024 + BAT-035/036 — slots.req 즉시 교체 + safety_sell_enabled
BAT-035 (dcy-025): trex.snapshot.req → trex.slots.req 즉시 교체
- topology: SNAPSHOT_REQ_QUEUE 제거, SLOTS_REQ_QUEUE = "trex.slots.req" 추가
- portfolio.py: View/build_snapshot_envelope/SnapshotEnvelope/_asset_to_dict 제거;
  slot_to_dict 시그니처 확장(snapshot_store/watchdog_store/pause_store/watchdog_timeout_sec)
  — asset_quantity(hub)/cash_balance/cash_estimated/warned/watchdog{}/paused 병합 (REQ-074)
- messaging_handlers.py: make_snapshot_rpc_handler 제거, make_slots_rpc_handler 추가
  — filter(all/inactive/pending/holding/error) + spy(bool) 처리; strategy 필드 제외 (REQ-073/074)
- daemon.py: _snapshot_rpc_loop → _slots_rpc_loop, make_slots_rpc_handler 연결
- cli.py: universe/slots → slots_queue + spy=True + server-side filter; buyable→inactive 매핑 (REQ-063)
- rabbitmq.py: snapshot_queue → slots_queue
- docs: interface-contract.md + runtime-flows.md slots.req 계약으로 업데이트 (REQ-075)
- REQ-028: Implemented → Deprecated (코드 삭제 완료)
- 테스트: test_snapshot_handler/selection/rpc_watchdog/messaging_snapshot_consumer 삭제;
  test_slots_handler.py(신규, 13 cases), test_killswitch_masking_resume 재작성,
  test_ledger_option_d._apply_cash_estimate → slots handler 경유, test_topology/cli_operator 갱신

BAT-036 (dcy-024): per-instance safety_sell_enabled 플래그
- config.py: DaemonInstanceConfig + DaemonConfig 에 safety_sell_enabled: bool = True 추가;
  from_toml 파싱, from_config 전파
- daemon.py: start() workers 조건부 — safety_sell_enabled=false 시 trex-safety-sell 미기동 + WARNING
- tests: test_instance_config.py 에 safety_sell_enabled 파싱 3개 케이스 추가

REQ: 073/074/075/021/034/063/048/005 Approved → Implemented

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 14:45:45 +09:00

9.8 KiB
Raw Blame History

req-034: per-slot 워치독 — snapshot RPC 기반 전략 모듈 활성 감지

  • Status: Implemented
  • Type: Interface
  • Priority: High
  • Owner: project maintainers

Intent

전략 모듈이 슬롯을 활성 관리 중인지 데몬이 감지하기 위해, snapshot RPC 응답 시 해당 슬롯들의 last_seen_at 타임스탬프를 in-memory 워치독 store에 기록한다. TREX_WATCHDOG_TIMEOUT 이상 갱신되지 않은 슬롯은 "전략 모듈 미감시" 상태로 판정해 자율 안전 매도 체크 대상이 된다(dcy-007 FR-5).

Requirement

  • 시스템은 trex.snapshot.req 요청을 처리할 때, 응답 envelope에 포함되는 holding 슬롯들의 last_seen_at을 in-memory 워치독 store(dict[slot_id, datetime])에 현재 시각(UTC 또는 KST 일관 적용)으로 갱신해야 한다.
  • 시스템은 now() − last_seen_at > TREX_WATCHDOG_TIMEOUT(초) 조건이 성립하는 슬롯을 "워치독 만료(watchdog-expired)"로 판정해야 한다.
  • 데몬 기동 후 TREX_WATCHDOG_GRACE_PERIOD(초) 동안은 워치독 만료 판정을 유예해야 한다(grace period). grace period 중에는 어떤 슬롯도 만료로 판정하지 않는다.
  • 워치독 store는 Postgres에 영속하지 않으며 데몬 재시작 시 초기화된다.

Acceptance Criteria

  1. Given trex.snapshot.req handler가 응답을 산출할 때, When 응답 슬롯 목록에 slot_id = S가 포함되면, Then watchdog_store[S]가 현재 시각으로 갱신된다.
  2. Given TREX_WATCHDOG_TIMEOUT=120이고 slot S의 watchdog_store[S]가 121초 전일 때, When 워치독 만료 여부를 평가하면, Then S는 만료로 판정된다.
  3. Given TREX_WATCHDOG_TIMEOUT=120이고 slot S의 watchdog_store[S]가 60초 전일 때, When 워치독 만료 여부를 평가하면, Then S는 만료로 판정되지 않는다.
  4. Given 데몬이 기동된 지 TREX_WATCHDOG_GRACE_PERIOD=60 초 이내일 때, When 워치독 만료 평가를 수행하면, Then 모든 슬롯의 만료 판정이 유예된다(store 비어 있는 슬롯 포함).
  5. Given 데몬 재시작이 발생하면, When 기동 직후 워치독 store를 조회하면, Then store는 비어 있다.
  6. Given 전략 모듈이 TREX_WATCHDOG_TIMEOUT / 2 미만 주기로 snapshot RPC를 보낼 때, When 정상 동작 중이면, Then 해당 슬롯의 워치독이 만료되지 않는다(NFR-4 관계식 검증).

Impacted Area

  • Docs:
    • docs/runtime-flows.md — 워치독 갱신 흐름 추가 (REQ-042 참조)
    • docs/interface-contract.md — snapshot RPC가 watchdog 갱신 신호임을 명시 (REQ-042 참조)
  • Modules:
    • trex_core/application/messaging_handlers.py — make_snapshot_rpc_handler 확장: 응답 슬롯의 last_seen_at 갱신
    • trex_core/application/portfolio.py 또는 신규 trex_core/application/watchdog.py — WatchdogStore (dict[slot_id, datetime]), grace period 시작 타임스탬프 관리
  • Tests:
    • make_snapshot_rpc_handler 단위 테스트 — last_seen_at 갱신 확인
    • 워치독 만료 판정 단위 테스트 — 만료/비만료/grace period 시나리오

Notes

  • 워치독 store 갱신은 snapshot RPC 응답 슬롯 기준이다. intent RPC(매수/매도)는 갱신 신호가 아니다(update_thresholds 액션은 제외 — REQ-040 참조).
  • NFR-4 권장 관계식: snapshot RPC 호출 주기 < TREX_WATCHDOG_TIMEOUT / 2. 기본값 기준 전략 모듈은 60초 이내 주기로 snapshot RPC를 호출해야 한다. 관계식 위반 시 정상 동작 슬롯에서도 워치독 오탐 발생.
  • 워치독 store 구현 위치(portfolio.py 확장 vs 신규 watchdog.py)는 batch planning에서 결정한다.
  • TREX_WATCHDOG_TIMEOUT, TREX_WATCHDOG_GRACE_PERIOD env var 파싱은 REQ-041 참조.

Change Log

CHG-20260607-01

  • Date: 2026-06-07
  • Author: Justin Ko

Change Summary

  • dcy-007 confirmed → REQ-034 초안 생성

Intent

  • per-slot 워치독 메커니즘(FR-5)을 독립 구현·검증 단위로 정규화

Acceptance Criteria Delta

  • Added: AC-1~6 전체

Impacted Area Delta

  • Docs: runtime-flows.md, interface-contract.md (REQ-042에서 처리)
  • Modules: messaging_handlers.py, watchdog store 신규/확장
  • Tests: snapshot handler + 워치독 판정 단위 테스트

Delivery Trace Delta

  • Batches: none (미할당)
  • Releases: none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: suggest-batch-reqs 후 batch 배정

CHG-20260607-02

  • Date: 2026-06-07
  • Author: Justin Ko

Change Summary

  • Proposed → Approved (confirm-req)

Intent

  • 승인 게이트 통과: 필수 필드·AC·Impacted Area·Change Log 완비 확인. dcy-007(confirmed) 범위 및 결정 사항과 모순 없음.

Acceptance Criteria Delta

  • (변경 없음)

Impacted Area Delta

  • (변경 없음)

Delivery Trace Delta

  • Batches: none (미할당)
  • Releases: none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: suggest-batch-reqs 후 batch 배정

CHG-20260608-01

  • Date: 2026-06-08
  • Author: Justin Ko

Change Summary

  • (change-req, dcy-016) 워치독 갱신 부수효과를 운영자 조회에서 억제: snapshot RPC 핸들러가 touch_watchdog=false/actor="operator" 요청에 대해 holding 슬롯 last_seen_at 갱신을 건너뛴다. 전략 폴링 기본 동작은 불변(REQ-034 핵심 의미 유지). BAT-020 재구현·재검증 완료 → Implemented 유지.

Intent

  • 운영자 CLI(universe/slots) 조회가 워치독 생존 신호로 작동해 죽은 전략의 safety-sell 을 억제하는 안전 결함(R-4)을 제거.

Acceptance Criteria Delta

  • Updated:
    • 워치독 last_seen_at 갱신은 전략 폴링(기본)에만 적용; 운영자 억제 플래그 요청은 제외.

Impacted Area Delta

  • Modules: trex_core/application/messaging_handlers.py(snapshot 핸들러 워치독 분기)
  • Tests: tests/application/test_messaging_snapshot_consumer.py::test_operator_query_suppresses_watchdog_touch

Delivery Trace Delta

  • Batches: BAT-020
  • Releases: none

Revalidation Impact

  • Reverification Needed: yes (BAT-020 에서 완료)
  • Existing Implementation Invalidated: no (기본 전략 폴링 동작 불변)
  • Status Recommendation: Implemented (change-req → BAT-020 재검증)
  • Follow-up Action: confirm-req-implemented(BAT-020).

Validation Plan

  • BAT-020: operator 요청 시 watchdog.update 미호출, 기본 요청 시 호출 단위.

CHG-20260608-02

  • Date: 2026-06-08
  • Author: Justin Ko

Change Summary

  • (change-req, dcy-017/issue #12) 워치독 상태 가시화: WatchdogStore.last_seen(slot_id) read-only getter 추가, snapshot RPC 응답에 holding 슬롯 워치독 상태(expired/last_seen) read-only 동봉(best-effort). 판정 로직·timeout 불변(관측만 추가). BAT-021 재구현·재검증 완료 → Implemented 유지.

Intent

  • 전략 이탈로 슬롯이 안전망(워치독) 소유로 넘어간 상태를 운영자가 인지 가능하게(무성 → 가시화).

Acceptance Criteria Delta

  • Added:
    • snapshot 응답 워치독 상태 노출 + last_seen getter. 판정 동작 불변.

Impacted Area Delta

  • Modules: trex_core/application/watchdog.py(last_seen), trex_core/application/messaging_handlers.py(_attach_watchdog)
  • Tests: tests/application/test_messaging_snapshot_consumer.py::test_snapshot_exposes_watchdog_state_for_holding_slots

Delivery Trace Delta

  • Batches: BAT-021
  • Releases: none

Revalidation Impact

  • Reverification Needed: yes (BAT-021 에서 완료)
  • Existing Implementation Invalidated: no (관측만 추가, 판정 불변)
  • Status Recommendation: Implemented (change-req → BAT-021 재검증)
  • Follow-up Action: confirm-req-implemented(BAT-021).

Validation Plan

  • BAT-021: 워치독 만료 holding 슬롯의 expired/last_seen 노출 단위.

CHG-20260611-01

  • Date: 2026-06-11
  • Author: Justin Ko

Change Summary

  • (change-req, dcy-025) 워치독 갱신 트리거 표면을 trex.snapshot.req → trex.slots.req(REQ-073)로 정합한다. 갱신 시맨틱: 기본 조회(holding 슬롯 포함)가 last_seen_at 을 터치하고, spy=true 면 무터치(기존 actor="operator"/touch_watchdog=false ad-hoc 플래그의 일반화·대체). 응답 노출은 top-level watchdog[] 배열이 아니라 슬롯 행의 watchdog:{expired,last_seen}(REQ-074). 만료 판정·grace period·in-memory store 는 불변.

Intent

  • read 표면 교체 후에도 전략 폴링=생존 신호 / 비침습 조회 구분(R-4)을 보존.

Acceptance Criteria Delta

  • Updated:
    • 워치독 갱신 트리거: trex.snapshot.req 처리 시 → trex.slots.req 기본 조회 시(holding 슬롯 last_seen 갱신).
    • 비침습 조회: actor="operator"/touch_watchdog=false → spy=true(무터치).
    • 노출: 응답 watchdog[] 배열 → 슬롯 행 watchdog:{expired,last_seen}.
  • Added/Removed: none

Impacted Area Delta

  • Modules: messaging_handlers.py(터치 분기), portfolio.py(slot_to_dict watchdog 흡수)
  • Docs: docs/interface-contract.md(REQ-075)
  • Tests: spy 무터치/기본 터치, 행 watchdog 필드

Delivery Trace Delta

  • Batches: 신규 batch(REQ-073/074/075 와 동일 배치, dcy-025)
  • Releases: none

Revalidation Impact

  • Reverification Needed: yes (신규 batch 에서 갱신 AC 검증)
  • Existing Implementation Invalidated: yes (snapshot 표면 기반 터치·watchdog[] 노출 evidence 가 표면 교체로 무효화)
  • Status Recommendation: Implemented → Approved (batch 재구현·재검증 후 복귀)
  • Follow-up Action: draft-batch → 구현/검증 → confirm-req-implemented

Validation Plan

  • 신규 BAT: 기본 조회 터치/spy 무터치 단위(REQ-073 AC-4 와 공유), 행 watchdog 필드(REQ-074 AC-1), 만료·grace 회귀.