Files
awoooi/docs/adr/ADR-078-gap-a4-placeholder-resolution.md
OG T aa4e5757a2
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 15m46s
fix: 技術債清理 — report_generation 重試機制 + GAP-A4 文件化
技術債 #1: postmortem 發送失敗靜默吞掉
- 3 次指數退避重試 (2s → 4s → 6s)
- 全失敗後送簡化降級通知到 SRE 群組
- 防止事後檢討默默消失

技術債 #2 (QueryBuilder 抽象): DEFER
- 全專案僅 1 處用 outcome JSON path query
- 違反「Don't design for hypothetical future requirements」
- 待第二 caller 出現再抽

技術債 #3 (E2E 測試): 已涵蓋
- test_gap_a4_placeholder_resolution.py TestMatchRuleRejection
- Mission C prod 鏈路實測(KubePodCrashLooping)
- Playwright K8s/Telegram staging 留待 staging 環境就緒

新增文件:
- ADR-078-gap-a4-placeholder-resolution.md
- LOGBOOK 2026-04-14 深夜收官條目

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-14 18:46:25 +08:00

3.4 KiB
Raw Blame History

ADR-078: GAP-A4 規則模板 Placeholder 解析強化

日期: 2026-04-14台北傍晚
狀態: Accepted
作者: Claude Sonnet 4.6(首席架構師)+ 統帥戰場偵察 相關: ADR-064 Rule Engine、ADR-077 MASTER 藍圖收案、GAP-A1 kubectl 注入防護


問題

MASTER 藍圖收案後,統帥 log 巡察發現真正的隱性病灶

auto_execute_blocked_unresolved_placeholder
  action: kubectl rollout restart deployment HostHighCpuLoad   ← target=alertname!
  action: kubectl rollout restart deployment unknown
  action: kubectl scale deployment unknown --replicas=3

大量告警在規則引擎路徑產生垃圾指令 → GAP-A1 防注入閘攔下 → 自動修復卡死 → 飛輪沉默 8.3 小時

MASTER 藍圖未涵蓋此缺口,命名為 GAP-A4規則 Action 模板 Placeholder 解析缺漏


根因

alert_rule_engine._extract_vars() 解析邏輯在 Prometheus 告警deployment label 時:

  • 退回 alertname"unknown" 作為 target
  • 填入 {target} placeholder → 產生 kubectl rollout restart deployment HostHighCpuLoad

決策

三層防護

  1. 新增 _strip_pod_suffix() — Pod 名稱還原 Deployment/StatefulSet base name

    • Deployment: awoooi-api-7d6b776f78-4sgjlawoooi-api
    • StatefulSet: postgresql-0postgresql
  2. 新增 _is_bad_target() — 垃圾 target 識別

    • 空/unknown/none/null
    • 等於 alertname 本身
    • IP:port、純 IP、含空白/括號/引號
  3. 重寫 _extract_vars() — 多層 label 查找(權威優先) deployment > app > statefulset > pod(去後綴) > container > service > target_resource

  4. match_rule() 後置雙驗證

    • bad target → 清空 kubectl_command → 降級 LLM
    • 殘留 {} → 清空 kubectl_command → 降級 LLM

降級策略

規則引擎清空 kubectl_command 後,decision_manager 會自然降級到 LLM 路徑OpenClaw/NemoTronLLM 有能力從 log 內容推理真實 deployment 名稱。若 LLM 也無解,進 TYPE-4 人工扶梯。


結果

  • Commit 10b74af
  • 33 個新單元測試214/214 回歸全綠
  • LOG: rule_kubectl_command_discarded_bad_target 取代 auto_execute_blocked_unresolved_placeholder
  • 飛輪恢復運轉可能性大幅提升LLM 會接手處理無 deployment label 的告警)

教訓

  1. 防注入閘是盡責的守門員,但會遮蔽上游 bug。遇到大量攔截日誌必須追上游。
  2. 測試告警需涵蓋缺 label 的 sad path。原單元測試只測 happy path。
  3. log 監控不能取代 metrics 告警auto_execute_blocked_unresolved_placeholder 累積 8.3 小時才被人工發現,應加 Prometheus 告警規則。

後續

  • 加 Prometheus 告警規則:rule_kubectl_command_discarded_bad_target rate > 5/min 觸發 TYPE-8M flywheel_health
  • 補 E2E 測試:真實 Alertmanager 發 HostHighCpuLoad → 驗證 target 正確降級
  • 檢查其他規則(如 SSH 路徑)是否有類似 placeholder 解析問題

相關

Accepted by 統帥 @ 2026-04-14 台北深夜