CI Feedback Loop
Pull failing GitHub Actions context (status → failed jobs → step logs → artifacts) into the local working session so the agent can fix issues without round-tripping through the GitHub UI.
A small Go CLI (in this skill folder) wraps the gh CLI for orchestration, parses logs/artifacts, and writes everything under debug/ci/<run_id>/ — the debug/** path is already covered by .gitignore.
When to Use
- A PR is open and one or more workflow runs failed
- User asks to "debug CI", "check the pipeline", "fix the failing tests in CI", "fetch the CI logs"
- Iterating on a feature branch where commits keep breaking specific jobs
- Need cluster-state artifacts (kubectl dumps, helm logs, pod descriptions) attached to a failed run
Prerequisites
ghCLI authenticated (gh auth status)go≥ 1.23 onPATH- Working directory inside the target git repo on the feature branch
Setup
The CLI lives in .github/skills/ci-feedback-loop as its own Go module. Invoke it with the helper alias (run once per shell):
ci_fb() { (cd "$(git rev-parse --show-toplevel)/.github/skills/ci-feedback-loop" && go run . "$@"); }
Then use ci_fb <subcommand> from anywhere in the repo. All examples below assume this alias is defined.
Available subcommands: locate, summarize, logs, artifacts. Pass --help to any of them for flags.
Procedure
1. Locate the target run
ci_fb locate # list 10 most recent runs (non-blocking)
ci_fb locate --latest # print only the latest RUN_ID (non-blocking)
ci_fb locate <RUN_ID> # print this RUN_ID (non-blocking)
ci_fb locate --wait # block until every in-progress run finishes (hard timeout)
ci_fb locate --latest --wait # wait, then print the latest RUN_ID
ci_fb locate <RUN_ID> --wait # wait specifically on this run
Default is non-blocking — listing returns immediately and flags any pending runs in the footer (⏳ N run(s) still in progress). The agent should re-invoke later rather than blocking the conversation.
When --wait is set, the command polls every 30 s without streaming logs, and aborts with a clear message after --wait-timeout seconds (default 1800 = 30 min). This prevents the calling agent from hanging.
The command emits a single RUN_ID=<id> line on stdout when resolved (with --latest or an explicit id). Capture it for later steps.
2. Summarize failures
ci_fb summarize <RUN_ID>
Prints workflow metadata + only the failed/cancelled jobs with their failing step numbers. Compact enough to keep in context — use it to decide which logs/artifacts to pull next.
3. Fetch focused logs
ci_fb logs <RUN_ID> [--job <substring>] [--tail 200] [--context 80]
Behavior:
- Downloads the run's full log archive once into
debug/ci/<RUN_ID>/_run.zip - Extracts to
debug/ci/<RUN_ID>/logs/ - For each failed job (optionally filtered by
--job), prints:- the last
--taillines of its log - the first error context (regex
error|fail|fatal|panic, ±lines, capped at--contextlines)
- the last
Read the printed excerpts directly. Open debug/ci/<RUN_ID>/logs/<job>.txt only if excerpts are insufficient.
4. Download artifacts (cluster state, etc.)
ci_fb artifacts <RUN_ID> # list only
ci_fb artifacts <RUN_ID> --name cluster-dump # download matching
Stored under debug/ci/<RUN_ID>/artifacts/<name>/. Always list first, pick by name (e.g. cluster-dump, pod-logs-kind, helm-status), then download.
After download, inspect the most useful files:
*.yaml/*.json— read directly*.log/*.txt—tailorgrepfor the error keywords from step 2*.tar.gz/*.zip— extract in place before reading
5. Diagnose and fix
With logs + artifacts in debug/ci/<RUN_ID>/:
- Map the error message to the source (workflow step, action, script, app code)
- Read that source file before editing
- Apply the minimal fix
- Verify locally if possible (lint, unit test, dry-run)
6. Push and re-loop
Commit the fix under the repository's staging and message rules — AGENTS.md,
"Agent collaboration rules". This skill does not own the commit convention; do
not reach for git add -u here.
Then re-enter the loop:
# Either: poll later non-blockingly
ci_fb locate
# Or: explicitly wait (safe — hard timeout)
ci_fb locate --latest --wait
Repeat steps 2–6 until the pipeline is green.
Cleanup
debug/** is gitignored. Delete anytime: rm -rf debug/ci.
Anti-patterns
- Don't dump full logs into the conversation. Use
summarize+logsexcerpts. - Don't download every artifact blindly — list first, then pick by
--name. - Don't push-and-pray. Always re-watch the run after fixing.
- Don't edit the workflow YAML to "skip" a check just to make CI pass — fix the underlying issue.