From cbb719b4a1d8a667f7d24c33970fa04fed7a9dfb Mon Sep 17 00:00:00 2001 From: OG T Date: Fri, 17 Apr 2026 22:44:41 +0800 Subject: [PATCH] =?UTF-8?q?fix(decision=5Fmanager):=20ADR-091=20hotfix=20?= =?UTF-8?q?=E2=80=94=20=E4=BF=AE=E5=BE=A9=20d5dbfc9=20=E5=96=AA=E5=B1=8D?= =?UTF-8?q?=E9=96=98=E9=96=80=E9=82=8F=E8=BC=AF=E6=BC=8F=E6=B4=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit d5dbfc9 引入的閘門條件 `not action.strip()` 在 action="待分析" 時 判斷為 False(非空字串),導致閘門失效,喪屍卡片仍然突圍廣播。 根本原因:c759b4e P1 修復讓 suggested_action fallback 為 "待分析" 而非 "",使原本的 empty-string 檢查形同虛設。 修復:改用集合判斷 `_action_text in {"", "待分析", "NO_ACTION", "待分析 - 系統自動保護"}`, 涵蓋所有已知失敗狀態 token,完全封堵喪屍卡片廣播路徑。 Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/services/decision_manager.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/api/src/services/decision_manager.py b/apps/api/src/services/decision_manager.py index 65c57181..d022f708 100644 --- a/apps/api/src/services/decision_manager.py +++ b/apps/api/src/services/decision_manager.py @@ -267,14 +267,21 @@ async def _push_decision_to_telegram( # 🚨 ADR-091 鐵律 (2026-04-17 ogt + Claude Sonnet 4.6): 禁止分析失敗廣播 # 問題: GET /incidents 觸發 Agent Debate → LLM 全部失敗 → description="待分析" + action="" # → 系統每隔幾分鐘廣播「待分析」喪屍卡片 → 告警疲勞(SRE 最致命的殺手) - # 規則: description="待分析" + action="" = Phase 2 所有 Agent 無有效輸出 → 靜默退出 + # 規則: description="待分析" + action 屬於失敗狀態集合 = Phase 2 所有 Agent 無有效輸出 → 靜默退出 # 已完成: DB 狀態已在上方更新 (update_action_by_incident_id),不需要 Telegram 廣播 # 禁止改動: 此閘門保護全域告警信噪比,任何「加例外」需首席架構師書面授權 - if description.strip() == "待分析" and not action.strip(): + # 2026-04-17 ogt + Claude Sonnet 4.6 (hotfix): 修復 d5dbfc9 邏輯漏洞 + # 舊 bug: `not action.strip()` 在 action="待分析" 時為 False → 閘門失效 → 喪屍卡片突圍 + # 原因: c759b4e P1 修復讓 suggested_action fallback 為 "待分析"(非空字串)而非 "" + # 修復: action 必須不在失敗狀態集合才允許廣播 + _action_text = action.strip() + _FAILED_ACTION_TOKENS = {"", "待分析", "NO_ACTION", "待分析 - 系統自動保護"} + if description.strip() == "待分析" and _action_text in _FAILED_ACTION_TOKENS: logger.info( "telegram_push_suppressed_no_analysis", incident_id=incident.incident_id, - reason="Agent Debate 無有效輸出 (description=待分析, action=空白)", + action_text=_action_text, + reason="Agent Debate 無有效輸出 (description=待分析, action 屬於失敗狀態集合)", ) return