diff --git a/apps/api/src/services/decision_manager.py b/apps/api/src/services/decision_manager.py index a1748ebc..eb4771d8 100644 --- a/apps/api/src/services/decision_manager.py +++ b/apps/api/src/services/decision_manager.py @@ -53,10 +53,16 @@ def _fire_and_forget(coro) -> asyncio.Task: return task # P1 fix 2026-04-11: kubectl action dangerous char whitelist +# 2026-04-25 ogt + Claude Sonnet 4.6: 補允許 K8s resource type keyword +# LLM 常輸出 "kubectl rollout restart deployment clickhouse" (含 deployment 關鍵字) +# 原 pattern 只允許 verb 後直接接名稱,導致 _action_safe=False → 全部被攔截 → 飛輪 0 +# 修法:在名稱前加可選的 resource type group (deployment/pod/service/...) import re as _re_module _ALLOWED_KUBECTL_PATTERN = _re_module.compile( r"^kubectl\s+(rollout restart|rollout undo|scale|delete pod|get|describe|logs)" - r"\s+[a-zA-Z0-9_./-]+(\s+(-n|--namespace)\s+[a-zA-Z0-9_-]+)?$" + r"\s+(?:(?:deployment|pod|pods|service|services|statefulset|sts|daemonset|ds|svc|configmap|cm)\s+)?" + r"[a-zA-Z0-9_./-]+(\s+(-n|--namespace)\s+[a-zA-Z0-9_-]+)?$", + _re_module.ASCII, ) @@ -2082,6 +2088,14 @@ class DecisionManager: _push_auto_repair_result(incident, action, success=_exec_success) ) + # 2026-04-25 ogt + Claude Sonnet 4.6: 飛輪閉環 — auto_execute 路徑補 KM 寫入 + # 根因:Explore agent 確認 _write_execution_result_to_km 只在人工審核路徑呼叫 + # auto_execute 路徑執行完成後沒有 KM 回寫 → 學習飛輪斷鏈 + # 修法:複用 executor._write_execution_result_to_km,與人工路徑共享同一 KM schema + _fire_and_forget( + executor._write_execution_result_to_km(approval, _exec_success, None) + ) + except Exception as e: logger.error( "auto_execute_failed",