docs(discovery): dcy-027 모든 OQ Answered — 중장기 슬롯 운영 결정 완료

OQ-1: (a′) 기존 슬롯 도메인 유지 + 운영 프로파일/규칙 추가 (PositionBook 불필요)
OQ-2: safety_sell_enabled=false → 코어 손절매 루틴 없음, 전략 모듈 전적 책임
OQ-3: per-instance watchdog_timeout_sec 연장 (1800s 이상 권장), 알림은 후속 Discovery
OQ-4: 중장기 전략 폴링 주기 최소 1분·최대 10분

feat(bat-041): REQ-076/077/078 — watchdog timeout TOML + 중장기 운영 프로파일 + baseline

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 22:19:33 +09:00
co-authored by Claude Sonnet 4.6
parent d737467d70
commit 6786ffd05d
16 changed files with 634 additions and 44 deletions
+20
View File
@@ -154,6 +154,10 @@ class DaemonInstanceConfig:
# dcy-024 / REQ-048 CHG-20260611-01: disable autonomous safety-sell worker.
# Absent = True (safe default). False → trex-safety-sell thread not started.
safety_sell_enabled: bool = True
# dcy-027 / REQ-076: per-instance watchdog timeout (seconds). None = fall
# back to env TREX_WATCHDOG_TIMEOUT (default 120). Long-term instances
# polling every 1-10 min should set >= 1800 so expired stays meaningful.
watchdog_timeout_sec: Optional[int] = None
@staticmethod
def from_toml(path: str) -> "DaemonInstanceConfig":
@@ -178,6 +182,12 @@ class DaemonInstanceConfig:
raise RuntimeError(
f"instance TOML 'default_order_timeout_sec' must be > 0, got {raw_timeout}: {path}"
)
raw_wd = data.get("watchdog_timeout_sec")
watchdog_timeout = int(raw_wd) if raw_wd is not None else None
if watchdog_timeout is not None and watchdog_timeout <= 0:
raise RuntimeError(
f"instance TOML 'watchdog_timeout_sec' must be > 0, got {raw_wd}: {path}"
)
return DaemonInstanceConfig(
instance_key=str(instance_key),
portfolio_hub_token=str(data.get("portfolio_hub_token") or ""),
@@ -185,6 +195,7 @@ class DaemonInstanceConfig:
max_active_slots=max_active,
default_order_timeout_sec=default_timeout,
safety_sell_enabled=bool(data.get("safety_sell_enabled", True)),
watchdog_timeout_sec=watchdog_timeout,
)
@@ -340,6 +351,14 @@ class DaemonConfig:
pf = base.portfolio_hub
if inst.portfolio_hub_token and pf is not None:
pf = replace(pf, token=inst.portfolio_hub_token)
# dcy-027 / REQ-076: per-instance watchdog timeout. TOML wins over the
# env-derived value; absent keeps env TREX_WATCHDOG_TIMEOUT (default 120)
# so existing instances are byte-for-byte unaffected.
safety_sell = base.safety_sell
if inst.watchdog_timeout_sec is not None:
safety_sell = replace(
safety_sell, watchdog_timeout_sec=inst.watchdog_timeout_sec
)
return replace(
base,
instance_key=inst.instance_key,
@@ -347,4 +366,5 @@ class DaemonConfig:
trading_timezone=inst.trading_timezone,
max_active_slots=inst.max_active_slots,
safety_sell_enabled=inst.safety_sell_enabled,
safety_sell=safety_sell,
)