Repository navigation
feat(alerts): maintenance windows - #2323
Merged
Merged
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.
materializewrites each enabled window's next 48 hours as window-ownedalert_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_baselinesdrop their hours from golden-signal baselines - v2
/v2/alerts/maintenance_windowsCRUD withmw_ids and audit events, plus three MCP tools
Before merge
- Migration · Check it is safe on production data and with the code still deployed ·
packages/db/drizzle/20261106195741_alert_maintenance_windows/migration.sql - Migration · Check it is safe on production data and with the code still deployed ·
packages/db/drizzle/20261106203630_merge_maintenance_windows_escalation_lease/migration.sql - Migration · Check it is safe on production data and with the code still deployed ·
packages/db/drizzle/20261106235808_merge_maintenance_windows_escalation_chains/migration.sql - Migration · Check it is safe on production data and with the code still deployed ·
packages/db/drizzle/20261107000733_merge_maintenance_windows_oncall/migration.sql - Manual · Ship migration
20261106195741_alert_maintenance_windows(and its three merge migrations) in the same prd deploy that starts the 15-minute lane
Still open from earlier reviews
- 🔵 Note · F6 · Unchanged check compares a millisecond
updatedAt·packages/backend/src/services/alerts/alert-maintenance-window-sync.ts:112 - 🔵 Note · F7 · The 100-window cap is counted outside the insert transaction ·
packages/backend/src/services/alerts/AlertMaintenanceWindowsService.ts:262 - 🔵 Note · F8 ·
MAINTENANCE_WEEKDAYSrestates the domain's weekday literals ·apps/ai/src/mcp/lib/maintenance-windows.ts:16
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:
forUpdateon the window plusenabled/updatedAtmatch before any write (alert-maintenance-window-sync.ts:105) - Baseline exclusion reads only window-owned opt-out silences, filtered by
orgIdon the(orgId, endsAt)index (alert-maintenance-window-store.ts:101) - Re-enable reopens an ended occurrence through
startedStartsandrefresh(alert-maintenance-window-sync.ts:136), pinned byAlertMaintenanceWindowsService.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.
Loading