docs/compliance/terms.md section 7).
Summary
How availability is measured
Theprober runs outside Azure, on a server of the operator, so an outage of the platform
cannot also take down its measurement (deploy/probe.md). Every 30 seconds it
pushes one result per measure to Gatus beside it (docs/reference/observability.md,
Measures), and Uptime Kuma alerts on each measure through ntfy.
- Ingestion (
slo_ingestion) is available in an interval when both answered: the gateway accepted the probe’s web event with 202, and the collector accepted its OTLP metric with 200. Both are real sends through the public endpoints, using an internal probe tenant that is hidden from the operator views. - Dashboards (
slo_dashboard) is available when the console, the web dashboard host and an authenticated metrics API call (/web/hourlywith the probe’s scoped key) all answered. - Freshness is reported separately and is not part of either percentage: probe events older than 10 minutes must be visible through the metrics API, for web and for API data.
slo-report.yml copies each day’s raw results into docs/slo/data/
every night, and on the first day of a month cmd/sloreport computes the month’s
availability per measure from those files and opens a pull request with docs/slo/<YYYY-MM>.md.
The monthly report is the record of whether a target was met. A measure gets a verdict of
met only when the probe measured at least 95% of the covered range (coverage). Below that
floor the verdict is not measured, so a month with one day of clean probe data does not read
as compliant. The one exception is a measure whose failed intervals alone already exceed the
downtime budget: that is missed at any coverage, because the unmeasured time cannot undo it.
TestVerdictCoverageFloor (internal/sloreport) pins these rules. TestCollectThenReport
(cmd/sloreport) and the internal/sloreport tests check the computation against raw data.
How the 24-hour patch target is measured
The steps are in runbooks/security-patch.md. The clock starts when the first signal is filed, not when someone reads it:security.ymlchecks every hour for upstream advisories at the pinned versions (Umami and the Next.js and React it ships, NATS, Caddy, etcd, the collector modules, PostgreSQL), runs Trivy on the deployed image digests, govulncheck andpnpm audit, and opens one issue labelledsecurity-findingper finding;- private reports arrive through GitHub private vulnerability reporting;
- Dependabot opens update pull requests.
Hosting for the service window
The providers (Microsoft Azure, region Sweden Central, and Cloudflare DNS), the monthly cost per environment (about 261 USD for production pay as you go, or about 179 USD with 1-year reserved VMs, read 2026-11-13) and the billing requirements for the 12 months of hosting are in deploy/prerequisites.md, “Hosting”. Who holds the accounts and pays is an open question to SCF and is not decided.What stands behind the targets today
As of 2026-11-13. No production or staging environment exists yet. The domain (veristar.app),
the Azure subscription and the Cloudflare token are supplied, and tofu plan ran against them;
the first apply follows review. The targets are designed for, not yet demonstrated.
Availability
The availability statement with the arithmetic is reference/availability.md. The design keeps ingestion separate from everything that can be slow or down: three edge nodes in three Azure availability zones accept events and metrics into a replicated queue (NATS JetStream, three replicas) and answer without touching PostgreSQL or Umami. The queue holds web events for 72 hours, so a full outage of the core tier costs the dashboards, not ingestion. Windows that follow from the configuration, not from measurement:
With those windows the 99.99% ingestion budget of 259 s a month absorbs five edge losses a
month, and the 99.90% dashboard budget of 2,592 s absorbs 19 core node losses, 64 database
failovers or one 43-minute core outage. The staging drills measure the real windows.
Dependencies
From reference/availability.md, “Dependencies the targets rest on”: one Azure region with three availability zones (the loss of any one zone is tolerated), Traffic Manager and Cloudflare for DNS failover, resolver caching (MultiValue answers carry every healthy address), the port-80 check that sees no TLS failure (the prober checks every node’s certificate andCertificateExpiringSoon fires 14 days ahead), the web event drain rate
of two Umami processes per core node (bursts queue and drain after), two database nodes, and
billing.
What was and was not drilled
The drills of plan phase 16 ran on 2026-11-13 on a local stand-in (six Debian 13 nodes on one host, location delays simulated), not on staging. The record is reference/drills/2026-11-13.md.
Measured on staging, which needs the first apply: Traffic Manager removal timing, backups on
Azure Blob Storage, latency between availability zones, and ACME certificate issuance through
Cloudflare DNS.
Monitoring
37 alert rules (plus 5 recording rules) with promtool tests, the prober, the status page and the SLO report were built and verified on a local test stack (plan phase 17). In the alert fire-drills 16 alerts fired and resolved and 3 more fired for real without a drill (runbooks/alerts.md, “Fire-drills”). The observability role is applied bysite.yml on the edge and core nodes. Not yet done: delivery of alerts to the real
receiver (Discord webhook, input I8) and the probe bundle with its Uptime Kuma monitors on the
operator’s server.