# 路由 Playbook

这份文档补充 `SKILL.md` 的详细路由细节、命中样例、阻塞条件和输出习惯。先看 `SKILL.md` 顶部优先级，再在这里找细节。

## 路由优先级

按下面顺序判定：

1. 报告/使用分析
2. 配置/组织/连通性/解析
3. 权限关系
4. 审计调查
5. 对象查询
6. 治理/聚合分析

如果一个请求同时命中多类，使用优先级更高的那一类。

例子：

- “帮我看下昨天堡垒机使用情况” -> 报告/使用分析
- “看看某天使用情况” -> 报告/使用分析
- “帮我出 3 月 24 号日报，顺便看看异常登录” -> 仍然先走报告模板
- “分析 20260310” -> 报告/使用分析
- “某天发生了什么” -> 如果核心是在问某天的 JumpServer 使用数据分析，走报告模板
- “帮我看某天登录/会话/命令情况” -> 如果带有明确日期或时间段，走报告模板
- “帮我看看昨天登录情况” -> 如果核心是在看整体情况或汇总，走报告模板
- “看下 3 月 10 号使用情况” -> 报告/使用分析
- “想看上周谁登录最多” -> 报告/使用分析
- “查昨天 30 条登录日志” -> 审计调查
- “看这条授权规则详情” -> 权限关系
- “查某用户有哪些资产” -> 对象查询或访问分析；如果用户是在问访问范围，优先 `jms_diagnose.py`
- “分析 3 月上旬谁用资产最多” -> 报告/使用分析

## 典型触发词

不要把这一节当成“字面关键词表”。优先看“时间词 + 核心对象 + 输出诉求”；一句话里如果同时命中多类，仍按上面的路由优先级处理。动作词如 `看下` / `看看` / `帮我看看` / `想看` / `过一下` 只是在包装请求，不单独决定路由。

报告/使用分析优先匹配模式：

- `时间词` + `使用情况` / `使用分析` / `使用统计` / `使用汇总` / `使用概览` / `整体情况`
- `时间词` + `登录` / `会话` / `命令` / `传输` + `情况` / `概览` / `汇总`
- `时间词` + `谁最多` / `TOP` / `排行` / `哪些最活跃` / `分布`
- `看下` / `看看` / `帮我看看` / `想看` / `过一下` / `分析` + 上面任一模式
- 即使用户没有明确说“报告”，只要核心是在看某天或某时间段的 JumpServer 整体使用面，也按模板报告处理

报告/使用分析高信号：

- `使用报告` / `日报` / `周报` / `月报` / `出报告` / `生成报告`
- `昨天` / `某天` / `某时间段` / `上周` / `本月` + `使用情况` / `使用分析` / `使用统计` / `使用汇总` / `使用概览`
- `某天发生了什么`
- `某天登录情况` / `某天会话情况` / `某天命令情况` / `某天传输情况`
- `分析 20260310` / `看下 3 月 10 号使用情况` / `看看某天使用情况`
- `帮我看看昨天登录情况` / `想看上周谁登录最多` / `过一下 3 月上旬会话概览`
- `usage report` / `daily usage report` / `usage analysis` / `JumpServer usage overview` / `bastion usage`

配置 / 组织 / 连通性 / 解析高信号：

- `检查配置` / `配置状态` / `检查连通性` / `ping`
- `切组织` / `选择组织` / `全局组织`
- `许可证` / `系统设置` / `报表` / `工单` / `存储` / `终端`
- `解析资产` / `解析用户` / `resolve`

权限关系高信号：

- `授权规则` / `权限详情` / `ACL` / `RBAC`
- `为什么某人能访问某资产`
- `谁能访问这台资产`
- `这条授权规则详情`

审计调查高信号：

- `登录日志` / `会话记录` / `命令记录` / `文件传输`
- `异常行为` / `失败登录` / `高危命令` / `特权账号使用审计`
- `看最近登录` / `看最近会话` / `查某时间段命令`
- `audit login` / `session audit` / `command audit` / `file transfer audit`

对象查询高信号：

- `查资产` / `查账号` / `查用户` / `查用户组` / `查组织`
- `查平台` / `查节点` / `查标签` / `查网域`
- `某用户有哪些资产` / `某资产有哪些账号`
- `asset query` / `user query` / `organization detail`

治理 / 聚合分析高信号：

- `治理巡检` / `聚合分析` / `账号治理` / `资产治理`
- `访问分析` / `系统巡检` / `capability`
- `governance inspection` / `access inspection`

容易混淆时这样判：

- `某天登录情况` / `某天会话情况` / `某天命令情况` -> 报告/使用分析
- `某天登录日志` / `某天会话明细` / `某天命令记录` -> 审计调查
- `某时间段谁登录最多` / `谁用得最多` / `哪些资产最活跃` -> 报告/使用分析
- `查最近 30 条登录日志` / `看某条会话详情` / `导出某天命令明细` -> 审计调查

弱信号，不能单独定路由：

