Files
awoooi/docs/adr/ADR-093-telegram-group-migration.md
Your Name 433f7b068e
All checks were successful
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
fix(aiops): close ssh and telegram remediation gaps
2026-05-01 16:53:02 +08:00

82 lines
4.6 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-093: Telegram 告警全面遷移至 SRE 戰情室群組
> **狀態**: ✅ 已全面切換
> **日期**: 2026-04-24
> **決策者**: 統帥 + 12-Agent 全景分析團隊onboarder / debugger / db-expert / tool-expert / web-researcher / planner / critic / frontend-designer / fullstack-engineer / refactor-specialist / migration-engineer / vuln-verifier
## 背景
原 Telegram 告警雙軌路由設計:
- 所有告警類TYPE-3/4/4D/8M預設發私人 DM `OPENCLAW_TG_CHAT_ID`
- 僅心跳報告、週月報、AI 三頭分析發群組 `SRE_GROUP_CHAT_ID=-1003711974679`
- `_interactive_types` 黑名單曾把互動式告警擋在群組外
使用者需求:把**所有**告警(含需人工簽核的 TYPE-3/4/4D/8M遷到 AwoooI SRE 戰情室群組4 名成員),以便團隊共同監察。
## 決策
採取**群組優先、個人只作缺設定 fallback**
1. **所有告警卡片**TYPE-1/2/3/4/4D/5S/6B/7E/8M`SRE_GROUP_CHAT_ID`
2. **所有告警旁路通知**自動修復結果、rollback 提案、provider failover、成本、容量、規則品質、合規、coverage、Gitea/Code Review`SRE_GROUP_CHAT_ID`
3. `OPENCLAW_TG_CHAT_ID` 只保留為 `SRE_GROUP_CHAT_ID` 缺失時的 fail-soft fallback不再是正式告警收件人
正式入口由 `TelegramGateway.alert_chat_id` 維護;直接呼叫 Bot API 的告警旁路必須使用 `settings.SRE_GROUP_CHAT_ID or settings.OPENCLAW_TG_CHAT_ID`
所有告警生命週期操作都屬於群組遷移範圍initial send、analyzing placeholder、deleteMessage、editMessageText、editMessageReplyMarkup、CI progress、action-result update。只把新卡片送進 SRE 群組,但後續 edit/delete 還打 `self.chat_id` / 個人 DM會造成 ghost button 與狀態分裂,視為遷移未完成。
## 理由
### 為什麼是群組(而非純 DM
- SRE 戰情室 4 名成員需**即時共同監察**,避免單一收件人漏讀
- 系統日報已在群組,告警分散到 DM 造成資訊割裂
- 符合 SRE best practicePagerDuty / Opsgenie 都是群組導向)
### 為什麼需要新 nonce 模型P0-1 修)
- 現有 callback_data 格式 `approve:{approval_id}:{timestamp}:{random}` 不含 user_id 簽章
- 進群組 = CSRF 簽核漏洞:任何 member 可按批准按鈕
- **新格式** `apr:{short_id}:{action}:{user_id_hash}` + Redis `cb:{short_id}` 後端映射
- Handler 強制 `callback_query.from.id == bound_user_id`,違反 → 回 `answer_callback_query(text="⛔ 你未被指派")`
### 為什麼要 Approvers Allowlist
- Telegram group admin 可在未通知下新增成員
- `chat_member` webhook 事件同步維護 Approvers 白名單
- 按鈕先顯示給所有人,**按下後檢查** `from.id ∈ APPROVERS_WHITELIST`
## 後果
### 優點
- SRE 團隊共同可見所有告警,降低漏讀率
- 清理 24 處硬編 chat_id 技術債
- 統一路由矩陣便於未來擴充
### 缺點
- 遷移期間 pending ApprovalRecord 卡片需重發48h editMessage 限制,見 ADR-094 §F1
- 需新建 Approvers 白名單 + `chat_member` 同步機制
- 破壞 ADR-075 斷點 C 的「DM only」假設 → 修訂 ADR-075 D4
### 風險
- **CSRF 簽核**:若 user_id binding 實作有缺陷,非授權者可簽核 → 必須有 Round 3 vuln-verifier 的 PoC 測試把關
- **Telegram group 20 msg/min rate limit**12 agent 回覆 + 告警齊發可能觸 429 → 必須走 `TelegramRouter` token bucket
- **群組成員動態變動**admin 隨時可拉人進群 → `chat_member` webhook 必須即時同步 Approvers
## Rollback
Feature flag `TG_GROUP_CUTOVER ∈ {off, 10%, 50%, 100%}`,以 `alert.labels.env` hash 分桶切流。失敗回 `off` 恢復 DM 模式。
## 參考
- 上位:[ADR-075](ADR-075-telegram-notification-standard.md)(需修訂 D4 加 allowlist 子條款)
- 平行:[ADR-094](ADR-094-hermes-nl-interface.md) / [ADR-095](ADR-095-12agent-sdk-integration.md)
- Memory: `feedback_no_ghost_buttons.md` / `feedback_telegram_alert_format.md`
- 實施Round 3 planner 的 WS0-WS5`/Users/ogt/awoooi/docs/design/hermes-telegram-flows/hermes-flows.html`
## 變更紀錄
| 版本 | 日期 | 執行者 | 變更內容 |
|------|------|--------|---------|
| v1.0 | 2026-04-24 | 12-Agent 全景分析 | 初版 Proposed |
| v1.1 | 2026-04-25 | Claude Sonnet 4.6 | WS2-WS5 實作完成NotificationMatrix + BIGINT + approval_records prod 建立 + Approvers 白名單 |
| v2.0 | 2026-04-30 | Codex | 告警訊息全面切到 AwoooI SRE 戰情室群組;個人 DM 僅保留缺群組設定 fallback |
| v2.1 | 2026-05-01 | Codex | 補齊 placeholder/delete/edit/CI progress/action update 的 `alert_chat_id` 路由,封住 group card + DM edit 的 ghost-button 路徑 |