Your Name
4111ea4f9f
fix(ai): remove 188 ollama provider
Code Review / ai-code-review (push) Successful in 12s
CD Pipeline / tests (push) Successful in 1m13s
CD Pipeline / build-and-deploy (push) Successful in 3m36s
CD Pipeline / post-deploy-checks (push) Successful in 1m20s
2026-05-06 14:34:48 +08:00
Your Name
c2c0b1ec82
fix(alerts): let GCP Ollama finish before cloud fallback
Code Review / ai-code-review (push) Successful in 10s
CD Pipeline / tests (push) Successful in 1m9s
CD Pipeline / build-and-deploy (push) Successful in 4m21s
CD Pipeline / post-deploy-checks (push) Successful in 1m16s
2026-05-06 05:27:55 +08:00
Your Name
5ed396e390
fix(decision): derive telegram dedup from incident signals
CD Pipeline / tests (push) Successful in 58s
Code Review / ai-code-review (push) Successful in 10s
CD Pipeline / build-and-deploy (push) Successful in 3m30s
CD Pipeline / post-deploy-checks (push) Successful in 2m19s
2026-05-06 00:19:35 +08:00
Your Name
14bf86a462
fix(awooop): Phase 2 初批 P0 修正 + Phase 1 Task 1.7 integration tests
...
## P0 安全 / 架構修正
### P0-08 telemetry.py — 移除硬碼 IP assert(ADR-121)
- config.py:新增 OTEL_ALLOWED_ENDPOINTS(預設 192.168.0.188)+ OTEL_FORBIDDEN_ENDPOINTS
- telemetry.py:_validate_endpoint() 改為 config-driven allowlist/forbidlist
- EwoooC 可用 env 覆寫 OTEL_ALLOWED_ENDPOINTS 指向自己的 SigNoz host
### P0-13 mcp_bridge.py — K8s namespace 由 settings 提供
- config.py:新增 AWOOOI_K8S_NAMESPACE(預設 "awoooi-prod")
- mcp_bridge.py:5 處 parameters.get("namespace", "awoooi-prod") → settings.AWOOOI_K8S_NAMESPACE
- EwoooC/Tsenyang 可設自己的 namespace
### P1-24 decision_manager.py — silence key 常數統一
- 新增 from src.services.telegram_gateway import SILENCE_KEY_PREFIX
- f"telegram_silence:{target}" → f"{SILENCE_KEY_PREFIX}{target}"
- 消除跨兩處重複定義(ADR-118 No Island Coding 原則)
## Phase 1 Task 1.7 Integration Tests
- tests/integration/test_awooop_phase1_schema.py:31 個測試案例
- awooop_projects CHECK 約束(4 cases)
- revision 不可變性 trigger(5 cases:draft 可改、published 鎖住、身份欄不可改、非法流轉、DELETE 禁止)
- awooop_published_revisions VIEW draft/published 隔離(2 cases)
- active_pointer_guard(3 cases:不可指向 draft、可指向 active、跨租戶 mismatch)
- RLS fail-closed(3 cases:未設/錯設/正確設 project_id)
- outbox FK + dedup(2 cases)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-04 13:46:19 +08:00
Your Name
b1ef05fa8c
feat(ollama): ADR-110 GCP 三層容災架構(GCP-A → GCP-B → Local → Gemini)
...
Code Review / ai-code-review (push) Successful in 50s
CD Pipeline / tests (push) Failing after 1m14s
CD Pipeline / build-and-deploy (push) Has been skipped
CD Pipeline / post-deploy-checks (push) Has been skipped
## 變更摘要
- Primary: http://34.143.170.20:11434 (GCP-A SSD, 9x 載速 + 2x 推理)
- Secondary: http://34.21.145.224:11434 (GCP-B SSD)
- Fallback: http://192.168.0.111:11434 (M1 Pro Local HDD,最後防線)
- 廢止 ADR-105「111 唯一鐵律」,新建 ADR-110
## 核心改動
- config.py: 新增 OLLAMA_SECONDARY_URL;validator 加 GCP IP 白名單(34.143.170.20, 34.21.145.224)
- ollama_failover_manager.py: 三層 Ollama 決策矩陣;並行健康檢查三台;health_111 → health_gcp_a
- ollama_health_monitor.py: host label 萃取改為通用版(支援 GCP 公網 IP)
- failover_alerter.py: 故障/恢復主機動態顯示,不再硬編碼「Ollama 111 (GPU)」
- ollama_auto_recovery.py: notify_recovery 改為 ollama_gcp_a;recovered_host 動態
- k8s/awoooi-prod: configmap + deployment + network-policy 同步更新(egress 加 GCP /32)
- 服務層: 10 個服務檔案硬編碼 192.168.0.111 改為讀 settings.OLLAMA_URL
- 測試: URL 常數更新,新增三層容災場景,GCP IP 白名單驗證測試
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-03 22:49:23 +08:00
Your Name
b371edb70c
fix host alert auto-repair routing and backup false positives
2026-05-02 23:44:12 +08:00
Your Name
da772a1605
fix(decision): block kubectl actions on bare_metal host alerts
...
Code Review / ai-code-review (push) Successful in 54s
CD Pipeline / tests (push) Successful in 3m47s
CD Pipeline / build-and-deploy (push) Successful in 13m26s
CD Pipeline / post-deploy-checks (push) Successful in 5m45s
When HostHighCpuLoad / HostOutOfMemory fire on a bare-metal host
(192.168.0.110 et al, where Sentry / ClickHouse / Snuba are eating
CPU), the LLM kept proposing "kubectl rollout restart awoooi-api",
which is a wrong-domain action — restarting awoooi cannot fix a
third-party process's CPU usage on the host. Auto-execute would then
either run the no-op kubectl restart (wasted) or escalate after
ssh_diagnose because no safe action was found, producing the
"AI 自動修復失敗" Telegram noise the user just complained about.
Adds a guard at the top of DecisionManager._auto_execute: if the
incident's primary signal carries host_type=bare_metal AND the
proposed action starts with "kubectl", refuse to execute. The
incident is marked READY with a clear blocked_reason so human
operators see why automation declined, and emergency_escalation
records the event in AOL for audit.
Also patches /home/wooo/monitoring/alerts.yml on 110 (and the new
ops/monitoring/alerts.yml in repo) to add an explicit
auto_repair_action annotation on HostHighCpuLoad / HostOutOfMemory
that hints LLM toward `ssh ... ps aux` rather than kubectl restart.
Prometheus reload returned 200.
Tests: tests/test_decision_manager_bare_metal_kubectl_guard.py
covers (1) bare_metal+kubectl blocked, (2) kubectl get also blocked,
(3) bare_metal+ssh NOT blocked, (4) k8s host_type+kubectl NOT
blocked, (5) missing host_type label NOT blocked.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-02 17:41:28 +08:00
Your Name
b3a0f0d766
fix(telegram): dedup by fingerprint + 24h TTL to stop repeat alerts
...
CD Pipeline / tests (push) Successful in 2m22s
Code Review / ai-code-review (push) Successful in 57s
CD Pipeline / build-and-deploy (push) Successful in 21m3s
CD Pipeline / post-deploy-checks (push) Successful in 5m2s
Telegram 重複發告警鐵證(4 個 agent 真實數據):
- INC-6FE3BD (HostBackupFailed) 24h 內被推 15 次
- INC-FD6E21 (HostHighCpuLoad) 24h 內被推 6 次
- 06:44:18 同秒兩送 = pod 並發 race
根因:
1. `telegram_sent:{incident_id}` dedup key 綁 uuid4 隨機 INC ID,
同 fingerprint 換新 INC 完全不去重
2. dedup TTL=600s 比 incident_analysis_sweeper 重觸週期 1h、
alertmanager repeat_interval 4h 都短 → 每輪都過期通過
3. pod restart 走 _resend_unconfirmed_ready_tokens 用同一 incident_id key
→ 重啟必炸一波
修法(不消音、是「AI 認得這是同一事故」):
- decision_manager.py:207-225 dedup key 改 alertname+target fingerprint
- decision_manager.py:573-578 TTL 600s → 86400s (蓋住 sweeper 1h × alertmanager 4h)
- decision_manager.py:3189-3208 pod restart resend 路徑同步改 fingerprint
- incident_analysis_sweeper.py:37-42 sweeper_done TTL 3600s → 86400s
預期:同症狀 24h 內最多發 1 張 decision card;resolved 後 line 220-226
status check 會 early return,不影響復發偵測。
Tests: 35 passed (test_telegram_adr050 + test_decision_manager_docker_prune_routing)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-02 16:25:48 +08:00
Your Name
84ba3216ee
feat(notifications): tag autonomous repair actions with [AUTO] prefix
...
Code Review / ai-code-review (push) Successful in 57s
CD Pipeline / tests (push) Successful in 2m36s
CD Pipeline / build-and-deploy (push) Failing after 31m11s
CD Pipeline / post-deploy-checks (push) Has been skipped
Per user request: every AI-driven repair must surface a Telegram trace
even when it succeeds, so nobody can later deny what the autonomy did.
Adds 🤖 [AUTO] markers and an explicit `Actor: leWOOOgo (autonomous)`
line to both success and failure status messages emitted by
_push_auto_repair_result, making them clearly distinguishable from
human-clicked approval cards.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-02 12:49:43 +08:00
Your Name
3156ff1c69
feat(aiops): add ssh_docker_prune to auto-repair flywheel for disk-full alerts
...
Adds Group B SSH MCP tool ssh_docker_prune (image+volume+builder prune
with ≥75% disk usage gate) and routes "docker prune" actions through it.
Flips HostDiskUsageHigh from auto_repair=false to true with mcp_provider
routing labels so the flywheel can self-heal next disk-full event without
hitting the emergency_channel Telegram path.
Trigger: 2026-05-01 → 05-02 Telegram alert storm (peak 53/hr) caused by
empty ssh-mcp-key/known_hosts secret rejecting all SSH and forcing every
disk-full alert through "Host key is not trusted → escalate" loop.
known_hosts patched live; this commit closes the playbook gap so the
next occurrence resolves without manual intervention.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-02 12:31:37 +08:00
Your Name
433f7b068e
fix(aiops): close ssh and telegram remediation gaps
CD Pipeline / tests (push) Successful in 2m7s
Code Review / ai-code-review (push) Successful in 42s
CD Pipeline / build-and-deploy (push) Successful in 13m14s
CD Pipeline / post-deploy-checks (push) Successful in 4m29s
2026-05-01 16:53:02 +08:00
Your Name
11673d80ea
fix(aiops): route backup decisions through ssh
CD Pipeline / tests (push) Successful in 1m35s
Code Review / ai-code-review (push) Successful in 34s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-05-01 12:50:01 +08:00
Your Name
f0d14ab6c4
fix(aiops): escalate blocked auto repair
CD Pipeline / tests (push) Successful in 1m33s
Code Review / ai-code-review (push) Successful in 28s
Deploy Alert Rules / Deploy Prometheus Alert Rules (push) Successful in 40s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-30 23:49:17 +08:00
Your Name
95110971f3
fix(telegram): close remaining DM alert routes
CD Pipeline / tests (push) Successful in 1m27s
Code Review / ai-code-review (push) Successful in 29s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-30 23:02:17 +08:00
Your Name
61f5a6a419
fix(telegram): route alerts to SRE war room
CD Pipeline / tests (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
Code Review / ai-code-review (push) Has been cancelled
2026-04-30 15:01:23 +08:00
Your Name
80defbed7c
fix(aiops): fallback and escalate automation blockers
CD Pipeline / tests (push) Successful in 2m41s
Code Review / ai-code-review (push) Successful in 24s
CD Pipeline / build-and-deploy (push) Successful in 7m51s
CD Pipeline / post-deploy-checks (push) Failing after 2m15s
2026-04-30 14:13:57 +08:00
Your Name
dccdcdbaf5
fix(flywheel): unblock action safety and Claude fallback
CD Pipeline / build-and-deploy (push) Successful in 9m45s
2026-04-29 21:51:18 +08:00
Your Name
c5753e1c57
fix(critic-review): KMWriter 名實統一 + Alertmanager 修抑制 + drift checker AST 化
...
critic PR review 揭示已 push commits 的 7 個 blocker,本 commit 全部修復。
## C1 + C2 + M1 + M2 + M3 — KMWriter 真正統一契約(critic 最嚴重 5 條)
### C1 km_writer.py:194 — backfill 自打臉修
- 裸 asyncio.create_task(_backfill_path_a_approval) → await _backfill_path_a_approval_safe()
- 同步 await + 獨立 DLQ km:backfill:dlq + try/except 不阻塞主寫入
- 新增 km_backfill_reconciler_job.py(每 5 分鐘掃 DLQ)+ ENABLE_KM_BACKFILL_RECONCILER flag
- 防 Path B 比 Path A 先完成 → related_approval_id 永遠 NULL 的 race
### C2 km_writer.py:391 — KM_WRITE_AWAIT=false 路徑收緊
- 從 ensure_future(fire-and-forget 比舊版同步寫更糟)
- 改 await writer.write(retry=1, timeout=2.0)(仍 await 但只試一次、超時短)
- docstring 明確標註「緊急回滾用,不保證可靠性」
### M1 decision_manager.py:2178/2203 — 移除 _fire_and_forget 旁路
- 兩處 _fire_and_forget(executor.write_execution_result_to_km(...))
- 改 await asyncio.shield(...) + BaseException 保護(防上層 cancel 中斷)
- KM_WRITE_AWAIT=true 在這條路徑終於真正 await
### M2 incident_service.py:1099 — 自製 path 加 retry+DLQ
- 原本 if settings.KM_WRITE_AWAIT: await asyncio.wait_for else create_task
- 改 3 次指數退避 retry + DLQ 保護(呼叫 km_writer 私有 helper)
### M3 km_writer.py:166 — 冪等聲明對齊實作
- knowledge_repository.create() 加 UPSERT 路徑(pg_insert ON CONFLICT DO UPDATE)
- KnowledgeEntryCreate / KnowledgeEntryRecord 加 path_type 欄位
- migration: ADD COLUMN path_type + partial unique index uix_knowledge_incident_path
## M4 alertmanager.yml — equal: [] 收緊(critic 防爆炸抑制)
- OllamaInstanceDown / KMConverterDown 抑制加 equal: ['cluster'] 約束
- 防多 cluster 場景下任一 Ollama down 誤抑全 AI/SLO 告警
## M5 Alertmanager 版本驗證(已確認 v0.31.1,遠超 v0.22+)
## M6 governance_agent.py — health score 區分 skipped vs ok vs violated
- check_slo_compliance 加 _meta {violated_count, skipped_count, ok_count, all_skipped, status}
- run_self_check: SLO 全 skipped 時獨立發 governance_slo_data_gap 告警
(不污染 self_failure 計數,因為 no_data 是 emitter 未實作不是治理機制故障)
## M7 scripts/check_config_drift.py — 改 AST 解析
- regex 改 ast.parse 找 Settings ClassDef AnnAssign Field(default=...)
- 避免多行 list / default_factory= / 含跳行字串的 false negative
- 4 欄位(AI_FALLBACK_ORDER / ARGOCD_URL / PROMETHEUS_URL / OLLAMA_URL)全對齊
## 新增測試
- test_km_writer_backfill_reconciler.py: 7 cases(C1 reconciler + safe helper)
- test_km_writer_idempotent.py: 5 cases(M3 path_type 注入 + UPSERT 分支)
## 驗證
- 1585 unit tests 全綠(+13 從 1572)
- amtool check-config SUCCESS(8 inhibit_rules / 2 receivers)
- drift checker AST-based 4 欄位全對齊
- Alertmanager v0.31.1 確認支援新語法
## 期望影響
- KMWriter 名實統一:飛輪閉環 KM 寫入路徑 100% 可靠
- M4 抑制爆炸風險解除
- 治理層不再對 SLO no_data 靜默
- drift checker false negative 風險解除
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-29 10:44:39 +08:00
Your Name
c22e5f334e
feat(km): P1-1 KMWriter 統一契約 + 5 caller 切換 + M4 反查鏈補齊
...
12-Agent 全景診斷揪出 KM 寫入鏈路 5 條入口無統一契約,fire-and-forget
在 Pod recycle 時會丟失條目。本次抽 KMWriter 強制 7 條契約。
## 7 條契約強制
1. 同步底線:強制 await asyncio.wait_for(timeout)
2. 重試:3 次指數退避 1s/2s/4s(OperationalError / 網路類例外)
3. 失敗回收:3 次後寫 Redis DLQ km:dlq + log
4. 觀測:structlog event + 預留 metric hook(P1-3 補 emitter)
5. 冪等:incident_id + path_type 為 unique key
6. 禁止吞例外:except 必須 log + raise/DLQ
7. M4 反查鏈:payload 含 approval_id 時自動填 related_approval_id 並回填 Path A
## Caller 切換(5 條入口統一介面)
- incident_service.py:1086 Path A(KB extractor + km_conversion)
- approval_execution.py:771 Path B-人工
- decision_manager.py:2178 Path B-自動成功(消除跨類私有方法調用 M1)
- decision_manager.py:2200 Path B-自動失敗(修 B2 早期吞例外)
- playbook_service.py:210 PlaybookKM(兩份 T0 報告都漏的第三條)
## M4 反查鏈補齊
- knowledge.py + models.py: 補 related_approval_id ORM 欄位
- 對齊 phase26_incident_km_integration.sql:20 schema(partial index 已存在)
- approval↔KM 雙向反查鏈完整(dual-path 縫合線)
## Feature Flag (rollback 保險)
- KM_WRITE_AWAIT=true (default): await + timeout + DLQ 強制
- KM_WRITE_AWAIT=false: fire-and-forget(舊行為)
## 測試
- apps/api/tests/test_km_writer.py: 18 測試全綠
覆蓋 success / timeout / retry / DLQ / 冪等 / KMWriteError /
on_failure=raise / 反查鏈回填
- 1552 unit tests 全綠(無回歸)
## 驗收
飛輪閉環核心 — KM 寫入不再靜默丟失,AI 學習鏈不斷裂。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-29 10:44:39 +08:00
Your Name
143c15f052
feat(wave2+km): LLM 動態按鈕啟用 + KM 自動寫入 + AI Router dead code 標記
...
CD Pipeline / build-and-deploy (push) Successful in 9m52s
- ConfigMap: USE_LLM_DYNAMIC_BUTTONS=true(B2/B3/B4 handler 全就緒)
- decision_manager: auto_execute 失敗路徑補 KM fire-and-forget 寫入
- ai_router: _build_fallback_chain 標記 DEPRECATED 2026-04-28
- tests: test_golden_regression.py 新增 172 行 golden 回歸測試
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-28 15:27:33 +08:00
Your Name
c1a1be61bd
fix(ssh-auto): 主機告警 SSH 自動診斷授權(HostHighCpuLoad 不再卡人工審核)
...
CD Pipeline / build-and-deploy (push) Successful in 9m7s
根因:SSH_MCP_ALLOWED_HOSTS 未設定 → _ssh_execute() 全部攔截
+ auto_approve 只認 kubectl 不認 ssh → 主機告警永遠降級人工
修復:
- ConfigMap: 補 SSH_MCP_ALLOWED_HOSTS 四主機白名單
- alert_rules: HostHighCpuLoad 等從 NO_ACTION 改為 ssh_diagnose 指令
- auto_approve: _has_executable 加入 ssh 開頭識別
- decision_manager: _ssh_execute() 加入 ssh_diagnose 路由
- ssh_provider: 新增 ssh_diagnose tool(ps aux + free -h + df -h,只讀)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-27 20:13:07 +08:00
Your Name
cc547736ab
feat(wave6-8): P2.1 fusion + P2.2 governance + P2.4 consensus + Wave 7/8 BLOCKER 修復
...
承接 Wave 6/7/8 多 engineer 在 agent 限額前完成的代碼,補 commit 解 production
HEAD 隱性 import error(decision_fusion 已被 decision_manager 引用但檔案 untracked)。
新增(後端核心):
- decision_fusion.py (562 行) — P2.1 方法 III(OpenClaw + Hermes + Elephant 三 LLM 融合)
- aiops_timeline.py + aiops_timeline_service.py — critic B4 修復
/api/v1/aiops/timeline endpoint,DB 存取抽到 service 層遵守 leWOOOgo 積木化
- migrations/p2_decision_fusion_columns.sql + rollback — approval_records fusion 欄位
修改(後端整合):
- decision_manager.py — fusion 三斷鏈修補(critic B1+B2+B3):
· B1: 寫 _evidence_snapshot_ref 到 token.proposal_data
· B2: fusion 前計算 complexity_score 並寫 token
· B3: fusion composite 寫 token.proposal_data["decision_fusion"]
- auto_approve.py — fusion + consensus 認識(critic B3+B5):
· composite > 0.7 → auto_execute_eligible bypass min_confidence
· source=consensus_engine + score>=0.6 → 規則可信路徑
- consensus_engine.py — db-fix _save_consensus 重用 agent_sessions
- governance_agent.py — db-fix _alert PG 寫入 ai_governance_events
- approval_db.py — fusion 3 欄位 + 2 partial index + CheckConstraint
- db/models.py — schema 對齊 migration
- core/config.py — vuln #1 修復:OLLAMA_URL/_FALLBACK_URL field_validator
拒絕公網 IP + 外部域名,僅允許私網/loopback/K8s SVC 白名單
- core/feature_flags.py — P2 fusion + consensus flags
- main.py — governance_agent lifespan 啟動
- failover_alerter.py — Wave8-X2: in-memory dedup fallback(Redis 拒絕後不 fail-open)
- ollama_*.py — metrics 整合 + recovery 改善
- auto_repair_service.py — verifier 接線
新增(測試 2438 行):
- test_decision_fusion.py / test_governance_agent.py / test_consensus_integration.py
- test_p2_db_fixes.py / test_wave8_fusion_fixes.py
- test_config_url_validation.py(vuln #1 12 tests)
- test_failover_alerter.py +Wave8-X2 in-memory dedup 補測
驗收: 116 tests pass (decision_fusion + wave8_fusion + config_url + consensus +
governance + p2_db_fixes + failover_alerter)
Conflict resolution:
- 3 檔(config.py + auto_approve.py + decision_manager.py)git stash pop 衝突
保留 stashed (engineer 最終版),補回 ValueError 「公網 IP」字樣對齊 test
Note: 此 commit 解 production HEAD 隱性 import error
仍未修: vuln #4 prompt injection / debugger B14 quota fail-closed
/ B25-B26 drain_pending_tasks / B8 governance fail alert
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
Co-Authored-By: Multiple Engineers (Wave 6/7/8) <noreply@anthropic.com >
2026-04-27 08:11:40 +08:00
Your Name
6baa5054bc
fix(auto-execute): 修復 kubectl pattern 攔截 + 補 auto_execute KM 寫入
...
CD Pipeline / build-and-deploy (push) Has been cancelled
問題 1:_ALLOWED_KUBECTL_PATTERN 不允許 resource type keyword
根因:LLM 輸出 "kubectl rollout restart deployment clickhouse"
但 pattern 只允許 "kubectl rollout restart clickhouse"(無 deployment 關鍵字)
結果:_action_safe=False → auto_execute_blocked_unresolved_placeholder
→ 所有 low/medium risk 告警降為人工審核,飛輪完全停轉
修法:pattern 新增可選的 resource type group(deployment/pod/service/...)
+ re.ASCII flag 防 unicode bypass,12/12 test cases 通過
問題 2:auto_execute 路徑 KM 寫入斷鏈
根因:_write_execution_result_to_km 只在人工審核路徑呼叫
修法:auto_execute 完成後補 _fire_and_forget(executor._write_execution_result_to_km)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-25 09:47:35 +08:00
Your Name
04ff22563e
fix(aiops-p1): Playbook 學習閉環 5斷點全修 + DB Migration(ADR-092 B4)
...
run-migration / migrate (push) Failing after 14s
CD Pipeline / build-and-deploy (push) Failing after 2m7s
【P0.4 補丁】pre_decision_investigator Prometheus query 欄位缺失
- _build_tool_params() 補 "query" 欄位(prometheus_query tool 必要參數)
- 新增 _build_prometheus_query() — 依告警類型生成 PromQL(CPU/Memory/Crash/Disk/HTTP/Pod/fallback)
- 修復後 D3_METRICS 感官維度實際取得資料(原本 100% 回 missing_query_parameter)
【P1 Playbook 學習閉環 B1-B5 全修】
- B2 db/models.py: ApprovalRecord 新增 matched_playbook_id 欄位 + ix_approval_matched_playbook index
- B2 db/models.py: TimelineEvent 新增 incident_id 欄位(MCP 稽核用)+ index
- B3 approval_db.py: record→ApprovalRequest 補回 incident_id + matched_playbook_id
- B4 approval_repository.py: 同 B3(兩個轉換函式必須同步)
- B5 approval_db.py: approval_request_to_record_data 補 matched_playbook_id → DB 才能存值
【P1.5 KM 寫入】approval_execution.py: fire-and-forget → await wait_for(30s)
- 根因:asyncio.create_task 在 Pod recycle 時被殺,KM 寫入靜默遺失
- 修復:await asyncio.wait_for(..., timeout=30.0) + TimeoutError log
【Migration 文件】adr092_p1_learning_chain_fix.sql
- ALTER TABLE approval_records ADD COLUMN matched_playbook_id VARCHAR(36)
- ALTER TABLE timeline_events ADD COLUMN incident_id VARCHAR(64)
- 執行:psql $DATABASE_URL -f apps/api/migrations/adr092_p1_learning_chain_fix.sql
【附帶 Agent 改動】
- decision_manager: Phase 2 YAML NO_ACTION 優先門(主機層/外部服務跳過 Agent Debate)
- alert_rules.yaml: Sentry/ClickHouse + HostDiskUsageHigh/Critical 新規則
- solver_agent: action_title 語意合成兜底(取代靜默丟棄)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-24 15:41:35 +08:00
Your Name
7f4088bcd0
fix(aiops-p0): 六大病根 P0 全面修復(ADR-092 B4)
...
【P0.1】knowledge_extractor_service.py:210 — AttributeError 修復
- Signal.description 欄位不存在(100% 失敗,KM 每天+5 根因)
- 改用 alert_name + annotations.summary 拼接文字
【P0.2+P0.3】Gate 9+11 唯讀指令鬆綁
- blast_radius_calculator: kubectl get/top/describe/logs/version → score=1(非 50)
- operation_parser: 增加 INVESTIGATE 類型識別(唯讀 kubectl 不回 None)
- executor.py: OperationType 新增 INVESTIGATE enum
- approval_execution.py: INVESTIGATE 路徑直接呼叫 execute_kubectl_command
【P0.4】MCP SSH/K8s Provider 修復
- decision_manager: params= → parameters=(符合 MCPToolProvider.execute 簽名)
- decision_manager: MCPToolResult .get() → .success/.output(dataclass 用法)
- decision_manager + ssh_provider: 補入 hosts 120/121(原 default 缺失)
- auto_approve: phase2_agent_debate source bypass confidence 閾值
【P0.5】告警規則語義矛盾修復
- alert_rules.yaml: 8 條 kubectl 查詢規則 RESTART_DEPLOYMENT → NO_ACTION
(CrashLoopBackOff/PostgreSQL 連線/慢查詢/MinIO 磁碟/K3s 節點/告警鏈路/SSL/CoreDNS 等)
- incident_service.py: cAdvisor/CoreDNS 從 general 拆出獨立分類
【P0.6】proactive_inspector 動態基線 PromQL 全修
- 5 個 MONITORED_METRICS PromQL 全部修正(cadvisor label/datname/blackbox)
- db_connection_pool: datname="awoooi" → "awoooi_prod"
- http_error_rate: 無效 http_requests_total → blackbox probe_success
- cpu/memory: namespace label → name=~"k8s_api_awoooi-api.*"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-24 15:32:23 +08:00
Your Name
45dbe07188
fix(flywheel): 自動化飛輪六大能力修復(ADR-092 B3)
...
run-migration / migrate (push) Failing after 22s
Deploy Alert Rules / Deploy Prometheus Alert Rules (push) Successful in 53s
Type Sync Check / check-type-sync (push) Successful in 2m54s
CD Pipeline / build-and-deploy (push) Has been cancelled
Ansible Lint / lint (push) Has been cancelled
【根因鏈修復】
MCP Provider bugs → PreDecisionInvestigator 失敗 → Agent Debate 無上下文
→ LLM 逾時 → description="待分析" → ADR-091 鐵閘攔截 → tg_sent 未設
→ W-2 Watchdog 誤報「靜默故障」
【六大修復】
1. MCP Provider 三蟲修復
- ssh_provider: asyncssh.run() → conn.run()
- prometheus_provider: KeyError 'query' → .get() 容錯
- k8s_provider: 空 pod_name → 早返回錯誤字典
2. Agent Debate / 決策品質
- decision_manager: 逾時降級文字改為明確描述(繞過 ADR-091 鐵閘)
- intent_classifier: LLM 逾時降級至關鍵字分類(非 None)
3. Watchdog 誤報修復(ADR-092 B3)
- W-2: tg_sent Redis TTL → telegram_message_id IS NULL(DB 真值)
- W-5 新增: suggested_action IN 空/待分析/NO_ACTION + tg_id IS NULL
- approval_timeout_resolver: 60min → 15min,batch 50 → 200
4. Config Drift 自動化
- drift_adopt_service: auto_adopt_if_safe() 六條件安全閘
- drift.py: 背景任務先嘗試自動採納再發人工 Telegram 卡片
5. Playbook 飛輪穩定
- playbook_seed_service: 修復幂等性(deprecated 不視為缺失)
- playbook_evolver: 只載 DRAFT+APPROVED(非全部 294 筆)
6. 可觀測性
- alert_rule_engine: auto_rule 結構化日誌 + Redis 計數器(pipeline)
- auto_approve: reject 原因 Redis 計數器
- heartbeat_report_service: 新增「⚙️ 自動化統計(今日)」區塊
【待人工執行】
psql $DATABASE_URL -f apps/api/migrations/cleanup_duplicate_deprecated_playbooks.sql
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-24 10:55:50 +08:00
OG T
cf50a5ce25
fix(solver+execution): Checkpoint-1 假成功修復 + Checkpoint-2 K8s 環境感知
...
CD Pipeline / build-and-deploy (push) Successful in 10m55s
## Checkpoint-1: 假成功根治
- approval_execution.py: execute_approved_action 改返回 bool
(原返回 None,呼叫端無法判斷 K8s 是否接受指令)
- decision_manager.py auto-execute 路徑: 用 _exec_success 取代硬編 success=True
修復: K8s 拒絕指令時正確發 ❌ 而非 ✅ 自動修復完成
## Checkpoint-2: K8s 環境感知 (Inventory Pre-flight)
- solver_agent.py: 新增 _fetch_k8s_inventory() — 生成 kubectl 指令前先拉
kubectl get deployments,statefulsets -n awoooi-prod,將真實名稱清單
注入 Solver prompt,LLM 必須從清單選擇,防止幻覺(awooiii-api 三個 i)
- 超時 5s 或失敗 → 返回 "",prompt 顯示警示但不中斷主流程
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 23:08:23 +08:00
OG T
cbb719b4a1
fix(decision_manager): ADR-091 hotfix — 修復 d5dbfc9 喪屍閘門邏輯漏洞
...
CD Pipeline / build-and-deploy (push) Successful in 11m9s
d5dbfc9 引入的閘門條件 `not action.strip()` 在 action="待分析" 時
判斷為 False(非空字串),導致閘門失效,喪屍卡片仍然突圍廣播。
根本原因:c759b4e P1 修復讓 suggested_action fallback 為 "待分析"
而非 "",使原本的 empty-string 檢查形同虛設。
修復:改用集合判斷 `_action_text in {"", "待分析", "NO_ACTION", "待分析 - 系統自動保護"}`,
涵蓋所有已知失敗狀態 token,完全封堵喪屍卡片廣播路徑。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 22:44:53 +08:00
OG T
af2adb5b96
fix(telegram): ADR-091 禁止 Agent Debate 分析失敗時廣播「待分析」喪屍卡片
...
CD Pipeline / build-and-deploy (push) Successful in 10m51s
問題根因:
GET /incidents 觸發 Phase 2 Agent Debate → LLM 全失敗
→ description="待分析" + action="" → 每隔幾分鐘廣播新 Telegram 卡片
→ 告警疲勞(SRE 最致命的殺手)
架構缺陷 (anti-pattern):
GET 請求(讀取操作)產生對外廣播副作用 → 違反 RESTful 原則
修復 (_push_decision_to_telegram):
在 DB 更新完成後、Telegram 推送前加入閘門:
description="待分析" AND action="" → 靜默退出,絕不廣播
ADR-091 鐵律:
只有 Alertmanager Webhook POST(真實新告警)可觸發 Telegram 廣播
Agent Debate 失敗分析 → 靜默 DB 更新,不污染頻道
2026-04-17 ogt + Claude Sonnet 4.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 22:26:35 +08:00
OG T
c759b4eeab
fix(webhook+decision): ADR-089 async webhook + 超時髒資料修復
...
CD Pipeline / build-and-deploy (push) Successful in 10m16s
P0 — Webhook async (ADR-089):
- Alertmanager 收到告警立即回 202,不再同步等 90s LLM
- 新增 _process_new_alert_background():LLM 分析/Approval/Incident/Telegram 全進背景
- 根治 Alertmanager Fallback 風暴(超時 → 重送 → 指數退避風暴)
P1 — 超時髒資料 (decision_manager):
- _package_to_proposal_data: blocked_reason 禁止進 desc_parts(禁進卡片)
- _push_decision_to_telegram: suggested_action fallback 改「待分析」,禁止 description 流入
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 16:29:24 +08:00
OG T
1ae9e9f389
fix(code-review): P0-1 action fallback 語意修正 + P1-2 reason enum + P2-2 secops 清洗
...
CD Pipeline / build-and-deploy (push) Successful in 10m7s
Code Review 發現 (2026-04-17 首席架構師審查):
P0-1 auto_approve.py 條件 1d 語意修正:
- 原:用 `action` 變數(已 fallback = action or kubectl_command)做 kubectl 判斷
→ action="" + kubectl_command="kubectl get pods" → action="kubectl get pods" → 1d 通過
→ _kubectl_cmd 與 action 同值(重複判斷同一來源),掩蓋 action 本身是自然語言的情況
- 修:改用 proposal_data.get("action", "") 原始值(_raw_action)
→ 直接檢查 action 欄位本身,邏輯語意明確
P1-2 auto_approve.py NO_EXECUTABLE_ACTION 新增:
- 新增 AutoApproveReason.NO_EXECUTABLE_ACTION enum 值
- 條件 1d 改用此 reason(原 NO_PLAYBOOK 語意為「無匹配 Playbook」,不適用此場景)
- 避免污染 KM 飛輪學習資料的根因分類(ADR-068)
P2-2 decision_manager.py secops 分支:
- threat_behavior 改用 _parse_debate_summary → 取 diagnosis 欄位
- 與 BUG-A/BUG-C 修復一致,不再傾倒完整 debate_summary 前 150 字
ADR-082: Phase 2 多 Agent 協作
2026-04-17 ogt + Claude Sonnet 4.6(亞太): Code Review 後修正
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 15:23:35 +08:00
OG T
f421e652d3
fix(telegram): BUG-C TYPE-3 排版清洗 + 批准/拒絕永遠置頂(ADR-075 UI 第三波修復)
...
CD Pipeline / build-and-deploy (push) Has been cancelled
Checkpoint 1 — decision_manager.py TYPE-3 root_cause 清洗:
- 舊: root_cause=_smt(reasoning, 500) → debate_summary 全文(診斷/方案/審查/質疑)全部傾倒到 AI 診斷欄
- 新: _parse_debate_summary 只取 diagnosis 欄位 + _smt 截斷 300 字
- 移除 _requires_human 變數(已無用途)
Checkpoint 2 — telegram_gateway.py _build_inline_keyboard 按鈕順序重構:
- 舊: K8s 類別按鈕置頂,批准/拒絕受 requires_human_approval 控制 → 死卡
- 新: [✅ 批准][❌ 拒絕] 永遠第一行,K8s/DB/Host 操作按鈕置後
- 移除 requires_human_approval 參數(邏輯已簡化為無條件置頂)
修改範圍: decision_manager.py else 路由段 + _build_inline_keyboard + send_approval_card 簽名,
telegram_gateway.py 模板/訊息格式零改動。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 14:42:29 +08:00
OG T
418d73540b
fix(telegram): BUG-A TYPE-1 + BUG-B TYPE-4D 資料前處理(ADR-075 UI 第二波修復)
...
CD Pipeline / build-and-deploy (push) Successful in 10m25s
BUG-A (TYPE-1 純資訊通知):
- 舊: message=reasoning[:200] → debate_summary 全文傾倒(診斷/方案/審查/質疑一起出現)
- 新: _parse_debate_summary(reasoning) 只取 diagnosis 欄位 + _smt 截斷 200 字
BUG-B (TYPE-4D Config Drift):
- 舊: diff_summary=description[:500] → LLM 輸出的 JSON 原文直接顯示在 <pre> 區塊
- 新: JSON Catcher — json.loads(description) 成功則格式化「📝 建議操作/📖 說明/⏪ 回滾方案」
失敗 (JSONDecodeError/TypeError/AttributeError) → 平滑降級為純文字截斷
僅修改 decision_manager.py 路由準備段,telegram_gateway.py 模板層零改動。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 14:14:10 +08:00
OG T
6baa2e91da
fix(telegram): 修復死卡按鈕 + 重複渲染 + 智能截斷三連修
...
CD Pipeline / build-and-deploy (push) Successful in 10m26s
問題 1 — 批准/拒絕按鈕消失(死卡)
根因:_build_inline_keyboard 有 alert_category 動態按鈕時走 category 路徑,
approve/reject 行被跳過 → requires_human_approval 卡片無審核扳機
修復:新增 requires_human_approval 參數;True 時強制在動態按鈕後插入批准/拒絕行
影響:decision_manager 傳入 proposal_data.requires_human_review
問題 2 — TYPE-8M 三欄重複渲染
根因:diagnosis/system_impact/probable_cause 全用 reasoning[:100] → 同一段字
修復:新增 _parse_debate_summary(),拆分 debate_summary 的「診斷/方案/安全審查/質疑」
各欄位填入不同語意的組件
問題 3 — 幽靈截斷「質疑:無(通」
根因:粗暴 [:N] 在括號/中文字中間切斷
修復:新增 _smart_truncate(),在句子邊界(。!?;,)截斷,補 …[截斷] 標記
驗證:verify_telegram_ui.py 全部通過(括號平衡 ✅ 、欄位不重複 ✅ 、按鈕存在 ✅ )
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 13:57:42 +08:00
OG T
0ab92c20d6
fix(telegram): root_cause 截斷上限 300→500 — 修復「質疑:無(通」幽靈重現
...
CD Pipeline / build-and-deploy (push) Successful in 10m31s
根因:debate_summary 結構為「診斷(≤220字);方案;安全審查;質疑」
診斷假設長時總長超過 300 chars → root_cause 截斷在「通」字
修復:300 → 500(Telegram 單卡 4096 限制,安全)
2026-04-17 ogt + Claude Sonnet 4.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 13:28:16 +08:00
OG T
b7c2b691bb
fix(p2-backlog): 修復 suggested_action「待分析」— action 空時 fallback 到 description
...
CD Pipeline / build-and-deploy (push) Failing after 1m26s
根因:_push_decision_to_telegram() 的 suggested_action 只有兩條路:
- action 有值 → 顯示 action[:120]
- action 空 → 顯示「待分析」
但 _package_to_proposal_data() 已從 hypothesis 組出 description
(含「根因:...(信心 X%);方案:...」),此時 action="" 卻還是顯示「待分析」
導致 SRE 在 Telegram 卡片看不到 AI 的診斷結論。
修復:action 空時,優先用 description[:120] 作為 suggested_action
(description 已包含根因摘要,比「待分析」有意義)
fallback chain: action → description → "待分析"
2026-04-17 ogt + Claude Sonnet 4.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 11:48:49 +08:00
OG T
0388e50d0e
fix(p1-backlog): 修復「待分析」死結與 Telegram 訊息截斷
...
CD Pipeline / build-and-deploy (push) Successful in 30m25s
問題 1:REQUEST_REVISION → 待分析
根因:safe_candidates=[] → selected=None → recommended_action=None
→ decision_manager action="" → TG 卡顯示「待分析」(資訊流斷裂)
修復 coordinator_agent.py:
無安全候選時回退至 Solver 原始最優方案
標記「[Reviewer 未核准,僅供參考] {action}」
SRE 永遠能看到 AI 建議,資訊流絕不中斷
問題 2:debate_summary 在 (blast_radius... 中間截斷顯示 (bl
根因:root_cause=reasoning[:150] — 150 字元對中文 debate_summary 過短
修復 decision_manager.py:
root_cause 截斷 150 → 300
suggested_action 截斷 80 → 120
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 11:12:02 +08:00
OG T
0c15fa5988
refactor(decision): 狀態機重構 — YAML NO_ACTION 閘門上移至決策路由中樞
...
CD Pipeline / build-and-deploy (push) Has been cancelled
架構師指令(2026-04-17):通知層禁止查詢業務邏輯。
撤銷 c05bcdb 的 inline YAML 查詢(義大利麵補丁),
將 NO_ACTION / INVALID_TARGET 判斷移至正確位置。
重構方向:
① 移除 _push_decision_to_telegram() 的 inline YAML 查詢
→ 通知層只做 blocked_reason → NotificationType 轉譯(Single Responsibility)
② 新增 decide() 第 4c 步:YAML NO_ACTION 路由閘門
位置:_dual_engine_analyze() 返回後、auto_approve.evaluate() 之前
邏輯:
- NO_ACTION → blocked_reason="YAML: NO_ACTION" + is_informational_only=True
→ 短路跳過 auto_approve + Blast Radius → TYPE-1(或 critical → TYPE-4)
- INVALID_TARGET → blocked_reason="INVALID_TARGET-..." → 短路 → TYPE-4
- 閘門查詢失敗 → 靜默降級,繼續正常流程
Checkpoint 覆蓋:
CP1 上移 YAML 評估層 ✅
CP2 短路跳過 auto_approve ✅
CP3 通知層純粹轉譯 ✅
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 10:20:01 +08:00
OG T
c05bcdbbd4
fix(decision): inline YAML NO_ACTION 補查 — 修復 Phase 2 路徑盲點
...
CD Pipeline / build-and-deploy (push) Failing after 4m0s
根因: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 <noreply@anthropic.com >
2026-04-17 10:15:28 +08:00
OG T
83ab5e32d7
fix(happy-path): Happy Path 全境加固 — INVALID_TARGET + critical NO_ACTION + 空指令攔截
...
CD Pipeline / build-and-deploy (push) Has been cancelled
問題 1 (P0) — deployment/unknown 無效重啟:
- alert_rule_engine: 追蹤 _invalid_target flag,回傳 blocked_reason="INVALID_TARGET-..."
- decision_manager: auto_execute 路徑偵測 INVALID_TARGET → 提早返回 + TYPE-4 人工確認
- auto_approve: 新增條件 1c — action 為空字串直接拒絕,防止誤報「即將執行」
問題 2 (P1) — critical+NO_ACTION 靜默:
- decision_manager: blocked_reason 感知層重構
① INVALID_TARGET → TYPE-4
② NO_ACTION + critical → TYPE-4(升級,SRE 不可錯過)
③ NO_ACTION + 非 critical → TYPE-1(維持純資訊卡)
問題 3 (P1) — 規則匹配信心黑洞:
- auto_approve 條件 1c 確保空 action 不通過 auto-approve
即便 is_rule_based=True 也無法在無指令時自動執行
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-16 22:57:50 +08:00
OG T
92b39ab840
fix(no-action-notify): YAML NO_ACTION 告警改為 TYPE-1 資訊通知(移除無意義審核按鈕)
...
CD Pipeline / build-and-deploy (push) Has been cancelled
根因:
- host_resource/postgresql_disk_monitoring YAML 規則設 NO_ACTION
- 但 classify_notification() 不知道 NO_ACTION
- confidence=0.2(感應器無資料)→ 判為 TYPE-4(信心不足需人工審核)
- SRE 看到「審核批准/拒絕」按鈕,卻沒有任何自動修復動作可執行 → 毫無意義
修復:
- _push_decision_to_telegram 偵測 blocked_reason 含 "NO_ACTION"
- 強制 _notif_type = TYPE-1(純資訊通知,無審核按鈕)
- SRE 看到資訊卡「主機 CPU/負載/磁碟告警 (觀察即可)」而非假的審核請求
2026-04-16 ogt + Claude Sonnet 4.6 (台北時區)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-16 22:37:15 +08:00
OG T
54d6818b8d
fix(sensors+rules+dedup): 全景三根因修復 — asyncssh缺失/YAML規則空洞/重複卡片
...
CD Pipeline / build-and-deploy (push) Has been cancelled
Fix 1: asyncssh 未安裝 → sensors_succeeded 永遠=0
- apps/api/pyproject.toml 加入 asyncssh>=2.14.0
- 根因:ssh_provider.py 的 import asyncssh 在 try/except 外,ImportError 直接噴出
- 效果:15 個 SSH tool 全部恢復可用
Fix 2: YAML 規則空洞 → HostHighLoadAverage/PostgreSQLDiskGrowthRate 落 generic_fallback → restart
- 合併 host_cpu_high 為 host_resource_alert,覆蓋 25+ 個主機層 alertname
- 新增 postgresql_disk_monitoring 規則,覆蓋磁碟增長/exporter/vacuum 類告警
- 所有主機層/磁碟監控告警 → NO_ACTION,禁止 kubectl restart
Fix 3: 同一 incident 被多 pod 同時處理 → 送出 3 張重複 Telegram 卡
- decision_manager.get_or_create_decision(): ANALYZING 狀態加入早返回
- 根因:ANALYZING 不在 (READY/EXECUTING/COMPLETED) 條件 → pod-B/C 各自建新 token
2026-04-16 ogt + Claude Sonnet 4.6 (台北時區)
2026-04-16 22:23:49 +08:00
OG T
513232e90b
fix(decision_manager): Agent 分析結果覆寫 Webhook 垃圾 action
...
CD Pipeline / build-and-deploy (push) Successful in 28m30s
根因 (INC-20260416-C365D0 事故完整根因分析):
- Webhook inline LLM 建立 ApprovalRecord.action = "kubectl rollout restart awoooi-prod"
- Agent 分析正確(postgres disk → NO_ACTION)但只發新 Telegram 卡,未覆寫 DB
- 用戶批准 Agent 卡 → 系統查 incident_id → 找到 Webhook 舊 ApprovalRecord
→ 執行垃圾 action(rollout restart 一個磁碟告警!)
修復:
- approval_db.py: 新增 update_action_by_incident_id()(按 incident_id 更新 PENDING 記錄)
- decision_manager.py: Agent 確認 action 後立即覆寫 ApprovalRecord
若 action="" (NO_ACTION): 存 "NO_ACTION - {description}" 讓用戶知道 Agent 建議觀察
用戶批准時執行的是 Agent 的正確建議,而非 Webhook 的通用 action
2026-04-16 ogt + Claude Sonnet 4.6(亞太)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-16 20:07:15 +08:00
OG T
8b2a3df64b
fix(telegram): 修復 Telegram 卡片 description 顯示 debug garbage
...
CD Pipeline / build-and-deploy (push) Failing after 3m12s
問題:description = debate_summary[:500],用戶看到的是內部審計文字
修復:從 diagnosis.top_hypothesis + action_plan.top_candidate 組出人類可讀摘要
格式:「根因:[描述](信心 X%);方案:[動作]」
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-16 18:42:13 +08:00
OG T
27ba97e586
fix(ollama): 清除所有硬寫 188:11434 fallback — 全部改指向 111 GPU
...
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
5a3a649f8a
fix(decision): TYPE-1 告警重複洗版兩個根因修復
...
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)
...
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
0760315059
fix(decision-manager): 修正 CAST 語法 + 關閉 shadow_mode
...
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
457018c0f9
fix(decision-manager): AI 分析結果寫入 incidents.decision_chain (DB 長期保存)
...
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
ecfb7148bf
fix(prod): 接通 YAML 規則引擎與自動執行路徑 — 架構核心斷點
...
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