Execute Issue
GitHub Issue $0 の内容を読み取り、実装からPR作成までを完遂するスキルです。
Instructionsに従って順に実行し、各フェーズの「完了条件」を満たさないまま次のフェーズに進まないこと。
自律実行原則: ユーザーへの確認は行わず、判断はすべて本スキル内のルールに従って自動で決定する。中断条件に該当した場合のみ、理由を出力して終了する。
Instructions
実行モードの制約: サブエージェント・サブスキル・Bashをバックグラウンド実行しないこと
本スキルは claude-task-worker の cc-exec-issue ラベルをトリガーに自動起動される想定で、ワーカーはスキルプロセスの同期完了を根拠に cc-in-progress の除去や cc-pr-created 付与といったラベル遷移を進める。そのため、本スキル内部で呼び出す Agent / Skill / Bash を絶対にバックグラウンド実行しないこと:
Agentツールは既定がrun_in_background: true(バックグラウンド)。そのため呼び出しごとに 必ずrun_in_background: falseを明示指定 し、フォアグラウンドで同期的に結果を受け取ってから次の処理に進む。指定を省略した場合はバックグラウンドで走り、本スキルが未完のまま終了するSkillツール呼び出しにもrun_in_background: trueを指定しない(既定は同期)。同期完了を待ってから次へ進むBashツールにもrun_in_background: trueを指定しない。既定の同期実行で結果を受け取ってから次の処理に進む- 同一メッセージ内で複数の
Agent/Skillを並列に投げるのは「並列実行」であって「バックグラウンド実行」ではないため許容される。ただしAgentは個別にrun_in_background: falseを指定 し、その場で同期的に完了を待つ - シェルコマンド末尾に
&を付けたり、nohup/disown/setsidなどでプロセスをデタッチしたりしない ScheduleWakeupなどで処理を後回しにしない
理由: バックグラウンド化すると処理完了前に本スキルが終了し、ワーカーが「正常完了」と誤認してラベル遷移や後続ワーカー起動に進むため、実装未完のままワーカーが二重起動したり、テスト・PR作成未完のまま cc-pr-created が付与されたりして、Issue/PRの状態が壊れる。Agent ツールの既定が background であることを見落として run_in_background を省略すると、この事故が確実に起きる。
実行モードの制約: TaskCreate は1コール1タスクで発火する
進捗管理などで TaskCreate を使う場合、以下のルールを厳守すること。違反するとバリデーションエラー(missing subject/description や unexpected parameter tasks)で中断し、フェーズが未完のまま外側のワーカーが「正常完了」と誤認する。
- 1コール = 1タスク。
tasks/todosなどの配列パラメータは存在しない。複数タスクを登録したい場合は、同一メッセージ内でTaskCreateを複数回発行する(並列可) - 必須パラメータは
subject(短いタイトル)とdescription(何をするか)の2つ。いずれもトップレベル文字列として渡し、ネストしたオブジェクトの中に入れない TaskCreateは deferred tool のため、セッション開始時点ではスキーマがプロンプトに含まれない。使用前に必ずToolSearch(query: "select:TaskCreate")で1回だけスキーマをロードする。ロードせずに呼ぶと typed parameters が文字列化されてクライアント側でも弾かれる- そもそも本スキルは TaskCreate を必須としない。フェーズ1〜7の「並列/逐次グループ」内部管理で十分な場合は、TaskCreate を使わず直接次フェーズへ進んでよい
フェーズ0: 事前チェック(必ず最初に実施)
並列で以下を確認し、判断は自動で行う。ユーザーに質問しないこと。
pwdで.claude/worktrees/配下にいることを確認する。worktree外なら 中断 し、理由を出力して終了する(デフォルトブランチで作業してはならない)gh repo view --json defaultBranchRef -q .defaultBranchRef.nameでデフォルトブランチ名を取得し、git rev-parse --abbrev-ref HEADの現在ブランチと比較する。一致する場合は 中断。デフォルトブランチ名の取得に失敗した場合も 中断 する(fail-safe)gh issue view $0 --json number,title,state,labelsでIssueが存在しOPENであることを確認する。CLOSEDなら 中断git status --shortで未コミット変更を確認する。存在する場合はユーザーに確認せずgit stash push -u -m "exec-issue auto-stash $0"で自動退避し、その旨を最終報告に明記する
完了条件: worktree内、デフォルトブランチ以外のブランチ、Issue OPEN、作業ツリーがクリーンであること。
フェーズ1: Issue読み込みとタスク分解
read-github-issue skill を $0 で呼び出し、以下を取得する:
- Issue概要(タイトル・目的・背景)
- 分解されたタスク一覧(目的・対象範囲・完了条件付き)
- タスク間の依存関係
- スキル実行ステップ一覧(返却フォーマットで「## スキル実行ステップ」として区別されているもの。各ステップに呼び出すべきスキル名・引数・依存関係が明示される)
返却内容は後続フェーズで各サブエージェントに渡すため、全文を保持しておくこと。
スキル実行ステップの補完抽出(必ず本フェーズで実施)
返却にスキル実行ステップの明示マーキングがあればそれを尊重する。マーキングが欠けている・不完全と判断される場合は、実装プラン各ステップを走査し、以下の兆候があるステップを追加でスキル実行ステップとして抽出する:
- ステップ本文または対象範囲に「
○○スキルを実行する」「/○○を呼ぶ」「base-tools/skills/○○/SKILL.mdを発火する」等の明示的な呼び出し指示がある - 完了条件が「スキル固有の副作用(例: PR作成・ラベル遷移・スナップショット出力・フックによる後処理)」を要求している
- ステップ名または目的が既存スキル名(
base-tools/skills/*/SKILL.md)と一対一で対応する
抽出したステップは {ステップ名, 呼び出すべきスキル名, 引数, 依存関係} の構造で保持し、通常タスクと分けて管理する。判定が微妙なステップは「スキル実行ステップ候補」として別に列挙し、フェーズ2で最終判定する(推測で通常タスクに寄せない)。
完了条件: 実装タスクが「並列実行可能なグループ」「逐次グループ」「スキル実行ステップ」の3分類に整理できていること。
フェーズ2: タスク実行戦略の決定
スキル実行ステップの取り扱い(原則: メインエージェントが直接発火)
フェーズ1で抽出した「スキル実行ステップ」は、原則として メインエージェントが直接 Skill ツールで発火する。サブエージェントに委譲するとスキル固有の副作用(フック・ガードレール・PR作成・ラベル遷移・スナップショット出力等)が保証されず、独自判断で同等処理を手作業実装されるリスクがあるため。
- 依存する通常タスク・先行スキル実行の完了後にメインエージェントが
Skillツールで呼び出す - 依存関係のないスキル実行ステップ同士は、同一メッセージ内で複数の
Skilltool call を発行して並列実行してよい - やむを得ずサブエージェント経由で実行させる場合(例: 対象スキルの前提条件がサブエージェントのコンテキストに依存する場合)は、フェーズ3のブリーフィングで対象スキル名と「必ず
Skillツールで発火し、代替実装は禁止する」旨を明記する - スキル間の依存関係(先行スキル → 後続タスク/後続スキル)は、通常タスクの並列/逐次判断と同じルールで扱う
- 「スキル実行ステップ候補」は、対象スキルの実在(
base-tools/skills/○○/SKILL.mdの存在)を確認し、実在すればスキル実行ステップとして確定、実在しなければ通常タスクへ差し戻す
サブエージェント選定(通常タスク用)
通常タスク(スキル実行ステップ以外)は、以下の判断軸でサブエージェントを選定し、実行を委任する:
- frontend-implementer: UI/コンポーネント実装、デザイン適用、shadcn/ui等のフロントエンド作業。PencilのデザインデータからUIを実装する(
.penを参照元としてUIに変換する)場合は必ずこのエージェントを使うこと - pencil-design-updater: Pencilファイル(
.pen)自体の編集・更新(要素追加、レイアウト変更、スタイル修正、テキスト差し替えなど)。.penへの編集タスクは必ずこのエージェントに任せること - lightweight-assistant: 内容が具体的で探索不要・単一ファイル編集レベルの軽量タスク(型定義追加、定数追加、設定ファイル更新など)
- general-purpose-assistant: 上記以外、複数ファイルにまたがる実装、調査を伴うタスク、テスト/Lint修正
並列 vs 逐次の判断
以下のいずれかに該当するタスク同士は 逐次 で実行する:
- 同じファイルを編集する可能性がある
- 一方の出力(型・関数・スキーマ)に他方が依存する
- マイグレーションやスキーマ変更を含む
それ以外は 並列 で実行する。並列実行する場合は、1メッセージ内で複数のAgent tool callを発行すること(順次呼び出しでは並列にならない)。
フェーズ3: サブエージェントへのブリーフィング
サブエージェントは現在の会話履歴を持たないため、起動時に以下を すべて プロンプトに含めること(自己完結したブリーフィングが品質を決める)。
【背景】Issue #$0「<title>」: <要約 1-2行>
【あなたが担当するタスク】
<タスク名と目的>
【対象範囲(編集可ファイル/ディレクトリ)】
<具体パスを列挙。範囲外を触らないこと>
【触れてはいけないファイル】
<並列実行中の他タスクが触る予定のファイル>
【完了条件】
- <受け入れ基準1>
- <受け入れ基準2>
- 該当箇所のテストが追加・更新され、すべてpassすること
- `npm run lint`(またはプロジェクト指定のlint)に該当ファイルでエラーがないこと
【スキル実行の扱い】
本タスク内で他のスキル(`base-tools/skills/○○/SKILL.md` に定義されるもの)を呼び出す必要がある場合は、**必ず `Skill` ツール経由で対象スキルを発火すること**。代替実装(スキル手順を自前で再現するなど)は禁止する。スキル固有のフック・ガードレール・後処理が失われ、期待される副作用が保証されなくなるため。呼び出すべきスキル名が本ブリーフィング内に明示されている場合は、その名前で `Skill` ツールを呼び出す。対象スキル名が不明・存在しない場合は自前実装で代替せず、その旨を報告して呼び出し元の判断を仰ぐ。
【参考情報】
- Issueのリンク・関連画像パス
- 既存の類似実装の参照先(あれば)
【作業ディレクトリ】
<worktreeの絶対パス>。すべてのコマンドはここを基準に実行すること。
サブエージェントが完了報告を返したら、本体側で git diff --stat を実行して変更範囲が宣言通りか検証する。範囲外の変更があれば、当該サブエージェントを再起動して修正させる。
フェーズ4: スキル実行ステップの実行と取りこぼし検知
フェーズ2で確定した「スキル実行ステップ」を、依存関係に沿って実行する。
実行手順
- 依存関係のないステップは、同一メッセージ内で複数の
Skilltool call を発行して並列実行する - 依存関係のあるステップは、先行ステップの完了(Skill tool の返却)を確認してから後続を発火する
- 各実行の呼び出し履歴(スキル名・引数・返却サマリ・エラー有無)を「実行済みスキル一覧」として保持する
取りこぼし検知
すべての実行完了後、フェーズ1で抽出した「スキル実行ステップ」一覧(期待側)と「実行済みスキル一覧」(実測側。メインエージェント直接発火分 + フェーズ3でサブエージェントに委譲した分)を突き合わせる。期待側にあって実測側にないステップ、または期待した副作用(PR作成・ラベル遷移・スナップショット等)が発生していないステップは 未実行 と判定し、依存関係を再確認したうえで本フェーズ内で Skill ツールにより再発火する(サブエージェントに再委譲しない)。
再発火してもスキルが失敗する場合、失敗ログ・対象スキル名・依存関係を最終報告に含めた上で次フェーズへ進む(ユーザーに判断を仰がない)。
スキル実行ステップがない場合
フェーズ1で抽出されなかった場合、本フェーズは何もせずスキップしてよい(その旨を最終報告に一行で明記する)。
完了条件: 抽出したすべてのスキル実行ステップが実測側で確認できているか、あるいは再発火失敗として最終報告に記録されていること。
フェーズ5: テストとLintの収束ループ
すべてのサブエージェントとスキル実行ステップが完了したら、本体で以下を順に実行:
- プロジェクトのテストコマンドを実行(
package.jsonのscripts.testを確認) - プロジェクトのLintコマンドを実行(
scripts.lint) - 失敗した場合、
general-purpose-assistantに 失敗ログ全文と該当ファイルパス を渡して修正させる - 修正後、再度テストとLintを実行
テスト/Lintコマンドがプロジェクトに存在しない場合はスキップしてよい(その旨を最終報告に含めること)。
修正ループは最大3回まで自動で繰り返す。3回試行しても収束しない場合は、失敗ログ・残課題・推定原因をまとめて最終報告に含めた上でフェーズ6へ進む(ユーザーに判断を仰がない)。
フェーズ6: 変更の有無で分岐
まず差分の基準ブランチ(BASE_BRANCH)を決定する。Issue $0 が parent(Epic Issue)を持つ場合、worktree は cc-epic-<parent番号> ブランチから派生しているため、epic ブランチを基準にする。デフォルトブランチを基準にすると、epic ブランチへマージ済みの他サブIssueの差分が混ざり、「本Issueでのコード変更の有無」を誤判定する(create-pr スキルのベースブランチ決定と同じ確定的導出を用いる)。
BASE_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD | sed 's@^origin/@@')
if ! PARENT=$(gh issue view "$0" --json parent --jq '.parent.number // empty'); then
echo "failed to resolve issue parent" >&2
exit 1
fi
if [ -n "${PARENT}" ] && git rev-parse --verify --quiet "refs/remotes/origin/cc-epic-${PARENT}" >/dev/null; then
BASE_BRANCH="cc-epic-${PARENT}"
fi
git status --short
git diff "origin/${BASE_BRANCH}..HEAD" --stat
- コード変更がない場合(PRを作成しない場合):
- Issueに調査結果を構造化したコメントを投稿する。コメントは以下のテンプレートに従い、
gh issue comment $0 --body-file -にヒアドキュメントで渡す(Markdownの体裁を保つため)。## 調査結果サマリ <Issue要件に対して何を確認したか 1-3行> ## コード変更が不要と判断した理由 <根拠。既に実装済み・要件が再現しない・別Issueでカバー済み等を具体的に> ## 確認したファイル / 参考情報 - <パスやリンクを列挙。なければ「該当なし」> - コメント投稿の成功を確認した上で
gh issue close $0 --reason "not planned"を実行する。コメントに失敗した場合はクローズせず、失敗ログを最終報告に含めて終了する(説明なしでクローズしない) - 最終報告に「PR未作成・Issueクローズ済み」と判断理由を明記して処理終了
- Issueに調査結果を構造化したコメントを投稿する。コメントは以下のテンプレートに従い、
- コード変更がある場合: フェーズ7へ
フェーズ7: コミットとPR作成
commit-pushskill を呼び出し、変更をコミット・pushcreate-prskill を$0で呼び出し、PRを作成- 作成されたPRのURLを最終報告として出力
注意事項
- デフォルトブランチで作業しない: フェーズ0で必ず確認。途中でもファイル編集前には
pwdを再確認することを推奨 - サブエージェントの結果を鵜呑みにしない: 完了報告は「やったつもり」を示すだけ。
git diffで実際の差分を必ず検証する - スキル実行ステップは Skill ツールで確実に発火: 原則メインエージェントが
Skillツールで直接呼び出す。サブエージェントに委譲する場合もブリーフィングで対象スキル名と Skill ツール発火を必須指示とし、代替実装で誤魔化さない。フェーズ4の取りこぼし検知で未実行のステップがないか必ず確認する - コメントは残さない: 生成コードに「なぜ」を説明する以外のコメントを入れないよう、サブエージェントへのブリーフィングにも明記する
- エラーの根本原因に向き合う: テスト失敗時に
--no-verifyやテストのスキップで誤魔化さない。原因を特定してから修正する - ユーザーに判断を求めない: フェーズ0の中断条件以外は、すべて本スキル内のルールに基づいて自動で意思決定する。曖昧な場合は「より安全な側(破壊的でない側)」を選択し、その判断と根拠を最終報告に明記する
- PR未作成時はIssueに必ず説明を残す: コード変更が不要と判断した場合は、フェーズ6のテンプレートに沿った構造化コメントを投稿してからIssueをクローズする。説明なしのサイレントクローズは禁止する