Back to Nightingale

Nightingale (n9e) Alert Subscription Rule Copilot

aiagent/skill/embedded/builtin/alert-subscribe-copilot/SKILL.md

9.1.18.6 KB
Original Source

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)

FileContentWhen to read
reference.mdFull config field table, new vs. old notification version differences, redefine fields, complete examplesWhen you're unsure about a field while assembling config
troubleshooting.mdSubscription-not-taking-effect troubleshooting chain (in engine matching order), behavioral semantics, gotcha tableWhen the user says "I subscribed but didn't receive anything"
http-api.mdHTTP API paths (for A2A / external agents), tryrun validation endpointOnly 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).