Skip to content

feat: SLOs & uptime reports, status-page incident publications, PagerDuty (replaces Opsgenie), remote-CDP browser checks, SMTP send-mode - #240

Merged
fclairamb merged 438 commits into
mainfrom
batch/2026-08-17
Aug 20, 2026
Merged

fclairamb merged 438 commits into
mainfrom
batch/2026-08-17

Conversation

@fclairamb

@fclairamb fclairamb commented Aug 18, 2026 •

Copy link
Copy Markdown
Owner

Summary

A large batch branch (batch/2026-08-17) landing ~30 audited specs. Highlights, grouped:

New capabilities

  • Service Level Objectives — define an SLO over a check or group with a rolling or calendar window; status, error budget and a per-step burn-down chart. DST-safe calendar math, maintenance tagged at ingest so planned downtime never eats the budget, maxSlos entitlement, full dash0 list/detail/edit pages and an SLO coverage chip.
  • Scheduled uptime reports — recurring email digest attached to an SLO: schedule CRUD, test send, delivery job, email template with List-Unsubscribe headers and per-recipient links.
  • Status-page incident publications — a first-class editable overlay on top of a check incident: manual publish/unpublish or page-level auto-publish with a debounce and per-resource override, resolve/relapse sync, subscriber fan-out, webhook events. status0 renders active publications, a severity banner, affected-component badges and a collapsible history; dash0 gets page settings, the publish block and a dedicated editor route. Also exposed via MCP.
  • Incident failure diagnostics — opt-in capture of the failing HTTP response, persisted on incident open/reopen, shown as a "What the probe saw" card. Carried on a dedicated Diagnostics channel and kept out of the assertion body so enabling it cannot move a verdict.
  • PagerDuty (Events API v2) replaces Opsgenie across backend, dashboard and docs.
  • Matrix as an org-level notification integration.
  • Remote-CDP browser checks — checkers.browser.cdp_url / chrome_path, concurrency cap, a per-region browser capability reported by workers, a creation-time warning when a region has no headless Chrome, surfaced under the region picker.
  • Send-mode SMTP checks — submit a real probe email and pair it with delivery.
  • Change password from the dashboard — authenticated POST /api/v1/auth/change-password plus a Password card on the account security page.
  • Agent build versions — reported over the wire, stored, surfaced in AgentResponse and flagged on drift; long-revoked agents are purged by agent_gc and a second DELETE purges immediately.

Reliability & observability

  • Migration integrity guard — catches migrations whose content changed after being recorded as applied (the failure that silently skipped 013 and left workers.capabilities missing). warn mode, a self-healing 014, and a solidping migrate repair CLI.
  • Abandoned result status — abandoned probes are reaped into a dedicated status, excluded from availability, declared in OpenAPI and rendered neutrally.
  • Slow-query WARNs with a callsite label, a results row-count gauge, db.slow_query_threshold (default 500ms).
  • Sentry — 5xx reporting from the handler error funnel, check/job panic tags, the recovery middleware the panic path was re-panicking into (mounted inside the request timeout), environment defaulted to the run mode, SP_SENTRY_TRACES_SAMPLE_RATE bound.

Performance

  • Per-check availability fans out with a bounded errgroup instead of a serial loop (~8s → parallel).
  • Incidents list N+1 removed: member enrichment opt-in via with=members, the rest batched into ≤3 queries per page.
  • Uptime bar split into tier-aligned raw and rollup queries, raw retention resolved from live performance parameters.

Fixes

mail_from SMTP/header-injection hole closed · auto-slug races on create/clone · JSONPath assertions with no body matcher · notification route/contact deletion + dangling-route cleanup · SQLite post-006 unique index across the 016 rebuild · results list with=checkSlug,checkName join · status0 availability-bar tooltip staleness · 2FA temp token as a Bearer header · blast-radius UUIDs/overflow · duplicate empty-state CTAs.

BREAKING CHANGE: Opsgenie is removed — migration 015 hard-deletes existing Opsgenie integrations on upgrade; recreate them as PagerDuty integrations using an Events API v2 routing key.

BREAKING CHANGE: the results list endpoint no longer returns pagination.total, nextCursor or hasMore — they were never populated with real values.

Test plan

  • make test — backend suite green
  • make lint — backend + dash lint clean (no new errors in touched files)
  • make test-dash — dash0 Playwright E2E green
  • Each spec independently audited for completeness before archiving; negatives covered with positive controls (storm-cap and leak tests, concurrency pinned by a counting barrier rather than wall-clock)

