| name | ci-auto-fix |
| description | Diagnoses a failed CI check, classifies it with an explicit verdict (code-bug | workflow-bug | dep-bug | env-bug | flaky | unsure), confidence-gates the fix (>=90 auto, 80-89 ask, <80 escalate), applies it, pushes, and iteratively verifies until CI passes — reverting the last commit if a brand-new failure appears. Provider-agnostic in scope; currently implements the GitHub Actions path via `gh`. Hard- refuses to disable, skip, or weaken checks. Triggers on "CI is failing", "fix the CI", "the build is red", "auto-fix this PR's checks", "GitHub Actions failed", "/ci-auto-fix".
|
| disable-model-invocation | false |
| argument-hint | [<pr-url>|<run-id>] |
| license | MIT |
| metadata | {"author":"mthines","version":"3.2.0","workflow_type":"command","tags":["ci","github-actions","auto-fix","confidence-gate","regression-detection","guardrails","gh"]} |
CI Auto-Fix
Diagnose and fix a failed CI check, then verify it passes.
Generic across repositories; currently implements the GitHub Actions path via gh.
This SKILL.md is the orchestration index.
Load the matching rule file when you need detail — do not preload them.
Always read rules/anti-patterns.md first.
The refusals apply to every phase.
Input
The user provides one of:
- A GitHub Actions check/run URL (e.g.
https://github.com/owner/repo/actions/runs/12345678)
- A check run ID or workflow run ID
- A PR URL with failing checks (e.g.
https://github.com/owner/repo/pull/42)
- Nothing — if
$ARGUMENTS is empty, auto-detect the failing CI for the current branch's PR (see Phase 0).
The argument is: $ARGUMENTS.
Phase 0 — Resolve the target
If $ARGUMENTS is empty, do not ask the user — resolve automatically:
-
Get the current branch:
git rev-parse --abbrev-ref HEAD
-
Find the open PR for this branch:
gh pr list --head "<branch>" --state open --json number,url,headRepositoryOwner --limit 1
-
Print the resolved target before continuing:
Auto-detected target: <PR URL or run ID> on branch <branch>.
Phase 1 — Identify the failure
Based on the input:
-
Run URL or run ID — fetch the failed job logs:
gh run view <run-id> --log-failed
-
PR URL — list the failing checks first:
gh pr checks <pr-number> --repo <owner/repo>
Then fetch logs for each failing check.
-
Check suite / check run ID:
gh api repos/<owner>/<repo>/check-runs/<check-run-id>
Extract and summarize:
- Which job(s) failed.
- The specific error messages and exit codes.
- Which step within the job failed.
- The full error context (surrounding log lines).
Phase 2 — Understand the workflow holistically
Before making any changes, read every workflow file in the repository:
find .github/workflows -name '*.yml' -o -name '*.yaml'
Build a mental model of:
- How jobs depend on each other (
needs:).
- What triggers each workflow (
on:).
- Shared steps, reusable workflows, composite actions.
- Environment variables and secrets used.
- Matrix strategies.
- Caching strategies.
- Artifact passing between jobs.
This holistic understanding prevents fixes that solve one problem but break another job or workflow.
Phase 3 — Classify the failure (verdict required)
Pick exactly one verdict per failure.
The verdict binds behavior; do not skip this step.
Full decision table and per-verdict notes: rules/verdicts.md.
Verdicts at a glance:
code-bug / workflow-bug / dep-bug / env-bug → continue to Phase 3.5.
flaky / unsure → escalate. Stop.
Phase 3.5 — Plan artifact + confidence gate
-
Write or update the plan at .agent/{branch}/ci-auto-fix-plan.md using templates/plan-artifact.md.
The plan is read-only documentation of intent — the user can pre-empt before any code is written.
-
Run the confidence gate per rules/confidence-gate.md:
| Score | Action |
|---|
| ≥ 90 | Auto-apply. Continue to Phase 4. |
| 80–89 | Show the diff, ask once, apply on approval. |
| < 80 | Escalate. Do not write. |
The gate is non-negotiable.
Phase 4 — Fix the error
Apply the minimal, targeted fix per the verdict:
code-bug — fix the actual code issue.
workflow-bug — fix the workflow YAML.
dep-bug — update the lockfile or correct the version constraint.
env-bug — pin or bump the runner-side version.
Hard refusals (full list in rules/anti-patterns.md):
- Do not disable, skip, or weaken any check.
- Do not add
continue-on-error: true.
- Do not add
.skip / it.only to silence a test.
- Do not skip hooks with
--no-verify.
- Do not refactor surrounding code.
Do:
- Make the smallest change that fixes the root cause.
- Stay consistent with the rest of the codebase.
- If fixing a test, verify the test is the one that's wrong (not the code it tests).
Phase 5 — Verify locally
Before pushing, run the same checks that failed:
- If build failed: run the build command.
- If lint failed: run the linter.
- If tests failed: run the tests.
- If typecheck failed: run the type checker.
Only proceed to push if local verification passes.
Phase 6 — Commit and push
-
Stage only the files relevant to the fix.
-
Write a clear commit message:
fix(ci): <description of what was fixed>
<brief explanation of root cause and fix>
-
Sync with the remote before pushing — a parallel worker may have pushed:
git pull --rebase origin "<branch>"
If the rebase conflicts, run git rebase --abort, stop, and report the conflicting files to the user. Do not auto-resolve.
-
Push:
git push origin "<branch>"
-
If the push is rejected as non-fast-forward, rebase and retry the push once.
If the retry also fails, or the rebase conflicts, stop and report. Never --force push from this skill.
Phase 7 — Wait for CI
After pushing, monitor the check:
-
Wait briefly for the workflow to trigger:
sleep 10
-
Find the new workflow run:
gh run list --branch <current-branch> --limit 5
-
Watch the run until completion, bounded at 30 minutes:
timeout 1800 gh run watch <new-run-id>
If timeout expires (exit code 124), run gh run view <new-run-id> to capture pending jobs, report them, and escalate. Same bounded-poll pattern as the reviewer-feedback watch loop in ../../workflow/implement-suggestion/rules/watch-mode.md.
-
Check the result:
gh run view <new-run-id>
Phase 8 — Iterate with regression detection
Full decision table: rules/regression-detection.md.
At a glance:
- Same failure → re-classify in Phase 3.
- Strict subset → continue with the remaining failures.
- New failure that did not exist before → revert the last commit (
git revert HEAD && git push) and re-plan or escalate.
Maximum 4 iterations.
After 4, escalate with the structured exit summary.
Phase 9 — Report
Always end with a structured summary block, regardless of outcome:
ci-auto-fix run
Outcome: <green | escalated | regression-reverted | max-iterations>
Original failure: <workflow / job / step + one-line cause>
Verdict: <code-bug | workflow-bug | dep-bug | env-bug | flaky | unsure>
Iterations: <N>/4
Plan: .agent/{branch}/ci-auto-fix-plan.md
Successful run: <URL> # if green
Escalation reason: <…> # if not green
On success, include the original error, the fix applied, confirmation that all checks pass, and a link to the successful run.
On escalation, include what was tried (one line per iteration), what remains, and suggested next steps for manual investigation.
Self-Improvement
/ci-auto-fix gets better across runs through a two-tier lessons loop (fast
episodic tier + gated promotion), like autonomous-workflow and fix-bug. It
reads ci-auto-fix-lessons at Phase 3 (biasing the verdict and the Phase 8
regression call) and writes at Phase 8 (on a revert — the strongest negative
signal) and Phase 9 (on the CI outcome). Lessons are advisory — they never
relax the confidence gate, the revert-on-new-failure rule, or any refusal in
rules/anti-patterns.md.
This loop is deliberately more conservative than the others because the
verdict is inferred from CI logs alone: verdict lessons default to the
repo::{owner}/{repo} scope (repo-specific failure shapes are far more
reliable than cross-repo generalizations) with a raised promotion bar
(seen_count >= 5), and regression lessons are volatile with a 30-day
expiry since error signatures churn. A lesson can never authorize a
check-weakening or soft-refusal action — those still re-gate on this run. Full
contract and the two ci-auto-fix-specific entrenchment guards:
rules/self-improvement-loop.md. LoreKit
(the lorekit-memory skill's memory.* tools) is optional; the loop is a silent
no-op if not connected.
Definition of done
The run is done when ANY of the following is true:
- All checks are green AND the structured exit summary has been printed.
- The verdict was
flaky or unsure and the failure was escalated to the user.
- The confidence gate scored < 80 and the fix was not written.
- A regression was detected and reverted, and the user owns the next step.
--max-iterations (default 4) was reached.