Files
SenMeshNet/docs/plan-management-and-alert-remediation.md
zhaolei 1bb5390263
Some checks failed
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
docs: add system overview and plan-management-and-alert-remediation v1.3 design doc
- system-overview.md: full platform summary for NetMesh v2.x

- plan-management-and-alert-remediation.md: dual-track alert response design with 26 decisions

- alertRecordStore.cjs: remove auto_recover per D25 (alerts must be manually closed)
2026-10-30 16:35:50 +08:00

996 lines
61 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
# NetMesh 预案管理与告警联动 —— 设计方案 v1.3
> 版本:v1.3 · 日期:2026-10-30 · 状态:评审中
> v1.3 变更:补全 AI 初始响应包性能保护、AlertStateMonitor 升级执行载体、处置引擎 ↔ AI Agent 集成通路、auto_close 语义修正、human_action ↔ remediation 映射约束、plan_snapshot 冻结时机、notification_chain.auto 一期范围、AI 预案 Review Workflow、裁决表新增 D21-D26
> v1.2 变更:引入值班员动作预案层级,与操作级预案双轨绑定;新增处置步骤执行权限分级;新增 AI 初始响应包自动推送
---
## 〇、裁决表(Decision Table)
多轮讨论后固化所有争议点,正文所有章节强制对齐此表。
| # | 争议点 | 最终结论 | 理由 |
|---|--------|----------|------|
| D1 | 预案与现有 `alertRuleStore` 的关系 | **预案增强规则**,不取代 | alertRuleStore 负责「指标异常检测 → 产出原始告警」,预案在后面做二次匹配 + 处置编排,渐进式接入 |
| D2 | 聚合升级触发方式 | **实时触发**(每来一条新告警就检查窗口内计数) | 巡检调度器周期执行,多台故障告警扎堆进来,实时触发比窗口到期触发延迟更小;窗口状态直接复用 alertRecordStore 活跃告警列表 |
| D3 | 匹配优先级 | **同 level 下 scope 最精确者胜出**,level 从高到低过滤 | 正常配置下每个 device_type × level 只应有一份预案,多命中是配置错误 |
| D4 | 白名单方式 | **预置命令 ID(方式 C)为主** + 临时处置用前缀匹配(方式 A)+ confirm | 预置 ID 最安全,运维选而不是写;临时输入走严格校验 + 确认 |
| D5 | 处置会话来源 | 复用现有 AI Agent capabilityTools 的 SSH/terminal 通路(通过 aiBridge 调用 Catty Agent session) | 凭据、审计、权限全部统一,不另开 SSH |
| D6 | 聚合窗口维度 | 初始版本开放 `catalog_type` + `tier` 两个维度 | 覆盖 80% 场景,太多维度会把配置搞复杂 |
| D7 | 模板 vs 预案的边界 | 模板**不含**匹配条件、值班员动作预案、处置步骤,只含公共联动配置 | 避免路由器/服务器处置步骤串台 |
| D8 | 处置失败回滚 | 初始版本**不做自动回滚**,步骤级配置 `on_failure` 动作(retry/stop/escalate) | 回滚逻辑和设备类型强相关,路由器命令的回滚和服务器完全不同,一期不做 |
| D9 | 预案版本化 | **匹配到预案的那一刻就冻结 snapshot**(写入 alertRecord.matched_plan_snapshot) | 处置开始后才冻结有窗口期漏洞——initial_response 用旧预案但 remediation 用新预案导致信息不一致;匹配时刻冻结保证整条链路一致 |
| D10 | 并发处置 | 聚合升级告警的多设备处置**串行执行**,不做并发 | 串行安全性高,且 AI Agent 已有 sessionExecutionQueue 做执行排队;并发留到后续 |
| D11 | 安全类告警分类 | 新增 alert_type 分类,安全类(firewall_intrusion 等)优先级独立于 performance/connectivity | 在聚合升级和匹配中权重更高 |
| D12 | 一期通知通道 | **监控大屏弹窗增强 + webhook**。dingtalk/wechat/email 外置推送后置(P5) | 现有值班员通过监控大屏弹窗感知告警,一期在现有弹窗内嵌入 AI 初始响应包,值班员弹窗一开即能看到完整响应信息 |
| D13 | 预案配置入口 | **AI 描述生成 + 表单手动 共存**,不是替代 | 新手用 AI 快速生成草稿,高级运维用表单精确控制;AI 生成的预案必须走人工审核节点才能启用 |
| D14 | AI 生成的安全边界 | **三重防线**:schema 验证 → 白名单交叉校验 → 人工审核 | AI 可能编造 command_id 或输出高危命令,必须机器校验 + 人工确认双保险 |
| D15 | AI Prompt 上下文 | **显式注入 command_catalog + catalog_type 字典 + 模板变量 Reference**,让 AI 查表而不是瞎猜 | 避免 AI 乱编 device_type、command_id、template variable;AI 只做"翻译"不做"发明" |
| D16 | 预案双轨绑定 | **同一个 device_plan 同时包含「值班员动作预案」和「操作级预案」**(称为"双轨"),匹配条件 + scope 是**匹配元数据**(不属于预案轨) | 操作步骤必须嵌入在人员动作链里(先通知 → 再处置 → 后确认),分开会断裂 |
| D17 | 处置步骤执行权限 | **三级执行权限:auto / confirm / manual_only** | show 类命令 AI 自动跑;重启/改配置需值班员确认;console 密码重置等禁止 AI 碰只能人工执行 |
| D18 | AI 初始响应包 | **告警触发后 AI 自动生成初始响应包,直接嵌入监控大屏弹窗**(不用等运维手动询问) | 弹窗内显示完整设备画像 + 告警详情 + 快速 checklist + 匹配预案摘要,值班员可以一键复制/转发运维群 |
| D19 | 值班员响应优先级 | **值班员动作预案的通知/确认/升级动作优先级高于 AI 自动处置** | AI 自动处置只能执行 `auto` 权限的步骤;`confirm` 和 `manual_only` 必须等值班员触发,值班员可以随时暂停 AI 自动处置 |
| D20 | 大屏弹窗增强策略 | **在现有告警弹窗(useMonitoringData → MonitoringTopologyView 里的 alert 展示位)基础上追加 AI 响应包面板**,不替换原有告警详情区 | 值班员已有大屏使用习惯,弹窗内新增"AI 响应包 Tab 或折叠面板"即可,降低学习成本 |
| D21 | 多告警关联 | **一期不支持同设备多条不同 rule 告警合成**,每条 alertRecord 独立匹配预案;P6 再做 | alertRecordStore 去重粒度是 device_id + rule_id,同设备不同 rule 产生 N 条独立告警;一期合成逻辑和处置步骤编排复杂度太高 |
| D22 | AI 初始响应包性能保护 | **三层保护**:① 去抖(同告警 5min 只生成一次)② 限流(最多 3 并发,PromiseQueue 排队)③ 超时降级(15s 硬超时,AI 不可用时用 human_action_guide 直接组装) | 巡检周期跑完可能一批告警同时触发 → N 次 AI 调用排队超时;降级保证即使 AI 不可用也有响应包 |
| D23 | 升级兜底执行载体 | **新增 AlertStateMonitor 模块**(每 5min 定时扫活跃告警),执行 escalation_fallback.auto_escalate_minutes 超时检查 + remediation 超时暂停 | 现有 alertAggregationEngine 是"事件驱动"(来一条新告警检查一次),不会主动扫存量告警的超时情况 |
| D24 | 处置引擎 ↔ AI Agent 集成 | **remediationEngine 通过 aiBridge 发工具调用请求**,让 Catty Agent 在它自己的 session 上下文里执行 | 凭据、审计、权限全部走 Catty Agent 现有链路;remediationEngine 不直接 import capabilityTools |
| D25 | auto_close 语义 | **字段改名为 auto_close_after_remediation_recovery**;只有 remediation.status === "completed" 时才检查指标恢复 → 自动关告警 | 之前模板里的 auto_close_on_recovery 和 processAlert 里 auto_recover 语义混淆,容易导致告警未处置就被指标恢复自动关掉 |
| D26 | notification_chain.auto 一期处理 | **webhook / desktop → 一期实现**;dingtalk/wechat → 标注 "pending_external" 需外置通知网关;phone → 标注 "manual_only" 显示电话号码让值班员自己拨 | 预案里写 auto: true 但一期不实现的通道,必须明确告知值班员哪些会自动发、哪些需要手动 |
---
## 一、两类预案体系
### 1.1 双轨绑定概念
**一个 device_plan 里包含匹配元数据 + 两个预案轨**,共同构成完整的告警响应闭环:
```
device_plan
├── 匹配元数据(不属于预案轨)
│ ├── match 匹配条件(metric_rules / alert_types / device_tiers / device_tags)
│ └── scope 适用范围(host_ids / host_groups)
│
├── human_action_guide ← 第一轨:值班员动作预案(人看的,指导怎么响应)
│ ├── receiving_alerts "收到告警第一时间做什么"
│ ├── info_gathering "先收集哪些信息"
│ ├── notification_chain "通知谁、怎么通知"
│ ├── escalation_triggers "什么情况必须升级/上报"
│ ├── pre_remediation "处置前必须做的防护动作"
│ └── post_remediation "处置完要做什么确认/回传/归档"
│
└── remediation ← 第二轨:操作级预案(机器执行的命令步骤)
└── steps[] 每个 step 带 execution: "auto" | "confirm" | "manual_only"
```
**两者的关系**:值班员动作预案是骨架/流程,操作级预案是骨架里嵌入的可自动执行的工具。
### 1.2 human_action ↔ remediation 映射约束
两者都描述"怎么处理",必须保持映射一致性。匹配器匹配成功后、处置引擎开始前做一次完整性检查:
```
human_action_guide ↔ remediation 映射规则:
├── info_gathering 条目 → auto / confirm step(按 priority 排序)
│ 例: info_gathering { priority: 1, action: "SSH display cpu-usage" }
│ → remediation.steps[0] = { command_id: "...", execution: "auto" }
│
├── pre_remediation 条目 → confirm 或 manual_only step
│ (备份 running-config → confirm;创建变更单 → manual_only)
│
├── escalation_triggers → 不映射 step
│ (由 AlertStateMonitor 定时检查,不进处置引擎)
│
└── post_remediation 条目 → manual_only step
(值班员手动勾完成,不自动调用 AI)
完整性检查:
- human_action_guide 里每个 info_gathering 条目必须有对应的 remediation step
- 缺失 → 在 initial_response.warnings 里标注,不阻断告警
- 值班员可以在处置工作台手动补全缺失 step
```
### 1.3 典型场景对照
**场景:核心交换机 CPU 持续 > 90% 5 分钟**
```
┌──────────────────────────────────────────────────────────────────────┐
│ 值班员动作预案(human_action_guide) │
│ │
│ 1. 收到告警 → 打开拓扑图确认设备位置(核心机房 A 架 12 位) │
│ 2. 用 console/SSH 登录,先观察 30 秒看是否自然恢复 │
│ 3. 如果持续不降 → 通知网络组 oncall(王工 138xxxx,钉钉已自动发) │
│ 4. 30 分钟未恢复 → 升级到三级预案,通知运维经理 + 值班经理 │
│ 5. 处置前:拍一张 show running-config 快照,写入变更单 │
│ 6. 处置后:show cpu-usage 确认恢复 → 回传截图到运维群 → 关闭告警 │
└──────────────────────────────────────────────────────────────────────┘
│ 第 3 步值班员看了一眼 CPU 确实 > 90% 持续不降
│ 点击"开始处置"按钮触发
▼
┌──────────────────────────────────────────────────────────────────────┐
│ 操作级预案(remediation) │
│ │
│ Step 1 [auto] show processes cpu │
│ → AI 自动执行,输出 CPU 使用率明细 │
│ → 值班员看输出判断是哪个进程 │
│ │
│ Step 2 [confirm] display diagnostic-information save │
│ → AI 执行前弹确认框,值班员点确认后执行 │
│ → 采集诊断信息上传告警归档 │
│ │
│ Step 3 [confirm] cpu-usage threshold 90 log │
│ → 调 CPU 告警阈值到 90% 避免重复告警(策略性调整) │
│ │
│ Step 4 [manual_only] 联系应用组停止异常进程 │
│ → 这条不产生命令,只是值班员的任务项 │
│ → 必须值班员手动完成后勾选"已完成" │
└──────────────────────────────────────────────────────────────────────┘
```
### 1.4 两类预案的职责边界
| 维度 | 值班员动作预案 | 操作级预案 |
|------|---------------|-----------|
| 执行主体 | 值班员(人) | AI Agent / 运维手动 |
| 核心内容 | 判断、通知、确认、升级、防护、归档 | 命令、脚本、SFTP、配置变更 |
| 载体 | checklist + 说明文字 + 联系人信息 | command_id / command_template + 参数 |
| 权限 | 流程级(什么时候该做什么人) | 操作级(哪些命令可以跑、谁来触发) |
| AI 能不能自动生成 | ✅ 可以,从自然语言描述翻译 | ✅ 可以,从 command_catalog 查表匹配 |
| AI 能不能自动执行 | ❌ 不行,必须值班员参与 | ✅ 看 execution 权限 |
---
## 二、模块职责与边界
```
┌──────────────────────────────────────────────────────────────────────────┐
│ 现有链路(保留不动) │
│ │
│ inspectionScheduler ──► alertRuleStore ──► alertRecordStore │
│ (定时巡检) (指标异常检测) (写入原始告警: active) │
└────────────────────────────────┬─────────────────────────────────────────┘
│ 每条新告警
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ 新模块(独立于现有链路) │
│ │
│ ┌──────────────────────────────────┐ │
│ │ 2.1 预案匹配器 │ │
│ │ alertPlanMatcher │ │
│ │ · 查 deviceStore 拿到设备画像 │ │
│ │ · 遍历设备预案做匹配 │ │
│ │ · 匹配时刻冻结 plan_snapshot │ ← D9: 匹配时刻冻结,不是处置开始时 │
│ │ · 合并模板 + 预案双轨配置 │ │
│ │ · 写 matched_plan_snapshot │ │
│ └───────────────┬──────────────────┘ │
│ │ │
│ ┌─────────┴──────────┐ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────────┐ │
│ │ 2.2 聚合升级引擎 │ │ 2.3 初始响应包生成器 │ │
│ │ alertAggregation │ │ initialResponseGen │ │
│ │ Engine │ │ │ │
│ │ · 实时检查窗口计数│ │ · 去抖 + 限流 + 超时 │ ← D22: 三层性能保护 │
│ │ · 产出升级告警 │ │ · 匹配 AI 不可用降级 │ │
│ └────────┬────────┘ └──────────┬──────────┘ │
│ │ │ │
│ ┌────────┴───────────────────────┴──────────┐ │
│ │ 2.4 处置执行引擎 │ │
│ │ remediationEngine │ │
│ │ · 按 execution 权限分级执行 │ │
│ │ · 通过 aiBridge 调 Catty Agent session │ ← D24: 不直接 import │
│ │ · 白名单校验 + 结果校验 │ │
│ │ · 审计日志 │ │
│ └─────────────────────────────┬──────────────┘ │
│ │ │
│ ┌─────────────────────────────┴──────────────┐ │
│ │ 2.5 AlertStateMonitor (定时扫描) │ ← D23: 新增执行载体 │
│ │ · 每 5min 扫活跃告警超时情况 │ │
│ │ · 处理 escalation_fallback.auto_escalate │ │
│ │ · 处置超时暂停 │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ 2.6 通知分发 notificationDispatcher │ │
│ │ · 监控大屏弹窗 AI 响应包面板(D20) │ │
│ │ · webhook │ │
│ │ · notification_chain.auto 分级处理(D26) │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ 2.7 AI 预案生成器 planGenerator │ │
│ │ · 双轨草稿生成 │ │
│ │ · 三重校验 │ │
│ │ · Review Workflow(D13/D26-补充) │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
```
### 各模块职责
**预案匹配器**(`alertPlanMatcher`)
- 触发时机:alertRecordStore 写入新告警后立即调用
- 核心输出:匹配到的模板 + devicePlan + **matched_plan_snapshot**(匹配时刻就冻结 JSON clone,保证整条链路一致,不被后续配置变更影响)
- 跳过 `status: "draft"` 的预案(AI 生成待审核的不参与自动匹配)
- 匹配后做 human_action ↔ remediation 完整性检查
**初始响应包生成器**(`initialResponseGenerator`)
- 触发时机:预案匹配成功后立即调用
- **三层性能保护(D22)**:
- 去抖:同一条告警 5 分钟内只生成一次(alertRecord.id 作为 key)
- 限流:全局最多 3 个并发 AI 调用,超出的进入 PromiseQueue 排队
- 超时:15s 硬超时(`AbortController`),超时后 `initial_response.status = "partial"` 只填模板固定字段
- 降级:AI provider 未配置或完全不可用时,跳过 AI 调用,直接用 `devicePlan.human_action_guide` + deviceStore 设备画像 + alertRecord 基础字段组装 initial_response(不走 AI 也能产出基本响应包)
- 写入 alertRecord.initial_response → 监控大屏弹窗自动渲染
**聚合升级引擎**(`alertAggregationEngine`)
- 输入:每条从 alertRecordStore 新写入的 active 告警
- 维护:窗口内活跃告警列表(直接读 alertRecordStore active 状态,不需要额外内存结构)
- 聚合规则按 `catalog_type` / `tier` 分组计数
- 命中规则时产出升级告警(新 alertRecord,`escalation` 字段标记来源)
**处置执行引擎**(`remediationEngine`)
- **AI Agent 集成通路(D24)**:不直接 import harness 的 capabilityTools,而是通过 aiBridge 发一个"执行一次工具调用"的请求,让 Catty Agent 在它自己的 session 上下文里执行。好处:凭据管理、审计日志、权限控制全部走 Catty Agent 现有链路
- 按 `step.execution` 分级执行:
- `auto` → AI 自动执行(不需要值班员触发)
- `confirm` → 执行前弹确认框,值班员点"允许"后执行
- `manual_only` → 不调用 AI,只在工作台展示 checklist 卡片,值班员手动完成后点"标记完成"
- 值班员可以**随时暂停** AI 自动处置(所有 auto 步骤停止排队,已在跑的 step 执行完当前命令后停止)
- `auto_close_after_remediation_recovery`(D25):只有 remediation.status === "completed" 且处置后指标恢复正常时,才自动关告警。不影响未进入处置的告警
**AlertStateMonitor**(`alertStateMonitor`)—— D23 新增
- 定时任务:每 5 分钟跑一次
- 扫描 alertRecordStore 里 status=active + status=acknowledged + 已匹配预案的告警
- 检查:
- 告警挂了多久 → 超 `escalation_fallback.auto_escalate_minutes` → 调用 alertAggregationEngine.escalateAlert()
- `human_action_guide.escalation_triggers` 里的时间条件是否满足
- remediation.status === "running" 超时 → 暂停处置 + 通知值班员
- remediation.status === "completed" → 检查 `auto_close_after_remediation_recovery`
**通知分发**(`notificationDispatcher`)
- **一期主通道**:监控大屏弹窗增强
- **一期辅助通道**:webhook
- **notification_chain.auto 分级处理(D26)**:
- `channel === "webhook"` → 一期实现,推送到配置的 webhook URL
- `channel === "desktop"` → 一期实现,监控大屏弹窗
- `channel === "dingtalk" | "wechat" | "email"` → 标注 `pending_external`,在 initial_response.auto_notifications_sent 里注明"需外置通知网关"
- `channel === "phone"` → 标注 `manual_only`,在 initial_response.pending_notifications 里显示电话号码让值班员自己拨
**AI 预案生成器**(`planGenerator`)+ Review Workflow
- 同时生成 `human_action_guide` + `remediation` 两个层级的草稿
- 三重校验:schema 验证 → 白名单交叉校验 → 人工审核
- **Review Workflow**:
1. AI 生成 → devicePlan.status = "draft", source = "ai"
2. 预案列表页标记 `[草稿·待审核]`
3. 点开预案 → 表单页顶部有"审核"面板:
- `[通过并启用]` → status = "active"(同时触发 matcher.index)
- `[驳回并反馈]` → 反馈文字存 devicePlan.reject_reason → 可以让 AI 基于反馈重新生成
4. 审核权限:required_role === "admin"
5. 审核历史:devicePlan.review_log = [{ ts, actor, action, reason }]
---
## 三、数据流时序
### 3.1 完整告警响应闭环(双轨预案 + 匹配时刻冻结 snapshot + 三层性能保护)
``
inspectionScheduler ──► 巡检设备 ──► CPU 91%(华为 S6720 核心交换机)
│
▼
alertRuleStore.evaluateRule
规则 "CPU > 90% 持续 2 次" ──► 命中
│
▼
alertRecordStore.processAlert
写入 active 告警 { level: "critical", alert_type: "performance_high" }
│
▼
alertAggregationEngine(实时事件驱动)
窗口内只有 1 台核心交换机 cpu_high → 未达聚合阈值 → 跳过
│
▼
★ alertPlanMatcher(匹配时刻冻结 snapshot,D9)
查 deviceStore: device_type=switch, tier=core
匹配: plan_switch_critical_core(status !== draft)
合并模板 + 预案双轨配置
立即写入 alertRecord.matched_plan_snapshot = JSON.parse(JSON.stringify(devicePlan))
│
▼
★ 初始响应包生成器(D22 三层保护)
├── 去抖: 5 分钟内第一次 → 通过
├── 限流: 并发数 1 < 3 → 通过
├── 超时: 开始 15s 倒计时
├── 调 Catty Agent(用 initialResponse 专用 prompt)
├── 降级检查: AI provider 正常 → 继续
└── 生成成功 → initial_response.status = "complete"
│
▼
┌─────────────────────────────────────────┐
│ 📍 AI 初始响应包(完整包) │
│ │
│ 📍 设备画像 │
│ 核心交换机-01 | 华为 S6720 | 10.0.1.5 │
│ tier=core | 组=核心区 | 核心机房A架12位 │
│ │
│ 🔥 告警详情 │
│ cpu_high | level=critical │
│ 当前值 91% | 阈值 90% | 持续 300s │
│ │
│ 📋 快速 checklist(值班员先做这 3 件) │
│ 1. SSH 登录 → show processes cpu │
│ 2. 观察 30s 看是否自然恢复 │
│ 3. 持续不降 → 通知网络组 │
│ │
│ 🧭 匹配预案: 核心交换机三级预案 │
│ 30min 未恢复自动升级(AlertStateMonitor)│
│ │
│ 📞 通知链路(D26 分级): │
│ ✅ desktop + webhook → 一期实现 │
│ ⏸ dingtalk → pending_external(需网关)│
│ ✋ phone 王工 138xxxx → 手动拨打 │
│ │
└──────────────────┬──────────────────────┘
│
▼
notificationDispatcher
→ 监控大屏告警弹窗内追加 AI 响应包面板
值班员在大屏上看到完整包,一键复制转发运维群
webhook 同时推送到配置的外部网关
│
▼
值班员 SSH 登录 → 确认 CPU 持续不降
点"开始处置" → remediationEngine.start(alert_id)
│
▼
remediationEngine
读 alertRecord.matched_plan_snapshot(冻结快照,与 initial_response 同一份)
│
▼
for step in remediation.steps:
┌──────────────────────────────────────┐
│ execution === "auto" │
│ → aiBridge.requestToolCall( │
│ alertRecord.id, │
│ command_id, params │
│ ) │
│ → Catty Agent 执行 │
│ → 结果回写 step.stdout_preview │
│ + audit_log │
│ 值班员可以随时暂停 │
├──────────────────────────────────────┤
│ execution === "confirm" │
│ → 弹确认框 → 值班员点"允许" │
│ → 同上走 aiBridge → Catty Agent │
├──────────────────────────────────────┤
│ execution === "manual_only" │
│ → 工作台展示 checklist 卡片 │
│ → 值班员手动完成后点"标记完成" │
└──────────────────────────────────────┘
│
▼
处置完成 → remediation.status = "completed"
remediationEngine 检查 auto_close_after_remediation_recovery(D25)
→ 指标恢复正常 → alertRecord.status = "resolved"
→ 指标未恢复 → alertRecord 仍保持 active
audit_log 追加全链路记录
│
▼
值班员关闭告警 → 填写处置总结 note
通知网关推送到运维群:✅ 告警已关闭 | CPU 恢复 35% | 耗时 47 分钟
``
### 3.2 AlertStateMonitor 超时检查时序
`
AlertStateMonitor.start()
→ setInterval(run, 5 * 60 * 1000) // 每 5 分钟跑一次
run() {
activeAlerts = alertRecordStore.list({ status: ["active", "acknowledged"] })
for alert in activeAlerts {
plan = alert.matched_plan_snapshot
if (!plan) continue; // 没匹配预案的不处理
// 检查 1: escalation_fallback.auto_escalate_minutes
if (plan.escalation_fallback?.auto_escalate_minutes) {
elapsed = (Date.now() - alert.triggered_at) / 60000
if (elapsed >= plan.escalation_fallback.auto_escalate_minutes) {
alertAggregationEngine.escalateAlert(alert.id, {
reason: "escalation_fallback_timeout",
target_level: plan.escalation_fallback.escalation_target_level
})
}
}
// 检查 2: remediation 运行超时
if (alert.remediation?.status === "running") {
runningFor = (Date.now() - alert.remediation.started_at) / 60000
if (runningFor > 30) { // 30 分钟硬阈值
remediationEngine.pause(alert.id, { reason: "timeout" })
notificationDispatcher.notify(alert, { type: "remediation_timeout" })
}
}
}
}
`
### 3.3 多台设备同时故障(触发升级 + 匹配时刻冻结 + 初始响应包联动)
`
T=0min switch-A offline ──► 原始告警 (critical)
→ matcher 匹配 switch_offline_plan → 冻结 snapshot-A
T=0min switch-B offline ──► 原始告警 (critical)
→ matcher 匹配 switch_offline_plan → 冻结 snapshot-A(同一份预案)
T=1min switch-C offline ──► 原始告警 (critical)
→ matcher 匹配 switch_offline_plan → 冻结 snapshot-A
│
▼
alertAggregationEngine 实时检查:
每次新告警进来都检查窗口内计数
第 3 条进来时: catalog_type=switch, tier=core,
window=5min, threshold=3 台 offline → 命中!
│
▼
写入升级告警 (新 alertRecord):
level: "critical",
escalation: { trigger: "aggregation",
source_alert_ids: [A,B,C] }
│
▼
alertPlanMatcher(重新匹配升级后的 critical 预案)
匹配 switch_critical_escalation_plan
冻结 snapshot-escalation
│
▼
AI 初始响应包(聚合版,snapshot-escalation):
📊 聚合: 3 台核心交换机同时离线(5分钟内)
📍 设备: switch-A(10.0.1.1), switch-B(10.0.1.2), switch-C(10.0.1.3)
🔥 可能原因: 核心机房 A 架配电故障 / 光纤中断
📋 值班员 checklist:
1. 电话确认机房 A 架配电状态
2. 查 SNMP 网关是否能连通机房设备
3. 通知机房运维到场
📞 通知: 网络组 oncall + 机房运维经理 + 值班经理
(聚合升级的初始响应包重点突出可能原因和通知链路)
│
▼
推送到值班员 + 运维群
`
### 3.4 AI 初始响应包三层保护具体流程
`
initialResponseGenerator.generate(alertRecord) {
// ① 去抖
const debounceKey = initial_response:;
if (_generatedCache.has(debounceKey)) {
log('[initialResponse] skip: 5min 内已生成过');
return _generatedCache.get(debounceKey);
}
// ② 限流
if (_activeCount >= 3) {
log('[initialResponse] queue: 并发已满,等待');
return _queue.enqueue(() => generate(alertRecord));
}
_activeCount++;
try {
// ③ 超时控制
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 15000);
// 降级检查
const provider = getAIProvider();
if (!provider) {
log('[initialResponse] 降级: AI 不可用,直接组装');
return this._fallbackGenerate(alertRecord);
}
// 调 Catty Agent
const result = await cattyAgent.streamText({
provider,
systemPrompt: INITIAL_RESPONSE_SYSTEM_PROMPT,
userMessage: buildInitialResponseUserMessage(alertRecord, matchedSnapshot, deviceProfile),
tools: [], // 响应包生成不需要 AI 调工具
signal: controller.signal,
});
clearTimeout(timeoutId);
// AI 解析可能有问题 → 降级到 fallback
let parsed;
try { parsed = JSON.parse(result.text); }
catch { parsed = this._fallbackGenerate(alertRecord); parsed.status = "partial_ai_invalid"; }
return parsed;
} catch (err) {
log('[initialResponse] 失败/超时,降级到 fallback', err.message);
return this._fallbackGenerate(alertRecord, { reason: err.message });
} finally {
_activeCount--;
_generatedCache.set(debounceKey, result, 5 * 60 * 1000);
}
}
_fallbackGenerate(alert, options = {}) {
// 不用 AI,直接组装: human_action_guide + deviceStore + alertRecord
return {
status: options.reason ? "partial_fallback" : "complete_fallback",
device: extractFromDeviceStore(alert),
alert: extractFromAlertRecord(alert),
quick_checklist: alert.matched_plan_snapshot.human_action_guide?.info_gathering ?? [],
matched_plan: { name: alert.matched_plan_snapshot?.name ?? "未知预案" },
possible_causes: [], // AI 推断字段 fallback 不填
...aggregateExtraFields(alert),
};
}
`
### 3.5 notification_chain.auto 分级处理(D26)
`
notificationDispatcher.resolveChannels(humanActionGuide.notification_chain) {
for (const item of humanActionGuide.notification_chain) {
if (!item.auto) continue; // auto=false 的手动通知直接跳过
const resolved = { channel: item.channel, status: "", target: null, note: "" };
switch (item.channel) {
case "webhook":
resolved.status = "sent"; // 一期实现
resolved.target = findWebhookConfig(item.role);
break;
case "desktop":
resolved.status = "sent"; // 一期实现(大屏弹窗 = desktop 通知)
break;
case "dingtalk":
case "wechat":
case "email":
resolved.status = "pending_external";
resolved.note = "需外置通知网关(P5 实现)";
break;
case "phone":
resolved.status = "manual_only";
resolved.note = 请值班员手动拨打 ;
break;
default:
resolved.status = "unknown";
}
results.push(resolved);
}
// 写回 alertRecord.initial_response.auto_notifications_sent
// + alertRecord.initial_response.pending_notifications
return results;
}
`
---
## 四、关键数据结构
### 4.1 新增存储 key
在 electron/bridges/inspection/storageKeys.cjs 里加:
`
STORAGE_KEY_PLAN_TEMPLATES → plan_templates_v1
STORAGE_KEY_DEVICE_PLANS → device_plans_v1
STORAGE_KEY_AGGREGATION_RULES → aggregation_rules_v1
STORAGE_KEY_COMMAND_CATALOG → command_catalog_v1
`
### 4.2 预案模板(plan_template)
模板**不含**匹配条件、值班员动作预案、处置步骤——这些全是设备预案层的。模板只存公共联动配置。
``js
{
id: "tpl_level3_critical",
name: "三级预案模板(严重)",
level: "critical", // critical | warning | info(与现有 ALERT_LEVELS 对齐)
builtin: true, // 系统预置 vs 自定义
description: "...",
── 大屏样式 ──
display: {
color: "#ef4444", icon: "alert-octagon", blink: true,
sound: "builtin_alarm",
},
── 通知策略 ──
notification: {
channels: ["desktop", "webhook"],
recipients: [ { type: "webhook", target: "https://hooks.example.com/alert" } ],
repeat_interval_minutes: 5,
max_repeats: 12,
},
── 升级兜底(D23 AlertStateMonitor 读取)──
escalation_fallback: {
auto_escalate_minutes: 30, // 挂 30min 没处置 → 自动升级
escalation_target_level: "critical",
},
── 处置安全默认值 ──
remediation_defaults: {
require_confirmation: true,
auto_close_after_remediation_recovery: true, // ← D25: 改名
execution_timeout_sec: 120,
},
── 审计 ──
created_at: 1729800000000,
updated_at: 1729800000000,
}
``
**约束**:模板不含 match、scope、human_action_guide、
emediation.steps、security —— 这些全是设备预案层的。
### 4.3 设备预案(device_plan)—— 双轨完整结构
``js
{
id: "plan_switch_critical_core",
template_id: "tpl_level3_critical",
device_type: "switch", // router | switch | server | firewall | plugin:xxx
level: "critical",
enabled: true,
builtin: false,
status: "active" | "draft", // draft = AI 生成待审核
source: "manual" | "ai",
ai_provider: null | "catty-minimax",
ai_prompt_version: null | "v2",
reject_reason: null | "xxx", // 审核驳回原因
review_log: [ // Review Workflow(D13)
{ ts: 1729800000000, actor: "admin", action: "approve", reason: null },
{ ts: 1729799000000, actor: "admin", action: "reject", reason: "command_id 不完整" },
],
description: "核心交换机三级预案 - CPU 过载处置",
═══════════════════════════════════════════════════════════════
【匹配元数据(不属于预案轨)】
═══════════════════════════════════════════════════════════════
match: {
metric_rules: [ { metric_key: "cpu_usage", op: ">", value: 90 } ],
alert_types: ["performance_high"],
device_tiers: ["core"],
device_tags: [],
},
scope: { host_ids: [], host_groups: [] },
═══════════════════════════════════════════════════════════════
【第一轨】值班员动作预案
═══════════════════════════════════════════════════════════════
human_action_guide: {
receiving_alerts: [
"在拓扑图定位设备位置",
"确认告警是否已被其他值班员处理",
],
info_gathering: [
{ priority: 1, action: "SSH 登录执行 display cpu-usage",
purpose: "确认 CPU 持续时间", expected_output: "平均 CPU 使用率" },
{ priority: 2, action: "查最近 24h 巡检历史",
purpose: "确认是否之前有过类似告警" },
{ priority: 3, action: "display diagnostic-information",
purpose: "采集诊断信息,保存归档" },
],
notification_chain: [
{ role: "网络组 oncall", channel: "dingtalk",
trigger: "收到告警立即", contact: "王工 138xxxx", auto: true },
{ role: "机房运维经理", channel: "phone",
trigger: "30 分钟未恢复", contact: "李经理 137xxxx", auto: false },
{ role: "值班经理", channel: "phone",
trigger: "60 分钟未恢复 或 聚合升级", contact: "张经理 136xxxx", auto: false },
],
escalation_triggers: [
{ condition: "告警持续 30 分钟未恢复", target_level: "critical" },
{ condition: "聚合升级触发(≥3 台同类型核心设备)",
target_level: "critical" },
{ condition: "安全告警(firewall_intrusion 等)",
target_level: "critical", note: "禁止 AI 自动处置" },
],
pre_remediation: [
"备份当前 running-config",
"确认运维变更单已创建",
"通知相关业务方(如有业务影响)",
],
post_remediation: [
"show cpu-usage 确认恢复到正常阈值以下",
"show logging 检查处置命令产生的日志",
"将处置过程 + AI 输出截图上传告警归档",
"关闭告警时填写处置总结 note",
],
},
═══════════════════════════════════════════════════════════════
【第二轨】操作级预案(含 execution 权限分级)
═══════════════════════════════════════════════════════════════
remediation: {
require_confirmation: true,
steps: [
{
order: 1,
action: "command",
command_id: "switch_show_cpu",
command_params: {},
timeout_sec: 30,
execution: "auto",
required_confirmation: false,
on_success: "next",
on_failure: "stop",
},
{
order: 2,
action: "command",
command_id: "switch_collect_diagnostic",
command_params: {},
timeout_sec: 120,
execution: "confirm",
required_confirmation: true,
on_success: "next",
on_failure: "retry:2",
},
{
order: 3,
action: "command",
command_id: "switch_adjust_cpu_threshold",
command_params: { threshold: "95" },
timeout_sec: 30,
execution: "confirm",
required_confirmation: true,
on_success: "next",
on_failure: "escalate",
},
{
order: 4,
action: "note",
title: "联系应用组确认",
description: "CPU 高负载疑似应用进程导致,需联系应用组确认是否可以停止",
contact: "应用组 oncall 李工 139xxxx",
execution: "manual_only",
},
],
},
═══════════════════════════════════════════════════════════════
【安全 + 权限】
═══════════════════════════════════════════════════════════════
security: {
allowed_command_ids: [ "switch_show_cpu", "switch_collect_diagnostic" ],
allowed_commands: [ "show *", "display *" ],
blocked_patterns: [ "rm -rf /", "shutdown now", "reload" ],
},
required_role: "operator",
created_at: 1729800000000,
updated_at: 1729800000000,
}
``
### 4.4 执行权限分级(execution)
| 权限值 | 谁触发 | AI 是否执行 | 对应能力 |
|--------|--------|------------|----------|
| "auto" | AI 自动 | ✅ 直接执行 | show/display/info 命令、无风险查询 |
| "confirm" | 值班员点击"允许" | ✅ 值班员允许后执行 | 重启接口、调阈值、改配置、备份、采集诊断 |
| "manual_only" | 值班员手动完成后点"标记完成" | ❌ 不执行 AI | 联系应用组、console 密码重置、到场操作、策略性确认 |
**AI 自动处置边界**:AI 只负责 uto 权限步骤,confirm 必须等值班员点击,manual_only 只展示 checklist 卡片。值班员可以随时**暂停全部处置**(所有 auto 步骤停止排队,已在跑的 step 执行完当前命令后停止)。
### 4.5 初始响应包结构(initial_response)
`js
{
alert_id: "alert_cpu_high_switch_01",
generated_at: 1729800000000,
generator: "catty-agent" | "fallback",
status: "complete" | "partial" | "partial_ai_invalid" | "complete_fallback" | "partial_fallback",
── 设备画像 ──
device: {
host_id, label, hostname, catalog_type, tier, group, location,
last_inspection: { at, health_score }
},
── 告警详情 ──
alert: { alert_type, metric_key, metric_value, threshold, duration_seconds, level, triggered_at },
── 快速 checklist(值班员先做这几件事) ──
quick_checklist: [ { priority, action, purpose } ],
── 匹配预案摘要 ──
matched_plan: { name, level, escalation_target_level, escalate_after_minutes },
── 通知链路(D26 分级)──
auto_notifications_sent: [
{ role: "网络组 oncall", channel: "webhook", at: 1729800000000, status: "sent" },
{ role: "网络组 oncall", channel: "dingtalk", status: "pending_external",
note: "需外置通知网关(P5 实现)" },
],
pending_notifications: [
{ role: "机房运维经理", channel: "phone", trigger: "30 分钟未恢复",
contact: "李经理 137xxxx", status: "manual_only" },
],
── 可能原因(AI 推断,非确定) ──
possible_causes: [
{ probability: "high", label: "应用进程异常占用 CPU", hint: "display cpu-usage" },
],
── 聚合版额外字段 ──
aggregate: null | {
type: "escalation",
trigger: "aggregation",
device_count: 3,
device_labels: ["switch-A", "switch-B", "switch-C"],
possible_root_cause: "核心机房 A 架配电故障",
},
── D22: 降级/警告 ──
warnings: [
"human_action_guide.info_gathering 第 3 条未找到对应 remediation step(处置步骤缺失)",
"AI provider 不可用,响应包为 fallback 组装,possible_causes 为空",
],
}
`
### 4.6 alertRecord 扩展字段(向后兼容)
**matched_plan_snapshot(D9: 匹配时刻冻结)** 是核心新字段,initial_response 和 remediation 都读这同一份:
``js
{
// ── 原有字段保留不动 ──
id, rule_id, rule_name, device_id, device_name,
metric, metric_value, threshold, level, message,
triggered_at, status, acknowledged_by, acknowledged_at,
resolved_at, resolved_reason, note,
// ── 预案匹配(D9: 匹配时刻冻结 snapshot)──
matched_plan_id, matched_template_id, match_score,
matched_plan_snapshot: { ...完整 devicePlan JSON clone }, // ← 核心
// ── 升级信息 ──
escalation: null | { trigger, source_alert_ids, ... },
// ── v1.2: AI 初始响应包 ──
initial_response: { ...initial_response 结构 },
// ── v1.2: 值班员动作任务进度 ──
human_action_tasks: [
{ id, action, status: "pending"|"done"|"skipped", completed_by, completed_at }
],
// ── 处置执行(扩展 execution 权限 + auto_close 语义修正)──
remediation: {
plan_snapshot: { ... }, // ← 指向 matched_plan_snapshot 的同一份引用
frozen_at: 1729800000000,
status: "pending" | "running" | "completed" | "partial" | "failed" | "cancelled" | "paused",
paused_at: null | 1729800120000,
auto_close_after_recovery: true, // ← D25 字段名
steps: [
{
order, execution: "auto"|"confirm"|"manual_only",
status: "pending"|"running"|"success"|"failed"|"timeout"|"skipped",
started_at, finished_at, executor, exit_code,
stdout_preview, confirmed_by, confirmed_at, error
}
]
},
// ── 全链路审计 ──
audit_log: [
{ ts, actor, action, detail }
// v1.3 新增 action 类型:
// "initial_response_generated" (AI 自动生成,含 status)
// "initial_response_fallback" (AI 不可用降级)
// "notification_sent" / "notification_pending_external" / "notification_manual_only"
// "auto_execution_paused" / "remediation_timeout"
// "aggregation_escalation" (聚合升级触发)
// "escalation_fallback_timeout" (AlertStateMonitor 兜底升级)
]
}
``
---
## 五、模板变量 Reference
处置步骤 command_params 里可用的模板变量(同 v1.2 不变)。
---
## 六、AI 预案生成 + Review Workflow
### 6.1 定位与边界
AI 描述生成 + 表单手动共存。AI 生成的预案 status = "draft",必须走人工审核才能启用。
### 6.2 Prompt 设计骨架(双轨 Prompt)
同 v1.2,不变。
### 6.3 Review Workflow 前端交互
`
预案列表页
├── [自动刷新·AI 生成预案在最顶部]
├── 行标记 [草稿·待审核] badge(source=ai + status=draft)
├── 点击预案 → 表单页(已预填 AI 生成内容)
│ └── 顶部审核面板:
│ ┌──────────────────────────────────────────────────┐
│ │ ✨ AI 生成预案草稿 │
│ │ provider: catty-minimax | prompt_version: v2 │
│ │ warnings: command_id 'switch_collect_diagnostic' │
│ risk_level=high,启用需人工确认 │
│ │ │
│ │ 审核: │
│ │ [✅ 通过并启用] [❌ 驳回并反馈] │
│ └──────────────────────────────────────────────────┘
│
└── 审核记录折叠面板:
┌─────────────────────────────────────┐
│ 📋 审核历史 │
│ 2026-10-30 14:20 admin 通过 │
│ 2026-10-30 14:18 admin 驳回 │
│ 原因: command_id 不完整 │
└─────────────────────────────────────┘
`
### 6.4 初始响应包生成器(initialResponseGenerator)
同 v1.2 的 Prompt 骨架 + v1.3 的三层保护(见 3.4 节完整实现流程)。
---
## 七、现有代码的具体改动落点
| 位置 | 改动 | 类型 |
|------|------|------|
| electron/bridges/inspection/storageKeys.cjs | 新增 4 个存储 key | 扩展 |
| electron/bridges/inspection/types.cjs | 新增 ALERT_TYPE_CATEGORIES | 扩展 |
| electron/bridges/inspection/alertRuleStore.cjs | rule 新增 lert_type | 扩展(向后兼容) |
| electron/bridges/inspection/alertRecordStore.cjs | alertRecord 扩展(matched_plan_snapshot、human_action_tasks、initial_response、remediation.auto_close_after_recovery、audit_log 新增 action 类型);新增 escalateAlert()、listActiveForMonitor()(给 AlertStateMonitor 用) | 扩展(向后兼容) |
| electron/bridges/inspection/index.cjs | inspection 回调链插入:告警写完 → matcher(**匹配时刻冻结 snapshot**) → 聚合检查 → 初始响应包生成(**三层保护**);注册 AlertStateMonitor 定时任务 | 新增调用点 |
| **新建** electron/bridges/inspection/planTemplateStore.cjs | 预案模板 CRUD + 预置 seed | 新文件 |
| **新建** electron/bridges/inspection/devicePlanStore.cjs | 设备预案 CRUD + 匹配(scope 排序、AND 条件校验、白名单校验)+ Review Workflow(approve/reject + review_log)+ snapshot 冻结逻辑 | 新文件 |
| **新建** electron/bridges/inspection/aggregationEngine.cjs | 实时聚合检查 + 升级告警产出 + escalateAlert()(给 AlertStateMonitor 用) | 新文件 |
| **新建** electron/bridges/inspection/commandCatalogStore.cjs | 预置命令 ID 目录 | 新文件 |
| **新建** electron/bridges/inspection/remediationEngine.cjs | 处置引擎;**通过 aiBridge.requestToolCall 调 Catty Agent**(不直接 import capabilityTools);execution 权限分级;暂停/恢复;auto_close_after_recovery(D25) | 新文件 |
| **新建** electron/bridges/inspection/alertStateMonitor.cjs | **D23 新增**:每 5min 定时扫活跃告警;处理 escalation_fallback.auto_escalate_minutes;处置超时暂停;auto_close_after_recovery 检查 | 新文件 |
| **新建** electron/bridges/inspection/planGenerator.cjs | AI 双轨预案生成器 + Review Workflow | 新文件 |
| **新建** electron/bridges/inspection/initialResponseGenerator.cjs | AI 初始响应包自动生成;**D22 三层性能保护**(去抖 / 限流 PromiseQueue / 超时 AbortController + fallback);**D26 notification_chain 分级处理** | 新文件 |
| **新建** electron/bridges/inspection/devicePlan.schema.json | 设备预案 JSON Schema | 新文件 |
| **新建** electron/bridges/inspection/initialResponse.schema.json | 初始响应包 JSON Schema | 新文件 |
| electron/remoteHttpServer.cjs | 新增路由:预案 CRUD、聚合规则、命令目录、plan/generate、plan/approve、plan/reject、plan-context、alert/:id/remediation/*、alert/:id/initial-response、alertStateMonitor/status | 扩展路由 |
| electron/preload/api.cjs | 暴露预案相关 IPC | 扩展 |
| **前端** components/inspection/ | 预案模板管理页、设备预案管理页(双轨表单 + AI 生成面板 + Review Workflow 审核面板)、聚合规则配置页、处置工作台(含值班员 checklist 卡片 + 执行权限分级 UI) | 新组件 |
| components/monitoring/MonitoringTopologyView.tsx | 现有告警弹窗内追加 AI 响应包面板(Tab 切换:告警详情 / AI 响应包 / 处置工作台);匹配预案名、处置状态灯 | 扩展(不替换原有弹窗) |
| components/monitoring/useMonitoringData.ts | hook 扩展:拉 alertRecord 时取 initial_response;matched_plan_snapshot;aggregation 识别 | 扩展 |
| electron/bridges/aiBridge.cjs | 扩展一个轻量
equestToolCall(alert_id, command_id, params) 方法,供 remediationEngine 调用 | 扩展(薄封装) |
---
## 八、实施阶段建议
| 阶段 | 内容 | 前置 | 关键风险 |
|------|------|------|----------|
| **P0 - 骨架** | storageKeys、types、7 个 store 文件(模板/预案/命令目录/聚合规则/**预案生成**/**初始响应包**/**AlertStateMonitor**)、2 个 schema、远程 HTTP 路由、AJV 校验、Prompt 工程、**aiBridge.requestToolCall 薄封装** | 无 | AI provider 未配置时 initialResponseGenerator 必须能降级 |
| **P1 - 匹配链路** | alertRecord 扩展 + 预案匹配器对接(**匹配时刻冻结 snapshot**);human_action ↔ remediation 完整性检查;AI 生成的 draft 预案跳过匹配 | P0 | matcher 跳过 draft 预案后,draft 预案不会参与自动匹配 |
| **P2 - 聚合升级** | 聚合引擎 + 升级告警产出 + AlertStateMonitor 注册定时任务 + alertRuleStore alert_type 扩展 | P1 | AlertStateMonitor 扫存量告警时不能重复 escalate(需 dedup) |
| **P3 - 处置执行** | remediationEngine(**通过 aiBridge 调 Catty Agent**)+ execution 权限分级 + 暂停/恢复 + 处置工作台前端;**auto_close_after_recovery** 只在 remediation.completed 后检查 | P1(可与 P2 并行) | D24: remediationEngine ↔ aiBridge 集成是关键 |
| **P4 - 通知 + 大屏** | monitoringDispatcher(**D26 分级处理**)+ 大屏弹窗 AI 响应包面板 | P2 + P3 | 大屏弹窗原有告警详情区必须保留,AI 响应包做 Tab 切换 |
| **P5 - Review Workflow + 外置通知** | planGenerator Review Workflow 审核面板 + dingtalk/wechat/email 外置通知网关适配 | P4 | 外置通知网关需要凭据管理模块 |
| **P6 - 多告警关联** | 同设备多条不同 rule 告警合成 + 综合预案匹配 | P5 | D21 已声明一期不支持,P6 重做 matcher 逻辑 |
---
## 九、开放问题(后续版本讨论)
| # | 问题 | 说明 |
|---|------|------|
| Q1 | 预案能不能跨设备类型? | 现在 device_type 单值,未来能不能一个预案同时匹配 router + switch? |
| Q2 | command_catalog 谁来 review? | 预置命令的 risk_level 标注和审批流程,需要和运维团队对齐 |
| Q3 | Catty Agent session 隔离 | 处置执行时调 Catty Agent,会不会和值班员正在用的 Catty session 冲突?需要 dedicated session |
| Q4 | AlertStateMonitor 怎么部署 | 和 inspectionScheduler 同进程?还是独立 worker?主进程已经有 scheduler 了 |
| Q5 | initialResponse 的多语言 | 响应包都是中文,有没有英文环境需求? |
| Q6 | plan_snapshot 的存储量 | 每条告警都存一份完整 devicePlan clone(几十 KB),活跃告警多了 localStorage 会不会爆? |
| Q7 | 处置结果和巡检闭环 | 处置执行的输出能不能反馈给 inspectionScheduler 自动触发巡检复查? |
| Q8 | AI 初始响应包的效果追踪 | 有没有反馈机制让值班员评价 initial_response 有用没用?反向改进 Prompt |
| Q9 | 预案导入导出 | 预案模板和设备预案能不能 JSON 导入导出?跨环境同步 |
| Q10 | command_catalog 与 vault 的凭据关联 | 有些命令需要 vault 里的特定凭据(比如 enable secret),command_catalog 怎么声明依赖? |