Repository navigation
feat(status-pages): page service, publisher, break-glass import, auto incidents - #1929
Merged
Merged
Maple Review Bot / Maple / review
succeeded
Oct 31, 2026 in 1m 10s
Confidence 8/10 · No issues found
🟢 Confidence 8/10 · likely safe to merge. Held at 8 because earlier reviews of this pull request found 7 defects.
3 notes · tests partial −1 · risk medium · 4/4 new units observable · 7 defects fixed in earlier rounds
Adds the status-page service, publisher, break-glass reconciler and auto incidents. The latest commit closes the publish-race, slug-route, defect-swallowing and mid-publish-delete gaps in the publisher and alert tick, each with a test that fails on the old code.
publishclearspublishedHashand bumps the page when its compare-and-set loses- A page deleted mid-publish has its KV/R2 snapshot and route removed via
cleanEdge - An unchanged publish re-reads the slug route and rewrites it when it is gone
syncStatusPagesusesEffect.catchCauseunder a 3 s timeout, so a defect cannot abort the alert tick
Still open from earlier reviews
- 🔵 Note · F11 · No test covers the 3 s bound or the swallowed status-page failure ·
packages/backend/src/services/alerts/AlertsService.ts:674 - 🔵 Note · F16 ·
groupByPagecopies the whole map per key, makingreconcileAllquadratic ·packages/backend/src/services/status-pages/StatusPageReconciler.ts:333 - 🔵 Note · F9 · Heartbeat query scans
uptime_monitor_dailywith no index onday·packages/backend/src/services/status-pages/StatusPagePublisher.ts:226
Fixed since the last review
- ✅
F13 · A lost publish race keeps the winner's hash with a stale KV body, so no sweep rewrites it - ✅
F14 · A defect insyncStatusPagesescapesEffect.catchand aborts the alert tick - ✅
F15 ·putRoutesruns only insideif (written), so a lost or dropped slug route is never rewritten for an unchanged page
Production impact
Production traffic of the changed files (last 7 days)
| File | Calls/day | Busiest operations |
|---|---|---|
packages/backend/src/services/status-pages/status-page-test-support.ts |
1.7k | GET 985/day, 1.4% errGET 701/day, 11.2% err |
packages/backend/src/services/status-pages/StatusPagePublisher.ts |
1.1k | StatusPagePublisher.sweep 526/day, 0.1% errStatusPagePublisher.heartbeat 525/day, 0.0% errStatusPagePublisher.publish 81/day, 0.0% err |
packages/backend/src/services/status-pages/StatusPageReconciler.ts |
1.1k | StatusPageReconciler.reconcileAll 526/day, 0.0% errStatusPageReconciler.repairAutoIncidents 526/day, 0.1% err |
packages/backend/src/services/status-pages/StatusPageStore.ts |
1.1k | StatusPageStore.call 1.1k/day, 0.0% err |
packages/backend/src/services/status-pages/StatusPageSnapshotBuilder.ts |
81 | StatusPageSnapshotBuilder.build 81/day, 0.0% err |
packages/backend/src/services/status-pages/StatusPagesService.ts |
26 | StatusPagesService.get 16/day, 8.3% errStatusPagesService.listComponents 10/day, 11.4% err |
Telemetry this change adds and removes (18)
- ➕ span name
StatusPageReconciler.reconcilePage·packages/backend/src/services/status-pages/StatusPageReconciler.ts:243 - ➕ span name
StatusPageReconciler.reconcile·packages/backend/src/services/status-pages/StatusPageReconciler.ts:336 - ➕ span name
StatusPagesService.list·packages/backend/src/services/status-pages/StatusPagesService.ts:540 - ➕ span name
StatusPagesService.create·packages/backend/src/services/status-pages/StatusPagesService.ts:558 - ➕ span name
StatusPagesService.update·packages/backend/src/services/status-pages/StatusPagesService.ts:609 - ➕ span name
StatusPagesService.remove·packages/backend/src/services/status-pages/StatusPagesService.ts:667 - ➕ span name
StatusPagesService.rotateBreakGlassToken·packages/backend/src/services/status-pages/StatusPagesService.ts:689 - ➕ span name
StatusPagesService.revokeBreakGlassToken·packages/backend/src/services/status-pages/StatusPagesService.ts:718 - ➕ span name
StatusPagesService.createComponent·packages/backend/src/services/status-pages/StatusPagesService.ts:762 - ➕ span name
StatusPagesService.updateComponent·packages/backend/src/services/status-pages/StatusPagesService.ts:815 - ➕ span name
StatusPagesService.removeComponent·packages/backend/src/services/status-pages/StatusPagesService.ts:866 - ➕ span name
StatusPagesService.reorderComponents·packages/backend/src/services/status-pages/StatusPagesService.ts:888 - ➕ span name
StatusPagesService.listIncidents·packages/backend/src/services/status-pages/StatusPagesService.ts:931 - ➕ span name
StatusPagesService.getIncident·packages/backend/src/services/status-pages/StatusPagesService.ts:957 - ➕ span name
StatusPagesService.createIncident·packages/backend/src/services/status-pages/StatusPagesService.ts:965 - ➕ span name
StatusPagesService.postUpdate·packages/backend/src/services/status-pages/StatusPagesService.ts:1037 - ➕ span name
StatusPagesService.updateIncident·packages/backend/src/services/status-pages/StatusPagesService.ts:1090 - ➕ span name
StatusPagesService.removeIncident·packages/backend/src/services/status-pages/StatusPagesService.ts:1146
What was checked
- Lost-race branch sets
publishedHash: nullandbumpPage, so the next sweep rewrites the body (StatusPagePublisher.ts:156,170) catchCausecatches defects, not just typed failures (AlertsService.ts:679), andsummarizeCauseis imported- Slug-route repair compares the KV page id before rewriting, so another page's slug is untouched (StatusPagePublisher.ts:121-126)
Observability coverage: 4 of 4 changes observable
| Change | Kind | Observable | Evidence |
|---|---|---|---|
| StatusPagePublisher.publish | worker step | yes | StatusPagePublisher.publish span with maple.status_page.id, revision, written (StatusPagePublisher.ts:86,172) |
| StatusPagePublisher.sweep | cron sweep | yes | StatusPagePublisher.sweep span with due/written/failed/cleaned counts and per-page failure logs (StatusPagePublisher.ts:263,308,336) |
| StatusPagePublisher.heartbeat | cron side-write | yes | own span plus a warning log on store failure (StatusPagePublisher.ts:243,331) |
| Auto incident open/resolve from the alert tick | background write in alert evaluation | yes | runs inside the traced alert tick; timeout/failure logged with orgId and maple.alert.incident_id (AlertsService.ts:680-687) |
4b26f13 · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.
Loading