Runbooks & Remediation
A runbook is a declarative YAML spec that InfraSage compiles and executes as a dependency graph, behind human approval gates sized to how much the runbook has earned your trust. This page covers the execution side; see Authoring & Import for how runbooks get written, reviewed, and promoted.
The spec
runbook_id: reset-payment-pool
name: Reset payment DB connection pool
description: >
Recycles the payment service's DB pool. Use when RCA points at pool
exhaustion / DB latency on payment-service.
service_id: payment-service
tier: T2
enabled: true
steps:
- step_id: confirm-impact
name: Confirm pool saturation before recycling
skill_id: legacy:manual_confirm
params:
instruction: "Confirm payment p99 is still elevated before recycling."
- step_id: reset-pool
name: Recycle the connection pool
skill_id: legacy:http
params: { url: "https://ops.internal/payment/reset-pool", method: "POST" }
depends_on: [confirm-impact]
on_failure: stop
max_retries: 2
- step_id: announce
name: Announce remediation
skill_id: legacy:slack_notify
params: { message: "payment DB pool recycled via runbook" }
depends_on: [reset-pool]
on_failure: continue
Step types: HTTP calls, Kubernetes operations (scale / restart / drain), gated shell, Slack
notifications, timed waits, n8n workflow triggers, manual_confirm (a checkpoint that pauses the
run until a human answers in the console or Slack), and runner_http, which executes an HTTP call
inside your cluster via the in-cluster runner. That last one buys you cluster-local
URLs, no public exposure of ops endpoints, and deterministic cluster targeting.
HTTP steps retry transport-level dial failures automatically, meaning a connection refused or a
timeout before the request was sent. That is safe for any method, since the request never reached
the server. HTTP status errors are never retried implicitly; use max_retries for that,
deliberately.
Semantics worth knowing:
depends_onbuilds a DAG; independent branches run concurrently.on_failure: stop | continueper step; downstream steps of a stopped branch are skipped.max_retriesre-attempts a failed step. HTTP steps additionally retry transport-level failures (connection refused/reset, where the request never reached the server) automatically, since those are safe for any method.- Strict variables:
{{vars}}resolve from the trigger context; unknown variables fail compilation loudly rather than becoming empty strings. - Trigger context flows in.
{{alert.severity}},{{service_id}}and friends resolve from the alert or manual trigger that started the run.
How runs start
- Manually, from an incident. The console's applicable runbooks panel curates promoted, enabled runbooks matching the alert's source; one click queues the run for approval.
- From the RCA. Analyses surface remediation candidates, and executing one goes through the same approval gate.
- From triggers (optional, flag-gated). Alert-matching rules on service glob, severity, detector, alert-name glob, environment, and labels fire runbooks automatically into the approval queue, not into execution.
The approval loop
Every T2/T1 run pauses as a pending action in the
Decision Queue (console and Slack). The card shows
the runbook, target service, trigger context, and tier. Approve dispatches to the DAG engine
and returns the execution id; reject records why. manual_confirm steps pause mid-run the
same way. Who decided, when, and from which surface is all recorded.
Observing a run
Console → Knowledge → Runbooks shows the catalog (tier, trust, last runs); each runbook's pane shows execution history with per-step status, inputs, outputs, and errors. For finished runs:
- Replay reconstructs the step-by-step timeline for review.
- Post-mortem export produces a downloadable markdown dossier of the run.
GET /api/v1/runbooks # catalog
GET /api/v1/runbooks/{runbook_id} # spec + recent executions
POST /api/v1/runbooks/{runbook_id}/manual-trigger # queue for approval
POST /api/v1/agent/actions/{action_id}/approve # dispatch (or /reject)
GET /api/v1/runbook-executions/{execution_id} # status + step results
GET /api/v1/runbooks/executions/{execution_id}/replay
GET /api/v1/runbooks/executions/{execution_id}/postmortem
Verified end to end
The full loop runs as a live control scenario against production, and it must pass before
detection or remediation changes ship: detector fires → RCA names the cause and cites the deploy →
operator approves reset-payment-pool → the HTTP step clears a sticky injected fault → recovery
observed from the target's side.
:::note Network prerequisites Runbook steps execute from InfraSage's control plane, so HTTP targets must be reachable from its egress; private targets typically expose an allowlisted endpoint. An in-cluster runner that executes steps inside your network (no inbound exposure) is on the roadmap. :::