Skip to content

feat(alerts): maintenance windows - #2323

Merged
Makisuo merged 64 commits into
mainfrom
feat/alerts-maintenance-windows
Nov 7, 2026
Merged

Makisuo merged 64 commits into
mainfrom
feat/alerts-maintenance-windows

Merge remote-tracking branch 'origin/main' into feat/alerts-maintenan…

1a16bad
Select commit
Loading
Failed to load commit list.
Maple Review Bot / Maple / review succeeded Nov 7, 2026 in 4m 0s

Confidence 10/10 · No issues found

🟢 Confidence 10/10 · safe to merge. Two child reviewers returned unusable output, so I read the sync, service, schema, route, MCP and test hunks myself; three earlier notes remain unfixed.
3 notes · tests covered · risk medium · 4/4 new units observable

Adds maintenance windows end to end: schedule model, a 15-minute lane writing occurrences as alert_silences, v2 CRUD, three MCP tools, anomaly baseline exclusion. No new defect; the three earlier notes remain unfixed, and the McpQueryError/VcsWebhookEnqueueFailure stacks this touches are untouched.

  • materialize writes each enabled window's next 48 hours as window-owned alert_silences
  • Silence API refuses to edit or end a window's silences; they skip the 200 open-silence cap
  • Occurrences that ran with exclude_from_baselines drop their hours from golden-signal baselines
  • v2 /v2/alerts/maintenance_windows CRUD with mw_ ids and audit events, plus three MCP tools

Before merge

Still open from earlier reviews

Production impact

Open errors in the changed files (3)
Issue Service Occurrences File
@maple/mcp/errors/McpQueryError (4 issues) maple-chat 30 apps/ai/src/mcp/tools/registry.ts
@maple/api/routes/VcsWebhookEnqueueFailure (2 issues) maple-api 9 apps/api/src/runtime/http-graph.ts
@maple/mcp/errors/McpQueryError (4 issues) maple-ai 12 apps/ai/src/mcp/tools/registry.ts

After this merges, Maple checks whether they stop.

Telemetry this change adds and removes (13)
  • ➕ span name McpTool.createMaintenanceWindow · apps/ai/src/mcp/tools/create-maintenance-window.ts:116
  • ➕ span name McpTool.deleteMaintenanceWindow · apps/ai/src/mcp/tools/delete-maintenance-window.ts:24
  • ➕ span name McpTool.listMaintenanceWindows · apps/ai/src/mcp/tools/list-maintenance-windows.ts:27
  • ➕ span name AlertMaintenanceWindowsService.findRow · packages/backend/src/services/alerts/AlertMaintenanceWindowsService.ts:145
  • ➕ span name AlertMaintenanceWindowsService.requireRuleIds · packages/backend/src/services/alerts/AlertMaintenanceWindowsService.ts:167
  • ➕ span name AlertMaintenanceWindowsService.materializeWindow · packages/backend/src/services/alerts/AlertMaintenanceWindowsService.ts:196
  • ➕ span name AlertMaintenanceWindowsService.list · packages/backend/src/services/alerts/AlertMaintenanceWindowsService.ts:210
  • ➕ span name AlertMaintenanceWindowsService.get · packages/backend/src/services/alerts/AlertMaintenanceWindowsService.ts:230
  • ➕ span name AlertMaintenanceWindowsService.create · packages/backend/src/services/alerts/AlertMaintenanceWindowsService.ts:239
  • ➕ span name AlertMaintenanceWindowsService.update · packages/backend/src/services/alerts/AlertMaintenanceWindowsService.ts:301
  • ➕ span name AlertMaintenanceWindowsService.delete · packages/backend/src/services/alerts/AlertMaintenanceWindowsService.ts:362
  • ➕ span name AlertMaintenanceWindowsService.materialize · packages/backend/src/services/alerts/AlertMaintenanceWindowsService.ts:463
  • ➕ span name AlertSilencesService.requireUnmanaged · packages/backend/src/services/alerts/AlertSilencesService.ts:160
What was checked
  • Race guard: forUpdate on the window plus enabled/updatedAt match before any write (alert-maintenance-window-sync.ts:105)
  • Baseline exclusion reads only window-owned opt-out silences, filtered by orgId on the (orgId, endsAt) index (alert-maintenance-window-store.ts:101)
  • Re-enable reopens an ended occurrence through startedStarts and refresh (alert-maintenance-window-sync.ts:136), pinned by AlertMaintenanceWindowsService.sync.test.ts:193
Observability coverage: 4 of 4 changes observable
Change Kind Observable Evidence
maintenance_windows 15-minute lane cron yes makeTick span plus maple.maintenance_window.* attributes and failure/timeout logs (AlertMaintenanceWindowsService.ts:479, apps/alerting/src/scheduled.ts:293)
v2 maintenance window endpoints (list/retrieve/create/update/delete) HTTP handler yes Effect.fn spans AlertMaintenanceWindowsService.*; group wired at apps/api/src/runtime/http-graph.ts:51
MCP list/create/delete maintenance window tools MCP tool yes Effect.fn("McpTool.*MaintenanceWindow*") with orgId/result.rowCount attributes (list-maintenance-windows.ts:35)
maintenance exclusions read in the anomaly detector DB query yes maple.anomaly.maintenance_exclusions span attribute (AnomalyDetectionService.ts:1365)

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