# BAT-041 Implementation - Status: completed - Batch: BAT-041 ## Plan Summary - `DaemonInstanceConfig.watchdog_timeout_sec`(TOML, env 폴백) + `from_config` 단일 지점 override, `config/longterm.example.toml` 표준 프로파일, runtime-flows 중장기 운영 flow, 테스트 7종. ## Changed Files - `trex_core/runtime/config.py` — `DaemonInstanceConfig.watchdog_timeout_sec: Optional[int] = None` + `from_toml` 파싱(<=0 거부) + `from_config` 에서 `SafetySellConfig` `dataclasses.replace` override(TOML 우선, env 폴백) - `config/longterm.example.toml` (신규) — 중장기 표준 프로파일(instance_key=longterm, safety_sell_enabled=false, watchdog_timeout_sec=1800, max_active_slots=10) + 키별 중장기 의미 주석(forced_close_at 미사용, market-close env 미설정 포함) - `docs/runtime-flows.md` — `중장기(멀티데이) 인스턴스 병행 운영` flow 신설(6단계: 분리 기동/프로파일/보유 유지/보호 경계/forced_close_at 미사용/watchdog 의미) + Change Log - `tests/runtime/test_watchdog_timeout_toml.py` (신규, 7 테스트) ## Execution Log 1. `config.py`: `DaemonInstanceConfig` 에 optional 필드 추가, `from_toml` 에 기존 `max_active_slots` 검증 패턴으로 파싱+거부, `from_config` 에서 `inst.watchdog_timeout_sec is not None` 시 `safety_sell` replace — 소비자 2곳(slots RPC 핸들러 daemon.py:284, SafetySellService `_cfg`)이 모두 `config.safety_sell` 을 읽으므로 단일 지점으로 일치(design Key Decision 1). 2. `longterm.example.toml`: REQ-077 레시피 — 운영자 복제 사용 가능한 주석 포함. 3. `runtime-flows.md`: multi-instance 라우팅 섹션 뒤에 중장기 운영 flow 신설. 4. 테스트: TOML 적용(1800)/TOML>env 우선/env 폴백(300)/기본 120/인스턴스별 독립/<=0 거부/예시 프로파일 조합 로딩(longterm·false·1800·10). ## Validation - `pytest tests/runtime/test_watchdog_timeout_toml.py` — 7 passed (신규) - `pytest tests/` — **446 passed, 46 skipped** (BAT-040 439 → +7, 회귀 0 — NFR-1 당일 무회귀 게이트 green) - `ruff check trex_core tests` — All checks passed - instance 격리(NFR-2): 인스턴스별 독립 timeout 테스트 + 기존 instance topology 테스트 회귀 green. ## Remaining Risks - 없음. R-1(소비자 불일치)=단일 지점 override 로 제거, R-2(frozen)=`replace` 사용, R-3(장기 run 재현)=설정·기동 구성 단위 검증 + BAT-036 evidence 재참조, 실 데몬 장기 운영 검증은 release 단계 위임(verification 명시). ## Out-of-scope Finding (별도 후속) - **pre-existing bug 발견**: `DaemonInstanceConfig.from_toml` 은 `default_order_timeout_sec` 를 파싱하지만 `DaemonConfig.from_config` 의 `replace(...)` 에 전파 누락 — TOML 의 `default_order_timeout_sec` 가 런타임에서 조용히 무시됨(daemon.py:156 은 `config.default_order_timeout_sec` 를 읽으나 항상 env-base 값). REQ-068/REQ-048 영역 — 본 batch 범위 밖, change-req 후속 필요.