fclairamb and others added 29 commits August 19, 2026 02:22
Line 37's 10-native-channels list already counted PagerDuty as shipped;
line 65's gap list still called it missing, contradicting itself. Telegram
and Microsoft Teams stay listed as the genuine remaining gaps.
Line 37's 10-native-channels list already counted PagerDuty as shipped;
line 65's gap list still called it missing, contradicting itself. Telegram
and Microsoft Teams stay listed as the genuine remaining gaps.
New top-level Comparisons docs section, seeded with an honest
Checkmate comparison: stacks, check-type mapping, distribution
models (first-party regions vs GlobalPing), and manual-migration
guidance since no Checkmate importer exists yet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fclairamb and others added 22 commits August 20, 2026 20:27
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tate CTA

The "Empty state: no rows at all" prose told every page to add a primary CTA
button inside the empty card, duplicating the create action already in the
page header. Rewrite the rule to icon + title + hint only, and drop the
button from the live preview and importLine snippet to match.
…pages

status-updates, escalation-policies, on-call, my-notifications, and slos each
rendered a create/settings button inside the empty-state card that duplicated
the action already in the page header. Drop the in-card button on all five,
matching the Maintenance Windows empty-state structure (icon, title, hint,
nothing else). me.notifications keeps its icon/title/hint stack, only the
button is removed.
Sweep for the same duplicate-CTA pattern beyond the five pages named in the
spec turned up status-pages.index.tsx, which also gained an in-card "New
Status Page" button today. Remove it; the header already has one. Swept the
rest of the *.index.tsx list routes (integrations, report-schedules,
private-locations, jobs, dependencies, discovery, account.organizations,
incidents) — none duplicate their header CTA inside the empty-state block.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ry call site

Collapses the ProtocolBadge if-chain (checks.index.tsx) and the duplicated
PROTOCOL_BADGE_TONES copy (design-reference.tsx) into CheckTypeBadge. Adds a
leading tone-colored icon to the type picker and the check detail page.
… chrome

StatusUpdateCard gains variant?: "card" | "plain" (default "card"). Plain
drops the rounded/border/bg/p-4 chrome while keeping id/scroll anchor,
header, badges, hardened Markdown body, "Read more" link, and all
data-testid hooks. StatusUpdateThreadList threads the variant through and
both nested call sites (active-incident card, "Incident thread" timeline
section) now pass variant="plain" so updates no longer render as a
card-inside-a-card. Standalone timeline updates keep the default "card".
Extends the existing "open publication renders..." E2E test to check the
narrative update nested inside the active-incident card carries none of
its own rounded/border/bg-card classes, confirming the plain variant is
applied.
Replace the plain grey Badge on the discovery scan detail page with the
registry-driven CheckTypeBadge, matching the checks list rendering.
- generic attachments and incident screenshots
- status update edit changes not saved
- organization breadcrumb missing tabs
- test report send returns 202 with an empty body
@fclairamb fclairamb changed the title Availability fan-out, blast-radius table, Sentry env binding, incidents N+1, migration integrity guard feat: SLOs & uptime reports, status-page incident publications, PagerDuty (replaces Opsgenie), remote-CDP browser checks, SMTP send-mode Aug 20, 2026
@fclairamb
fclairamb enabled auto-merge (squash) August 20, 2026 23:06
@fclairamb
fclairamb merged commit 749f108 into main Aug 20, 2026
11 checks passed
@fclairamb
fclairamb deleted the batch/2026-08-17 branch August 20, 2026 23:33
fclairamb added a commit that referenced this pull request Aug 20, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.17.0](v0.16.2...v0.17.0)
(2026-08-20)


### Features

* **analytics:** serve PostHog capture first-party through /ingest
([#235](#235))
([b9f6858](b9f6858))
* SLOs & uptime reports, status-page incident publications, PagerDuty
(replaces Opsgenie), remote-CDP browser checks, SMTP send-mode
([#240](#240))
([749f108](749f108))


### Bug Fixes

* **deps:** update go dependencies (non-major)
([#243](#243))
([29a25af](29a25af))
* **deps:** update module github.com/arran4/golang-ical to v0.3.6
([#242](#242))
([5d53ff8](5d53ff8))
* **deps:** update module github.com/rabbitmq/amqp091-go to v1.14.0
([#241](#241))
([7fd51a3](7fd51a3))
* **deps:** update module github.com/stretchr/testify to v1.12.0
([#236](#236))
([763543f](763543f))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
This was referenced Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant