Commit Graph

694 Commits

Author SHA1 Message Date
OG T
cd1c0ffdb8 fix(openclaw): call() 5值→3值 — 修復全部 AI 分析降級根因
根因: _call_with_fallback() 回傳 5-tuple,但 call() 直接 return
導致呼叫端 (diagnostician/solver/critic agents) 3-var unpack
→ ValueError: too many values to unpack → 全部 降級 20%

修復: call() 明確解包再回傳 (response, provider, success)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 03:27:48 +08:00
OG T
62e2efda85 fix(heartbeat): 恢復 30 分鐘心跳報告到 SRE 戰情室
2026-04-15 停用理由(forwarded_to_separate_group)有誤,
SRE 戰情室就是 SRE_GROUP_CHAT_ID,不應停用。
恢復 start_heartbeat_monitor(interval=30min)。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 03:05:01 +08:00
OG T
27ba97e586 fix(ollama): 清除所有硬寫 188:11434 fallback — 全部改指向 111 GPU
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 15m59s
- decision_manager.py: 兩處 getattr fallback 188 → 111
- routes/agent.py: OLLAMA_BASE_URL 188 → 111
- knowledge_extractor_service.py: _OLLAMA_BASE 188 → 111

config.py 預設早已是 111,此次清掉 code 層殘留的 188 硬寫值。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 03:01:31 +08:00
OG T
7e3cc8b3b0 fix(agents): 移除人工 per-agent timeout,LLM 必須等完整回應
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
原設計 asyncio.wait_for(timeout_sec=25s) 是任意截斷,
只要 LLM 超過時限就降級為 confidence=20%,根本沒有分析。

正確做法:
- 移除所有 4 個 agent 的 asyncio.wait_for() 包裝
- 只留 except Exception 捕真實異常(連線失敗、模型崩潰)
- 全流程由 Orchestrator GLOBAL_TIMEOUT_SEC=90s 防掛死
- _PER_AGENT_TIMEOUT_SEC 常數廢棄移除

影響:LLM 推理多久就等多久,不再人工截斷,
      deepseek-r1:14b 等模型得以完整輸出分析結果。

2026-04-16 ogt + Claude Sonnet 4.6

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 02:54:34 +08:00
OG T
5a3a649f8a fix(decision): TYPE-1 告警重複洗版兩個根因修復
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
根因 1: TYPE-1 bypass 在 existing_token 檢查之前執行
→ 每次 get_or_create_decision() 不管 token 是否存在,都直接推 TG
→ 修復: existing_token 檢查提前到 TYPE-1 bypass 之前(統一入口)

根因 2: TYPE-1 token TTL 僅 3600s
→ 1h 後 token 過期,下次掃描重新建立並再推 TG
→ 修復: TYPE-1 token TTL 提升至 86400s (24h)

影響: HostBackupFailed 等 TYPE-1 告警每個 incident 只推 1 次(24h 內)

2026-04-16 ogt + Claude Sonnet 4.6

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 02:49:31 +08:00
OG T
62bcc50770 fix(tg+km): 補齊 Telegram 操作紀錄揭露與 KM 分類修復 (ADR-076)
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
Telegram 訊息新增欄位:
- alert_category 分類標籤(🏷️ 主機/K8s/資料庫/服務等)
- playbook_name 顯示匹配到的 Playbook 名稱
- 頻率統計從 count_24h>1 降至 >=1(初次告警也顯示)
- TelegramMessage 新增 alert_category/playbook_name 欄位
- decision_manager → send_approval_card 穿透 playbook_name

KM 修復:
- EntryType.PLAYBOOK → EntryType.AUTO_RUNBOOK(前者不存在,會 AttributeError)
- category "auto_generated" → "ai_system"(前端 i18n 有對應翻譯)
- runbook_generator 同步修正 category
- KM 建立後推 Telegram 通知(best-effort)

DB decision_chain 補欄位:
- 新增 playbook_id / playbook_name / alert_category

2026-04-16 ogt + Claude Sonnet 4.6

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 02:46:17 +08:00
OG T
9538f6cca4 fix(agents): 修正 Agent 5s timeout 導致 LLM 推理全部失敗
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 16m14s
根本原因: deepseek-r1:14b 實測推理 2.2-27.3s avg 10.6s
但 Diagnostician/Critic/Solver/Reviewer 全部使用 timeout_sec=5.0 (開發機測試值)
→ 67% 的 Agent 推理 timeout → 降級 confidence=20% → 自動修復從不觸發

修復:
- _PER_AGENT_TIMEOUT_SEC: 5s → 25s (覆蓋 avg 的 2.3x buffer)
- GLOBAL_TIMEOUT_SEC: 30s → 90s (3個序列Agent × 25s + buffer)
- 明確傳遞 timeout_sec 給所有 4 個 Agent 呼叫

