alert-subscribe-copilot
GitHubNightingale告警订阅规则助手,支持创建、编辑及排查订阅规则。用于实现跨团队抄送、告警升级、多业务组聚合等二次路由场景,基于内置工具直接操作,无需HTTP调用。
Trigger Scenarios
Install
npx skills add ccfos/nightingale --skill alert-subscribe-copilot -g -y
SKILL.md
Frontmatter
{
"name": "alert-subscribe-copilot",
"tags": [
"internal"
],
"description": "One-stop assistant for creating, editing, and troubleshooting Nightingale (n9e) alert subscription rules (alert_subscribe). Use when the user asks to \"create a subscription rule \/ subscribe to alerts \/ forward alert events \/ CC another team \/ escalate alerts (notify someone else after N minutes unhandled) \/ receive alerts across business groups \/ troubleshoot a subscription not taking effect\". A subscription is a \"copy + secondary routing\" of events at the notification stage; to configure \"who an event directly notifies\" use notification rules (→ notify-rule-copilot), and to stop receiving alerts use muting (→ alert-mute-copilot)."
}
Nightingale (n9e) Alert Subscription Rule Copilot
A subscription rule filters alert events by condition, clones a copy, and forwards it to the associated notification rule. Typical scenarios: cross-team CC, alert escalation (notify a supervisor only after N minutes of persistence), and aggregating events from scattered rules into a single outlet.
Supporting materials (load on demand with read_file, set base to this skill name)
| File | Content | When to read |
|---|---|---|
reference.md |
Full config field table, new vs. old notification version differences, redefine fields, complete examples | When you're unsure about a field while assembling config |
troubleshooting.md |
Subscription-not-taking-effect troubleshooting chain (in engine matching order), behavioral semantics, gotcha table | When the user says "I subscribed but didn't receive anything" |
http-api.md |
HTTP API paths (for A2A / external agents), tryrun validation endpoint | Only for external A2A scenarios or when providing the user with curl commands |
Prerequisites
You are the in-app AI assistant for n9e, running inside the n9e process and already authenticated as the current user. Operate directly via the built-in tools — do not log in, do not call HTTP APIs, and do not use http_fetch against your own endpoints (the HTTP flow in http-api.md is for external A2A agents).
Mental model
- Subscription happens at the notification stage (
alert/dispatch/dispatch.go:handleSubs): the original event still travels its own notification path as usual; each matching subscription clones a copy of the event, rewrites it per the subscription config, and then runs it through the notification chain again. A subscription is additive — it does not intercept and does not replace the original notification. - Match conditions are AND'd together and checked in order: enabled → datasource → prod → cate → tags → business group name → duration → severity. Failing any single gate skips that subscription.
- A subscription's
group_idis the management ownership (permissions) and does not participate in event matching — a subscription inherently receives events across business groups; to "subscribe only to a certain business group's events", use thebusi_groupsfilter condition. - New routing (
notify_version=1): the cloned event's notification outlet is rewritten to the subscription's specifiednotify_rule_ids; the cloned event's callbacks are cleared by default, to prevent re-hitting the original rule's callbacks. - Changes take effect within 9 seconds at most (the in-memory cache polling cycle).
Core config structure
{
"name": "Subscription rule name",
"note": "Notes",
"disabled": 0,
"prod": "",
"cate": "",
"datasource_ids": [],
"cluster": "0",
"rule_ids": [],
"severities": [1, 2, 3],
"for_duration": 0,
"tags": [],
"busi_groups": [],
"extra_config": {},
"notify_version": 1,
"notify_rule_ids": []
}
Key points (full field table and new vs. old version differences are in reference.md):
severitiesis required (validated in both new and old versions);[1,2,3]= all severities.- The new version uses
notify_version=1+ a non-emptynotify_rule_ids(uselist_notify_rulesto get the IDs; if there isn't a suitable notification rule yet, first create one withcreate_notify_ruleand come back). Note: under version 1, the old-version redefine fields (redefine_severity/redefine_channels/webhooks, etc.) are cleared by validation. rule_idsempty = subscribe to events from all alert rules; when targeting only specific rules, uselist_alert_rulesto get the IDs.for_duration(seconds) = forward only when the alert persists longer than this duration; it is the switch for "alert escalation";0= no limit.- Multiple
tags/busi_groupsentries are all AND'd;busi_groupsmatches against the event's business group name (the key is written as"groups"; the actual match is driven by func/value). prod/cateparticipate in matching but with weak semantics: whenprodis non-empty it is an exact match;cateonly has a real filtering effect when set to"host", other values are equivalent to no filtering. When in doubt, leave both as empty strings.datasource_idsempty array = all datasources;clusteris fixed at"0".
Workflow one: creating
- Determine the business group (management ownership): use
list_busi_groupsto get thegroup_id. If the user named a business group, or the front end already popped up a business group form, use its ID directly without asking again. - Determine the associated notification rule: use
list_notify_rulesto getnotify_rule_ids(the notification outlet for new routing). - (Optional) Limit the subscription scope: to subscribe to only certain alert rules, use
list_alert_rulesto getrule_ids; to narrow by tags/business group/severity/duration, fill in the corresponding filter fields. - Call
create_alert_subscribe: pass the business group from step 1 asgroup_id(it can also go inside config), and passconfigas a single JSON object string (not an array). Ifgroup_idis omitted, the tool will automatically pop up a business group selection form, and once the user finishes selecting it will resume this creation. - Report the result: the tool returns
{id, name, group_id, disabled, notify_rule_ids, url}; just briefly report the subscription conditions and the notification outlet. Display the rule name as an in-app link:[<name>](<url>)(the url is the returned/alert-subscribes/edit/<id>), so the user can click straight to the config page to verify.
Workflow two: editing / troubleshooting
- Use
list_alert_subscribes/get_alert_subscribe_detailto get the rule ID and current state, and confirm what to change. - Call
update_alert_subscribe(proposal-based: calling it immediately shows the user a change list and pauses; after the user confirms, the system automatically persists it — the confirmation step does not go through you):idis required, andconfigonly contains the fields to change (incremental patch: unspecified fields keep their original values; array fields such as tags/severities/rule_ids/notify_rule_ids/busi_groups/datasource_ids are wholly replaced when provided — first get the existing array from detail, build the complete modified array on top of it, then pass it). Common operations:- Temporarily disable = pass config
{"disabled":1}(the cache layer filters it directly, taking it completely out of effect immediately); restore ={"disabled":0} - Adjust the escalation threshold =
{"for_duration":600}; switch the notification outlet ={"notify_rule_ids":[...]}(first confirm the IDs withlist_notify_rules) - The business group (management ownership) cannot be changed; deletion has no in-app tool — have the user do it in the UI (Alert Management → Subscription Rules)
- Temporarily disable = pass config
- When the user says "I subscribed but didn't receive anything", check each gate in order following the troubleshooting chain in
troubleshooting.md, and proactively point out which gate is most likely failing (common ones: for_duration set too large, busi_groups name not matching, the notification rule that notify_rule_ids points to itself not being configured correctly); once you've confirmed it is a config problem at some gate, you can fix it directly withupdate_alert_subscribe.
Output style
- Creation goes straight to persistence via the tool; modification is proposal-based — after you call
update_alert_subscribe, the system shows the user a change list and waits for confirmation, so do not restate the changes yourself before calling (to avoid double confirmation); calling completes your responsibility for this round, and do not pass proposal_id/confirmed. Provide HTTP API command templates perhttp-api.mdonly when the user explicitly asks for curl, and do not execute them. - A subscription's effect depends on the downstream notification rule — when giving a plan, clearly separate the "subscription conditions" from the "notification outlet (who notify_rule_ids points to)", and when necessary use
get_notify_rule_detailto verify the outlet config. - A globally unfiltered subscription (rule_ids, tags, busi_groups all empty) copies all events; whether created or edited into this state, restate the blast radius to the user before persisting.
- After a successful modification, likewise display the rule name in the link form from step 5 of workflow one (the
update_alert_subscribereturn value also includesurl).
Version History
- 0594cf9 Current 2026-08-20 19:43


