Skip to content

Commit 163875f

Browse files
committed
feat(skill): clean public boundary, merge oncall→schedule, bilingual index, fault-analysis script
Rework the flashduty skill per review feedback: - SKILL.md is now a clean PUBLIC router: strip Safari-internal behavior (credential injection, subagent dispatch, the `task` tool). Only the reference/*.md cards and scripts/ are shared with the Safari embed; each consumer owns its own SKILL.md. - Merge the `oncall` domain into `schedule` (one on-call / 值班 domain). `oncall who` is kept as the deprecated current-on-call lookup; the durable path is schedule-native `info --start now`. Drop reference/oncall.md. - Add reference/change.md (the `change` group was previously uncovered). - Make the domain index bilingual (Chinese + English routing terms per row). - Add scripts/incident-summary.sh: one call fetches all six fault-analysis aspects (detail/alerts/timeline/similar/post-mortem/changes) so a compound summary is written from real output instead of fabricated piecemeal.
1 parent a2464cc commit 163875f

6 files changed

Lines changed: 169 additions & 123 deletions

File tree

skills/flashduty/SKILL.md

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name: flashduty
33
version: "3.0"
44
description: "USE FIRST for Flashduty tasks — status pages, incidents, alerts, on-call, monitors, RUM, members. `fduty` CLI = the whole API. ALWAYS load this skill + read reference/<domain>.md for exact verbs & flags BEFORE running fduty. Don't guess or --help-dance."
5-
allowed-tools: bash, read, task
5+
allowed-tools: bash, read
66
---
77

88
# Flashduty CLI
@@ -11,7 +11,7 @@ allowed-tools: bash, read, task
1111

1212
## Auth & availability
1313

14-
- **Auth is automatic.** Safari injects the credential into each `fduty` subprocess. You never handle it and *cannot* read it — commands that reference `FLASHDUTY_APP_KEY` / `$FLASHDUTY_*` by name or dump the environment are rejected. Just call the verb.
14+
- **Auth.** Set your Flashduty app key once — `export FLASHDUTY_APP_KEY=<key>`or pass `--app-key <key>` per call. Then just call the verb.
1515
- **No curl for the API.** The CLI is the only supported path to Flashduty — never hand-roll an HTTP call.
1616
- **If `fduty: command not found`** (rare — it is normally on PATH at startup): install from the Flashduty CDN into a user-writable dir (no sudo, no hang), then tell the user — don't work around it: `curl -sSL https://static.flashcat.cloud/flashduty-cli/install.sh | FLASHDUTY_INSTALL_DIR="$HOME/.local/bin" INSTALLED_NAME=fduty sh && export PATH="$HOME/.local/bin:$PATH"`.
1717

@@ -25,40 +25,48 @@ Append `--output-format toon` to read commands: it drops the per-row repeated ke
2525

2626
**Empty result = authoritative not-found.** A filter returning `[]` means no such entity in scope — report it (optionally the 1–2 closest names) and stop. Do **not** brute-force (no shifted-keyword re-queries, no widening past caps, no full-dump grep). Never infer "feature not enabled" from an empty list, and never fabricate data absent from tool output.
2727

28+
**A result you did not fetch is "unknown", never "empty".** You may report a command's result — including "returned empty" or any count/list/finding — **only if that exact command appears in your tool-call history this turn**. If you did not run it, the honest answer is "未查询 / not queried", followed by the command to run. Writing "`incident similar` 返回空" or "无变更" for a command you never executed is fabrication, not a summary.
29+
2830
## Command names — don't guess, read the card
2931

3032
The hot path: **read the domain card** (index below) for the exact verb + flags. Command groups are hyphenated (`status-page`, `alert-event`), not concatenated (`statuspage`) — guessing the wrong form costs a failed call. For a command outside the cards, derive it from its API path: **group = first path segment, verb = the rest joined by `-`** (`POST /status-page/change/create``fduty status-page change-create`), then confirm with `fduty <group> <verb> --help`. Pass nested-object / array fields as JSON via `--data '{...}'`; typed scalar flags override matching `--data` keys.
3133

3234
**Positional arguments.** A card heading like `### change-create <page-id>` means that id is **positional** — pass it as the first bare argument (`change-create 5759… --type incident`), not as `--page-id`. A heading with no `<…>` takes all inputs as flags. Cards mark each positional with a `(positional, required)` row; trust the heading over your instinct to use a flag.
3335

34-
## fduty answers directly — don't dispatch or grep
36+
## fduty answers directly — don't grep or browse
3537

36-
Configuration, permission-model, enrichment, monitor, and on-call questions are answered by `fduty` itself (the cards + the live commands). Do **not** grep documentation, browse the web, or dispatch a subagent / product-guide agent for something the CLI covers — that wastes a turn and usually returns staler information than the live API. Read the card, run the verb.
38+
Configuration, permission-model, enrichment, monitor, and on-call questions are answered by `fduty` itself (the cards + the live commands). Do **not** grep external documentation or browse the web for something the CLI covers — that usually returns staler information than the live API. Read the card, run the verb.
3739

3840
## Safety — confirm before mutating
3941

4042
Read verbs (`list`, `get`, `info`, `detail`, `timeline`) are free. Mutating verbs (`create`, `update`, `delete`, `merge`, `ack`, `close`, `assign`, `move`, …) change state — recommend the action and get explicit per-target confirmation first. `merge` / `delete` are **irreversible** — double-check IDs. `create` notifies responders/subscribers. `list` before any bulk mutate to confirm the IDs.
4143

44+
## Compound flows — bundled scripts
45+
46+
Some asks span several commands. For those the skill ships a script that fetches everything in one call — run it as your **first action** for that ask, rather than hand-picking commands and writing the rest from memory:
47+
48+
- **Full incident fault analysis** (详情 + 关联告警 + 变更 + 时间线 + 相似故障 + 复盘 / detail + alerts + changes + timeline + similar + post-mortems): `bash scripts/incident-summary.sh <incident-id>` — runs all six reads and prints them in one block, so the summary is written from real output. See `reference/incident.md`.
49+
4250
## Domain index — read the card for the task
4351

44-
| 意图 / intent | card |
52+
| intent / 意图 (terms route in either language) | card |
4553
|---|---|
46-
| 事件 / 故障 / incident / 分诊 / 认领 / 合并 / 升级 / 事后复盘 / 告警关联 | **`reference/incident.md`** |
47-
| 告警 / alert / 去重 / 告警字段 / 告警管道 / 告警关联事件 | **`reference/alert.md`** |
48-
| 监控 / monitor / 告警规则 / 数据源 / 监控诊断 / 巡检 / 规则配置 | **`reference/monit.md`** |
49-
| 指标查询 / 日志查询 / PromQL / LogsQL / SQL 验证 / 趋势 / 日志聚类 / 数据源 RCA | **`reference/monit-query.md`** |
50-
| 主机诊断 / on-box / 进程 / 负载 / / 慢查询 / mysql 诊断 / 可达性 | **`reference/monit-agent.md`** |
51-
| 协作空间 / channel / 集成 / 分派规则 / 升级规则 / 降噪 | **`reference/channel.md`** |
52-
| 数据加工 / 富化 / enrichment / 集成 schema / 字段映射 / 提取 | **`reference/enrichment.md`** |
53-
| 洞察 / 统计 / 趋势 / MTTA / MTTR / Top 告警 / 故障导出 | **`reference/insight.md`** |
54-
| 谁在值班 / 当前值班 / on-call / 值班人查询 | **`reference/oncall.md`** |
55-
| 排班 / 轮值 / schedule / 值班层级 / 排班预览 | **`reference/schedule.md`** |
56-
| 日历 / calendar / 值班日历 / 日历事件 / 休假日历 | **`reference/calendar.md`** |
57-
| 通知模板 / 消息模板 / template / 卡片模板 | **`reference/template.md`** |
58-
| 角色 / 权限 / role / RBAC / 权限因子 | **`reference/role.md`** |
59-
| 团队 / team / 团队成员归属 / HR 同步 | **`reference/team.md`** |
60-
| 成员 / 人员 / member / 邀请 / 角色授予 | **`reference/member.md`** |
61-
| 自定义字段 / custom field / 字段选项 | **`reference/field.md`** |
62-
| 分派路由 / route / 集成路由 / 路由用例 | **`reference/route.md`** |
63-
| 真实用户监控 / RUM / 前端 / 应用 / issue | **`reference/rum.md`** |
64-
| 公开事件 / 状态页 / 公开时间线 / 维护窗口 / 订阅者 / 状态页迁移 | **`reference/status-page.md`** |
54+
| incident / fault / 故障 / 事件 / triage 分诊 / acknowledge 认领 / merge 合并 / escalate 升级 / postmortem 复盘 / **summarize or analyze an incident 故障汇总分析** | **`reference/incident.md`** |
55+
| alert / 告警 / dedup 去重 / alert fields 告警字段 / alert pipeline 告警管道 | **`reference/alert.md`** |
56+
| change / 变更 / deployment 部署 / release 发布 / correlated change 变更关联 / what changed | **`reference/change.md`** |
57+
| monitor / 监控 / alert rule 告警规则 / datasource 数据源 / inspection 巡检 / rule config 规则配置 | **`reference/monit.md`** |
58+
| metric/log query / 指标查询 / 日志查询 / PromQL / LogsQL / SQL / trend 趋势 / log clustering 日志聚类 / datasource RCA 数据源排查 | **`reference/monit-query.md`** |
59+
| host diagnostics / 主机诊断 / on-box / process 进程 / load 负载 / lock 锁 / slow query 慢查询 / mysql / reachability 可达性 | **`reference/monit-agent.md`** |
60+
| channel / 协作空间 / collaboration space / 频道 / integration 集成 / dispatch rule 分派规则 / escalation 升级规则 / noise reduction 降噪 / silence 静默 / inhibit 抑制 | **`reference/channel.md`** |
61+
| enrichment / 数据加工 / 富化 / label mapping 字段映射 / extraction 提取 / mapping schema 集成 schema | **`reference/enrichment.md`** |
62+
| insight / 洞察 / stats 统计 / trend 趋势 / MTTA / MTTR / top alerts Top 告警 / incident export 故障导出 | **`reference/insight.md`** |
63+
| schedule / on-call / 值班 / 排班 / rotation 轮值 / who is on call 谁在值班 / shift 班次 / next responder 下一班 | **`reference/schedule.md`** |
64+
| calendar / 日历 / on-call calendar 值班日历 / calendar event 日历事件 / holiday 休假 | **`reference/calendar.md`** |
65+
| template / 通知模板 / message template 消息模板 / card template 卡片模板 | **`reference/template.md`** |
66+
| role / 角色 / permission 权限 / RBAC / permission factor 权限因子 | **`reference/role.md`** |
67+
| team / 团队 / team membership 团队成员归属 / HR sync HR 同步 | **`reference/team.md`** |
68+
| member / 成员 / person 人员 / invite 邀请 / grant role 角色授予 | **`reference/member.md`** |
69+
| custom field / 自定义字段 / field option 字段选项 | **`reference/field.md`** |
70+
| route / 分派路由 / alert routing 告警路由 / integration routing 集成路由 / routing case 路由用例 | **`reference/route.md`** |
71+
| RUM / real user monitoring / 真实用户监控 / frontend 前端 / application 应用 / issue | **`reference/rum.md`** |
72+
| status page / 状态页 / public incident 公开事件 / public timeline 公开时间线 / maintenance window 维护窗口 / subscriber 订阅者 | **`reference/status-page.md`** |
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# fduty change — command card
2+
3+
Prereq: `SKILL.md` read. One read-only verb. Change events are the "what changed" signal you correlate against an incident during fault analysis.
4+
5+
## Route here when
6+
7+
"变更 / 变更事件 / 变更关联 / 发布 / 部署 / change / change event / deployment / release / what changed / correlated change" → **change**. Change events carry `labels`; they correlate to incidents by **shared labels + time proximity** (there is no foreign key). For *status-page* maintenance/incident events use `status-page` instead — that is a different "change".
8+
9+
## Intent → verb
10+
11+
| want | verb |
12+
|---|---|
13+
| list recent change events (filter by window / channel / integration / keyword) | `list` |
14+
15+
## Hot flow — find changes around an incident
16+
17+
```bash
18+
# Pull recent changes in the incident's window, then eyeball label/time overlap with the incident.
19+
fduty change list --since 24h --output-format toon
20+
21+
# Narrow by the integration or channel that emitted them, or by a keyword:
22+
fduty change list --since 48h --integration <integration-id> --query "deploy" --output-format toon
23+
```
24+
25+
<!-- GENERATED:change START · 由 fduty __dump-commands 同步 · 勿手改 fence 内 -->
26+
27+
### list
28+
List changes
29+
- `--channel` string
30+
- `--integration` string
31+
- `--limit` int
32+
- `--page` int
33+
- `--query` string
34+
- `--since` string
35+
- `--until` string
36+
37+
<!-- GENERATED:change END -->
38+
39+
## Key concepts
40+
41+
- **Correlation is heuristic, not relational.** A change is "related" to an incident when their `labels` overlap and their timestamps are close — there is no `incident_id` on a change. Judge the overlap yourself; do not claim a causal link the data doesn't support.
42+
- **`--integration` / `--channel`** scope to the source that emitted the change; **`--since` / `--until`** bound the window (relative like `24h`, `-1h`, `now`, or Unix seconds).
43+
44+
## Gotchas
45+
46+
- **List-only domain.** There is no `change get` / `change detail` verb — `list` (with filters) is the whole surface. Don't guess a detail verb.
47+
- **Empty result is authoritative** — no changes in that window/scope. Report it; don't widen blindly or invent a change to explain the incident.
48+
49+
## Worked example
50+
51+
```bash
52+
# Changes in the last 6h on a specific integration, newest first
53+
fduty change list --since 6h --integration 5759613685214 --output-format toon
54+
```

skills/flashduty/reference/incident.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,30 @@ fduty incident comment <incident-id> --comment "Root cause identified: DB failov
6363
fduty incident resolve <incident-id> --root-cause "DB primary failover delay" --resolution "Failover completed; latency normal."
6464
```
6565

66+
## Hot flow — full fault analysis (read-only summary)
67+
68+
When asked to **summarize / analyze** an incident — 详情 + 关联告警 + 变更 + 时间线 + 相似故障 + 复盘 — `incident detail` does **not** contain the alerts / timeline / similar / post-mortem / change data; each is its own command. **Your first action must be the bundled script** — do not hand-pick one or two commands and write the rest from memory. One call fetches all six aspects:
69+
70+
```bash
71+
bash <skill-dir>/scripts/incident-summary.sh <incident-id>
72+
```
73+
74+
`<skill-dir>` is this skill's base directory — you were given it when the skill loaded (it is also the folder you read this card from). The script runs every command below and prints the results in one block, so each section of your summary is backed by real output and there is nothing to guess. (To tie post-mortems to *this* incident, re-run `incident post-mortem-list --channel-ids <channel-id>` with the `channel_id` from `detail`.)
75+
76+
If you fetch the pieces by hand instead, run **all six** — they are cheap reads:
77+
78+
```bash
79+
ID=<incident-id> # 24-char id from `incident list`
80+
fduty incident detail "$ID" --output-format toon # ① 详情 + AI summary + alert counts + channel_id
81+
fduty incident alerts "$ID" --output-format toon # ② contributing alerts (detail's embedded alerts are empty here)
82+
fduty incident timeline "$ID" --output-format toon # ④ timeline (or `incident feed "$ID"` for the paginated view)
83+
fduty incident similar "$ID" --limit 5 --output-format toon # ⑤ similar past incidents (channel-backed; see Gotchas)
84+
fduty incident post-mortem-list --channel-ids <channel-id> --output-format toon # ⑥ post-mortems for this incident's channel
85+
fduty change list --since 24h --output-format toon # ③ correlated changes — by shared labels + time; see reference/change.md
86+
```
87+
88+
> **Never report a result you didn't fetch.** Do not write "返回空" / "无" / a count for any aspect whose command is **absent from your tool-call history this turn** — write `未查询 — 可运行 <command>` instead. "Empty" is a claim only a command you actually ran can make; inventing it is the worst failure mode of a fault summary.
89+
6690
## Hot flow — resolve, document, and merge duplicates
6791

6892
```bash

skills/flashduty/reference/oncall.md

Lines changed: 0 additions & 94 deletions
This file was deleted.

0 commit comments

Comments
 (0)