Skip to content

Incident runbook

How to declare, work, and close a platform incident. The firm commits to 99.9% monthly availability (43.2 minutes of error budget per 30 days).

Severity targets

| Severity | Acknowledge within | Resolve within | |----------|-------------------|----------------| | SEV1 | 15 minutes | 4 hours | | SEV2 | 1 hour | 24 hours | | SEV3 | 8 hours | 7 days |

The drill clock starts at openedAt. A drill passes only when both the acknowledgment and the resolution land inside their targets.

Declare (SUPER_ADMIN only)

  1. POST /api/status with { "action": "open", "id", "title", "severity" }.
  2. IDs must be unique — replays return 409.

  3. Confirm the public page moves: GET /api/status (no auth) and /status.
  4. Any open SEV1 reads as an outage; any open SEV2 reads as degraded.

Work

  1. POST /api/status with { "action": "acknowledge", "id" } the moment a
  2. human owns the incident. Re-acks are safe no-ops.

  3. Keep firm data paths untouched: incident records live in the shared
  4. platform namespace, never in firm rows.

  5. Page the firm through the normal dispatch channels; do not improvise new
  6. recipient lists mid-incident.

Resolve

  1. POST /api/status with { "action": "resolve", "id" }. Skipped
  2. acknowledgments are stamped at resolve time so the clock stays honest.

  3. Verify /status returns to operational. Resolved rows stay in history —
  4. the page derives state at read time, so nothing can stick on outage.

  5. Read the drill verdict off the incident timestamps before the retro:
  6. ack minutes and resolve minutes against the table above.

Client notice

Every successful write returns { incident, notice } alongside the incident. The notice is the client-facing message for that exact event — subject carries severity and title ([SEV1] Incident Opened: ...) for inbox triage; the body carries id, severity, reached-event timestamps, and the /status pointer. Forward it verbatim through the normal dispatch channels; do not reword severity or timestamps.

Rules

Source: docs/dev/incident-runbook.md