預期效果: 正常告警 AI 分析 confidence ≥ 0.5 → 觸發自動修復

2026-04-16 Claude Sonnet 4.6 Asia/Taipei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 02:28:05 +08:00
OG T
a07daf7e3f fix(incidents): GET /incidents 加 48h age filter,阻止舊 incident 反覆觸發 AI 分析
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
根本原因: DECISION_TOKEN_TTL=3600s → 舊 incident token 每小時過期
→ GET /api/v1/incidents 重複觸發 get_or_create_decision → OPENCLAW_NEMO timeout
→ Expert System fallback (confidence=20%) → Telegram 洪水

修復: 只對 created_at 在 48h 內的 incident 觸發背景 AI 分析
48h+ 的舊 incident 不再觸發(仍顯示在列表,只是不重新分析)

2026-04-16 Claude Sonnet 4.6 Asia/Taipei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 02:21:53 +08:00
OG T
f5e33da2fc fix(telegram): 修正 _make_request → _send_request 方法名稱不一致
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 15m48s
7 處呼叫 _make_request 但方法實際名稱為 _send_request,
導致 sweeper 分析完後 telegram_decision_push_failed 錯誤。

影響方法:send_push_notification, send_drift_card 等 ADR-071 系列。
_send_request 定義於 line 1272,OTEL 追蹤已含括。

2026-04-16 Claude Sonnet 4.6 Asia/Taipei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 01:44:29 +08:00
OG T
1e86cc2896 fix(flywheel): 修正 incidents.outcomes → outcome 欄位錯誤
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
GET /api/v1/stats/summary 觸發 UndefinedColumnError: column "outcomes" does not exist
實際欄位為 incidents.outcome (json 型別)

2026-04-16 Claude Sonnet 4.6 Asia/Taipei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 01:42:14 +08:00
OG T
9bfa6fc045 fix(sweeper): 限制只掃 48h 內 incident,防止歷史舊案洗版 Telegram
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
問題:
  首次部署 sweeper 時,找到 117 個無 sweeper_done: 標記的舊 incident
  (最舊 2026-04-09,7 天前) → 觸發全部 LLM 分析
  舊 incident 資料格式 → OPENCLAW_NEMO timeout → Expert System 降級
  confidence=0.2 "降級" → Telegram 連發相同格式告警洗版

修正:
  加入 _MAX_INCIDENT_AGE_HOURS=48 過濾
  只處理 48h 內的 INVESTIGATING incident
  確保 created_at 時區安全(naive → UTC)

2026-04-16 Claude Sonnet 4.6 Asia/Taipei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 01:27:02 +08:00
OG T
0760315059 fix(decision-manager): 修正 CAST 語法 + 關閉 shadow_mode
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
decision_chain_persist_failed 根因:
  asyncpg 不支援 :dc::json 語法 (:: 與具名參數 : 衝突)
  改為 CAST(:dc AS jsonb) — asyncpg 標準寫法

configmap:
  AIOPS_P4_SHADOW_MODE: true → false
  真實主動監控啟用 (proactive_inspector 輸出供 PreDecisionInvestigator 讀取)

2026-04-16 Claude Sonnet 4.6 Asia/Taipei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 01:24:48 +08:00
OG T
20b3fefca7 fix(sweeper): 修正 decision key 格式 BUG (decision:INC-* → sweeper_done:INC-*)
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
根本原因:
  decision token 實際 key 格式為 decision:DEC-{HEX12}
  sweeper 錯誤地查詢 decision:{incident_id} (永遠 = 0)
  → 每 90s 將 186 個 incident 全部列為「未分析」
  → 觸發大量重複 AI 分析請求 (雖 get_or_create_decision 有去重保護)

修正方式:
  改用 sweeper_done:{incident_id} 輕量標記 (TTL 1h)
  分析完成後才設標記,確保失敗的 incident 下輪仍會重試
  get_or_create_decision 內部已有 COMPLETED/READY 去重,雙重保護

2026-04-16 Claude Sonnet 4.6 Asia/Taipei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 01:20:16 +08:00
OG T
457018c0f9 fix(decision-manager): AI 分析結果寫入 incidents.decision_chain (DB 長期保存)
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
修復 Gap: decision token 只有 Redis TTL 12min,AI 診斷歷史永久丟失
  - 新增 _persist_decision_to_db() method
  - get_or_create_decision() 完成後 fire-and-forget 寫入 PG
  - 寫入: ts / confidence / risk_level / provider / source / diagnosis[:200]
  - try/except 吞錯不影響主流程,warning log 追蹤

DB/Cache 分層:
  PG (長期): incidents.decision_chain (歷史) + outcomes + KM entries
  Redis (短期): decision token dedup + working memory + playbook cache

2026-04-16 Claude Sonnet 4.6 Asia/Taipei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 01:08:30 +08:00
OG T
ce1a4d286e feat(sweeper): 新增 Incident Analysis Sweeper — 自動觸發未分析 Incident AI 決策
Gap修復:
  Signal Worker 創建 Incident 後,AI 分析只在 GET /api/v1/incidents 被呼叫時觸發
  若前端無人訪問,新 Incident 永遠沒有 AI 分析與 Telegram 通知

解法:
  新增 src/jobs/incident_analysis_sweeper.py
  每 90 秒掃描無 decision token 的 INVESTIGATING incidents
  自動背景觸發 get_or_create_decision() — Semaphore(3) 限流,每批最多 5 筆
  main.py lifespan 啟動時 asyncio.create_task() 掛載

2026-04-16 Claude Sonnet 4.6 Asia/Taipei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 01:08:30 +08:00
OG T
d258a1fb87 test(ai-router): 更新 DIAGNOSE routing 測試 — None → OPENCLAW_NEMO
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 14m52s
test_diagnose_override_is_none → test_diagnose_override_is_openclaw_nemo
配合 ai_router.py DIAGNOSE 路由修復(Ollama 238s timeout 根因修復)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 00:13:00 +08:00
OG T
d4fed639f6 fix(ai-router): DIAGNOSE 恢復 OPENCLAW_NEMO 路由,修復全部 timeout 降級問題
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 2m16s
根因: 2026-04-12 patch 把 DIAGNOSE 改為 None(複雜度路由)
→ 落入 Rule 6 → Ollama deepseek-r1:14b (CPU 238s) → timeout
→ 降級 20% 信心 + 「待分析」→ 全部 unknown

修復:
1. ai_router.py: DIAGNOSE → OPENCLAW_NEMO(via 188:8088 NVIDIA NIM, 2-27s)
2. ai_router.py: 移除 Rule 6 的 DIAGNOSE deepseek 特殊case(已無用)
3. 04-configmap.yaml: AI_FALLBACK_ORDER 改為 nvidia 優先
   gemini→ollama→nvidia(舊)→ nvidia→gemini→ollama(新)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 00:03:04 +08:00
OG T
c9efaa3740 fix(playbook-seed): 修正 get_db_context import 路徑(db.session → db.base)
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
seed 啟動時靜默失敗的根因:
  from src.db.session import get_db_context  ← 模組不存在
  from src.db.base import get_db_context     ← 正確路徑

此 bug 導致 yaml_rule playbooks 完全無法建立。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 23:49:56 +08:00
OG T
800ab1685f fix(playbook+flywheel): 修復 PlaybookSource enum + repair_steps 相容 + KM stats raw SQL
Some checks failed
CD Pipeline / build-and-deploy (push) Successful in 14m58s
Type Sync Check / check-type-sync (push) Failing after 1m17s
修復三個串聯 bug,讓 Playbook seed 能正常執行:

1. PlaybookSource 新增 YAML_RULE enum(alert_rules.yaml 匯入專用)
2. playbook_seed_service: source=YAML_RULE,dedup 改用 raw SQL by name,
   不再呼叫 list_playbooks(舊格式 repair_steps 會 validation error)
3. playbook_repository._orm_to_pydantic: 舊格式 repair_steps 補齊
   step_number/action_type 必填欄位(向下相容)
4. flywheel_stats_service: embedding IS NULL 改用 raw SQL,
   修復 KnowledgeEntryRecord ORM 無 embedding 屬性的 AttributeError

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 23:32:04 +08:00
OG T
77a92eb469 feat(P6): 提交 offline_replay_service + model_rollback_service (漏提)
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 14m59s
Phase 6 ADR-087 治理閉環兩個核心服務,
之前建立後沒有 git add,一直是 untracked 狀態。

2026-04-15 Claude Sonnet 4.6 Asia/Taipei
2026-04-15 22:29:09 +08:00
OG T
85c4e3b434 fix(km): 修復 KM 寫入全為 unknown 的根因 (三個節點)
Some checks are pending
CD Pipeline / build-and-deploy (push) Has started running
Bug-A: approval_execution.py 呼叫不存在的 get_incident() → AttributeError
被 except 吞掉 → alertname/alert_category/affected_services 全用預設值
修復: 改用 get_from_working_memory() + get_from_episodic_memory() 雙路徑

Bug-B: _record_to_incident() 從 PG 還原 Incident 時漏掉
notification_type + alert_category 欄位 → km_conversion 讀到 None
修復: 加入這兩個欄位的還原

Bug-C: main.py working_memory_warmup 重建 Incident 時同樣遺漏
notification_type + alert_category
修復: 同步補上

2026-04-15 Claude Sonnet 4.6 Asia/Taipei
2026-04-15 22:28:48 +08:00
OG T
256a24e843 fix(deps+startup): drain3/statsmodels 補入 pyproject + warmup skip 舊資料
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 17m23s
- pyproject.toml: 補 drain3>=0.9.11, statsmodels>=0.14.0, sse-starlette
  → Docker build 從 pyproject 裝,requirements.txt 的套件之前沒裝進 image
  → P4 LogAnomalyDetector 400次 drain3_not_available 告警排除
