Skip to content

feat(alerts): anomalies page through alert rules - #2318

Merged
Makisuo merged 14 commits into
mainfrom
feat/alerts-unified-incidents
Nov 6, 2026
Merged

Makisuo merged 14 commits into
mainfrom
feat/alerts-unified-incidents

fix(alerts): unrouted anomaly tiers never push; disabling detection r…

6204940
Select commit
Loading
Failed to load commit list.
Maple Review Bot / Maple / review completed Nov 6, 2026 in 3m 40s

Confidence 6/10 · 1 issue to address

🟡 Confidence 6/10 · needs attention. Held at 6 because a correctness warning is open.
1 warning −1 · 1 note · tests covered · risk high −1 · 3/3 new units observable

Anomalies now page through alert rules: a new anomaly signal that reads the detector instead of the warehouse, one protected unscoped default rule per org, scoped rules with assignment and handover, and group_label in place of the incident id across transports, MCP, v2 and the dashboard. The implementation reads sound and is well tested; the open v2 enum break for installed iOS builds is the one unresolved issue.

  • AnomalyAlertSource turns the detector's open anomalies into per-rule observations
  • assignAnomalyRule picks the most specific qualifying rule, ties by lowest id
  • One unrouted default anomaly rule per org, guarded from delete, disable and scoping
  • groupLabel replaces the anomaly incident id in channels, MCP, v2 and web

Before merge

Still open from earlier reviews

Production impact

Production traffic of the changed files (last 7 days)
File Calls/day Busiest operations
packages/backend/src/services/alerts/AlertDeliveryDispatch.ts 25 test 25/day, 19.3% err
packages/backend/src/services/alerts/alert-formatting.ts 25 test 25/day, 19.3% err
Telemetry this change adds and removes (3)
  • ➕ span name AnomalyAlertSource.observe · packages/backend/src/services/alerts/anomaly/AnomalyAlertSource.ts:126
  • ➕ span name AnomalyAlertSource.backfillDefaultRules · packages/backend/src/services/alerts/anomaly/AnomalyAlertSource.ts:384
  • ➕ span name AnomalyAlertSource.observeScope · packages/backend/src/services/alerts/anomaly/AnomalyAlertSource.ts:386
What was checked
  • Anomaly rules skip orphan probing and keep their heartbeat state row (AlertsService.ts:5342-5355; eligible keeps the ungrouped key)
  • Assignment order and handover read in anomaly-rule.ts: specificity descends, id ascends, handover only on strictly more specific
  • Default-rule delete/disable/scope guards and cap exclusion read at AlertRulesService.ts:276-320; every read filters orgId
Observability coverage: 3 of 3 changes observable
Change Kind Observable Evidence
Anomaly rule evaluation in the alerting tick (evaluateRule to AnomalyAlertSource.observe) cron worker step yes Effect.fn("AnomalyAlertSource.observe") span with maple.alert.observation_count, existing evaluateRule span and AlertingMetrics.ruleEvaluationDurationMs
Default anomaly rule backfill tick (anomaly_default_rules) cron yes Effect.withSpan("AnomalyAlertSource.backfillDefaultRules") plus makeTick timer, completion log and maple.alerting.tick
v2 alert rule and incident fields (anomaly_signals, anomaly_incident_id, group_label) HTTP API surface yes existing v2 route spans; no new outbound call added

6204940 · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.