Anthropic logo

Skill

triage

investigate and diagnose system alerts

Covers Monitoring Incident Response Triage Debugging

Description

Investigate an alert or incident in this channel: classify the symptom, load the matching triage reference, check lessons.md for known causes, and post a grounded first-pass diagnosis with evidence links and a proposed (never executed) fix. Use when an alert fires, a routine detects a new anomaly, or someone reports something broken ("tests aren't running", "deploys look stuck", "is CI down?").

SKILL.md

Triage

Standing rules in CLAUDE.md apply — especially: propose, don't act (rule 1); every claim carries a link (rule 4); data before theory (rule 5); log to lessons.md without asking (rule 8).

Procedure

  1. Load context. Read ONCALL.md (policy + routing), STACK.md (capability bindings), and lessons.md (known causes) from disk. Files over memory (rule 7).
  2. Classify the symptom. Match against the failure classes in references/:
    Symptom looks likeLoad
    Tests failing, flaking, or silently not runningreferences/test-failures.md
    PRs stuck, queue depth growing, merges slowreferences/merge-queue.md
    Jobs not starting, agents stuck, capacity errorsreferences/runner-infra.md
    Bad deploy, rollout stuck, post-deploy regressionreferences/deploy-rollout.md
    None of the aboveNo reference — say so explicitly, and investigate from first principles: timeline first (what changed around onset — deploys, flags, config), then blast radius, then narrow.

    (Classes are the CI defaults; your setup phase may have replaced them. The table above must match the files actually present in references/ — if they've diverged, trust the directory and flag the drift.)
  3. Check the log first. Search lessons.md for this class's #tag and read the matching entries — never ingest the whole file; it grows unbounded by design. A matching past incident is your first hypothesis — cheapest to confirm or kill.

3a. Correlate before you classify. Sweep the other alert channels (and the incidents binding) for the same time window. Five alerts are often one incident: if this symptom is downstream of something already broken — a cluster problem, a shared dependency, another team's incident — say so in the diagnosis ("correlates with X in #infra-alerts; likely one incident, not five") and route to the upstream owner instead of investigating the echo.

3b. Alert storms get ONE triage, not one each. If several alerts have landed in a short window — or new alerts arrive while you're already investigating — treat them as a batch: group by likely common cause, run a single investigation for the group, and post one diagnosis that lists every alert it accounts for ("these 14 alerts trace to one upstream: …"). If an incident record is already open for the cause, attach new alerts to it (post in its thread/record) instead of opening a parallel investigation. If the batch looks like a real incident and no record exists, propose declaring one per ONCALL.md — a human declares it (the incident-record invariant); you never do. Batching is for shared cause only: if the evidence says the batch contains genuinely unrelated failures, say so explicitly and treat them as distinct incidents — separate diagnoses, separate records, each with its own severity call. Never merge for tidiness.

  1. Run the reference's first checks against the bound capabilities in STACK.md. Establish the timeline: when did the symptom start, and what changed within the preceding window — deploys, flags change history, config, merges?

4a. Fan-out (page-severity only; sequential is the default below it). Where the channel's platform supports spawning parallel subagents, you are the orchestrator: spawn one investigator per bound source of truth the reference's first checks touch — metrics, logs, code/deploys, pager, alert-channels. Each investigator receives exactly four things: the symptom sentence, the onset window, its binding line from STACK.md, and the reference's first-check queries for its source — nothing else, so a poisoned thread can't steer it (rule 9a applies inside subagents too). Each returns the fixed shape:

  • CHECKED: queries run, with links
  • FOUND: observations with timestamps — observations, never root causes
  • NOT FOUND: what was looked for and absent — absence counts only if the run/window was complete
  • CANNOT ACCESS: anything that 403'd or timed out (surfaces in the diagnosis as a gap, never silently dropped)

Synthesis is yours alone: correlate, deconflict (two investigators dating onset differently is itself a finding), and write the one diagnosis. Fan-out multiplies token cost — worth it for a page, never for a morning-log item.

  1. Apply the reference's correlation table. Where observations match a row, you have a candidate root cause; verify it against the timeline before promoting it (rule 5).

5a. Cross-check blame against "still happening" (CLAUDE.md rule 5a). A blame verdict — bisect, revert notice, "that PR broke it" — names the change that started the failure; before naming it as the live cause, confirm the symptom appears in the most recent completed run/window. Presence always confirms red; absence confirms green only on a completed run.

  1. Post the diagnosis in this format, in-thread:

    What's happening: one sentence, fresh-reader test applied. Root cause (confidence high/medium/low): the mechanism, with each claim linked to its evidence. Blast radius: who/what is affected, linked. Proposed fix: the action, why it's safe, and what to watch after. Ruled out: alternatives checked and the evidence that killed them. Would change my mind: the one observation that would.

6a. Updates on long-running incidents. Any update posted >30 min after your first diagnosis opens with a 2–4 sentence story so far a newcomer can land on cold: when it started and what broke → the current best understanding of cause (not the first guess) → what's been tried → where it stands, one sentence. Then the delta. Ruled-out hypotheses don't reappear unless load-bearing. Never post a "no change" update — silence is a valid state, and noise trains readers to skip your updates.

  1. Route. If ONCALL.md's routing tree names an owner for this class, mention them. Otherwise mention no one (rule 12).
  2. On human questions or pushback ("could it be the schema change instead?"): treat it as a hypothesis to check, check it against the data, and report back with evidence either way. Never defend a diagnosis; re-derive it.
  3. When a fix is deployed (by a human, or a permitted gated action): watch it land — bounded. Check the affected metrics at the reference's expected-resolution window (once at half, once at full, once at double — three checks, not a polling loop), post when they return to baseline, or escalate per the routing tree if the window blows. Do not mark resolved (rule 2). If a human wants tighter watching, they can ask — continuous polling is never the default. Verify through the same door the failure came in: re-run the original failing path, or re-check the exact signal that detected the incident — never a proxy. "Merges are flowing" proves the merge path, not the whole provider; if your check can't see the original symptom, say the verification is partial and name what it can't see.
  4. Afterwards, append the incident to lessons.md in its entry format (rule 8). If this incident exposed a gap in a reference file, propose the amendment as a PR (rule 9) — you fix the playbook, not just the incident. And ask the alerting question: would a rule have caught this earlier? If detection was human or late, propose the rule in the postmortem — paste-ready in the format ONCALL.md names, with this incident as provenance. Install per ONCALL.md's install mode: default is a human pastes it; under the alert-editor extension you may create it yourself after explicit approval in the channel (additive only, logged to lessons.md — CLAUDE.md rule 1a).

© 2026 YourAI.tools. Every skill from an identity-verified publisher.

Independent catalog. Not affiliated with, endorsed by, or sponsored by Anthropic or any listed publisher. All trademarks belong to their respective owners.