- main.py: working_memory warmup per-record try/except
  → 舊 incident 含非法 source (node-exporter) → 跳過,不 crash 整個 warmup

2026-04-15 ogt + Claude Sonnet 4.6(亞太)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 22:08:13 +08:00
OG T
c05bac6112 fix(playbook): seed tuple unpack + text[] → jsonb migration
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
- playbook_seed_service.py: list_playbooks 回傳 tuple[list, int],
  缺少解包導致 'list' has no attribute 'source'
- fix_playbooks_array_to_jsonb.sql: source_incident_ids/tags text[] → jsonb
  (已手動套用 prod DB)

2026-04-15 ogt + Claude Sonnet 4.6(亞太)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 22:03:59 +08:00
OG T
da871fc149 chore(db): 補齊 AIOps P1/P2/P6 migration SQL(已套用到 prod)
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
incident_evidence / agent_sessions / ai_governance_events 三表
IF NOT EXISTS,production DB 已手動確認存在並 apply。

2026-04-15 ogt + Claude Sonnet 4.6(亞太)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 22:02:17 +08:00
OG T
76558a3cd9 feat(AIOps): 全開 P1-P6 feature flags + Nemotron + offline replay loop
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
- configmap: 啟用 AIOPS_P1~P6 全部總開關與子開關
- configmap: ENABLE_NEMOTRON_COLLABORATION=true(回歸 120s timeout)
- feature_flags.py: 補齊 AIOPS_P6_GOVERNANCE_ENABLED 缺失欄位
- main.py: 掛載 run_offline_replay_loop(ADR-087 Phase 6)

2026-04-15 ogt + Claude Sonnet 4.6(亞太)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:59:51 +08:00
OG T
ecfb7148bf fix(prod): 接通 YAML 規則引擎與自動執行路徑 — 架構核心斷點
Some checks are pending
CD Pipeline / build-and-deploy (push) Has started running
架構斷點根因:
  YAML 規則引擎(alert_rules.yaml)是人工審閱的權威動作來源,
  但自動執行路徑只讀 proposal_data["kubectl_command"](LLM 生成),
  兩者完全脫節 → HostHighCpuLoad 得到 kubectl restart,DockerContainerUnhealthy
  的 SSH 指令被 LLM 的 kubectl 覆蓋。

修復策略:
  在 auto_execute 入口,先查 YAML match_rule:
  1. YAML → NO_ACTION(如 HostHighCpuLoad)→ 立即返回,不執行任何操作
  2. YAML → 非 kubectl 指令(如 ssh docker restart)→ 覆蓋 LLM action,
     後續 infrastructure SSH 路由才能生效

影響:
  - HostHighCpuLoad / NodeCPUUsageHigh → 停止自動執行,降級人工審核
  - DockerContainerUnhealthy → SSH docker restart(若 labels 有 host/container)

2026-04-15 ogt + Claude Sonnet 4.6(亞太): 生產緊急修復第三批

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:50:25 +08:00
OG T
3696fb5938 fix(prod): 修復 host_resource 誤發 K8s kubectl + 自動執行重複風暴
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
1. decision_manager: host_resource 告警(HostHighCpuLoad 等)
   不得執行 kubectl 操作 → 降級人工審核
   根因:原本只擋 infrastructure,host_resource 漏進 K8s 路徑
   → 導致 kubectl rollout restart deployment/HostHighCpuLoad 被真實執行

2. decision_manager: auto_execute 路徑補入 Redis cooldown
   同一 target 5 分鐘內最多自動執行 2 次,防止 awoooi-worker 3x 風暴
   根因:decision_manager 自動執行路徑完全無冷卻保護

2026-04-15 ogt + Claude Sonnet 4.6(亞太): 生產緊急修復第二批

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:45:46 +08:00
OG T
67f437043a fix(prod): 修復四個生產致命 bug — outcome 寫入 / OpenClaw / Telegram 通知 / LLM 規則顯示
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
1. decision_manager: 移除 UPDATE incidents 中的 verification_result 欄位
   (incidents 表無此欄位 → 所有 outcome 寫入失敗 outcome_write_failed)

2. failure_watcher: get_openclaw_service → get_openclaw
   (函數名錯誤 → OpenClaw 分析全部 ImportError 崩潰)

3. failure_watcher: tg.send_message → tg.send_notification
   (TelegramGateway 無 send_message 方法 → 修復通知無法送出)

4. decision_manager: expert_analyze 補齊 initial_diagnosis / diagnosis_description key
   (openclaw.py 讀這兩個 key,但 expert_analyze 只有 matched_rule / description
    → LLM 永遠看到 Matched Rule=unknown,無法正確分析)

