Every incident send carries kind incident, event firing and the incident
id as the platform key. The template order is default_templates.incident,
then the alert's template, then the destination template, so an incident
override that does not fit a destination's transport falls through. Merged
destinations and external subjects use the incident template too.
When update_status_as resolves an incident, each PagerDuty, Opsgenie or
ServiceNow destination in the incident's destination merge gets one
protocol resolve, once, with errors logged and never retried (D8). No other
destination receives a message (D4). A second resolve of an incident that
is already resolved sends nothing. send_templated_to_destination had no
caller left and is deleted.
The anomaly sender calls notify(). An anomaly renders the compiled anomaly
card, or the config's template override, and now reaches email and SNS
destinations (D9). A generic webhook keeps today's JSON until a user
template applies or payload_format says rendered (D1). PagerDuty, Opsgenie
and ServiceNow get a trigger keyed by the anomaly id; the gated recovery
sends them one protocol resolve and sends the resolved card elsewhere (D8).
The scheduler's cooldown, budget, cursor hold and recovery gate are
unchanged.
Templates gain applies_to, stored in its own column. Saving checks the
values and refuses a narrowing that drops a kind an anomaly config, an
alert or the org default still binds. The o2_default_ prefix is reserved;
a migration renames user rows with a reserved name to user_{name} and the
alerts that named them follow.
The default_templates org key is settable through settings v2 and checks
each name. The template list filters by applies_to and type, GET shows
used_by, and delete refuses a template that is still used. Preview and test
send take a kind and return variables_for(kind). anomaly_detection_config
gains a template column.
Add NotificationKind, NotificationEvent and the platform rule table.
The notification context carries the kind, the event, the cluster name
and an optional legacy payload. Template precedence takes ordered level 1
candidates, the D2 reserved rule and the transport rule. The
default_templates org key is written at org creation and by the startup
backfill.
notify() resolves the destination and the template, applies the platform
rule (D8), the Jira rule and the legacy rule (D1), sends once and writes
one log line. It never retries and never records. The alert render and
send function moved to notifications/send.rs; the alert loop and the new
kinds both call it, and alert output is unchanged.
A ServiceNow resolve that finds no open record now returns success.
Preview and test send accept a kind.