- `看下` / `看看` / `帮我看看` / `想看` / `过一下` 只是动作词
- `分析` / `看一下` / `查一下` / `概览` / `汇总`
- 单独出现的 `使用情况` / `审计分析` / `发生了什么` / `情况`
- 单独出现的时间词，例如 `昨天` / `某天` / `上周`
- 没有时间范围的 `谁用得最多`
- `查某用户有哪些资产` 这类说法如果用户核心是在问“访问范围为什么这样”，优先回到权限关系或访问分析

## 模板例外优先级

按下面顺序判定：

1. 用户明确说“不要生成报告，直接分析”“先简单说下”“只给我结论”“不用模板” -> 允许跳过模板，直接给简短分析
2. 除上述明确例外外，只要核心对象是某一天或某一段时间内的 JumpServer 使用数据分析 -> 必走模板报告
3. “审计分析”不是自由文本摘要的默认入口；如果带有明确日期/时间范围且关注整体使用情况，仍然走模板

不要把“分析某天发生了什么”先翻译成自由文本摘要。模板报告的完成标准是“成功生成并验证通过的 HTML 报告”，不是“先答一个结论就算完成”。

## 组织优先级细节

先看用户是否明确给出组织。

- 给了组织：按用户指定组织执行。
- 用户明确说“所有组织”或“全局组织”，且语境是报告/使用分析：按全局组织 `00000000-0000-0000-0000-000000000000` 处理。
- 没给组织且是报告/使用分析：先尝试全局组织 `00000000-0000-0000-0000-000000000000`。
- 全局组织可访问性不只看候选组织列表；允许通过显式 `select-org` / 直连探测确认。
- 全局组织直连探测或显式选择验证失败：阻塞并返回 `candidate_orgs`。
- 没给组织且不是报告/使用分析：再使用 `{0002}` / `{0002,0004}` 的保留组织逻辑。
- 没给组织且存在多个可访问组织：返回 `candidate_orgs`，提醒用户选择查询组织。
- 当前组织已生效且仍有其他可访问组织：继续返回 `switchable_orgs`，提醒用户还可以切换到哪些组织查询。

不要把报告类请求误回退到 `0002` 默认规则。

## 时间归一化

模板报告先把自然语言日期归一化为明确时间窗：

- “昨天” -> 前一天 `00:00:00 ~ 23:59:59`
- `20260310` -> `2026-03-10 00:00:00 ~ 23:59:59`
- `2026-03-10` / `2026/03/10` / `3月10号` / `3 月 10 日` -> 同一天 `00:00:00 ~ 23:59:59`
- “上周” -> 上一个自然周，周一 `00:00:00 ~ 周日 23:59:59`
- “本月” -> 本月 1 日 `00:00:00` 到当前日期或月末 `23:59:59`

一旦能归一化成单日或时间段，就按模板报告处理，不因为表述短而退回“快速分析”。

## 正式入口边界

普通请求：

- 优先只选 1 个正式入口。
- 优先 capability，而不是手工拼多条零散查询。

模板报告请求：

- 必须优先使用 `python3 scripts/jumpserver_api/jms_report.py daily-usage ...`。
- 允许由正式报告入口按字段元数据串联多个正式入口。
- 不得超出 `references/metadata/daily_usage_report_template_fields.json` 里声明的来源。
- 不允许每次请求现场写临时构建逻辑。

## 阻塞条件

出现下面任一情况时先阻塞：

- 缺配置或鉴权不完整
- 当前组织不可访问
- 目标组织不明确且不能自动确定
- 名称重名或平台不明确
- 跨组织命中
- 普通命令审计查询需要 `command_storage_id` 且默认 storage 无法推导
- 用户要求写操作
- 用户要求绕过正式入口使用临时脚本
- 报告入口生成后自检失败

## 输出习惯

普通查询：

- 回显预检步骤
- 回显正式入口
- 回显 `effective_org`
- 有其他可切换组织时回显 `switchable_orgs`
- 回显执行命令摘要
- 给结果摘要

模板报告：

- 回显预检步骤
- 回显模板路径
- 回显字段元数据路径
- 回显 `effective_org`
- 有其他可切换组织时回显 `switchable_orgs`
- 回显 `queried_command_storage_ids`
- 回显 `queried_command_storage_count`
- 回显时间范围
- 回显 `validation_summary`
- 给最终 HTML 报告
- 可附加简短摘要，但不得仅返回摘要替代报告

阻塞：

- 说明阻塞原因
- 给 `candidate_orgs` 或 `candidate_objects`
- 给下一步安全动作

## 反例

下面这些说法不要误判：

- “给我写个临时脚本调 API” -> 不命中 skill 的正式执行路径
- “帮我创建一个新用户” -> 不在 skill 范围
- “直接猜一个组织继续查” -> 阻塞
- “随便给个摘要就行” 且上下文是使用报告/时段分析 -> 仍走模板报告
- “分析某天发生了什么” -> 默认不是普通自由文本分析入口，而是模板报告入口