2026-04-15 ogt + Claude Sonnet 4.6(亞太): 生產緊急修復

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:41:31 +08:00
OG T
e5e94f5fda fix(Phase 3): 管理員端點傳 force=True — 確保 Evolver 演練不受 flag 阻擋
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 14m56s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:09:13 +08:00
OG T
01fb531c02 fix(Phase 3): Evolver force=True bypass flag + 清理未使用 import
- run_evolver(force=True):管理員手動端點可繞過 feature flag
- 移除 typing.Any 未使用 import
- 移除 _merge_similar 中冗餘的 calculate_jaccard_similarity import

ADR-083 Phase 3 — 2026-04-15 ogt + Claude Sonnet 4.6(亞太)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:09:01 +08:00
OG T
4718c7667c feat(Phase 3): Evolver loop 排程 + 手動觸發端點 — 合併演練閘道完工
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
- playbook_evolver.py: 新增 run_evolver_loop()(24h 無限迴圈)
- main.py: 掛載 run_evolver_loop asyncio.create_task
- api/v1/learning.py: POST /api/v1/learning/evolver/run(Phase 3 exit #6 演練端點)
- MASTER §8: 補錄 66c4eda AgentSession + 本次 Evolver 完整退出條件清單

ADR-083 Phase 3 — 2026-04-15 ogt + Claude Sonnet 4.6(亞太)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:07:56 +08:00
OG T
66c4eda27a feat(Phase 3): AgentSession 學習接線 — record_agent_session() + orchestrator 辯證訊號
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
- learning_service.py: 新增 record_agent_session() — 5-Agent 辯證結果 → Redis analytics
  Critic 質疑 + matched_playbook_id → 輕度負向 EWMA;all_agents_degraded 記錄治理事件
- agent_orchestrator.py: run_agent_debate() 完成後 best-effort 呼叫 record_agent_session()
  Phase 3 L7×D2 學習訊號全部接線完成

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:00:18 +08:00
OG T
fb1bbd0e20 feat(Phase 3): 學習閉環補完 — Root cause 3 + 診斷 feedback + 知識遺忘 + Fine-tune 管線
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
- approval_execution.py: _run_post_execution_verify() 補接 record_verification_result()
  Root cause 3 終結:環境驗證結果(success/degraded/failed/timeout)不再孤立
- learning_service.py: 新增 record_verification_result() — 驗證結果 → Redis + Playbook EWMA
- learning_service.py: 新增 record_diagnosis_outcome() — 誤診負向訊號回寫(L3×D4)
- jobs/knowledge_decay_job.py: 新建 30d 知識遺忘 Job(未引用 draft/review → archived)
- services/finetune_exporter.py: 新建每週 JSONL 匯出(EvidenceSnapshot × AgentSession)
- main.py: 掛載 knowledge_decay_loop(24h)+ finetune_export_loop(7d)
- MASTER §8: Phase 3 核心改造項全部落地記錄

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 20:57:43 +08:00
OG T
ff448ad282 fix(incidents): 修復兩個 DB 完整性問題
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 14m52s
1. alertname IS NULL(4 筆歷史修復 + code fallback)
   - incident_repository.py: alertname 補 labels["alertname"] fallback
   - SQL UPDATE: 用 signals->0->>'alert_name' 修補存量 4 筆 NULL 記錄

2. TYPE-1 incidents 永遠卡 INVESTIGATING(18 筆修復 + code fix)
   - webhooks.py: TYPE-1 短路後立即加 resolve_incident background task
   - SQL UPDATE: 批次將存量 TYPE-1 INVESTIGATING → RESOLVED

根因: ADR-073 TYPE-1 短路設計只發通知,未關閉 incident 狀態
      backup/heartbeat 告警每小時觸發 → 無限累積 INVESTIGATING 記錄

2026-04-15 ogt + Claude Sonnet 4.6(亞太)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 20:38:08 +08:00
OG T
65838708ce fix(format): 剩餘 send_notification raw text 改為 ADR-075 TYPE-X 格式
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 18m11s
- decision_manager.py: 自動修復通知改為 TYPE-2 ├─/└─ 樹狀格式
- gitea_webhook_service.py: Code Review 通知改為 TYPE-1 格式,移除 ═══ border

至此所有 3 個外部 send_notification 呼叫者均符合 ADR-075 格式規範:
  1. ai_router.py — TYPE-1 AI Provider 不可用(已於 3ce5025 修復)
  2. decision_manager.py — TYPE-2 自動修復完成/失敗(本 commit)
  3. gitea_webhook_service.py — TYPE-1 Code Review(本 commit)

2026-04-15 ogt + Claude Sonnet 4.6(亞太): Phase 6 format enforcement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 20:05:49 +08:00
OG T
05b774386b feat(Phase 6): AI SLO REST API — GET /api/v1/ai/slo 收官
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
ADR-087 Phase 6 自我治理閉環最後一塊拼圖:

1. api/v1/ai_slo.py — GET /api/v1/ai/slo
   - Service 層快取優先(TTL 5min,AiSloCalculator.get_cached_report)
   - force_refresh=true 強制重算(AiSloCalculator.run)
   - Router 層零 Redis 直接存取(leWOOOgo 積木化鐵律)

2. main.py — 路由掛載 ai_slo_v1.router(prefix=/api/v1)

3. MASTER §8 Living Changelog 追加:
   - P0 告警靜默 3 根因 RCA 完整紀錄
   - P2 飛輪斷鏈修復摘要
   - Phase 6 全元件完成清單

Phase 6 退出條件 5/6 已達(生產驗證待 image 上線)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 19:57:26 +08:00
OG T
14579ce149 fix(heartbeat): 系統沉默閾值 2h → 24h,消除假陽性告警
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
無事故期間系統正常不寫 KM,2h 必然誤報。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 19:51:01 +08:00
OG T
3ce5025ca7 fix(alerts): 3 個飛輪沉默節點 — DIAGNOSE routing + 心跳停用 + 通知格式
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
1. openclaw.py: DIAGNOSE 移除 require_local=True
   - v4.3 已決定 NIM 為主力且無隱私問題
   - require_local=True 導致所有 provider 被 privacy_skip → 告警永遠失敗
   - 修後 DIAGNOSE 走 _full_fallback_chain(NIM → Gemini → Claude)

2. ai_router.py: require_local 失敗通知改為 ADR-075 TYPE-1 格式
   - 禁止純文字 raw notification(統帥鐵律:所有訊息必須符合格式模板)
   - 改用 ├─ / └─ 樹狀結構 + 語義化標籤

3. main.py: 停用 Telegram 心跳監控
   - 心跳已轉發到另一個 Telegram 群組,不需在此頻道重複發送

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 19:49:43 +08:00
OG T
f9ba200638 fix(db): Phase 6 migration 三條 CREATE INDEX 拆開各自 execute
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
asyncpg 不支援 prepared statement 內多條 SQL 指令,
原本一個 text("""...""") 包含三條 CREATE INDEX 導致 CrashLoopBackOff。
拆成三個獨立 conn.execute() 呼叫。

2026-04-15 ogt + Claude Sonnet 4.6(亞太)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 19:37:58 +08:00
OG T
f045506abd fix(flywheel): P2 Approval 逾期不結案 → KM 學習鏈斷鏈修復
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 12m11s
問題根因:
  PENDING approval 無人處置超過 48h 後應自動 EXPIRED,
  但 get_pending_approvals() 只在用戶開 UI 時觸發,
  若無人開 UI → Incident 永遠 PENDING → KM 永遠不寫入
  → Phase 6 SLO human_override_rate 低估,EWMA 缺少負向樣本。

修復:
  1. anomaly_counter.py: 新增 "timeout_ignored" disposition 類型,
     與 auto_repair / human_approved / manual_resolved 區分
  2. incident_service.py: resolve_incident() 新增 resolution_type 參數,
     resolution_type="timeout" 時記錄 "timeout_ignored" 而非 "manual_resolved"
  3. jobs/approval_timeout_resolver.py (新): 每小時掃描逾期 PENDING approval,
     批次標記 EXPIRED,對每筆有 incident_id 的記錄呼叫 resolve_incident("timeout")
  4. main.py: startup 掛載 approval_timeout_resolver 排程(interval=3600s)

效果:
  - 告警無人處置 48h → Incident 自動結案 → KM 寫入 → EWMA 取得樣本
  - disposition="timeout_ignored" 讓 SLO 計算正確區分「AI 建議被忽略」
  - 飛輪學習鏈對「無人處置告警」閉環

2026-04-15 ogt + Claude Sonnet 4.6(亞太)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 19:21:21 +08:00
OG T
f31b4e31ba fix(approval): create_approval_with_fingerprint 補注 48h expires_at 預設值
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
根因(盤點後確認):
  所有 webhook 建立 approval 的路徑(webhooks.py:908/1426/1566)均未傳
  expires_at,DB 欄位為 NULL。get_pending_approvals() 的自動過期邏輯
  WHERE expires_at < now 對 NULL 永遠為 False → 殭屍 PENDING 永不清理。

修正策略:
  在 create_approval_with_fingerprint()(告警 approval 唯一共用入口)
  注入預設 48h TTL,一次覆蓋全部 3 個 webhook 呼叫點。
  手動 API 建立(approvals.py)自行傳 expires_at,不受影響。

與 2026-04-15 24h PENDING_TTL_HOURS 補丁協同工作:
  - 24h: find_by_fingerprint 不再收斂過期 PENDING → 新告警重新觸發通知
  - 48h: get_pending_approvals auto-expire → UI 殭屍記錄自動清除

2026-04-15 ogt + Claude Sonnet 4.6(亞太):完整盤點後補完

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 19:08:17 +08:00
OG T
fab65e7d7a fix(alerts): PENDING 收斂無 TTL → 老記錄永久封鎖 Telegram 告警
Some checks are pending
CD Pipeline / build-and-deploy (push) Has started running
根因:find_by_fingerprint 的 PENDING 匹配條件無時間上限,
2026-04-12 建立的 3 筆 PENDING approval records(hit=77/30/17)
持續吃掉所有同指紋告警,造成 2+ 小時 Telegram 靜音。

修正(approval_db.py):
  - PENDING_TTL_HOURS = 24:PENDING 記錄逾 24h 不再收斂新告警
  - 原本:OR(status=PENDING, created_at>=30min前)
  - 修正:OR(PENDING AND created_at>=24h前, created_at>=30min前)

緊急修復:kubectl exec 直接將 7 筆過期 PENDING 記錄設為 expired,
即時恢復 Telegram 告警流(不等部署)。

Phase 6 AI 自我治理閉環(ADR-087):
  - feat(db): 新增 ai_governance_events 表 + 3 個 index(base.py + models.py)
  - feat(svc): ai_slo_calculator.py — 7d 滾動 SLO(success/override/false_neg)
  - feat(svc): trust_drift_detector.py — Playbook 信任度極端偏態偵測
  - feat(job): kb_rot_cleaner.py — K8s API/Prom metric/老舊 incident_case 腐爛清理
  - feat(svc): decision_manager.py — 自我降級守衛(SLO 違反 → 提高門檻/保守模式)

2026-04-15 ogt + Claude Sonnet 4.6(亞太)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 18:56:26 +08:00
OG T
4e2e6652e3 fix(db): 移除 IncidentEvidence.incident_id 的重複 index 定義
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 14m50s
根本原因:incident_id 同時設定 index=True(mapped_column)
與 __table_args__ 中的 Index("ix_incident_evidence_incident_id"),
導致 table.create 生成重複的 CREATE INDEX,
觸發 "already exists" 被靜默捕捉,整個 CREATE TABLE transaction 回滾。
直接效果:Pod 啟動時 incident_evidence 表永遠不會被建立,
導致後續 ALTER TABLE 失敗 → CrashLoopBackOff。

修法:移除 mapped_column 中的 index=True,
索引由 __table_args__ 統一管理。

注意:已在 PostgreSQL 直接建立 incident_evidence 表解除 CrashLoop。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 16:13:18 +08:00
OG T
655d1a568a feat(Phase 5): Declarative 修復抽象化 + Blast Radius 分控 全部完成
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
## Phase 5 交付(ADR-086)

### 新增服務(4 個)
- blast_radius_calculator.py: 爆炸半徑計算器(0-100 純函數)
  - 18 種 kubectl 動作基礎分 + 命名空間倍率 + 特殊 flag 修正
  - HARD_RULES 永擋:delete ns/pv/pvc/clusterrole + rm -rf + DROP TABLE
  - 分級:≤10 auto / 11-50 human / 51-99 dual / 100 blocked
- declarative_remediation.py: DeclarativeSpec 不可變規格(frozen dataclass)
  - evaluate() 封裝 Blast Radius + dry-run + rollback_plan + constraints
  - rollback_plan 從 kubectl 動作類型自動推導(不呼叫 LLM)
- gitops_pr_service.py: Gitea Issue 高風險修復審核(tier=dual)
  - 含 Blast Radius + 目標狀態 + 回滾計畫 + 雙人審核流程
  - AIOPS_P5_GITOPS_PR flag 守衛
- rollback_manager.py: 驗證失敗自動回滾
  - 先驗 rollout history ≥ 2 revision,防止無版本可回滾
  - kubectl rollout undo + 120s 收斂等待

### decision_manager.py 接線(AIOPS_P5_BLAST_RADIUS_CHECK)
- _auto_execute() 在安全守衛後、ApprovalRequest 前插入分級守衛
- blocked → 永擋 + 人工審核通知
- dual → 非同步 GitOps Issue + 升級人工審核
- human → 升級人工審核(不自動執行)
- auto(≤10)→ 原有自動執行流程
- 失敗降級:計算異常 → 保守升人工

### learning_service.py
- record_declarative_outcome(): 記錄 DeclarativeSpec 執行結果
  anomaly_key=declarative:{incident_id},含 blast_radius_score/tier/rollback

2026-04-15 ogt + Claude Sonnet 4.6(亞太): Phase 5 全部完成

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 16:06:54 +08:00
OG T
14a02263ae feat(Phase 4): 主動巡檢 + 趨勢預測 + 8D 感官升級 全部完成
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 12m32s
## Phase 4 完整交付(ADR-084)

### 新增服務
- trend_predictor.py: numpy 線性回歸,4h 閾值突破預警,R² 信心評分
- proactive_inspector.py: 每 5 分鐘主動巡檢協調器
  - DynamicBaselineService(3σ 偏離)
  - LogAnomalyDetector(新 Drain3 pattern)
  - TrendPredictor(斜率外推 4h 預測)
  - Shadow Mode + 30 分鐘去重 + Holt-Winters 背景重訓

### 8D 感官升級(EvidenceSnapshot Phase 4 增強)
- PreDecisionInvestigator._collect_phase4_anomalies(): 決策前讀取
  ProactiveInspector 最近巡檢快取 + LogAnomalyDetector 新 pattern
- EvidenceSnapshot.anomaly_context: 新欄位,Phase 4 動態異常上下文
- DiagnosticianAgent._build_prompt(): prompt 包含 anomaly_context,
  LLM RCA 可參考動態基線偏差與趨勢預警

### 資料庫遷移
- incident_evidence: ADD COLUMN anomaly_context JSONB(冪等)

### main.py
- 啟動 run_proactive_inspector_loop() asyncio task

2026-04-15 ogt + Claude Sonnet 4.6(亞太): Phase 4 全部完成

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:47:05 +08:00
OG T
952c10955b fix(db): 多 replica 並行啟動競爭 — 每 table 獨立 tx + DROP INDEX IF EXISTS
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
根因:單一大 transaction 內兩個 pod 同時建同一個 table,
其中一個 CREATE INDEX 失敗 → 整個 transaction ROLLBACK
→ table 也消失 → 下次重啟同樣情況 → 無限 CrashLoop。

修法三層:
1. 每個 table 用獨立 transaction 建立(失敗不影響其他)
2. 建 table 前先 DROP INDEX IF EXISTS 清殘留孤兒 index
3. 捕捉 "already exists" 讓並行 pod 優雅跳過(不 crash)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:38:43 +08:00
OG T
4a6aa16a94 fix(Phase 4): 修正呼叫點遺漏傳入參數 — promql 和 sample_log
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
關聯節點檢查發現:
- dynamic_baseline_service.py: _save_baseline() 在 train_baseline() 中
  未傳入 promql/lookback_hours → PG 記錄無法追蹤訓練來源
- log_anomaly_detector.py: _save_new_cluster() 未傳入 sample_log →
  PG 記錄 LogCluster 時 sample_log 欄位為空

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:34:33 +08:00
OG T
bf45b80bd2 feat(Phase 3.5 + Phase 4): AI 學習成果持久化到 PostgreSQL — 修正「AI 失憶」架構缺陷
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
ADR-085: AI 學習成果不可存在 Cache

架構鐵律確立:
- PostgreSQL = System of Record(AI 的永久記憶)
- Redis = Warm Cache(加速讀取,TTL 到期從 PG 復原)

核心變更:
1. models.py: 新增 PlaybookRecord / DynamicBaselineRecord / LogClusterRecord ORM
2. base.py: ALTER TABLE playbooks 補加 trust_score / requires_approval_level 等欄位
3. playbook_repository.py: 完整雙寫實作(PG upsert + Redis cache)
4. dynamic_baseline_service.py: Holt-Winters 訓練結果寫入 PG,Redis 只作 24h warm cache
5. log_anomaly_detector.py: Drain3 cluster template 寫入 PG(UPSERT on cluster_id)
6. main.py: 啟動時執行 backfill_redis_to_pg()(Redis → PG 冪等補救)

修正的問題:
- Playbook 7天 Redis TTL 到期 → AI 失去所有修復知識
- trust_score EWMA 隨 Redis TTL 歸零 → AI 重新回到初始信任度 0.3
- Holt-Winters 基線 24h TTL → AI 每天重新學習「正常」的定義
- Drain3 cluster 沒有持久化 → AI 把已知 log pattern 反覆當新 pattern

Phase 4 新服務(requirements.txt 已加入 statsmodels + drain3 + numpy)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:34:04 +08:00
OG T
0f2ec7987c fix(db): 改用 inspect 跳過現有 table,根治 CrashLoopBackOff
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 14m42s
checkfirst=True 只跳過 CREATE TABLE,SQLAlchemy 2.0 仍對
__table_args__ Index 物件發出獨立 CREATE INDEX → duplicate error。
改法:先 inspect 取得現有 tables,只對不存在的 table 呼叫
table.create(),index 永遠只隨新 table 建立,不再 duplicate。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:18:25 +08:00
OG T
a142e6e937 fix(db): create_all checkfirst=True 修復 CrashLoopBackOff
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 12m19s
rolling update 時 create_all 嘗試重建既有 index 導致
"ix_incident_evidence_incident_id already exists" 啟動失敗。
checkfirst=True 讓 SQLAlchemy 跳過已存在的 table/index,
init_db() 從此冪等,不再造成 CrashLoopBackOff。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:00:49 +08:00