From c05bcdbbd42c37c56cb3365814a6f16c3d03d892 Mon Sep 17 00:00:00 2001 From: OG T Date: Fri, 17 Apr 2026 10:15:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(decision):=20inline=20YAML=20NO=5FACTION=20?= =?UTF-8?q?=E8=A3=9C=E6=9F=A5=20=E2=80=94=20=E4=BF=AE=E5=BE=A9=20Phase=202?= =?UTF-8?q?=20=E8=B7=AF=E5=BE=91=E7=9B=B2=E9=BB=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:Phase 2 (agent debate → auto_approve 拒絕 → 直接推 TG) 不經過 auto_execute() 的 YAML check,Coordinator 不設 blocked_reason。 PostgreSQL disk / host resource 等 NO_ACTION 規則告警在 Phase 2 路徑仍顯示「ACTION REQUIRED」卡片(TYPE-3),而非 TYPE-1 資訊卡。 修復:_push_decision_to_telegram() 在 blocked_reason 為空時,補做一次 alertname inline YAML 查詢,任何路徑(Phase 2 / Expert / Webhook) 都能正確偵測 NO_ACTION → TYPE-1 / critical NO_ACTION → TYPE-4。 生產驗證觸發:INC-20260416-C365D0 PostgreSQL disk alert 顯示 ACTION REQUIRED 而非 TYPE-1,確認全景 Code Review 遺漏此執行路徑。 Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/services/decision_manager.py | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/apps/api/src/services/decision_manager.py b/apps/api/src/services/decision_manager.py index 52b61a59..322e9242 100644 --- a/apps/api/src/services/decision_manager.py +++ b/apps/api/src/services/decision_manager.py @@ -268,6 +268,31 @@ async def _push_decision_to_telegram( # ② NO_ACTION + critical → TYPE-4:critical 事件不能靜默,即便 AI 無法自動修復 # ③ NO_ACTION + non-critical → TYPE-1:一般資訊告警,純資訊卡即可 _blocked_reason = proposal_data.get("blocked_reason", "") + + # 2026-04-17 ogt + Claude Sonnet 4.6: Inline YAML NO_ACTION 補查 + # 根因:Phase 2 路徑(agent debate → auto_approve 拒絕 → 直接推 TG)不經過 + # auto_execute() 的 YAML check(lines 1427-1439),Coordinator 不設 blocked_reason。 + # 修復:在 _push_decision_to_telegram 內做一次 alertname 查詢,任何路徑都能偵測 NO_ACTION。 + if not _blocked_reason and incident.signals: + try: + from src.services.alert_rule_engine import match_rule as _notif_match + _notif_alertname = incident.signals[0].labels.get("alertname", "") + if _notif_alertname: + _notif_rule = _notif_match({ + "labels": incident.signals[0].labels, + "alert_type": _notif_alertname, + "message": "", + "target_resource": target, + "namespace": "awoooi-prod", + }) + if _notif_rule: + if _notif_rule.get("blocked_reason", "").startswith("INVALID_TARGET"): + _blocked_reason = _notif_rule["blocked_reason"] + elif _notif_rule.get("suggested_action") == "NO_ACTION": + _blocked_reason = f"YAML: NO_ACTION for {_notif_alertname}" + except Exception: + pass # 查詢失敗不影響主流程 + if "INVALID_TARGET" in _blocked_reason: _notif_type = NotificationType.TYPE_4 elif "NO_ACTION" in _blocked_reason: