From e5465ad136cffbf3e64c888e30611b4d1347da3b Mon Sep 17 00:00:00 2001 From: gahusb Date: Wed, 20 May 2026 02:41:09 +0900 Subject: [PATCH] =?UTF-8?q?fix(lotto-signals):=20pstdev=E2=86=92stdev=20(d?= =?UTF-8?q?dof=3D1=20sample)=20+=20z=3DNone=20contract=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- agent-office/app/curator/signals.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/agent-office/app/curator/signals.py b/agent-office/app/curator/signals.py index 0c63b67..9aae3bb 100644 --- a/agent-office/app/curator/signals.py +++ b/agent-office/app/curator/signals.py @@ -7,7 +7,7 @@ signal_runner.py에서 DB 연동 + cron 진입점 담당. from __future__ import annotations import math from dataclasses import dataclass, field -from statistics import mean, pstdev +from statistics import mean, stdev from typing import Any, Dict, List, Optional, Tuple @@ -92,7 +92,7 @@ class AdaptiveBaseline: @property def sigma(self) -> float: - return pstdev(self.window) if len(self.window) >= 2 else 0.0 + return stdev(self.window) if len(self.window) >= 2 else 0.0 def push(self, value: float, draw_no: Optional[int] = None) -> None: """FIFO push. window_max 초과 시 가장 오래된 값 제거.""" @@ -108,6 +108,10 @@ class AdaptiveBaseline: Returns: (z_score, fire_level) — z_score는 cold start/warmup이면 None. fire_level ∈ {'warmup', 'noop', 'normal', 'urgent'} + + NOTE: z_score is None when sigma==0 (degenerate window) or warmup. + Callers must treat None as "signal present but unquantified" — do not + compare None with thresholds directly. """ if self.size < 4: return None, "warmup"