Files
awoooi/docs/adr/ADR-072-aiops-bug-fixes.md
OG T 82e1c05df8
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
fix(review): Code Review C1/C2/I2/M2 修補
C1 drift_interpreter: 寫死 192.168.0.111 → settings.OLLAMA_URL
  違反 feedback_frontend_internal_ip_ban 鐵律(後端 service 層同樣禁止寫死內網 IP)

C2 km_conversion_service: BUG-004 補同步 Redis Working Memory vectorized 欄位
  原修復只更新 DB,Redis incident:{id} JSON 的 vectorized 未同步
  → 審計查 Redis 仍顯示 False,fly-wheel 閉環指標仍不準
  修復:DB 更新後 GET → JSON patch vectorized=True → SET(保留原 TTL)

I2 decision_manager: _ALERTNAME_KEYWORDS HostHighDiskUsage→HostOutOfDiskSpace
  + 補 DockerContainerExited
  + fallback 路徑加 debug log

M2 decision_manager: import json as _json 從 for 迴圈移至方法頂部

docs: ADR-072 新增 Code Review 發現與技術債記錄

2026-04-11 Claude Sonnet 4.6 Asia/Taipei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 20:36:59 +08:00

126 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-072: AIOps 閉環 Bug 修復清單
> **狀態**: ✅ 全部修復完成 (BUG-001~008)
> **建立**: 2026-04-11 (台北時間)
> **更新**: 2026-04-11 深夜 — P0 (BUG-001/002/003) + P1 (BUG-004/005/006) 全修復並推送 Gitea
> **背景**: Session 6 對 Redis DB10 + 程式碼全面審計發現 8 個系統性問題
---
## 背景
ADR-070/071 實作完成後Session 6 對 62 個 DecisionToken、112 個 Incidents 及 Telegram 告警進行全面審計,
發現 MCP 雖已實作但閉環仍未真正生效。本 ADR 記錄所有發現與修復方案。
---
## Bug 清單
### P0 — 立即修復(閉環核心失效)
#### ✅ BUG-001: drift_interpreter 永久失敗 (已修復 commit 88e3197)
- **位置**: `apps/api/src/services/drift_interpreter.py:112`
- **症狀**: 所有 K8s 漂移解析失敗,`too many values to unpack (expected 4)`
- **根因**: `response_text, success, _tokens, _cost = await nvidia.chat(...)` — nvidia_provider 已重構為返回 `NvidiaProviderResult` 物件,非 4-tuple
- **修復方案**: 改用 `drift_narrator_service`ADR-067 Phase 30qwen2.5:7b-instruct已存在做漂移摘要完全繞過 nvidia_provider
- **影響**: 所有 K8s config drift 告警無法生成可讀摘要
#### ✅ BUG-002: 自動修復 deployment name 全為 "unknown" (已修復 commit 88e3197)
- **位置**: `apps/api/src/services/decision_manager.py:_auto_execute()` + `apps/api/src/services/incident_service.py:extract_affected_services()`
- **症狀**: 24/62 DecisionToken = errorsafety guard 攔截(`"unknown" in action`
- **根因**: HostHighCpuLoad / DockerContainerUnhealthy 等主機層告警只有 `{alertname, host}` label`component`/`job`/`pod``extract_affected_services()` 返回 `[]` → target = "unknown"
- **修復方案**: 在 `_auto_execute()` 執行前,呼叫 K8s MCP `k8s_describe_pod` / `kubectl get pods` 根據 alert 類型動態查詢受影響 Pod填入 target
- **影響**: 所有非 K8s 源頭告警的自動修復全部失敗
#### ✅ BUG-003: nemotron_validation 接受無效 deployment name (已修復 commit 88e3197)
- **位置**: `apps/api/src/services/decision_manager.py:_nemoclaw_second_opinion()`
- **症狀**: `<deployment_name>``HostHighCpuLoad``unknown` 等無效值通過 schema 驗證
- **根因**: 只做 JSON schema 結構驗證,不驗證 deployment name 是否真實存在於 K8s
- **修復方案**: 加入 K8s MCP `k8s_describe_pod` 存在性檢查,若 deployment 不存在則拒絕並重新分析
- **影響**: 無效的修復指令被誤判為合法
---
### P1 — 本 Sprint 修復(功能性問題)
#### ✅ BUG-004: KM vectorization 108/112 = False (已修復 commit 5aa0244)
- **位置**: `apps/api/src/services/km_conversion_service.py`
- **症狀**: RAG 知識庫未累積飛輪自癒閉環ADR-068學習效果為零
- **根因**: KM 轉換服務呼叫後未確保 embedding 寫入 pgvectorSession 6 確認 `vectorized=False``persisted_to_pg=False`
- **修復方案**: 修復 `convert()` 後的 embedding 寫入流程,確保 `nomic-embed-text` 768d 向量化並持久化
#### ✅ BUG-005: 15 ready decisions 無人審核 (已修復 commit 5aa0244)
- **位置**: incident_id → approval UUID 對應流程
- **症狀**: 15 個 `status=ready` 的 DecisionToken 長期無審核Telegram 未發出審核卡片
- **根因**: approval flow 的 `incident_id` UUID 對應問題
- **修復方案**: 診斷 `incident_id` 查詢鏈,修復 Telegram 審核卡片未發送的問題
#### ✅ BUG-006: outcome/verification_result 全 null (已修復 commit 5aa0244)
- **位置**: `apps/api/src/services/decision_manager.py:_push_auto_repair_result()`
- **症狀**: 所有已完成修復無 outcome 記錄
- **根因**: post-repair 驗證邏輯未寫入 DB outcome 欄位
- **修復方案**: 修復 `_push_auto_repair_result()` 確保 outcome + verification_result 寫入
---
### P2 — 下 Sprint 修復(數據品質問題)
#### ✅ BUG-007: 所有告警 severity = P3/Highlabel 缺失)— 確認不需修 (2026-04-11)
- **位置**: `k8s/monitoring/alerts-unified.yml`
- **症狀**: 所有 62 個 DecisionToken 對應告警都是 P3mapping: no label → P3
- **根因**: Prometheus 告警規則大部分未設 `severity` label
- **修復方案**: 按告警類型補充 `severity: critical|high|warning|info` label
#### ✅ BUG-008: 69/112 incidents type = "custom" (已修復 commit f34fe19)
- **位置**: `apps/api/src/api/v1/webhooks.py:1103``alertname_to_type` 只有 9 筆)
- **症狀**: 大部分告警無法觸發對應 Playbook
- **根因**: `alertname_to_type` mapping 只覆蓋 9 種 K8s 告警,其他全部 → "custom"
- **修復方案**: 整合 ADR-064 Rule Engine從 YAML 規則動態推斷告警類型,取代靜態 9 筆 mapping
---
## 修復順序
```
BUG-001 (drift_interpreter) → BUG-002 (deployment_name) → BUG-003 (nemotron_validation)
→ BUG-004 (KM vectorization) → BUG-005 (approval flow) → BUG-006 (outcome)
→ BUG-007 (severity labels) → BUG-008 (alertname_to_type)
```
---
## 驗收標準
| Bug | 驗收 |
|-----|------|
| BUG-001 | K8s config drift 告警 → Telegram 出現可讀摘要(非錯誤訊息)|
| BUG-002 | HostHighCpuLoad 告警 → DecisionToken status = completed非 error|
| BUG-003 | 無效 deployment name → nemotron 拒絕並重新分析 |
| BUG-004 | 新 Incident 完成後 Redis + DB 兩處 vectorized = TrueC2 修復:同步 Redis|
| BUG-005 | ready decisions → Telegram 發出審核卡片 |
| BUG-006 | 修復完成後 outcome + verification_result 不為 null |
| BUG-007 | 確認不需修alerts-unified.yml 全 42 規則均有 severity label |
| BUG-008 | HostHighCpuLoad → incident_type = "host_cpu"(非 "custom"|
---
## Code Review 發現2026-04-11 首席架構師審查)
### 已修復C1/C2/I2/M2
| 項目 | 問題 | 修復 |
|------|------|------|
| C1 | `drift_interpreter.py` 寫死內網 IP `192.168.0.111` | 改從 `settings.OLLAMA_URL` 讀取 |
| C2 | BUG-004 只更新 DBRedis Working Memory `vectorized` 未同步 | 補 Redis JSON patch 同步 |
| I2 | `_ALERTNAME_KEYWORDS``HostHighDiskUsage`(與 alerts-unified.yml 不符) | 改為 `HostOutOfDiskSpace` + 補 `DockerContainerExited` + fallback log |
| M2 | `import json as _json` 在 for 迴圈體內 | 移至方法頂部 |
### 已記錄技術債(不阻塞合併)
| 項目 | 說明 | 後續 |
|------|------|------|
| I1 | BUG-008 規格說整合 ADR-064 Rule Engine實際改用靜態 dict 擴充 | 下 Sprint 整合 ADR-064 YAML 規則動態推斷;靜態 dict 為可接受中間狀態 |
| I3 | `resend_stale_ready_tokens()` 直接 Redis SCAN + DB 存取,輕微違反積木化 | Phase R 清理decision_manager 全域已有類似模式,不單獨修 |
| I4 | BUG-006 outcome 寫入非 atomic | 已足夠改善(從「永遠 null」到「大部分有值」完整 atomic 待 Phase R |
| M3 | `alertname_to_type` dict 應抽至 constants 模組 | 下 Sprint 與 ADR-064 整合時一起重構 |