Files
awoooi/docs/adr/ADR-075-telegram-notification-standard.md
Your Name 7795f027d2
Some checks failed
CD Pipeline / tests (push) Successful in 2m56s
Code Review / ai-code-review (push) Failing after 39s
CD Pipeline / build-and-deploy (push) Successful in 12m54s
CD Pipeline / post-deploy-checks (push) Successful in 4m40s
fix(aiops): persist emergency intervention traces
2026-05-01 20:34:33 +08:00

170 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-075Telegram 告警通知格式標準化與完整流程修復
> **狀態**: 🟡 批准實作中
> **建立日期**: 2026-04-12台北時間
> **決策者**: 統帥 ogt + Claude Sonnet 4.6
> **相關 ADR**: ADR-071四種通知類型、ADR-073飛輪修復、ADR-074監控補全
---
## 背景
ADR-0712026-04-11設計了 TYPE-1/2/3/4/4D 五種通知類型,並實作了 `classify_alert_early()``_build_inline_keyboard()` 等函數。但在 2026-04-12 的全面盤點中,發現整條資料流存在 **4 個斷點**,導致動態分類按鈕從未真正生效,所有 TYPE-3 告警一律 fallback 到通用的 [批准][拒絕][靜默] 三鍵。
同時,在與 Gemini 的架構討論中,確認了 8 種通知類型矩陣TYPE-1 到 TYPE-8M以及雙頻道發送策略。
---
## 問題診斷4 個斷點
```
斷點 Adecision_manager._push_decision_to_telegram()
呼叫 send_approval_card() 時沒有傳入 alert_category
斷點 Btelegram_gateway.send_approval_card()
呼叫 _build_inline_keyboard() 時沒有傳入 alert_category/notification_type
斷點 Ctelegram_gateway._send_approval_card_to_group()
含 Callback Button 的 TYPE-3 卡片也發到 SRE 群組 → nonce 洩漏安全漏洞
斷點 Dclassify_alert_early() 輸出 "kubernetes"
但 _build_inline_keyboard 期待 "k8s_workload" → 永遠不命中
另有 10 個告警分類錯誤host_resource/devops_tool/ssl_cert 等全落入 general
```
---
## 決策
### D1統一 Category 命名
- `k8s_workload` → 改為 `kubernetes`(語義更廣,涵蓋 Node/Service/Ingress
- `Host*` 告警從 `infrastructure` 分離為 `host_resource`
- `Docker*` 告警保留 `infrastructure`
### D2新增 7 個 Category
| Category | 告警 | 說明 |
|---------|------|------|
| `alertchain_health` | AlertChainBroken_* / NoAlertsReceived2Hours / AlertChainUnhealthy | meta-monitoring優先度最高 |
| `flywheel_health` | AutoRepairLowSuccessRate / PermanentFixRequired / Flywheel* | 飛輪自身健康 |
| `storage` | MinIODown | 物件儲存 |
| `devops_tool` | GiteaDown / HarborDown / SignOzDown / OpenClawDown / SentryDown / AlertmanagerDown | DevOps 工具鏈 |
| `external_site` | MoWoooWorkDown / TsenyangWebsiteDown / StockWoooWorkDown / BitanWoooWorkDown | 外部業務網站 |
| `ssl_cert` | ExternalSiteSSL* / TLSCert* | SSL 憑證 |
| `security_tool` | KaliScannerDown | 資安掃描工具 |
### D38 種通知類型矩陣(完整版)
| 類型 | 適用場景 | 按鈕 | 發送目標 |
|-----|---------|------|---------|
| TYPE-1 | 純資訊、備份成功、心跳 | 無 | SRE 群組 |
| TYPE-2 | AI 自動修復完成 | 無(結果通知)| SRE 群組 |
| TYPE-3 | 需人工審核(預設)| 依 category 動態 ≤4 個 | SRE 群組 |
| TYPE-4 | AI 無法判斷 | [手動記錄][查面板][忽略] | SRE 群組 |
| TYPE-4D | Config Drift | [查Diff][採納][回滾][忽略] | SRE 群組 |
| TYPE-5S | 資安防禦 | [隔離][封鎖IP][驅逐Pod][確認授權];危險動作先記授權/多簽 | SRE 群組 |
| TYPE-6B | 業務/FinOps未來| [暫停][查SignOz][忽略] | SRE 群組 |
| TYPE-7E | 重大事故升級 / auto-repair unavailable | 無 ghost callback人工/AI 接手先靠卡片與 timeline/AOL 留痕,按鈕需有 dispatcher 後才可開 | SRE 群組 |
| TYPE-8M | 飛輪/告警鏈路健康 | [觸發診斷][查看面板][靜默] | SRE 群組 |
### D4雙頻道路由規則
```
2026-04-30 起,正式告警收件通道統一為 AwoooI SRE 戰情室群組
SRE_GROUP_CHAT_ID=-1003711974679
OPENCLAW_TG_CHAT_ID 僅作 SRE_GROUP_CHAT_ID 缺失時的 fail-soft fallback。
```
### D5Telegram 卡片格式防腐規則
```python
# telegram_gateway.py 頂部常數ADR-075 鎖定)
NOTIFICATION_TYPE_RULES = {
"TYPE-1": "無按鈕,可有 URL Button嚴禁 Callback Button",
"TYPE-2": "無按鈕,可有 URL Button嚴禁 Callback Button",
"TYPE-3": "最多 4 個 Callback Button依 alert_category 動態選擇",
"TYPE-4": "固定 3 個按鈕:[手動記錄][查看面板][忽略]",
"TYPE-4D": "固定 4 個按鈕:[查看Diff][採納][回滾][忽略]",
"TYPE-5S": "固定 4 個按鈕:[隔離][封鎖IP][驅逐Pod][確認授權],危險動作只記授權/多簽",
"TYPE-6B": "最多 3 個按鈕:[暫停][查看SignOz][忽略]",
"TYPE-7E": "無 ghost callback未落地 dispatcher 前不顯示 callback button",
"TYPE-8M": "固定 3 個按鈕:[觸發診斷][飛輪面板][靜默]",
}
```
2026-05-01 補充TYPE-7E 已用於 `auto_repair_unavailable`
`drift_auto_adopt_blocked` 緊急通道。Telegram 卡片本身不是閉環;每次升級
必須寫入 `alert_operation_log``timeline_events`,讓 WarRoom、KM 與
learning loop 能反查。TYPE-5S 的 `record_authorization` 也必須寫 Redis TTL
和 AOL/timeline不得只回 Telegram toast。
---
## 實施計畫
完整計畫書:`docs/superpowers/plans/2026-04-12-adr075-telegram-alert-notification.md`
**Phase 1斷點修復同一 PR**
- Task 1-2重寫 `classify_alert_early()`(斷點 D
- Task 3`_build_inline_keyboard` 字典對齊(斷點 D
- Task 4`send_approval_card()` 接收並傳遞 `alert_category`(斷點 B
- Task 5雙頻道路由修正斷點 C
- Task 6`decision_manager` 傳入 `alert_category`(斷點 A
**Phase 2TYPE-8M 擴充)**
- Task 7-8新增 `send_meta_alert()` + decision_manager 路由
**Phase 3Prometheus 規則,獨立)**
- Task 9新增 6 個欠缺告警規則
---
## 驗收標準
| 驗收項目 | 驗收方式 |
|---------|---------|
| HostHighCpuLoad 出現 [查程序][重啟服務][清Log] | 送測試告警驗收 |
| KubePodCrashLooping 出現 [重啟][擴容][縮容][回滾] | 送測試告警驗收 |
| AlertChainBroken_* 出現 [啟動緊急診斷] | 送測試告警驗收 |
| TYPE-3 卡片不發 SRE 群組 | 確認群組無帶按鈕訊息 |
| TYPE-1 卡片只發 SRE 群組 | 確認個人 DM 無純資訊通知 |
| 全部單元測試通過 | pytest >620 passed |
---
## 範疇外(本 ADR 不包含)
- TYPE-5S SecOps 卡片(待 SecOps Prometheus 規則完備後)
- TYPE-6B Business 卡片(待 MomoScraper metrics 接入後)
- TYPE-7E Escalation Monitor Service
- FlywheelPlaybookZero 告警(依賴 ADR-074 Exporter
---
## 實作記錄2026-04-12
| Phase | Commit | 內容 |
|-------|--------|------|
| Phase 1 | 2cef209 | 4 斷點修復 + classify_alert_early 13 規則 + _CATEGORY_BUTTONS 更新 |
| Phase 2 | 561c1d8 | send_meta_alert() + decision_manager TYPE-8M elif |
| CR 修補 | 1cb654c | TYPE_8M 加入 enum + 死碼清理 + docstring 更新 |
**測試覆蓋**52 classify_alert_early tests + 664 total passed
**CR 評分**7/10首席架構師審查通過P0/P1 全修補)
**Phase 3Prometheus 規則)**:尚未實作,不阻擋 Phase 1/2 上線
---
## 更新引用2026-04-24
| ADR | 影響 | 說明 |
|-----|------|------|
| [ADR-093](ADR-093-telegram-group-migration.md) | 🔄 更新 D4 雙頻道路由 | 加「群組 Callback Button 授權模式」子條款TYPE-3/4/4D/8M 解除 `_interactive_types` 黑名單,改以 callback_data + user_id binding + Approvers 白名單保護P0-1 修)|
| [ADR-094](ADR-094-hermes-nl-interface.md) | 新增 NL 對話入口 | Hermes 透過 @mention 在群組處理自然語言對話,輸出仍遵守 ADR-075 D5 格式規則 |
| [ADR-095](ADR-095-12agent-sdk-integration.md) | 12-Agent 視覺分派 | TG 訊息加 `@hermes-*` 前綴 + emoji + hashtag 三件套,符合 ADR-086 UI 清洗後的視覺規範 |