ci-debug について
ci-debug は、特定の CI 実行、ジョブ、PR チェックを診断する Claude Code スキルです。取得したログとステータスメタデータを 11 種類のパターンと照合し、修正を適用せずに提案します。
主な機能
- 0111 種類のパターンで障害を分類
- 02ジョブログとステータスメタデータを取得
- 03最初に失敗したジョブを選択
- 04未分類の障害を報告
- 05修正を提案し適用はしない
活用シーン
- 01失敗した PR チェックの診断
- 02停滞したステータスと障害の識別
- 03CI 基盤のエラー分類
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill ci-debugインストール後、Claude Code で/ci-debugを入力して読み込まれたか確認します。
詳細
/ci-debug — 失敗した CI 実行を分類する
/insights で明らかになった、繰り返し発生する CI デバッグのパターンに直接対応します。3 週間で約 12 セッション、同じ分類作業を繰り返しています。このスキルでは 11 個のパターンを定義し、作業を検索だけで済むようにします。
入力
次のいずれかを指定して呼び出します。
- PR 番号:
/ci-debug 822(コンテキストからリポジトリを特定します。不明な場合は確認します) - 実行 URL:
/ci-debug https://github.com/owner/repo/actions/runs/12345 - ジョブ URL:
/ci-debug https://github.com/owner/repo/actions/runs/X/job/Y
実行
1. 失敗したジョブを特定する
# From PR number:
gh pr checks <n> --repo <owner>/<repo> --json bucket,link,name \
--jq '.[] | select(.bucket=="fail") | "\(.name)|\(.link)"'
# From run URL:
gh api repos/<owner>/<repo>/actions/runs/<run-id>/jobs \
--jq '.jobs[] | select(.conclusion=="failure")
| {id, name, runner_name, started_at, completed_at,
steps: [.steps[] | select(.conclusion=="failure") | {name, number}]}'
複数のジョブが失敗している場合は、実行時間が最も短いものを選びます。根本原因は通常、最初の失敗にあり、後続のジョブはその影響を受けて失敗するためです。
fail バケットにジョブがないのに、チェックが完了しない場合は? gh pr checks に fail バケットの項目が 0 件でも、ステータスが pending のまま解決せず、さらに gh pr view --json mergeStateStatus が mergeable=MERGEABLE とともに UNSTABLE を返す場合、これは失敗ではなく、スタックした外部ステータスです。パターン #11 に進んでください。取得できる失敗ログはありません。コミットステータスのメタデータ(gh api repos/<o>/<r>/commits/<sha>/status)に基づいて分類します。
2. 失敗ログを取得する
gh api repos/<owner>/<repo>/actions/jobs/<job_id>/logs 2>&1 \
| grep -iE '(error|fail|ERR_|CONFLICT|Process completed with exit code)' \
| head -30
最初に現れる、他と異なるエラーメッセージを記録します(後続の行はその繰り返しであることがよくあります)。
3. プレイブックと照合する
パターンを順に確認します。最初に一致したものを採用します。
| # | パターン | ログ内の特徴 | メモリ参照 | 提案する修正 |
|---|---|---|---|---|
| 1 | 課金ブロック | runner_name が空 + steps[] が空 + 実行時間が約3秒 + 注釈:「最近のアカウントへの支払いに失敗したか、利用上限を引き上げる必要があります」 | billing-surface-hosted-vs-self-hosted.md | 組織の管理者 → Settings → Billing & plans → 利用上限を引き上げる/カードを更新します。コード変更は不要です。 |
| 2 | ルートのロックファイルの不整合 | <ROOT>/typescript/<pkg>/package.json に言及する ERR_PNPM_OUTDATED_LOCKFILE | pnpm-lock-root-vs-workspace-duality.md | pnpm install --lockfile-only && git add pnpm-lock.yaml && git commit && git push を実行します。 |
| 3 | uv.lock の不整合 | error: The lockfile at uv.lock needs to be updated | changeset-release-uv-lock-drift.md | cd python && uv lock を実行してからコミットします。 |
| 4 | ci-shared.yml の permissions 欠落 | startup_failure パターン(runner_name が空 + steps[]=[] + 約3秒)だが、課金の問題は解決済み | ci-shared-permissions-block-required.md | 呼び出し元のワークフローに permissions: { contents: read, packages: read } を追加します。 |
| 5 | YAML への Python 埋め込み | python -c を含む複数行のブロックスカラーを指す YAML 解析エラー | yaml-python-embed.md | python -c を独立したシェルスクリプトの呼び出しに書き換えます。複数行の Python を YAML に直接記述しないでください。 |
| 6 | actionlint の ShellCheck 偽陽性 | 変更していないワークフロー YAML で SC2086/SC2046 が発生し、audit/actionlint ジョブが失敗する | audit-actionlint-triggers-on-workflow-edit.md | 必須チェックではありません。警告が変更前からある場合は、そのままマージしても問題ありません。任意:ShellCheck の無効化コメントを追加します。 |
| 7 | macOS BSD date の %3N | CI の出力に %3N がそのまま表示される/算術演算が失敗する | macos-bsd-date-no-percent-3N.md | date +%s%3N を node -e 'console.log(Date.now())' または python3 -c 'import time; print(int(time.time()*1000))' に置き換えます。 |
| 8 | Runner の pnpm における Rosetta アーキテクチャの不整合 | セルフホストランナーで pnpm install が "wrong-arch native bin"/dlopen エラーにより失敗する | runner-pnpm-rosetta-arch-drift.md | 影響を受けたランナープールを再起動します。根本原因は、node の x64↔arm64 の切り替わりにより、共有キャッシュに誤ったアーキテクチャのネイティブバイナリが保存されることです。 |
| 9 | 浅いクローンによる誤った差分判定 | PR は実際にはマージ済みなのに、git status がブランチの分岐を報告する | shallow-clone-false-divergence.md | git fetch origin <branch> --unshallow を実行し、続けて gh pr view --merge-commit で確認します。 |
| 10 | Publish の実行がキャンセルされた | Publish-tag ワークフローの実行で conclusion=cancelled が表示され、アーティファクトが生成されない | publish-runs-cancelled-need-redrive.md | gh workflow run publish-python.yml -f tag=<tag> で再実行します(使用する Publish ワークフローに応じて調整してください)。 |
| 11 | Vercel のステータスが孤立している(パスによるスキップ) | fail バケットにジョブがない一方で、Vercel がチェック実行ではなく コミットステータス として表示され、state=pending のまま、created_at == updated_at で終端更新がない。GitHub Actions のチェックはすべて成功しており、保護されていないベースブランチで mergeStateStatus=UNSTABLE + mergeable=MERGEABLE | vercel-pending-orphaned-on-path-skip.md | 失敗ではなく、表示上の問題です。Vercel が pending ステータスを投稿した後、ビルドをスキップしたため(プロジェクトルートのパスフィルターによるものです。例:apps/web に一切変更がないドキュメントのみの変更)、ステータスが孤立しています。安全にマージできます:gh pr merge <n> --repo <owner>/<repo> --squash。恒久的な修正:Vercel プロジェクトの Ignored Build Step が 0 で終了し、スキップされたパスについて成功を報告するようにします。これにより、ステータスが未解決のまま残らず切り替わります。 |
メモリ参照は、ユーザーが管理するメモリファイル(~/.claude/projects/<project>/memory/*.md)を指しています。まだメモリに存在しない場合でも、特徴の列だけで分類できます。メモリの引用はあると便利ですが、必須ではありません。
4. 報告する
一致したパターンの場合:
## CI Debug: <repo> · <pr-or-run-ref>
**Failing job:** `<job name>` (<duration>s) on runner `<runner_name>`
**Failing step:** <step name> (#<step number>)
**Error excerpt:**
\`\`\`
<first 3 lines of grep'd error>
\`\`\`
**Classification:** Pattern #<n> — <pattern name>
**Reference:** memory `<memory-file.md>`
**Proposed fix:**
<exact commands, one per line>
**Will I apply this?** No — awaiting your approval. Reply "go" to ship.
一致しない失敗の場合:
## CI Debug: <repo> · <pr-or-run-ref> · NOVEL
**Failing step:** <step name>
**Unique log lines:**
\`\`\`
<top 10 distinct error lines>
\`\`\`
This doesn't match any of the 11 playbook patterns. Surfacing the raw
evidence for your read. Once you identify the root cause, consider
adding it to the playbook (in this SKILL.md) so the next run catches
it automatically.
ヘッドレス実行(権限モード)
/ci-debug では Bash ツールへのアクセスが必須です。証拠の取得には gh pr checks、gh run view、gh api .../jobs/.../logs を使用します。ヘッドレスの claude -p 実行(ci-sentinel、cron)では、次のようにします。
--permission-mode acceptEditsを使用します。これは、ヘッドレスで「プロンプトなしでツールを使用する」モードです。このスキルは設計上読み取り専用なので、リスクのある権限は付与されません。- 絶対に
dontAskは使わないでください。権限が必要なツール(Bash を含む)を黙って拒否するため、すべての分析でエラーなしに出力が空になります(#1862 Bug C)。 claude -pは認証/権限エラーを stderr ではなく stdout に JSON で出力します。失敗時は両方のストリームを取得してログに記録してください(認証関連についてはshared/rules/cc-bare-auth-gotcha.mdを参照)。
重要なガードレール
- 修正を自動適用してはいけません。 このスキルが提案し、ユーザーが承認します。誤分類による無駄な作業こそ、対策を強化している失敗パターンです。
- ログ取得の手順を省略してはいけません。 実際のエラーテキストがなければ、分類は推測にすぎません。ログが消えている場合(90 日以上経過している、または実行が削除されている場合)は、その旨を伝えて終了してください。
- 該当する場合はセクション見出しとファイル名を含め、正確なメモリエントリーを引用してください。ユーザーが類似事例を確認できるようにします。
- 各分類には、誤りだと判定できる証拠が必要です。シグネチャが一致していなければなりません。期待だけでパターンマッチしてはいけません。
実行するタイミング
- 特定の CI 実行/ジョブ/PR チェックが失敗し、ユーザーが診断を求めている場合。
- ユーザーが実行 URL を貼り付けるか、「PR #N が失敗しています。原因は何ですか?」と尋ねた場合。
実行しないタイミング
- 「組織全体で何が失敗していますか?」という広範な質問には、代わりに
/statusを使用します。 - アプリケーションレベルのテスト失敗の場合(このプレイブックの対象は CI インフラに固有 であり、たとえば pytest の失敗は対象外です)。
- 実際のログを読む前。推測してはいけません。
パターンの追加
新しい CI の失敗が見つかった場合(UNMATCHED レポートが出力された場合)、上記の表に行を追加します。
- シグネチャ:十分に固有なログ行/メタデータの組み合わせ。誤りだと判定できるものでなければなりません。
- メモリ参照:インシデントの詳細な記録を書いたメモリファイルの名前。
- 提案する修正:正確なコマンドライン。説明文や「こうするとよいかもしれません」といった表現は不要です。このスキルはユーザーが実行するコマンドを提示するため、曖昧さがあっては目的を果たせません。
SKILL.md の変更を docs(ci-debug): add pattern #N (<short-name>) としてコミットします。ci-sentinel ワークフローは次回の確認時に新しいパターンを自動的に取り込みます。別途、連携処理を追加する必要はありません。
関連スキル
- 連携先 —
ci-sentinel(このスキルを、オープン状態の赤い PR に対して 1 時間ごとに自動実行するトリガー)。 - アンチパターン — 複数のリポジトリで
gh pr checksを手動で再実行し、ログを目視確認すること。これは、このスキルがなくすべき、まさにその手間です。 - 上流 —
/statusは組織全体を確認して失敗している PR を特定し、このスキルはその理由を明らかにします。