| Plane separation |
Paging path apart from the incident record |
This design |
One highly available application |
99.99% paid for on the path that wakes people only |
ADR-01 |
| Paging-path runtime |
Static Go binaries under systemd on dedicated hosts |
Open source |
Estate Kubernetes; per-cell Kubernetes |
Nothing it pages for is underneath it |
ADR-02 |
| Site topology |
Three active cells, one outside the estate; warm control plane |
This design |
Two sites; active-active control plane |
Survives losing both estate sites; control plane gets the RTO asked for |
ADR-03 |
| Partition behaviour |
Minority cells keep paging and label events |
This design |
Stop without quorum |
Duplicates are survivable; silence is not |
ADR-04 |
| Build boundary |
Build paging core; adopt the rest |
This design |
GoAlert; Grafana OnCall OSS |
Requirement-specific core owned, general operations borrowed |
ADR-05 |
| Paging state and streams |
NATS JetStream |
Open source |
Apache Kafka; etcd |
Streams, KV with CAS and TTL, Raft placement, one binary |
ADR-06 |
| Storm isolation |
Site-local ingest domain, three-site paging domain |
This design |
One stretched domain |
Bulk traffic never crosses a site link |
ADR-07 |
| System of record |
PostgreSQL append-only event log on CloudNativePG |
Open source |
Mutable record; dedicated event store |
Defensible history on a database the team can restore |
ADR-08 |
| Ledger archive and reporting |
ClickHouse |
Open source |
PostgreSQL; OpenSearch |
Columnar scans and TTL retention for 13 months of attempts |
ADR-09 |
| Tamper evidence |
Ceph RGW with Object Lock |
Open source |
WORM appliance |
Immutability enforced outside the database |
ADR-09 |
| Ingest edge |
HAProxy stick-table quotas, Go gateway, CEL mappings |
Open source |
Per-source adapter code |
Cheap refusal of the offender; mappings without deploys |
ADR-10 |
| Email ingest |
Postfix, per-integration addresses |
Open source |
IMAP polling |
Push delivery, sender allowlists, no mailbox dependency |
ADR-10 |
| Grouping |
Explicit keys within a service |
This design |
Topology-aware correlation |
Never hides a second failure in another service |
ADR-11 |
| Suppression |
Declared, expiring, recorded; attach not drop |
This design |
Automatic dependency suppression |
Silence is something a person signs for |
ADR-12 |
| Severity |
Declared, bound to obligation profiles |
This design |
Computed from signals |
Humans correct the rule and obligations follow |
ADR-13 |
| Coverage |
72 h of 15-minute buckets in JetStream KV |
This design |
Page-time resolution |
One read, survives three days of control-plane outage |
ADR-14 |
| Timezone correctness |
Two independent resolvers (Go and Python zoneinfo) |
This design |
One resolver with tests |
Disagreement catches what one author's tests miss |
ADR-15 |
| Escalation trigger |
Step timer on missing acknowledgement |
This design |
Advance on delivery failure |
Receipts speed up a step; only acknowledgement ends one |
ADR-16 |
| Timers |
Sharded wheels over durable KV records with leases |
This design |
Broker scheduled messages; polled rows |
Second-level accuracy, takeover in 3 s |
ADR-17 |
| Handoff |
Union of outgoing and incoming until acknowledged |
This design |
Pin or re-resolve |
No unpaged minute at a boundary |
ADR-18 |
| Duplicate control |
60-second claim per responder, channel, incident, step |
This design |
Exactly-once dispatch |
Retries stay safe; uncertainty sends |
ADR-19 |
| Voice |
Asterisk with PJSIP trunks to two carriers |
Open source |
FreeSWITCH |
IVR with DTMF acknowledgement, widely operated |
ADR-20 |
| SMS |
Jasmin SMS gateway over SMPP to two carriers |
Open source |
Kannel |
SMPP routing with inbound replies as acknowledgements |
ADR-20 |
| Push |
Push relay to APNs and FCM; own responder app |
This design |
Self-hosted UnifiedPush relay |
Only route that wakes iOS; entitlement held by own app |
ADR-20 |
| Provider failover |
Same channel on failure, next channel on silence |
This design |
Same channel on any trigger |
Fast failover without duplicate SMS |
ADR-21 |
| Acknowledgement |
Signed single-use tokens on every channel |
This design |
Console login |
Works through identity and DNS outages |
ADR-22 |
| Exhaustion |
Terminal state, repeating broadcast, platform SEV2 |
This design |
Silent close |
The worst outcome is the loudest |
ADR-23 |
| Chat |
Mattermost Team Edition via a chat bridge |
Open source |
Matrix with Element; Zulip |
Existing organisational chat; asynchronous, never on the paging path |
ADR-24 |
| Service catalogue |
YAML in Git, Backstage catalog-info format |
This design |
Backstage as runtime |
One reviewed ownership source, readable by other tools |
ADR-24 |
| Reviews and search |
Generated drafts; PostgreSQL full-text search |
Open source |
Wiki; OpenSearch |
Facts computed, blameless by template, search at the right scale |
ADR-25 |
| Identity |
Keycloak broker with WebAuthn break-glass |
Open source |
Direct federation |
Console reachable during identity outages, with fewer powers |
ADR-26 |
| Secrets |
OpenBao |
Open source |
HashiCorp Vault |
Vault's API under an open-source licence (MPL 2.0) |
ADR-27 |
| Contact data protection |
Per-responder keys via OpenBao transit |
This design |
Row deletion |
Erasure across immutable stores and backups |
ADR-28 |
| Sensitive incidents |
PostgreSQL row-level security, audited restriction |
Open source |
Separate tool |
Enforced for every reader; nothing hidden quietly |
ADR-29 |
| Self-verification |
Minute synthetic, site-C dead-man switch, Gammu fallback kit |
This design |
Internal health checks |
Watched from outside, fallback actually exercised |
ADR-30 |
| Release |
Forgejo, Harbor, cosign, Ansible in gated cell waves |
Open source |
All cells at once |
One failure domain at a time, rollback without network |
ADR-31 |
| Cost and human load |
Ledger-priced attempts, ClickHouse weekly report |
This design |
Central unattributed budget |
Noise has a price its owner sees |
ADR-32 |