Skip to main content

alert-subscribe-copilot

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).

Source facts

Repository
ccfos/nightingale
Last source activity
July 1, 2026 at 04:20
Detected SKILL.md language
English
Stars
13,412
Forks
1,793

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
4 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
alert-subscribe-copilot
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).
tags
["internal"]
# 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_id` is 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 the `busi_groups` filter condition. - New routing (`notify_version=1`): the cloned event's notification outlet is rewritten to the subscription's specified `notify_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 ```json { "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`): - **`severities` is required** (validated in both new and old versions); `[1,2,3]` = all severities. - **The new version uses `notify_version=1` + a non-empty `notify_rule_ids`** (use `list_notify_rules` to get the IDs; if there isn't a suitable notification rule yet, first create one with `create_notify_rule` and come back). Note: under version 1, the old-version redefine fields (redefine_severity/redefine_channels/webhooks, etc.) are **cleared** by validation. - `rule_ids` empty = subscribe to events from all alert rules; when targeting only specific rules, use `list_alert_rules` to 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_groups` entries are all **AND**'d; `busi_groups` matches against the event's **business group name** (the key is written as `"groups"`; the actual match is driven by func/value). - `prod` / `cate` participate in matching but with weak semantics: when `prod` is non-empty it is an exact match; `cate` **only 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_ids` empty array = all datasources; `cluster` is fixed at `"0"`. --- ## Workflow one: creating 1. **Determine the business group** (management ownership): use `list_busi_groups` to get the `group_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. 2. **Determine the associated notification rule**: use `list_notify_rules` to get `notify_rule_ids` (the notification outlet for new routing). 3. **(Optional) Limit the subscription scope**: to subscribe to only certain alert rules, use `list_alert_rules` to get `rule_ids`; to narrow by tags/business group/severity/duration, fill in the corresponding filter fields. 4. **Call `create_alert_subscribe`**: pass the business group from step 1 as `group_id` (it can also go inside config), and pass `config` as a single JSON object string (not an array). If `group_id` is omitted, the tool will automatically pop up a business group selection form, and once the user finishes selecting it will resume this creation. 5. **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 1. Use `list_alert_subscribes` / `get_alert_subscribe_detail` to get the rule ID and current state, and confirm what to change. 2. 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): `id` is required, and `config` only 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 with `list_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) 3. 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 with `update_alert_subscribe`. ## Output style 1. 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 per `http-api.md` only when the user explicitly asks for curl, and do not execute them. 2. 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_detail` to verify the outlet config. 3. 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. 4. After a successful modification, likewise display the rule name in the link form from step 5 of workflow one (the `update_alert_subscribe` return value also includes `url`).
View on GitHub