OG T
2abc91e360
fix(drift-card): 修 drift 卡片 2 bug — AI 研判 copy 樣式 + Diff 按鈕 AttributeError
...
CD Pipeline / build-and-deploy (push) Successful in 13m8s
Bug 1: 按「🔍 查看 Diff」失敗
錯誤: 'DriftReportRepository' object has no attribute 'get_by_id'
根因: DriftReportRepository 方法叫 get(), 其他 repo 都叫 get_by_id()
修法: 加 get_by_id() alias, 對齊 repo 介面慣例
Bug 2: AI 研判內容被渲染成 code block + copy 按鈕
根因: telegram_gateway line 1962 用 <pre> 包 diff_summary
但 diff_summary 是 AI 研判敘述 + emoji 清單, 非 code
修法: 移除 <pre>, 改以分隔線 + html.escape 純文字顯示
驗收:
- 下次 drift 卡片: AI 研判段落純文字(無紫色 code block + copy)
- 按「🔍 查看 Diff」→ 送完整 diff 詳情(非 AttributeError)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-19 11:27:13 +08:00
OG T
4b8be32610
fix(telegram+approval): TG-1 + AP-1/2/3 — 4 修 Telegram UX
...
CD Pipeline / build-and-deploy (push) Failing after 25m27s
Ansible Lint / lint (push) Has been cancelled
2026-04-19 凌晨(台北時區)— ogt + Claude Opus 4.7 (1M)
## TG-1: INFO_ACTIONS 加 view
security_interceptor.py — 'view' 按鈕現在走 2-part 讀格式,
不再誤觸發 4-part nonce 寫格式。
## AP-1: approval_records.telegram_message_id 持久化
telegram_gateway.send_approval_card send 成功後,在 DB 層 UPDATE
approval_records SET telegram_message_id, telegram_chat_id
(不只 Redis, Pod 重啟仍可找回原卡片)。
## AP-2: approval 執行完成原卡片 edit + KM/Playbook 增量
approval_execution._push_execution_result_to_alert 除了 reply 原卡片,
還 editMessageReplyMarkup 移除按鈕(修「永遠執行中」卡片問題)。
- 同步查 knowledge_entries/playbooks 2min 內增量,附加到訊息
顯示 "📚 KM +N 🎯 Playbook 更新×M"
- 成功: ✅ 執行成功 + action + KM 增量
- 失敗: ❌ 執行失敗 + 原因 + KM 增量
## AP-3: primary_responsibility 正規化降「❓ 未知」比例
openclaw._parse_analysis_result: 若 LLM 填空/None/不在白名單
(FE/BE/INFRA/DB/COLLAB),強制 fallback: kubectl 關鍵字有 → INFRA,
否則 BE。之前只檢查 "not in data" 但 None 或空字串會穿過。
## 跳過: TG-3 (refactor) + TG-5 (webhook 為棄用 endpoint,design 採 Long Polling)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-19 01:15:58 +08:00
OG T
68a42a3c97
fix(openclaw): 幻覺驗證雙路徑覆蓋 + 抽出共用 helper
...
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-19 凌晨(台北時區)— ogt + Claude Opus 4.7 (1M)
根因:
commit 7e9448f 的 Python hallucination validator 只裝在
`analyze_alert` (webhook path),但 incident sweeper 走
`generate_incident_proposal` (line 1552) 沒裝驗證 → 00:23
PostgreSQLDiskGrowthRate 卡片出現 "deployment/awoooi-prod"
幻覺未攔截。
修:
1. 抽出 `_validate_deployment_inventory(result, inventory, ns)` 共用方法
2. `analyze_alert` (line 1322 area) 呼叫此 helper — 原行內邏輯消除
3. `generate_incident_proposal` (line 1552) 動態抓 inventory + 呼叫 helper
4. helper 補:
- result.action_title = '[安全降級] 調查 {ns} 真實資源狀態'
(之前只改 description,action_title 沒變 → DB action 欄位仍殘留舊文字)
- 每個欄位賦值 try/except 保底,單欄失敗不影響其他
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-19 01:11:09 +08:00
OG T
fdce0a3ab9
fix(approval): NO_ACTION 不再誤標 EXECUTION_FAILED (MASTER §7.1 #11 修)
...
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-19 凌晨(台北時區)— ogt + Claude Opus 4.7 (1M)
根因:
approval.action='NO_ACTION - 待分析' (幻覺 validator 降級產物) 丟進
parse_operation_from_action → operation_type=None → background_execution_skip
→ update_execution_status(success=False) → 標為 EXECUTION_FAILED。
污染 KPI:
MASTER §7.1 #11 auto_execute 成功率 = EXECUTION_SUCCESS / (SUCCESS+FAILED)
NO_ACTION 本來就不該計入失敗,但卻被算進去拖垮指標。
實測 30d 成功率 0.9% 有很大比例是 NO_ACTION 誤標造成。
修復:
parse 失敗時先判斷是否 NO_ACTION 類 (action 含 NO_ACTION/OBSERVE/INVESTIGATE
等關鍵字) → 走專屬 noop 分支:
- log event=background_execution_noop (info 級)
- update_execution_status(success=True) → EXECUTION_SUCCESS
- timeline 標 ✅ 純觀察類動作完成
- reply 原告警卡片顯示成功
- return True
真正解析失敗 (非 NO_ACTION) 保留原失敗路徑,但補上 error_message
(P0.2 延伸),讓 rejection_reason 有 "Could not parse operation type from
action: <action>" 而非空字串。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-19 01:08:16 +08:00
OG T
2e988bdb81
fix(telegram): drift 執行結果貼回卡片 + audit log user_id
...
CD Pipeline / build-and-deploy (push) Has been cancelled
IDE 抓到 _stamp 未使用(結果沒送)+ user_id 未使用(audit 缺漏)。
修:
1. _edit_drift_card_outcome 不只移除按鈕,還 send 簽核戳訊息
(reply_to 原卡片,若 msg_id 存在),格式:
✅ 已採納 by @username (成功)
Drift <report_id>
2. _handle_drift_action 加 drift_callback_dispatched log(audit)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-19 01:07:13 +08:00
OG T
877c8479e0
fix(telegram): TG-2 + TG-4 修 drift 按鈕 black hole
...
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-19 凌晨(台北時區)— ogt + Claude Opus 4.7 (1M)
統帥截圖直擊: 按「查看 Diff」→ 變成「執行中」,且看不到還有 21 項。
全景盤點發現 9 個 Telegram 子系統 bug,本 commit 修 2 個最痛的:
## TG-2: drift_view/drift_adopt/drift_revert 3 按鈕**無 handler**
點擊 → fallthrough → UX 黑洞 / 誤觸發 approve 路徑。
修復: handle_callback 在 state guard 後(line 2752 後)加 Step 1.85
offroute: 3 個 drift_* action → _handle_drift_action 專職處理,
不走 nonce approve/reject dispatch,避免誤觸發執行流。
3 個按鈕實作:
- drift_view: 讀 drift_reports → 送新訊息展示全部 items
(HIGH/MEDIUM/INFO emoji + Git vs K8s 原值對照,上限 50 項 4000 字)
- drift_adopt: 呼叫 drift_adopt_service.adopt_drift()
- drift_revert: 呼叫 drift_remediator.revert()
## TG-4: drift card message_id 沒存 Redis → edit 回不了卡片
修復: send_drift_card 成功後 setex f"tg_drift:{incident_id}" TTL 24h,
供 _edit_drift_card_outcome 在 adopt/revert 執行後更新原卡片(先移除
按鈕 + 加「XX by @username (成功/失敗)」簽核戳)。
## 未包含(follow-up):
TG-1 INFO_ACTIONS 擴充(view) — 下一 commit
TG-3 handler 重複分派 — 評估中
TG-5 Bot webhook URL 未設 — 需統帥決策公開 URL
approval card NO_ACTION 誤標 FAILED — 下一 commit
approval card description 矛盾 / responsibility 未知 / 執行後 edit
全景 9 bug 清單詳見 project_phase7_round3_telegram_subsystem_audit(待建)。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-19 01:06:30 +08:00
OG T
98aef55b31
feat(kpi): ADR-090-D MASTER §7.1 北極星 KPI 5 斷鏈全修
...
CD Pipeline / build-and-deploy (push) Successful in 11m49s
run-migration / migrate (push) Failing after 15s
2026-04-18 晚(台北時區)— ogt + Claude Opus 4.7 (1M)
MASTER §7.1 15 個北極星 KPI 實測對標發現 5 個斷鏈:
#3 fine-tune JSONL /week — finetune_exports 表不存在
#4 MCP 呼叫/24h — timeline_events 沒 mcp_call event_type
#6 Declarative 修復使用率 — remediation_events 表不存在
#7 general 兜底 17.3% — classify_alert_early 漏 5 類
#10 notification_outcomes /week — 表不存在
本 commit 全修。
## 1. Migration: adr090d_kpi_data_sources.sql (3 張表)
- finetune_exports — P3 Fine-tune JSONL 追蹤
- remediation_events — P5 Declarative 修復追蹤
- notification_outcomes — 通知品質 + RLHF 語料
Idempotent (CREATE TABLE IF NOT EXISTS), 已 apply 進 prod。
## 2. classify_alert_early 擴 4 類規則 (降 general 兜底)
- test 攔截: Test*/FPTest/FingerprintTest/ADR089*Test/L4Closure*/*FreshUniq*
→ category='test', TYPE-1 純通知
- High*CPU/Memory/Disk/Load → host_resource
- TLS*/SSL*/*ProbeFailure* → ssl_cert
- PostgreSQL*/MySQL*/MongoDB*/*DiskGrowthRate → database
預期 general 17.3% → 3-5% (達標 <10%)。
## 3. finetune_exporter DB 寫入
_run_export() 結尾寫 finetune_exports 一筆,含 checksum/size/record_count。
## 4. declarative_remediation DB 寫入
evaluate() 後 fire-and-forget _log_remediation_event() 寫 remediation_events
(status='pending', remediation_type 依 tier 自動判為 declarative/imperative/gitops_pr)。
## 5. telegram_gateway DB 寫入 (send_approval_card)
_send_request 成功返回 message_id 後寫 notification_outcomes 一筆,
channel='telegram', delivery_status='delivered|failed'。未來人類按鈕時
update user_action → RLHF 訓料黃金。
## 6. pre_decision_investigator MCP 呼叫追蹤
_call_single_tool() finally 寫 timeline_events event_type='mcp_call',
含 provider/tool/status/duration_ms/error。24h 內 MCP 呼叫可 SQL 量測。
## 預期量化改善
| KPI | 修前 | 修後 24h 後應見 |
|-----|------|----------------|
| #3 fine-tune /week | 0 (表不存在) | >=10 (每週 cron 跑) |
| #4 MCP 呼叫/24h | 0 | >0 (實測將寫 timeline) |
| #6 declarative 使用率 | 表不存在 | 有資料 (pending/success/failed 分佈) |
| #7 general 兜底 | 17.3% | <10% |
| #10 notification_outcomes | 0 | 每次 approval card 寫一筆 |
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-19 00:00:31 +08:00
OG T
898145d68e
refactor(openclaw): SuggestedAction 改用頂部 import (避免 inline 三重巢狀)
...
CD Pipeline / build-and-deploy (push) Successful in 11m17s
Ansible Lint / lint (push) Has been cancelled
IDE 對 inline "from src.models.ai import" 誤報(但運行正常)。
改為頂部 import 既滿足 IDE 也更 Pythonic。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 23:28:19 +08:00
OG T
e6e484c1dc
fix(openclaw): import path 修正 — src.models.ai (非 openclaw_schema)
...
CD Pipeline / build-and-deploy (push) Has started running
IDE 正確抓到的 bug(非 false positive),SuggestedAction 在 src/models/ai.py。
_SA.NO_ACTION 現在能正確降級。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 23:26:45 +08:00
OG T
7e9448f6d0
fix(openclaw): 幻覺 deployment 名雙層防禦 — Prompt + Python validator
...
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-18 晚(台北時區)— ogt + Claude Opus 4.7 (1M)
生產事件 (approval f763bedf, 22:58):
- Alert: KubePodCrashLooping, labels.deployment="awoooi-api"
- NEMOTRON 雖收 inventory "awoooi-api, awoooi-web, awoooi-worker"
仍輸出 kubectl_command="kubectl rollout restart deployment/awoooi-prod"
(把 namespace 誤當 deployment 名)
- 執行結果: "Deployment 'awoooi-prod' not found in namespace 'awoooi-prod'"
## Layer 1: NEMOTRON_SYSTEM_PROMPT 強化 (prompts.py)
新增「🔒 DEPLOYMENT NAME RULE (STRICTLY ENFORCED)」區塊:
- namespace NEVER is a deployment name
- "awoooi-prod" 是 NAMESPACE,不可寫 deployment/awoooi-prod
- 若有 inventory,deployment 必須 exact match
- 優先用 labels.deployment,unknown → NO_ACTION
## Layer 2: Python 後驗證 (openclaw.py:1322+)
LLM 回應解析後 regex 抽出 deployment 名,對照 _k8s_inventory:
- 在清單內 → 通過
- 不在清單內 → 降級:
* kubectl_command → "kubectl get deploy -n {ns}"(純調查)
* suggested_action → NO_ACTION
* target_resource → "unknown(hallucinated)"
* confidence → 0.0
* description 加註 [安全降級] 並列出合法 inventory
- log 'openclaw_deployment_hallucination_detected' 記錄
效果: 就算 LLM 無視 prompt,Python 層也會擋下。
破壞性 kubectl 絕不執行於不存在的 deployment。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 23:26:09 +08:00
OG T
6ad73b4834
fix(flywheel): 三修 L5/L6 斷鏈 — RBAC 擴權 + 失敗原因入庫 + verifier 失敗時也跑
...
CD Pipeline / build-and-deploy (push) Successful in 11m6s
2026-04-18 晚(台北時區) — ogt + Claude Opus 4.7 (1M)
全景飛輪診斷暴露 3 個真斷鏈:
- L5 執行 30d: EXECUTION_FAILED 216 / EXECUTION_SUCCESS 2 (失敗率 99%)
- L6 驗證 7d: verification_result 全 NULL (988 筆 evidence 都沒驗)
- 所有 rejection_reason / error_message 欄位全空(無法診斷)
根因: awoooi-executor ServiceAccount RBAC 不足,executor.py 每次
kubectl get nodes/HPA 都 Forbidden,連 evidence 都抓不到,後面 repair
全炸,verifier 因為 execution 沒 success 永遠不 trigger,evidence
驗證結果永遠 NULL。修一個 RBAC 解 3 個節點。
## P0.1 RBAC 擴權 (k8s/awoooi-prod/07-rbac.yaml)
新增 cluster-scope 讀權(僅 list/get/watch,零寫入):
- nodes + nodes/status (evidence gathering 必需)
- horizontalpodautoscalers (HPA 狀態)
- metrics.k8s.io: nodes + pods (resource metrics)
- statefulsets + daemonsets (完整 workload 視圖)
已 kubectl apply + 煙霧測試: kubectl get nodes 可跑。
## P0.2 失敗時必寫 rejection_reason (approval_db.py)
update_execution_status() 新增 error_message 參數,失敗時寫入
rejection_reason (截 2000 字) → 之後診斷有依據。
approval_execution.py 呼叫端同步更新,result.error 一路傳進 DB。
## P0.3 Verifier 失敗時也跑 (approval_execution.py)
原邏輯: verifier 只在 result.success=True 時呼叫 → 99% 失敗下
永遠不跑。
新邏輯: 失敗 path 也 create_task 跑 verifier,action_taken 後綴
加 ":FAILED" 標記。verifier 抓 post_state 寫
verification_result='failed' 回 incident_evidence。
L7 learning 從此有失敗樣本可學,playbook trust 負向 2x 衰減才
真正生效。
預期效果:
- EXECUTION_FAILED 率 30d 內應從 99% 降到 <30%
- incident_evidence.verification_result NULL 率應從 100% 降到 <10%
- approval_records.rejection_reason 補齊率從 0% 到 100%
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 20:12:57 +08:00
OG T
b0d560dbb3
fix(drift-narrator): shortener 用 replace — 包容 LLM 加 'Resource/Name:' 前綴幻覺
...
CD Pipeline / build-and-deploy (push) Successful in 10m50s
2026-04-18 下午(台北時區)— ogt + Claude Opus 4.7
Round 4 LLM 自己在 field 前加資源識別符:
'Deployment/awoooi-web: spec.template.spec.containers'
導致 startswith 模式 shortener 失效(前綴不在開頭)。
防禦式修法: startswith 不中 → 改用 replace 清除任何位置的前綴。
結果:
'Deployment/awoooi-web: containers' ✅
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 18:12:15 +08:00
OG T
b63aed72df
fix(drift-narrator): 砍 spec.template.spec. 前綴 — 修 Telegram 自動換行醜陋排版
...
CD Pipeline / build-and-deploy (push) Successful in 12m1s
2026-04-18 下午(台北時區)— ogt + Claude Opus 4.7
統帥實彈三輪視覺回報: 字段名 'spec.template.spec.volumes' 共 24 字元,
加上 emoji+': '+summary 超過 Telegram <pre> 視覺寬度,自動換行
造成 emoji 與 field name 斷開、單獨成行的醜狀。
修復: _shorten_field_path() 砍 3 種常見前綴:
- 'spec.template.spec.' → ''
- 'spec.template.' → '' (後備)
- 'spec.' → '' (後備)
效果對比:
前: '🟡 spec.template.spec.affinity.podAntiAffinity.preferredDuringS: [清單 3 項]'
後: '🟡 affinity.podAntiAffinity.preferredDuringS: [清單 3 項]'
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 17:10:20 +08:00
OG T
f3960f36d2
fix(drift-narrator): fallback 強化 — 標註 K8s 預設值補齊 + 可操作數獨立計算
...
CD Pipeline / build-and-deploy (push) Successful in 10m37s
2026-04-18 下午(台北時區)—— ogt + Claude Opus 4.7 (1M)
統帥實彈測試回報: 卡片顯示「securityContext: (未設) → {物件 0 欄位}」毫無意義。
根因: _fallback_items 對「K8s controller 自動補齊空物件」的噪音
誤當成真實變更輸出。且「還有 29 項」數字包含白名單 + trivial。
修復 3 項:
1. _is_trivial_drift() 新判定函數
None/空字串/{}/[]/false/0 等互相視為「無實質變更」
捕捉 K8s controller 自動補齊場景
2. _summarize_item() 替代原本 smart_shorten
- trivial → "K8s 預設值補齊 (無實質變更)"
- None → value → "新增 xxx"
- value → None → "已刪除 (原: xxx)"
- 其他 → "from → to"
3. _fallback_items() 改進
- 按 level 排序 (HIGH 優先)
- 白名單 + HPA allowlist 先過濾
4. _count_nontrivial_drift() + Telegram 呈現
- 新增「可操作」計數 (去掉白名單 + trivial)
- 「還有 N 項」用可操作數,不會誤導
- items 為空時顯示「全為白名單或預設值補齊」
預期效果:
之前: "... 還有 29 項" (其實只 1 個是真實 drift)
現在: "... 還有 0 項" 或 "(全部為白名單或預設值補齊)"
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 16:29:49 +08:00
OG T
1606093dd2
fix(drift-narrator): 兩個 hotfix — NEMOTRON wrapper 解析 + tags asyncpg 型別
...
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-18 下午(台北時區)—— ogt + Claude Opus 4.7 (1M)
Live-fire test (report_id=80a34b58) 暴露兩個 bug:
## Bug 1: LLM JSON 被 NEMOTRON wrapper 吞掉
根因: openclaw.call() 經 NEMOTRON 路由時強制回 {description,...} 結構,
我的 prompt 要 {narrative, items} 無法穿透。
(同 1ff3405 早前碰過的 JSON 裸奔問題根源)
修復: 三路 fallback 解析
- Path 1: 直接我們的 {narrative, items}(Ollama 或 LLM 守規矩)
- Path 2: NEMOTRON wrapper,description 巢狀 JSON 含我們結構
- Path 3: description 是純敘述 → 當 narrative + Python fallback_items
## Bug 2: tags 參數 asyncpg DataError
根因: 傳 '{drift,type4d,llm_summary}' 字面量字串,asyncpg 要求 Python list
'(a sized iterable container expected (got type str))'
修復: tags 改傳 ['drift','type4d','llm_summary'] Python list,移除 CAST AS text[]
asyncpg 自動推斷 text[]
Live-fire 結果驗證:
- narrative ✅ 生成(fallback path)
- items ⚠️ 只 1 筆(NEMOTRON 未吐我們結構)
- DB write ❌ tags 型別錯
- Telegram ✅ 送出(雖 fallback 內容但視覺 OK)
本 commit 後預期:
- LLM 回應走 Path 2/3 → narrative + Python fallback items(5 筆 smart summary)
- DB write 成功 → automation_operation_log + ai_collaboration_trace 皆有記錄
- 若 LLM 未來學會走 Path 1(給我們 {narrative, items}),自動升級
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 16:26:17 +08:00
OG T
a156566b17
feat(drift-narrator): ADR-090-C L4 稽核閉環 — notification_formatted op 入庫
...
CD Pipeline / build-and-deploy (push) Successful in 10m47s
run-migration / migrate (push) Failing after 14s
2026-04-18 下午(台北時區)—— ogt + Claude Opus 4.7 (1M)
架構鐵律執行:
「沒有被記錄的 AI 決策,就等於沒有發生過。」
drift_narrator 每次呼叫 LLM 生成摘要,必須完整寫入
automation_operation_log + ai_collaboration_trace,形成 L4 稽核 + RLHF 語料。
本 commit 兩件事:
1. apps/api/migrations/adr090c_notification_formatted_op_type.sql
- 擴充 automation_operation_log.operation_type CHECK 加 'notification_formatted'
- DROP + ADD CONSTRAINT idempotent 模式
- 已用 awoooi(表 owner)apply 進 prod 驗證通過
2. apps/api/src/services/drift_narrator_service.py
- 新增 _log_ai_action_to_db() 負責 DB 稽核寫入
- 在 _generate_narrative_and_items() 結尾(success / fallback 都寫)呼叫
- automation_operation_log:
* operation_type='notification_formatted'
* actor='drift_narrator'
* input = {report_id, namespace, counts, items_scanned}
* output = {narrative, items, items_count}
* duration_ms, tags=['drift','type4d','llm_summary']
* parent_op_id 查詢 alert_fired 鏈路(未來 drift → alert 關聯)
- ai_collaboration_trace:
* agent='drift_narrator', model=provider (ollama / nemotron / 等)
* prompt(限 8000 字)+ response(JSONB)
* accepted = LLM JSON 解析成功 flag(未來 RLHF 訓料金礦)
- 錯誤處理: DB 寫入 try/except 包住,永不破壞 Telegram 通知主流程
P2.4 事件關聯:
- SELECT parent op via input->>'report_id' 或 'drift_report_id'
- 若找到則綁定 parent_op_id(形成 alert_fired → notification_formatted 追溯鏈)
- 目前 drift 本身不經 alert_fired,parent 為 NULL(等未來鏈路接通)
P2.5 RLHF 語料:
- ai_collaboration_trace.accepted=true 的紀錄即為「LLM 解析成功」樣本
- 未來統帥按 Telegram [✅ 採納變更] / [⏪ 回滾] 時,對應 trace 也可更新
outcome flag,形成完整 Human-in-the-loop 語料
技術細節:
- get_db_context() auto-commit(src/db/base.py:128),無需手動 commit
- prompt 最長 8000 字(一般 drift 約 2-3k)
- raw_response 保留前 500 字在 trace.response JSON 中
相關:
- feedback_ai_autonomous_direction.md L4 北極星
- feedback_secrets_leak_incidents_2026-04-18.md L1-L4 分層
- ADR-090 11 張神經網路表
- commit fb88512(B 方案視覺層)
IDE 可能顯示 src.db.base 找不到 —— 那是誤報(drift_repository.py 用同一條路徑)。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 16:04:23 +08:00
OG T
fb88512fcb
fix(drift-narrator): B 方案 LLM 驅動智能摘要 — 徹底消滅 str()[:30] 暴力截斷
...
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-18 下午(台北時區)—— ogt + Claude Opus 4.7 (1M)
根因:
_format_drift_summary() 對 dict/list 型別的 git_value/actual_value
直接呼叫 str()[:30] 暴力截斷,產生像 "[{'name': 'repair-ssh-key', 's"
這種亂碼掉半個 dict key 的亂七八糟輸出,徹底違背「AI 自主化」原則。
B 方案架構決策:
「捨棄 Python 寫死的字串解析邏輯。將原始 Config Diff 結構直接作為
Context,餵給 Hermes/NemoTron,利用 prompt 規定輸出格式,讓 LLM 自己
消化並輸出包含紅黃燈標示的 Top 5 人類易讀摘要。」
實作:
1. _NARRATIVE_PROMPT 重寫 — 要求 LLM 回傳 {narrative, items[]} JSON
- drift items 以 JSON serialize 餵進 prompt(保留 200 字 context)
- items 限 5 筆,HIGH 優先
- summary 30 字繁中口語(非技術 repr)
2. _generate_narrative_and_items() 新方法 — 解析 LLM JSON 並驗證結構
3. _format_drift_for_llm() 新方法 — 結構化 JSON 給 LLM(取代舊 str 版)
4. _render_telegram_body() 新方法 — 組裝乾淨的 Telegram 卡片
範例輸出:
🤖 AI 研判
<LLM 4-5 行敘述>
📊 漂移明細 (HIGH: 1 | MEDIUM: 29)
🔴 spec.template.spec.volumes: 新增 2 項 repair-ssh-key 掛載
🟡 spec.template.spec.serviceAccount: (未設) → awoooi-executor
... 還有 27 項 (按 🔍 查看 Diff)
5. Fallback 強化 — _smart_shorten() + _fallback_items()
LLM 失敗時用型別感知的 Python 摘要(dict/list 顯示大小,不暴力 repr)
移除:
- _format_drift_summary() — 舊的暴力截斷實作
- _generate_narrative() — 只回 string 的舊介面
保留:
- _fallback_narrative() / _format_intent_summary() — 仍有用
- Redis 快取 / trigger 條件 / DB update — 邏輯不變
MVP 階段:
本 commit 只改視覺呈現,沒動 automation_operation_log / ai_collaboration_trace
稽核寫入。等 Telegram 視覺驗證 OK 後再做 Phase 2 加入 DB 稽核。
相關:
- feedback_ai_autonomous_direction.md 北極星原則
- 1ff3405 今早的 JSON 裸奔 hotfix(只修了 narrative,沒修 items)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 15:54:16 +08:00
OG T
2d43751729
feat(ops): ADR-090-B 零信任收尾範本 — wrapper / sudoers / migrator / CI
...
CD Pipeline / build-and-deploy (push) Successful in 12m17s
run-migration / migrate (push) Failing after 14s
2026-04-18 台北時區 —— ogt + Claude Opus 4.7 (1M)
本 commit 響應本 Session 兩次憑證外洩事故
(feedback_secrets_leak_incidents_2026-04-18.md),
交付統帥可直接部署的零信任基礎設施範本.
檔案清單:
1. scripts/host-ops/awoooi-hosts-add.sh
- 110 主機 /etc/hosts 白名單 wrapper
- 只允許預定義主機名,idempotent,帶 IP 格式驗證
- 安裝: /usr/local/bin/awoooi-hosts-add (root:root 0755)
2. scripts/host-ops/awoooi-wrapper.sudoers
- 配套 sudoers 規則 (NOPASSWD for wrapper + SIGHUP only)
- 安裝: /etc/sudoers.d/awoooi-wrapper (root:root 0440)
- 禁 tee / bash / sh 這類 generic shell access
3. apps/api/migrations/adr090b_awoooi_migrator_role.sql
- PG 限權角色 awoooi_migrator
- 只能 DDL (CREATE/ALTER/DROP/INDEX/COMMENT)
- 明確 REVOKE 所有 DML + default privileges 鎖死
- 本檔由統帥執行 (需 superuser),不由 Claude 執行
4. k8s/awoooi-prod/awoooi-migrator-secret.template.yaml
- K8s Secret patch 範本
- 新增 MIGRATION_DATABASE_URL key (awoooi_migrator 連線串)
- 與應用 DATABASE_URL 拆開
5. .gitea/workflows/run-migration.yml
- CI 自動套用新 migration (單 transaction + ON_ERROR_STOP)
- 用 Gitea secret MIGRATION_DATABASE_URL,不走明碼
- 每次成功寫一筆 asset_discovery_run (audit trail)
零信任三層防線 (對應 feedback_secrets_leak_incidents):
L1 對話無密碼 -> wrapper 內建白名單
L2 操作經 wrapper -> sudoers + awoooi_migrator
L3 顯示強制遮蔽 -> CI 走 secret,不走 env
本 Session 發現的 3 次憑證外洩全部在 feedback_secrets_leak
memory 登記,並有對應 P0 輪替計畫.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 13:23:39 +08:00
OG T
5ae82d1d1f
feat(db): ADR-090 L4 AIOps 地基 — 資產盤點 × 7 項自動化覆蓋矩陣永久化 DB
...
CD Pipeline / build-and-deploy (push) Has been cancelled
2026-04-18 下午(台北時區)—— ogt + Claude Opus 4.7 (1M)
MoWoooWorkDown 假警報 RCA 暴露三重結構性失守:
- 110/188 主機 load 18/16 × 13 天 / cadvisor 288% / K3s 120/121 無監控
- Prometheus 僅 35 targets / 58 rules(覆蓋不到三成)
- HostHighCpuLoad 量錯維度(CPU idle vs load_avg)
統帥戰略指令:
- 全景資產 × 七大自動化 × 永久化 DB
- AI 四分工(OpenClaw × NemoTron × Hermes × Claude LLM)
- 所有自動化操作歷程必進 DB,不靠 MD(MD 會漂移)
本 commit 交付:
1. SQL migration (apps/api/migrations/adr090_asset_inventory_foundation.sql)
- 11 張表 + 33 indexes + 20 CHECK + 3 UNIQUE + 16 FK
- pgcrypto extension dependency
- 完整 idempotent(CREATE IF NOT EXISTS + single transaction)
- 已 apply 進 awoooi_prod(188 PG),驗證通過
2. ADR-090 (docs/adr/ADR-090-monitoring-blindspot-governance.md)
- 決策紀錄 + 7 引擎對映 + 4 替代方案否決
3. 主戰略文件 (docs/superpowers/specs/2026-04-18-blindspot-governance-capacity-l4.md)
- §0-§14: 背景 / 根因 / Schema DDL / 4 層防禦 / 7 Phase 實施 /
HARD_RULES / AI 分工矩陣 / 驗收指標 / 技術債 / 回滾 / 接手協議
4. MASTER §8 Living Changelog 追加 Phase 7 啟動條目
11 張表:
asset_inventory / asset_discovery_run / asset_coverage_snapshot /
asset_relationship / alert_rule_catalog / asset_change_event /
asset_compliance_snapshot / host_capacity_snapshot /
capacity_violation_event / automation_operation_log /
ai_collaboration_trace
首筆 bootstrap 記錄已 seed 進 asset_discovery_run
(run_id=6760c5bf-57e5-4a40-b82d-31b794464652)
相關 Memory (未 commit,存於 ~/.claude/...):
- project_blindspot_governance.md (跨 session 指針)
- feedback_monitor_self_monitoring.md (監控工具必須被監控)
- feedback_secrets_leak_incidents_2026-04-18.md (憑證外洩三防線)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-04-18 13:18:46 +08:00
OG T
1ff3405755
fix(drift-narrator): 修復 JSON 裸奔 — 從 NEMOTRON 回傳解析 description 欄位
...
CD Pipeline / build-and-deploy (push) Successful in 10m44s
根因:openclaw.call() 經 NEMOTRON 路由後強制輸出 JSON(NEMOTRON_SYSTEM_PROMPT 鐵律)
但 _generate_narrative 期待純文字 → JSON 整包吐到 Telegram <pre> 區塊裸奔
修復:收到 text 後先嘗試 JSON 解析
- 成功 → 按優先順序取 description / action_title / reasoning
- 失敗(非 JSON)→ 原文使用(向下相容 Ollama qwen 純文字回傳)
效果:Telegram Config Drift 卡片顯示繁中人話摘要,不再吐原始 JSON
2026-04-17 ogt + Claude Sonnet 4.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-18 01:08:32 +08:00
OG T
4f2e122fd2
fix(openclaw): Checkpoint-2 webhook path K8s inventory injection — 防止 NemoTron 幻覺 awoooi-service
...
CD Pipeline / build-and-deploy (push) Successful in 11m39s
根因:NemoTron 在 webhook path(analyze_alert)無叢集上下文
→ 盲猜 deployment/awoooi-service → kubectl not found → EXECUTION_FAILED → trust score 0 永遠
修復:
- analyze_alert() Step 0.5: 呼叫 _fetch_k8s_inventory_for_openclaw() 拉取真實 Deployment 清單
- 注入「🔒 叢集實際資源清單」section 到 full_prompt,強制 LLM 從清單選擇資源名
- 失敗/超時 → 返回空字串 → 注入警示提示,主流程不中斷
- available_len 計算納入 k8s_section 長度防止 4K 截斷
影響:
- Solver Agent path (solver_agent.py) 已在 cf50a5c 修復
- 本 commit 修復 Alertmanager webhook path(analyze_alert → NemoTron)
- 兩條路徑均有 K8s 環境感知,LLM 不再幻覺資源名
ADR-082: Phase 2 多 Agent 協作
2026-04-17 ogt + Claude Sonnet 4.6(Checkpoint-2 webhook path completion)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-18 00:53:27 +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
604d8eea37
fix(schema-drift): 補齊 prompts.py + Claude API schema enum 同步 (ADR-090)
...
CD Pipeline / build-and-deploy (push) Successful in 12m27s
問題: fe77e6d 擴充了 models/ai.py enum 至 8 值,但兩個地方未同步:
1. core/prompts.py L77: 缺 INVESTIGATE、OBSERVE
2. core/prompts.py L176 (NEMOTRON_SYSTEM_PROMPT): 缺 APPLY_HPA、INVESTIGATE、OBSERVE
3. openclaw.py L564 (_call_claude tools schema): 舊 4 值 enum 約束
影響: LLM 不知道可以輸出 INVESTIGATE/OBSERVE,只能選舊 4 值
修復: 三處統一對齊 8 個 suggested_action 值
RESTART_DEPLOYMENT|DELETE_POD|SCALE_DEPLOYMENT|APPLY_HPA|TUNE_RESOURCES|INVESTIGATE|OBSERVE|NO_ACTION
Closes: ADR-090 Prompt-Model 三層同步鐵律
2026-04-17 ogt + Claude Sonnet 4.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 22:10:18 +08:00
OG T
fe77e6d297
fix(ai): SuggestedAction enum 擴充 + Pydantic fallback 防護
...
CD Pipeline / build-and-deploy (push) Successful in 10m48s
Type Sync Check / check-type-sync (push) Failing after 2m52s
根本原因: NemoTron 輸出 "investigate" → Pydantic 只接受 4 個值 → 爆炸
→ openclaw_analysis_parse_failed → analysis_result=None → 全部 fallback 卡片顯示「待分析」
修復:
1. SuggestedAction enum 新增 INVESTIGATE/OBSERVE/APPLY_HPA/TUNE_RESOURCES
(prompt.py 列了 6 個,enum 只有 4 個,prompt/model 不同步是根源)
2. normalize_suggested_action validator: uppercase + 別名映射 + 未知值 fallback NO_ACTION
確保任何 LLM 輸出都不會讓 Pydantic 爆炸導致 analysis_result = None
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 21:36:36 +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
9d6aa7ea45
feat(trust): ADR-088 Trust Score 持久化 — L4 自動放行核心
...
CD Pipeline / build-and-deploy (push) Successful in 10m40s
TrustScoreManager 從記憶體升級為 PostgreSQL 持久化,
Pod 重啟後信任分數不再歸零,AI 能真正累積到 L4 自動放行門檻。
變更:
- migrations/adr088_trust_score_persistence.sql: trust_records 表
- db/models.py: TrustRecordDB ORM model
- repositories/interfaces.py: ITrustRepository Protocol
- repositories/trust_repository.py: PG upsert ON CONFLICT DO UPDATE
- services/trust_engine.py: bulk_load() 啟動 warm-up
- services/learning_service.py: _persist_trust() + 2 call sites
- main.py: 啟動時 load_all() → bulk_load()
流程: 批准 5 次 → score=5 寫入 DB → Pod 重啟 → warm-up 讀回
→ evaluate_adjusted_risk MEDIUM→LOW → 自動執行
2026-04-17 ogt + Claude Sonnet 4.6(亞太): ADR-088
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 16:14:44 +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
93205ceab0
fix(auto_approve+solver): P1 kubectl gate + P2 Nemo path kubectl 強制
...
CD Pipeline / build-and-deploy (push) Successful in 9m56s
P1 安全漏洞 (auto_approve.py):
- 新增條件 1d:action 必須含 kubectl 關鍵字才可自動執行
- Solver 經 OpenClaw Nemo 路徑輸出自然語言 → 條件 1c 通過但無法執行
- 修復:自然語言 action → 降級人工審核(NO_PLAYBOOK reason)
P2 執行障礙 (solver_agent.py):
- Nemo 格式路徑:action_title 不含 kubectl → return [] → 觸發 _degraded_plan
- _default_action_for_category:舊自然語言 → 真實 kubectl 調查指令
- 降級路徑現在輸出 kubectl get/top/exec 等唯讀指令,可被 auto_approve 1d 正確評估
ADR-082: Phase 2 多 Agent 協作
2026-04-17 ogt + Claude Sonnet 4.6(亞太): P1+P2 hotfix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 14:49:53 +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
58d9c0637a
fix(drift): drift_narrator 改用 OpenClaw AI Router — 修復「研判原因」空白
...
根因:drift_narrator_service.py 的 _generate_narrative() 直接呼叫
Ollama httpx (192.168.0.111:11434),繞過 AI Router,無 fallback。
192.168.0.111 為死亡 IP → httpx 連線失敗 → 降級 fallback_narrative()
→ fallback 中 interpretation.explanation 存在但顯示層截斷 → 空白
修復:改用 get_openclaw().call(prompt),統一走 AI Router
同 drift_interpreter.py 的修法(d952435)
移除 unused httpx import
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
e0bfcc7bd6
fix(phase5): 修復 Solver action 格式 — 強制輸出 kubectl 命令
...
CD Pipeline / build-and-deploy (push) Failing after 9m33s
根因:_build_prompt() 的 action 範例為 "restart_service:awoooi-api"(自訂格式),
LLM 模仿此格式輸出自然語言描述而非 kubectl 命令。
影響鏈:
Solver action = 自然語言描述
→ auto_approve Condition 1c 拒絕(無 kubectl 關鍵字)
→ _auto_execute() 永不被調用
→ blast_radius_calculator 永不被調用
→ blast_radius_score fill rate = 0/14 = 0%(Phase 5 驗收指標未達)
修復:
1. blast_radius 參考從抽象描述改為實際 kubectl 命令示例
2. 明確要求 action 欄位必須是真實 kubectl 命令(不可用自然語言)
3. 正確範例:kubectl rollout restart deployment/awoooi-api -n awoooi-prod
預期效果:LLM 輸出 kubectl 命令 → auto_approve 通過(低 blast_radius 情境)
→ blast_radius_calculator 被調用 → fill rate 趨向 100%
2026-04-17 ogt + Claude Sonnet 4.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 12:44:36 +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
d952435b60
fix(drift): 改用 OpenClaw AI Router 取代 Ollama httpx 直連
...
CD Pipeline / build-and-deploy (push) Successful in 32m34s
根因:_call_nemotron() 直接呼叫 Ollama httpx(settings.OLLAMA_URL)
繞過 AI Router,無 fallback → "All connection attempts failed"
→ Telegram 卡顯示「意圖分析失敗:All connection attempts failed」
修復:改走 get_openclaw().call(prompt)
自動享有 Provider 降級與 fallback 機制(與其他 Agent 一致)
廢棄:BUG-001 httpx 直連繞過法(nvidia_provider 介面已穩定)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-17 10:27:39 +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
0077ff9758
fix(solver): 傳遞 hypothesis 作為 alert_context 給 OPENCLAW_NEMO
...
CD Pipeline / build-and-deploy (push) Has been cancelled
根因:solver 呼叫 openclaw.call(prompt) 不傳 context
→ nemo fallback 把 prompt[:500](系統說明「軍師 Agent」)
當 signal description → LLM 回傳垃圾方案描述
修復:把 top.description 放進 alert_context.signals
讓 nemo 看到真實根因假設(與 diagnostician 同模式 7eb8375)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-16 22:51:30 +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
7eb837567d
fix(diagnostician): 修復 'AI 深度診斷' 垃圾根因顯示
...
CD Pipeline / build-and-deploy (push) Has been cancelled
根因三層鏈:
1. openclaw.call(prompt) 不傳 context
2. OPENCLAW_NEMO fallback 把 prompt[:500](系統說明文字)當 signal description
3. Nemo LLM 回傳 action_title="調查 AWOOOI SRE 系統的偵探 Agent"(任務描述)
4. _extract_hypotheses() 用 action_title 作為根因假設描述 → Telegram 顯示垃圾
修復:
- openclaw.call() 新增 alert_context 可選參數,透傳給 _call_with_fallback
- diagnostician._analyze() 建立 alert_context(incident_id + evidence_summary as signal)
→ nemo 使用結構化 API 收到真實感應器資料而非系統說明文字
- _extract_hypotheses() nemo 格式轉換:優先用 reasoning(為什麼)作為假設描述
而非 action_title(做什麼)— reasoning 更接近根因分析
2026-04-16 ogt + Claude Sonnet 4.6 (台北時區)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-16 22:34:48 +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
02a276127e
fix(sensors+drift+repair-card): 全景修復三個節點問題
...
CD Pipeline / build-and-deploy (push) Successful in 1h1m39s
Fix 1: sensors 7/8 失敗 — SSH host 短名展開 (pre_decision_investigator.py)
根因: Prometheus instance label 為 "110:9100",split(":")[0]="110"
SSH_MCP_ALLOWED_HOSTS 存完整 IP "192.168.0.110" → 7 個 SSH 工具全部失敗
修復: 加入 _SHORT_HOST_MAP,"110"→"192.168.0.110",四台主機全覆蓋
Fix 2: Config Drift 誤報 — K8s 預設欄位加入白名單 (drift_detector.py)
根因: kubectl rollout restart 後 restartedAt annotation 被偵測為 "medium" drift
restartPolicy/dnsPolicy/terminationGracePeriodSeconds 等 K8s 自動填入欄位未白名單
修復: _DEFAULT_ALLOWLIST_FIELDS 加入 13 個 K8s 執行時自動填入欄位
Fix 3: 修復請求卡內容垃圾 — fallback 帶入真實 error context (failure_watcher.py)
根因: LLM 分析失敗時 root_cause = "規則引擎分類: K8S_ERROR"(無任何有用資訊)
修復: fallback 改為 "[K8S_ERROR] {operation_type} 在 {target_resource} 失敗\n錯誤:{error_message[:200]}"
2026-04-16 ogt + Claude Sonnet 4.6(亞太)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-16 20:50:06 +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
a258d87767
fix(webhooks+prompts): 修復 LLM 對所有告警一律輸出「重啟 AWOOOI 服務」的根本問題
...
CD Pipeline / build-and-deploy (push) Has been cancelled
根因 (INC-20260416-C365D0 postgres 磁碟告警事故):
1. alert_context 中 alertname 埋在 labels 深處,LLM 看到 alert_type="custom" → 不知道是什麼告警
2. 快取鍵用 alert_type:target_resource → 不同 alertname 共用同一快取 → 全部回傳第一個 LLM 結果
3. 系統 Prompt 無 alert-category 指導 → LLM 永遠輸出 kubectl rollout restart
修復:
- webhooks.py: alert_context 置頂加入 alertname + alert_category + annotations
- openclaw.py: 快取鍵改用 alertname:target_resource(告警名稱才是主要識別符)
- prompts.py: OPENCLAW_SYSTEM_PROMPT + NEMOTRON_SYSTEM_PROMPT 加入 Alert-Specific Analysis Rules
database/storage 告警 → NO_ACTION + 調查指令;K8s 告警 → 對應重啟指令
禁止對非 K8s 告警輸出 kubectl rollout restart deployment/awoooi-prod
2026-04-16 ogt + Claude Sonnet 4.6(亞太)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-16 19:56:13 +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