POST — PagerDuty, Datadog monitors, Sentry alert rules, a curl in a runbook — into a trigger for a first responder. The agent investigates the alert against the codebase and recent commits, delivers a structured triage (to Slack when connected), stays in the thread for responder questions, and — when the evidence points at a clear, contained code fix — serves it up as a draft PR for humans to review and merge.
Use it when alerts routinely burn twenty minutes of “who touched this last?” before anyone forms a hypothesis.
How it works
The entry point is a custom webhook trigger: a trigger that declaresendpoint: plus an auth: policy instead of a provider connection. At apply time, auto reserves a globally unique slug for the endpoint and returns its ingest URL in the apply receipt. The posted JSON body becomes the event payload verbatim — so the trigger’s templates reference the alert’s own fields ({{title}}, {{severity}}), with no payload. prefix and no provider schema in between. See cron and webhooks.
The endpoint contract, in full:
- URL:
POST https://<your auto host>/api/v1/webhook-endpoints/{slug}/events. - Auth: this example uses
bearer_token— the caller sendsAuthorization: Bearer <secret>, and the secret is resolved server-side from the project secret named by the trigger’ssecretRef.hmac_sha256(anx-auto-signature-256header carrying a hex HMAC of the raw body, optionallysha256=-prefixed) andnoneare the alternatives. - Body: any JSON object. A top-level
"event"string selects the event key —"incident.opened"routes aswebhook.incident.opened; a body without one lands on thewebhook.receivedfallback key. - Response:
202with{ eventRecordId, created: true, routerStatus }on first delivery; a repeated optional top-leveldedupKeyreturns200withcreated: falseand never re-routes.
routing: { kind: spawn } starts one investigation session per alert.
Install from the consolidated agent package
The packaged Incident Response role is published in@auto/agents:
.auto/agents/incident-response.yaml
incident-webhook-secret, set from the web app’s Secrets settings so the value never lands in the repository or a transcript. See secrets.
Slack triage delivery is optional zero-configuration wiring on the standard slack connection and #incidents channel; without Slack, the run report is the complete triage. Merge for GitHub Sync to apply, take the endpoint’s ingest URL from the apply receipt (from a session, auto.webhooks.get returns it too), and point your alerting system at it.
The full configuration
.auto/fragments/environments/agent-runtime.yaml
.auto/agents/incident-response.yaml
contents: write + pullRequests: write exist so the agent can push a fix branch and open a draft PR, but there is no merge capability on the mount, so merge_pull_request is invisible and uncallable no matter what the prompt says — see mounts. The prompt’s payload fields ({{title}}, {{severity}}, {{service}}, {{description}}, {{link}}) assume the alert shape below; match them to whatever your alerting system actually sends, since the body passes through verbatim.
Walkthrough
1
An alert fires
Your monitoring system POSTs to the ingest URL:The bearer token is verified against the
incident-webhook-secret project secret in constant time; "event": "incident.opened" maps the body to the webhook.incident.opened key; dedupKey makes alert-source retries idempotent. The response is 202 with the recorded event id.2
One session per alert
The
incident-webhook trigger matches and spawns an investigation session. The raw alert body is the event payload, rendered into the initialPrompt — no translation layer to maintain.3
Evidence before hypothesis
The sandbox boots with
acme/widgets@main mounted 100 commits deep. The agent reads the alert, scans the last day of commits touching the affected area, pulls logs or metrics if an observability tool is wired (see the variation below), and forms a hypothesis with explicit confidence — what supports it, what would refute it.4
The triage lands, and the thread stays live
The run’s report is the triage: severity line, timeline, suspected cause with evidence, next steps, what was ruled out. With Slack connected, the agent posts one top-level message in
#incidents, threads the full triage under it, and binds the thread so responder questions in it deliver straight back into this session (attributedSessions) — same evidence discipline, same context.5
The fix on a platter
When the cause is a clear, contained change — a bad commit to revert, a config value to correct — the agent pushes a focused branch and opens a draft PR whose body states the hypothesis the fix encodes and how to verify it, then links it from the thread. It never merges, never pushes to main, and never declares the incident resolved; humans do that.
Variations
-
HMAC instead of bearer. For alert sources that sign payloads, switch the trigger to
auth: { kind: hmac_sha256, secretRef: incident-webhook-secret }; the caller sendsx-auto-signature-256: sha256=<hex HMAC-SHA256 of the raw body>. -
Catch unshaped providers. Sources you can’t teach to send an
eventfield land onwebhook.received. Add a second trigger onevent: webhook.receivedwithfallback: trueto the same endpoint and discriminate withwhereon the raw body — fallback triggers fire only when no non-fallback trigger on the same endpoint and event key matched. -
Severity routing. The payload is yours, so
wherefilters over it directly: sendsev1alerts to a paging flow and keep the agent on$.severity: { in: [sev2, sev3] }— one filter, no code. -
Wire in observability. Add a remote MCP tool for your observability stack so “pull the logs before speculating” is real, for example Datadog:
OAuth tokens for
mcp_oauthtools are held and refreshed server-side; the sandbox never sees them. See tools. -
Read-only responder. If you want triage without the fix path, set the mount to
contents: read,pullRequests: readand removecreate_pull_request/update_pull_request— the investigation and thread behavior are unchanged. -
Smoke test. After apply, send the
curlabove with a test payload and confirm a session spawns and a triage thread appears in#incidents; reply in the thread and confirm the agent answers.