Diagnose a CI workflow failure

SkillDocs & knowledge

Diagnose a failing CI workflow run (lint, markdown lint, build, or unit tests) — identify which job failed, the cause, and a concrete fix

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Diagnose a CI workflow failure skill

What this skill tells your AI

The instructions your AI receives, as published by adamayoung/tmdb in .claude/skills/diagnose-ci-failure/SKILL.md and read by ahel’s review.

Overview

The CI workflow (.github/workflows/ci.yml) gates every PR and the merge to main. Unlike the live-API integration suite, a CI failure is almost always caused by the change under review — a lint violation, a compile warning/error, a broken unit test, or a Linux-portability gap. Start from the diff, not from "maybe it's flaky".

CI fans out into six real jobs (plus a changes paths-filter job and a ci gate job that only aggregates results): Lint, Lint Markdown, Build and Test (macOS), Build (<platform>) (an iOS/tvOS/watchOS/visionOS simulator-build matrix), Build and Test (Linux), and Test (<timezone>) (a time-zone matrix re-running the unit suites). The diagnosis differs per job, so this skill is a router: identify the failing job, then follow the matching reference file for that job's causes, fixes, and local-reproduction command.

Wrong suite? If the Integration workflow (the live-API suite from integration.yml) failed — not a CI job — use /diagnose-integration-failure instead. It leads with the opposite assumption: a scheduled/live-API failure is usually backend or data drift, not your change.

Agent Behaviour Contract

  1. Identify the failing job firstLint, Lint Markdown, Build and Test (macOS), Build (<platform>), Build and Test (Linux), or Test (<timezone>). Don't guess the cause before you know the job.
  2. Assume the change caused it. CI gates the PR; read the diff and tie the failure to a changed file. Don't open with "transient" or "flaky".
  3. Treat warnings as errors. Build steps use -warnings-as-errors / --Werror — a deprecation or unused-binding warning is a real failure.
  4. Reproduce locally before declaring a fix using the matching tool (/lint, /build-for-testing, /test, make lint-markdown, make build-linux).
  5. Output the three sections (Summary / Cause / Fix) defined below — concise, tied to file:line.

Locate the failing run

Use the first that applies:

  • A path or run id the caller handed you.
  • The current branch's run via the GitHub MCP (owner/repo from the origin remote): mcp__github__actions_list method list_workflow_runs (resource_id: ci.yml, workflow_runs_filter: { branch: <branch> }), then mcp__github__get_job_logs (run_id: <id>, failed_only: true, return_content: true). (mcp__github__pull_request_read method get_check_runs also shows which job is red.) Headless / no MCP: gh run list --workflow CI --branch "$(git branch --show-current)" --limit 1, then gh run view <id> --log-failed.
  • CI pipes build/test output through xcsift in github-actions format, so the failing lines are GitHub ::error:: annotations carrying file:line — read those first.

Quick decision tree

Once you know which job failed:

  • Lint (swiftlint --strict / swiftformat --lint / one of the six Scripts/*.py gate steps)? └─ references/lint.md — style/format violations, the Python gates, and the version-drift gotcha
  • Lint Markdown (markdownlint)? └─ references/markdown.md — README / DocC / .claude/ / knowledge/ rules
  • Build and Test — the build step failed? └─ references/build.md — compile errors and --Werror warnings
  • Build and Test — the test step failed? └─ references/unit-tests.md — failing Suite/test, fixture/model mismatch
  • Build (iOS / tvOS / watchOS / visionOS) — a simulator matrix build failed? └─ references/build.md — platform-specific API availability; it is xcodebuild, not SwiftPM, so make build green does not clear it
  • Build and Test (Linux) — fails on Linux but passes on macOS? └─ references/linux.md — Apple-only API gating, Foundation differences
  • Test (America/Los_Angeles or Pacific/Auckland) — the TZ matrix failed? └─ references/unit-tests.md — a date/calendar assertion depending on the runner's zone; reproduce with TZ=<zone> make test

Triage-first playbook

Symptom → next move:

  • error: … is unavailable / cannot find … in scope, Linux job onlyreferences/linux.md
  • warning: … treated as errorreferences/build.md
  • error: from swiftc on macOS buildreferences/build.md
  • A Suite/test recorded a failure / #expect failedreferences/unit-tests.md
  • Test fails to decode a fixture (keyNotFound, valueNotFound)references/unit-tests.md
  • SwiftLint rule violation (error: … (rule_id))references/lint.md
  • superfluous_disable_command on unchanged codereferences/lint.md (suspect version drift)
  • SwiftFormat would reformat a file (--lint non-zero)references/lint.md
  • markdownlint MD0xx violationreferences/markdown.md

Output format

Produce exactly these three sections (keep it under ~150 words; if the caller asked for a file, write the markdown there and nothing else, otherwise reply directly):

Summary: which job and step failed, and the specific error (rule / file:line / failing Suite/test).

Cause: the root cause, tied to a changed file where possible.

Fix: the concrete next step from the relevant reference file.

Reference files

FileFailing jobCovers
references/_index.mdNavigation index by symptom
references/lint.mdLintSwiftLint --strict, SwiftFormat --lint, the six Scripts/*.py gates, pinned versions, drift
references/markdown.mdLint Markdownmarkdownlint on README, CLAUDE.md, DocC, .claude/, knowledge/, .github/*.md
references/build.mdBuild and Test (build step); Build (<platform>)compile errors, --Werror warnings, release build, simulator-matrix availability
references/unit-tests.mdBuild and Test (test step); Test (<timezone>)Swift Testing failures, JSON fixture/model mismatch, TZ-matrix date dependencies
references/linux.mdBuild and Test (Linux)Apple-only API gating, Foundation portability

Signals

GitHub stars
176
Forks
47
Last commit
Aug 2026
Advanced
Catalog kind
skill
Gateway key
diagnose-ci-failure
Source
github.com/adamayoung/tmdb