How we run incident response in Rootly: the service topology, the public status page, and the on-call rotation. This is the source of truth; the Linear project Rootly — Incident Management & On-Call tracks the setup work and links here.

Model

Rootly has three catalogs, and they’re easy to conflate:

  • Services — internal infra components. Alerts route here.
  • Functionalities — customer-observable capabilities. These feed the status page.
  • Environments — deploy stage (Production / Staging).

Many services roll up into one functionality. Only Production pages.

Topology

flowchart LR
  subgraph SRC[Alert sources · v1]
    SEN[Sentry]
    GCP[GCP monitoring + uptime]
    GRA[Grafana / Prometheus]
  end

  subgraph SVC[Rootly Services · internal]
    GW[Groudon Gateway]
    GH[Groudon Health]
    GA[Groudon Admin]
    GD[Groudon Dashboard]
    HA[Honcho API]
    HD[Honcho Deriver]
    XI[Xatu Ingestion]
    XC[Xatu Consumer]
    SA[Supabase Auth]
    TC[Tentacruel · LiteLLM]
    MG[Metagross · vLLM]
  end

  subgraph FUN[Functionalities → status page]
    F1[REST API]
    F2[Memory processing]
    F3[Recall / Dialectic]
    F4[Dashboard]
    F5[Website & Docs]
    F6[Authentication]
    F7[Billing & usage]
  end

  SRC --> ROUTE{{Alert routing · env=Production}}
  ROUTE --> EP[Escalation: Primary → Secondary → all-Platform]
  ROUTE -.tags service.-> SVC

  GW --> F1
  HA --> F1
  HA --> F3
  HD --> F2
  GD --> F4
  SA --> F6
  XI --> F7
  XC --> F7

Environments

Grounded in groudon/.env (APP_ENV = development | staging | honcho-production-saas).

  • Production — required, red; the only environment that pages. Gate every paging workflow on Environment = Production.
  • Staging — non-paging (Slack only).
  • Development is not modeled — don’t create environments you don’t operate distinctly.

Services (internal catalog)

ServiceRepo / processAlert sourcesNotes
Groudon Gatewaygroudon · gateway :8000GCP uptime, Sentry, GrafanaPublic API routing by key
Groudon Healthgroudon · health :9090Grafana, SentryMonitoring, recovery, upgrades, placeholder pool
Groudon Adminadmin :8001SentryInternal tenant/user mgmt
Groudon Dashboarddashboard (Next.js, app.honcho.dev)GCP uptime, SentryVercel
Honcho APIhoncho · api :8000GCP uptime, Sentry, GrafanaREST + dialectic
Honcho Deriverhoncho · deriverGrafana, Sentryderiver + dreamer background agents
Xatu Ingestionxatu · ingestion :9000Sentry, GrafanaCloudEvents intake
Xatu Consumerxatu · consumerSentryRedpanda → S3/Stripe
AlloyDB (control plane)managedGrafana / GCPGroudon groudon schema
AlloyDB (tenant)managedGrafana / GCPOne database per Honcho instance
Supabase AuthmanagedmanualDashboard auth (JWT, MFA)
Tentacruelplatform/tentacruelSentry, GrafanaLiteLLM proxy — LLM routing
Metagrossplatform/metagrossGrafanavLLM inference (tinybox)

Per-tenant modeling. “One tenant = one Honcho instance” is ~22,300 instances across 46 GKE clusters. Do not create a Rootly service per tenant. Keep Honcho API and Honcho Deriver as one logical service each; carry cluster and namespace as alert fields so routing and filtering still work per-tenant.

Public status page

status.honcho.dev, Honcho Cloud only — side-products (Kyogre etc.) stay off. 7 components in 3 groups + an informational providers group.

GroupComponentBacking servicesHealth signal
APIREST API (api.honcho.dev)Groudon Gateway + Honcho APIauto — GCP uptime
Memory processingHoncho Derivermanual → Grafana deriver-queue-depth probe
Recall / DialecticHoncho API (dialectic)manual → deep uptime check on dialectic endpoint
WebDashboard (app.honcho.dev)Groudon Dashboardauto — GCP uptime
Website & Docs (honcho.dev)Vercel / Cloudflareuptime check TBD — add to M2
AccountAuthenticationSupabase Authmanual (or link Supabase status)
Billing & usageXatumanual
Model providers (info)Anthropic / OpenAI / Vertexinformational — link provider status pages

Ship manual signals as manual-during-incident and add probes as they come online — don’t block launch on them.

On-call

One combined weekly on-call rotation — one hat, dev-team-staffed (decided 2026-07-23). The weekly owner carries both jobs; split into two hats only if volume outgrows one. (“Rotation” here means the org duty, not a Rootly object — see Schedules vs. rotations below.)

  • Incidents (paging) — prod alerts from Sentry / GCP / Grafana, and postmortems. Real paging.
  • Support & OSS (non-paging) — Discord + email Q&A, OSS issue/PR triage, contributor Q&A. Run the pr-triage skill at handoff. First-response + routing; deep code review routes to the area reviewer, not the on-call person.

Schedules vs. rotations (Rootly terms). A schedule is an on-call role that resolves to exactly one person at any moment (it’s what the escalation policy pages); a rotation is the rule inside a schedule that fills it — member order + cadence + handoff. One hat ≠ one schedule: our single combined hat is built as two schedules, Platform Primary and Platform Secondary, because a primary plus a live backup must be two schedules (one schedule = one current person). Each has a single weekly rotation over the same dev-team list, offset a week so this week’s Secondary is next week’s Primary. The escalation policy pages Primary → Secondary → all-Platform. (Multiple rotations within one schedule are only for splitting one seat across time — e.g. follow-the-sun — which we don’t need yet.)

Escalation vs. notification. The escalation policy escalates the person (Primary → 5m → Secondary → 5m → all-Platform). Each person’s notification rules escalate the medium (push 0m → SMS 5m → phone 10m). Keep loudness in notification rules, not duplicated across policy levels.

Alert sources (v1): Sentry, GCP monitoring/uptime, Grafana. Fly.io alerting is out of scope for v1.

Intake funnel: Discord/email + OSS GitHub issues/PRs → Linear Triage → answer/close or convert to a routed pillar issue (type: bug|feature).