| name | diagnose-ci |
| description | Diagnose and fix GitHub Actions CI failures for the current repository. Fetches failing job logs via gh CLI, reproduces the failure locally, identifies the root cause (code bug, flaky test, or infra/config issue), proposes a targeted fix, applies it after approval, then offers to commit and push to re-trigger CI. Global and project-agnostic (requires gh CLI). Trigger when the user says "diagnose CI", "diagnose-ci", "why is CI failing", "CI is red", "fix CI failures", "debug GitHub Actions", "CI is broken", "what's failing in CI", or "CI keeps failing". SKIP when the user is asking about a non-GitHub CI system. |
Diagnose and fix GitHub Actions CI failures
Project-agnostic, global skill. It fetches the latest GitHub Actions failure logs,
reproduces the failure locally, classifies the root cause, proposes a concrete fix, and
— after approval — applies it and offers to re-trigger CI via commit + push.
It is the operational companion to /setup-ci: that skill builds the pipeline; this one
keeps it green.
Failure taxonomy (classify before diagnosing)
Identifying the failure class first prevents wasted effort — the remediation is completely
different for each class:
| Class | Signals | Remedy |
|---|
| Code bug | assertion error, compile error, lint error in a source file | fix the code |
| Flaky test | same job failed intermittently across unrelated commits | quarantine test or add retry |
| Infra / config | "rate limit", "connection refused", "secret not found", "runner", "out of disk", "timeout" in system-level output | fix workflow config, rotate secret, re-run |
| Matrix-specific | fails on one version/OS cell, passes on others | version-specific code or env issue |
| Stale dependency | lock-file mismatch, registry error, version range now broken | update dependency or pin version |
Always classify first; never jump to fixing code when the failure is infra.
Procedure
1. Auth guard
- Run
gh auth status. If not authenticated, tell the user to run gh auth login
(or ! gh auth login to run it in this session), then stop — do not proceed until
auth is confirmed.
2. Identify failing runs
- Run
gh run list --branch $(git rev-parse --abbrev-ref HEAD) --limit 5 to get recent
runs on the current branch.
- If all runs are green: report "CI is passing on this branch" and stop.
- Select the most recent failed run; note its run ID, workflow file, and which jobs failed.
- If multiple workflows are failing, ask the user which to focus on first.
3. Fetch failure logs
- Run
gh run view <run-id> --log-failed to get the pre-filtered failure output.
- For each failing job, note: the job name, the failing step name, and the
error message (last meaningful non-blank lines of that step's output).
- For very long or noisy logs, delegate parsing to the
general-purpose agent with the
instruction: "extract the job name, failing step, and the first and last error lines
from this CI log; ignore setup/teardown noise."
4. Classify the failure
Apply the taxonomy above. Gather supporting evidence in parallel:
- Flaky check:
gh run list --workflow <file> --limit 20 --json conclusion,headSha
— if the same job shows non-consecutive failures on different SHAs, flag as likely flaky.
- Matrix check: inspect the run summary for matrix cells; note which cell(s) failed
vs. passed.
- Infra check: scan the log for the infra-signal keywords in the taxonomy table.
State the classification clearly before proceeding: "This looks like a [class] failure
because [evidence]."
5. Diff-aware root cause
For code bug and stale dependency failures only:
- Find the last green run:
gh run list --workflow <file> --status success --limit 1 --json headSha
- Run
git log --oneline <last-green-sha>..HEAD to see what changed since green.
- Cross-reference the changed files with the failing file/line from the log.
- Name the specific commit and file most likely responsible.
6. Reproduce locally
- Read the workflow YAML (
.github/workflows/<file>) to find the exact run: command
of the failing step.
- Run that command locally and capture output.
- Compare local output to CI log output to confirm the failure reproduces (or note if it
does not — that itself is diagnostic: environment divergence).
- If the failure does not reproduce locally, note potential causes: missing env var,
different runtime version, CI-only secret, or OS difference.
7. Diagnose (show before fixing)
Present a structured diagnosis before proposing anything:
Job: <job name>
Step: <step name>
Error: <error message>
Class: <Code bug | Flaky | Infra | Matrix-specific | Stale dependency>
Cause: <one-sentence root cause>
Commit: <sha and subject, if diff-aware narrowed it down>
8. Propose fix
Propose a concrete, targeted remedy matched to the failure class:
- Code bug: show the specific file + line change needed. If the fix is small, write it
inline for approval.
- Flaky test: propose quarantining (skip annotation) or adding retry logic; note the
test should be fixed properly later.
- Infra / config: describe the action needed (re-run, rotate secret, update workflow
YAML) and offer to make workflow changes if applicable.
- Matrix-specific: propose a version guard, conditional, or dependency pin.
- Stale dependency: propose the exact update command and offer to run it.
Show the proposed change and wait for explicit approval. Do not apply without it.
9. Apply + re-trigger
After approval:
- Apply the fix (edit files, run commands as needed).
- Offer to commit via the
/commit skill (hand off with the diagnosis as context for the
commit message body) and push to re-trigger CI.
- After push, offer to watch the new run:
gh run watch — the user can cancel at any time
with Ctrl-C.
Guardrails
- Always classify the failure class before proposing a fix; a misclassified failure leads
to the wrong remedy.
- Never apply a fix without explicit user approval in step 8.
- Never re-run a flaky test as a "fix" without flagging that the underlying flake remains.
- If local reproduction fails, say so explicitly — do not assume the fix is correct
without confirmation.
- For infra failures (secrets, runners), describe what the user must do in GitHub settings;
never fabricate secret values or assume what they should be.
- This skill is GitHub Actions + gh CLI only. If the repo uses a different CI system,
decline and name the right tool.
- Keep the diagnosis concise; do not dump raw log output at the user — summarize it.