All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 9m32s
## Hermes NL 補強(nl_gateway.py)
- T1 hermes_dispatch_log DB 寫入(asyncio.create_task 非阻擋)
- T2 Redis 速率限制:per-chat_id 20 req/min,fail-open
- T3 Multi-turn session:hermes:session:{chat_id}:{user_id} TTL=300s,最近 3 輪
## ConsensusEngine(ADR-095 宣告式設計)
- consensus_engine.py: CONSENSUS_WEIGHTS class 屬性
security=0.4 鎖定,9 個 Claude Code agent 分配 0.6
- config.py: ENABLE_12AGENT_CONSENSUS=False feature flag
## ADR 狀態
- ADR-093/094/095: Proposed → 🟡 批准實作中
- 各 ADR 加 v1.1 變更紀錄
## K8s ConfigMap
- prod 04-configmap.yaml: 加 3 個 feature flags(均 false)
- dev 02-configmap.yaml: 同步加入
## LOGBOOK
- 記錄 WS0–WS6 + 補強完成,feature flags 啟用指引
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
78 lines
4.1 KiB
Markdown
78 lines
4.1 KiB
Markdown
# 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 告警雙軌路由設計(`telegram_gateway.py:1667 vs 4570`):
|
||
- 所有告警類(TYPE-3/4/4D/8M)預設發私人 DM `OPENCLAW_TG_CHAT_ID=5619078117`
|
||
- 僅心跳報告、週月報、AI 三頭分析發群組 `SRE_GROUP_CHAT_ID=-1003711974679`
|
||
- `_interactive_types` 黑名單(ADR-075 斷點 C)把互動式告警擋在群組外,**原因是 callback 按鈕 nonce 只綁 approval_id 不綁 user_id,進群組 = 任何成員都能簽核**
|
||
|
||
使用者需求:把**所有**告警(含需人工簽核的 TYPE-3/4/4D/8M)遷到 AwoooI SRE 戰情室群組(4 名成員),以便團隊共同監察。
|
||
|
||
## 決策
|
||
|
||
採取**混合策略(allowlist 模式)**:
|
||
|
||
1. **TYPE-1/TYPE-2/TYPE-6B**(純資訊、自動修復完成、業務告警)→ 群組
|
||
2. **TYPE-3/TYPE-4/TYPE-4D/TYPE-8M**(互動式)→ **群組**,但 callback_data 必須包含 `user_id` binding + Approvers 白名單
|
||
3. **TYPE-5S/TYPE-7E**(資安、重大事故)→ 暫留 DM,v2 再討論
|
||
|
||
詳細觸發條件由 `apps/api/src/services/notification_matrix.py` 單一矩陣維護,**取代 telegram_gateway.py 內 24 處硬編 chat_id**。
|
||
|
||
## 理由
|
||
|
||
### 為什麼是群組(而非純 DM)
|
||
- SRE 戰情室 4 名成員需**即時共同監察**,避免單一收件人漏讀
|
||
- 系統日報已在群組,告警分散到 DM 造成資訊割裂
|
||
- 符合 SRE best practice(PagerDuty / 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 白名單 |
|