mcpField
G
gh-fix

gh-fix

github.com/lsegal開発571 回インストール1 週間前に更新
リポジトリ

gh-fix について

gh-fix は、GitHub Issue の確認から実装、プルリクエスト、CI、マージまでを自律的に進めるエージェントスキルです。別のクローンで作業し、既存のプルリクエストを再開できるほか、マージ許可がない場合は保留します。

主な機能

  1. 01GitHub Issue の確認と解釈
  2. 02条件に合うオープン PR の再開
  3. 03複数タスクのサブ Issue への分割
  4. 04別クローンでの修正実装
  5. 05CI の追跡と PR のマージまたは保留

活用シーン

  1. 01許可された Issue 修正のマージまでの自動化
  2. 02中断後の作業再開
  3. 03独立して進められるタスクのサブ Issue 化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/lsegal/glorp --skill gh-fix

インストール後、Claude Code で/gh-fixを入力して読み込まれたか確認します。

同梱ファイルagents/openai.yaml

詳細

マージまで行う GitHub Issue の修正

/gh-fix OWNER/REPO#ISSUENUMBER は、その Issue の修正を実装し、公開し、継続的に修正してマージする権限として扱ってください。呼び出しには、実行を指示した Glorp インスタンスを識別するため、identity:/glorp:<ID> が追加される場合があります。PR がマージされるまで、Issue でマージの許可が与えられない場合、またはユーザーの対応が必要な真の外部要因がある場合を除き、自律的に作業してください。ユーザーの既存のチェックアウトは変更せず、すべての変更を別のクローンで行ってください。

リクエストを検証する

  1. GitHub の issue 番号として、正の整数をちょうど 1 つ指定する必要があります。先頭の # は省略可能です。このワークフローで issue を指す箇所ではすべて、GitHub 形式の #NNN を使用してください。issue、コミット、その他のコンテキストに記載されていても、ABCD-123 のような外部トラッカーの識別子を issue 番号の代わりに使用してはいけません。また、末尾に省略可能な identity:/glorp:<ID> 引数を 1 つ指定できます。コメントの処理で、この identity を保持してください。identity が指定されている場合はその後に、末尾に省略可能な and do not merge の指示を指定できます。この実行では、これをマージ禁止の指示として扱ってください。さらに、identity とマージ禁止の指示(指定されている場合)の後に、末尾に省略可能な and no changelog の指示を指定できます。この実行では、これを変更履歴を追加しない指示として扱ってください。issue やリポジトリの規約で別の対応が求められていても、「Implement the fix」のステップ 4 をスキップし、変更履歴の項目を追加しないでください。
  2. GitHub リポジトリを特定してください。コマンド自体で OWNER/REPO が直接指定されている場合(glorp は常に /gh-fix OWNER/REPO#N としてディスパッチします)は、それを優先してください。これは信頼できる形式であり、追加の特定は不要です。コマンドが /gh-fix N のみで起動されている場合は、呼び出しの他の場所にある Repository: OWNER/REPO の行、またはユーザーが明示した OWNER/REPO を探して使用してください。上記のいずれかでリポジトリが指定されている場合は、git remote -v、gh repo view、その他のリポジトリ特定コマンドを実行してはいけません。呼び出しのどこにもリポジトリが指定されていない場合に限り、現在のチェックアウトの GitHub リモートから OWNER/REPO を推定してください。それでも特定できない場合に限り、ユーザーに確認してください。
  3. git、gh、およびリポジトリとワークフローへのアクセス権を持つ認証済みの gh セッションが必要です。issue が存在していても、この要件やその他の環境要件を満たせない場合は、プルリクエストを作成したり、リポジトリに変更を加えたりせずに停止してください。ただし、以下のルールに従い、修正を実装できなかった理由を説明するコメントを issue に 1 件だけ投稿してください。
  4. issue のタイトル、本文、ラベル、コメント、状態、および関連コンテキストを読み取ってください。identity が指定されている場合は、issue のすべてのコメントと、関連するプルリクエストの会話も、スレッド形式の会話として時系列順に読み取ってください。issue の本文を最初の依頼とし、その後のコメントでコンテキストが修正、明確化、または上書きされる場合があります。指定された identity と完全一致する @/glorp:<ID> のメンションを含むコメントは、このエージェントへの直接の指示であり、無視してはいけません。別の identity を指すメンションは、この実行への指示ではありません。issue が存在しない場合は停止してください。コメントを投稿する対象はありません。対応可能な issue でない場合、またはすでにクローズされている場合は、プルリクエストを作成したり、リポジトリに変更を加えたりせずに停止してください。ただし、以下のルールに従い、修正を実装できなかった理由を説明するコメントを issue に 1 件だけ投稿してください。
  5. issue にマージの許可が与えられていないかを判断し、コードを書く前にその判断を記録してください。次のいずれかをマージ保留の指示として扱ってください。マージ保留を示すラベル(donotmerge、do-not-merge、do not merge、no-merge、hold、needs-review)。大文字と小文字を区別せず、スペース、ハイフン、アンダースコアを無視して一致させてください。または、issue の本文やコメントのどこかにある、この修正をマージしないこと、オープンのままにすること、またはマージ前に停止することを求める表現。この実行宛ての @/glorp:<ID> による指示も含みます。スレッドは時系列順に読み取ってください。後のコメントで保留を追加または解除できるため、最も新しい記述を優先します。指示がある場合は、その正確なラベルを記録するか、該当する表現を引用し、実行全体を通じて保持してください。プルリクエストをレディ状態にするまでのすべての作業は行い、「Hold the pull request when merging is withheld」に従って、マージの代わりにプルリクエストを保留してください。
  6. 適用される AGENTS.md、コントリビューションガイド、ブランチとプルリクエストのルール、CI 設定、変更履歴の規約など、リポジトリの指示を読み取ってください。 あきらめる前に、必ずコメントを残し、フォローアップ作業を追跡してください。 このスキルが何らかの理由で、対象のイシューに対するプルリクエストを作成する前に停止する場合(無効または対応できないイシュー、環境要件の不足、解決できない曖昧さ、ツールの繰り返しの失敗、またはこのワークフローの早い段階で遭遇したその他の障害など)は、ユーザーが代わりにフォローアップ作業を明示的に依頼していない限り、実行を終了する前に、そのイシューに試したことと修正を実装しなかった理由を説明するコメントを1件だけ投稿してください。「複数パートのイシューをサブイシューに分割する」の項目で実行を終了する追跡用イシューは障害ではないため、このルールの対象外です。そのイシューを最初に分割するときに一度だけコメントし、それ以降の実行で新たに伝えることがない場合はコメントしません。ドラフトのプルリクエストを一度も開いていない場合でも、この対応を行ってください。プルリクエストが存在する場合、その後に発生した障害は、新しいイシューコメントではなく、「CIを完了まで進める」の項目に従ってプルリクエスト上で報告してください。どちらの場合も、停止する前に、実行可能なフォローアップイシューを作成またはリンクし、「フォローアップイシューを作成する」の項目に従って担当先を設定してください。これにより、呼び出し元への最終報告だけでなく、理由と次に行う具体的な作業の両方がGitHub上で確認できるようになります。

既存の作業を再開する(再入可能モード)

/gh-fix N は、中断後(Ctrl+C、セッションのクラッシュ、後から開始した新しいセッション)や、呼び出し元から以前の実行の引き継ぎを受けた後でも、安全に再実行できる必要があります。新しいものを作成する前に、次の手順を実行してください。

  1. N がイシューを指しているのか、すでにオープンしているプルリクエストを指しているのかを判定します。N がプルリクエストの場合は、その本文の Closes #<ISSUENUMBER> の行から、それがクローズするイシューを元のイシューとして特定し、新しいプルリクエストを開くのではなく、そのプルリクエスト自体を完了まで進めてください。
  2. N がイシューの場合は、ブランチの命名規則 fix/issue-N-* とプルリクエスト本文の Closes #N を照合の手がかりとして、そのイシューをクローズするプルリクエストを検索します。一致するプルリクエストがクローズ済みの場合は、マージ済みかどうかにかかわらず、決して再利用しないでください。一致したシグナルの種類に関係なく、再開して続行できるのはオープン中のプルリクエストのみです。一致するオープン中のプルリクエストが見つかった場合は、新しいドラフトを作成せず、そのプルリクエストとブランチを再開してください。見つからない場合は、クローズ済みのプルリクエストが一致していても、見つからなかったものとして処理を続けてください。
  3. イシューまたはプルリクエストの担当権限(対応を開始しても安全か、別のエージェントがまだ担当しているかの判断)は、このスキルの開始前に呼び出し元が解決するものであり、このスキルが解決するものではありません。担当権限の調整を目的として、プルリクエストまたはイシューのコメントを読んだり投稿したりしないでください。
  4. 再開時には、デフォルトブランチではなく既存のブランチをクローンし、コミット履歴、チェックポイント、途中までの実装を保持してください。プルリクエストの本文を読んで、すでに完了したこと、テストしたこと、残っている作業を把握してください。
  5. クローンしたら、ブランチを新規作成した場合とまったく同じように、このワークフローの残りを続けてください。チェックポイントを引き続き作成し、実際に準備が整うまでプルリクエストをドラフトのままにして、CIを完了まで進めてください。以前の作業がまだ有効な場合は、実装を最初からやり直さないでください。

複数の作業項目を含むイシューをサブイシューに分割する

複数の切り分け可能な作業項目が明確に記載されたイシューは、作業単位ではなくトラッキングイシューです。何かをクローンする前に一度だけ判断し、同じイシューを二度分割しないでください。

  1. まず、イシューに既存のサブイシューがあるか確認します。 イシューにサブイシューが1つ以上ある場合、すでに分割されています。これ以上サブイシューを作成せず、そのイシューのプルリクエストも作成しないでください。このようなイシューに対して /gh-fix が行うのは、クローズ可能かどうかの判断だけです。すべてのサブイシューの状態を確認します。サブイシューがすべてクローズされ、親イシュー自身の本文にも未実装の内容が残っていない場合は、完了したサブイシュー名を記載したコメントを投稿して親イシューをクローズします。サブイシューが1つでもオープンのままなら、残っているものを報告して実行を終了し、コメントは投稿しません。新たに報告することが何もない場合は、イシューに手を加えないでください。そうすることで、繰り返し実行しても同じコメントが蓄積されません。どちらの場合も、ここで実行を終了します。クローン、ブランチ作成、プルリクエストは行いません。
  2. すでに進行中の作業があるイシューは分割しないでください。 「既存の作業を再開」がそのイシューに対するオープンなプルリクエストに該当した場合は、そのプルリクエストの作業を再開し、このセクション全体をスキップします。
  3. イシュー自体に、明確に切り分け可能な複数の独立したタスクが記載されている場合に限り、分割します。 慎重に判断してください。イシューの開始時点では切り分け可能か判断できないことが多く、誤った分割は分割しない場合よりも大きな損失になります。各項目に独自の成果物が明記され、ほかの項目がなくても単独で実装、テスト、マージできる場合に限って分割してください。「修正を実装し、ドキュメントサイトを更新する」は2つのタスクです。各項目が同じ変更を別の言葉で説明している場合、一方がなければもう一方を検証できない、あるいは着手できない場合、または分割がイシュー自体の記述ではなく独自の推測に基づく場合は、分割しないでください。「機能を実装し、関連する検索バグを修正する」は、通常は単一のタスクです。その機能がなければバグに到達できないためです。迷った場合は分割せず、イシューを1つの修正として実装し、残りのワークフローを変更せずに続けてください。「Create follow-up issues」で定義されている手動のみの項目は、切り分け可能なタスクには該当しません。その項目のサブイシューは作成せず、分割の対象にも含めないでください。
  4. 分割が妥当な場合は、各項目を同じリポジトリ内の独立したイシューとして作成し、親と新しいイシューの GitHub イシュー ID を使って、GitHub のサブイシュー API で元のイシューに紐付けます。Markdown のチェックリストや単なるメンションで済ませてはいけません。各サブイシューには、焦点を絞ったタイトルと、親を読み直さなくても対応できるだけの背景情報および受け入れ条件を記載します。手動確認と自動化可能な作業が混在する項目は、自動化可能な作業だけをサブイシューにします。
  5. 新しいサブイシューはすべて、「Create follow-up issues」と同じ方法で振り分けます。サブイシュー自体に基づいてラベルを選び、現在も適切なラベルのみを引き継ぎ、親のマイルストーンと担当者を継承し、親のプロジェクトへの所属を Todo ステータスでコピーし、それ以外は .glorp.json の割り当てルールを適用します。これにより、次のエージェント枠でサブイシューに着手できるようになります。サブイシューの作成、紐付け、振り分けのいずれかに失敗した場合は、対処が必要なエラーとして再試行します。
  6. サブイシューが作成された時点で、親イシューはトラッキングイシューまたはメタイシューになります。クローズにプルリクエスト、コード、変更履歴の記載は必要なく、エージェント枠を消費してはいけません。作成したサブイシューを列挙し、すべて完了したら親をクローズすることを記載したコメントを1件だけ投稿します。手動のみの項目がある場合は、同じコメント内に Manual verification のチェックリストを設けます。その後、次のエージェント枠でサブイシューに着手できるよう、クローン、ブランチ作成、プルリクエストの作成をせずに実行を終了します。

オープンなブロッキングイシューに着手する

別のオープンなイシューによってブロックされているイシューでも、リポジトリが GitHub のスタック型プルリクエスト(gh-stack)に対応していれば、そのイシューの完了を待つ必要はありません。クローンする前の検証時に一度だけ判断し、実行中はその判断を記録しておきます。オープンなプルリクエストを再開する場合は、ベースブランチにスタック型かどうかがすでに記録されているため、このセクションはスキップしてください。

  1. イシューの未解決ブロッカーをすべて収集します。gh api repos/<OWNER>/<REPO>/issues/<ISSUENUMBER>/dependencies/blocked_by にある未解決のイシューすべてと、イシュー本文の Depends on #<N> 行で指定されている未解決のイシューすべてが対象です。
  2. gh api repos/<OWNER>/<REPO>/stacks?per_page=1 を使って、リポジトリでスタックされたプルリクエストが有効かどうかを確認します。リクエストが成功した場合は有効、404 Not Found の場合は無効です。
  3. スタックが有効で、未解決のブロッカーがちょうど1件あり、そのブロッカーをクローズする未解決のプルリクエストがある場合に限り、スタックします。そのブロッカーのプルリクエスト番号とヘッドブランチを、スタックのベースとして記録します。それ以外の場合はスタックせず、このワークフローの残りの説明どおりにデフォルトブランチを基点として作業します。
  4. 拡張機能がない場合は、gh extension install github/gh-stack でインストールします。インストールできない場合も、以下の説明どおりにブランチとプルリクエストをスタックし、gh stack コマンドはスキップして、プルリクエスト本文にスタックをリンクできなかったことを記載します。
  5. 新しいブランチはデフォルトブランチではなく、ブロッカーのヘッドブランチから作成します。ドラフトプルリクエストも、デフォルトブランチではなくそのブランチをベースとして作成します。ドラフトプルリクエストに関するその他の点は、これまでと同じです。
  6. GitHub で gh stack link を使ってプルリクエストをスタックにリンクします。ブロッカーのプルリクエストがすでにスタックに属している場合(gh api repos/<OWNER>/<REPO>/stacks?pull_request=<BLOCKERPR>)、そのスタックのプルリクエストを下から上の順に並べ、その後にこのプルリクエストを続けて指定します。そうでない場合は、<BLOCKERPR> <PRNUMBER> を指定します。プルリクエスト本文では、ブロッカーのプルリクエストを明記します。
  7. ブロッカーのブランチは別の実行に属します。このブランチに対して、コミット、リベース、プッシュ、マージを行ってはなりません。また、gh stack merge でスタックをマージしてはなりません。スタック内のすべてのブランチをプッシュする gh stack sync と gh stack push も使用できません。
  8. プッシュの前、および CI を待機している間は、上流の変更を確認します。ブロッカーのヘッドブランチをフェッチし、このブランチのベースと比較してください。ブロッカーに変更があった場合、またはマージされた場合は、このブランチから gh stack rebase --upstack を実行してこのブランチを更新します(ブロッカーがマージ済みの場合は、自動的に --onto に切り替わります)。コンフリクトを解決し、影響を受けるチェックを再実行して、このブランチだけを git push --force-with-lease=<BRANCH>:<PREVIOUSREMOTESHA> origin <BRANCH> でプッシュします。gh stack によるリベース後、この実行で作成したブランチをこのリースで保護されたプッシュで更新することだけが、強制プッシュを行わない原則の例外です。拡張機能がない場合は、代わりにブロッカーのブランチをこのブランチにマージし、通常どおりプッシュします。
  9. ブロッカーのプルリクエストがマージされたら、このプルリクエストのベースがデフォルトブランチになっていることを確認します。GitHub が変更していない場合は、gh pr edit <PRNUMBER> --base <DEFAULTBRANCH> で変更し、その後、新しいヘッドに対して通常どおり CI を実行します。ブロッカーのプルリクエストがマージされずにクローズされた場合は、gh stack unstack でスタックを解除し、同じ方法でこのブランチをデフォルトブランチにリベースして、プルリクエストのベースを変更し、クローズされたブロッカーについてプルリクエストで報告します。
  10. ベースがデフォルトブランチ以外のブランチである間は、スタックされたプルリクエストをマージしてはなりません。レビュー可能な状態になり、CI が成功し、ブロッカーのプルリクエストがまだ未解決の場合は、ブロッカーのマージを待たずに実行を終了します。プルリクエストに、レビュー可能な状態でブロッカーのプルリクエストに紐づいていることを伝えるコメントを1件投稿し、失敗やブロッカーではなく、保留中のプルリクエストを結果として報告します。後続のイシューを作成したり、イシューをクローズしたりしてはなりません。glorp が実行を開始した場合、glorp はこれを保留状態にし、エージェントの枠を解放して、ブロッカーが未解決でなくなった時点でイシューを再度実行します。後の実行ではこのプルリクエストを再開し、手順9に従って CI を実行し、「マージと検証」を続けます。CI が成功した時点ですでにブロッカーがマージされていた場合は、実行を終了せず、この実行で手順9に従います。

分離したクローンとブランチを作成する

  1. 正規の OWNER/REPO、クローン URL、デフォルトブランチを特定します。
  2. ディレクトリを変更する前に、実行時のディレクトリに .glorp.json があるかどうかを記録します。状態ファイルは通常無視され、分離したクローンには表示されないため、この情報は後続のルーティングに備えて保持します。
  3. 現在のチェックアウトの外に、<repo>-gh-fix-<N> など、一意の名前を付けた兄弟ディレクトリまたは一時ディレクトリを作成します。ユーザーの現在の作業ツリーを再利用または変更してはなりません。また、独立したクローンの代わりにワークツリーを使用してはなりません。
  4. 通常の方法でリポジトリをクローンします。上のセクションに従って作業を再開する場合は、既存のブランチをクローンしてチェックアウトし、その HEAD がリモートと一致することを確認します。それ以外の場合は、クローンのデフォルトブランチの HEAD がリモートと一致することを確認します。
  5. クローンを検証した直後に、GLORP_CHECKOUT_DIRECTORY=<absolute clone path> を、Markdown 形式を使わず、正確なプレーンテキストの進捗行として出力します。これにより、呼び出し元は実際の分離されたチェックアウトを表示および保存できます。作業再開中にチェックアウトが見つからず、再生成した場合も、この行を再度出力します。
  6. 既存のブランチから作業を再開する場合を除き、現在のリモートのデフォルトブランチから、または「オープン中のブロッカーとなる Issue に積み重ねる」で積み重ねると判断した場合は、ブロッカーのヘッドブランチから新しいブランチを作成します。リポジトリの指示で別の命名規則が定められていない限り、fix/issue-<N>-<short-slug> を使用します。
  7. このワークフローで作成したすべてのクローンディレクトリについて、作成後すぐにクリーンアップ処理を登録します。正常終了、エラー、パニックのいずれの場合も、終了前にそれらのディレクトリを削除します。ユーザーの既存のチェックアウトや無関係なディレクトリは削除しないでください。

クリーンアップは必ず実行してください。各クローンを作成したらすぐに、defer/finally 形式のクリーンアップガードを使用し、クリーンアップエラーを確認できるようにしつつ、元のエラーがある場合はそれを保持します。

ドラフトのプルリクエストを開く

ブランチを作成したらすぐに公開し、ドラフトのプルリクエストを開いて、開発の進捗を常に確認できるようにします。「既存の作業を再開する」に従って既存のドラフト PR から作業を再開する場合は、すでに PR が開かれているため、このセクション全体をスキップします。

  1. Start work on issue #<ISSUENUMBER> [skip ci] などの空の初期コミットを作成し、新しいブランチをアップストリーム追跡付きでプッシュします。[skip ci] マーカーを付けることで、デフォルトブランチと同一のツリーに対して CI が実行されるのを防ぎます。このマーカーを付けるのは、このコミットと「修正を実装する」に記載されたチェックポイントコミットだけです。強制プッシュは決して行わないでください。
  2. 簡潔な修正内容のタイトルを付け、現在のデフォルトブランチを対象にドラフト PR を開きます。積み重ねる場合は、ブロッカーのヘッドブランチを対象にします。
  3. Issue の概要と予定している作業をまとめた、適切な Markdown の本文を作成します。複数行の Markdown をファイルまたは標準入力に用意し、gh pr create --body-file(または同等の gh pr edit --body-file)で渡します。段落区切りを表すために、--body 引数にリテラルの \n エスケープシーケンスを記述してはなりません。ドラフトが元の Issue にリンクし、マージ時に Issue をクローズするよう、Closes #<ISSUENUMBER> を独立した行に含めます。さらに、作成した PR の本文を読み戻し、実際の改行が含まれていて、リテラルの \n テキストではないことを確認します。
  4. 本文の末尾に **Agents:** フッター行を追加し、Issue を担当する現在のエージェント CLI とモデルの名前を記載します(例:**Agents:** claude-code (claude-sonnet-5))。自身の実行時コンテキストから特定してください。これは、以下で説明する貢献エージェントのフッターです。
  5. PR 番号と URL を記録し、ヘッドブランチとベースブランチが正しいことを確認します。
貢献エージェントのフッターを維持する

PR 本文を作成または置き換えるたびに(下書きの作成、チェックポイントの更新、レビュー可能への変更時)、**Agents:** フッターを上書きせずに維持してください。

  1. まず現在の PR 本文を読み、**Agents:** の行があれば、その位置を確認します。
  2. 実行時のコンテキストから、自分が現在使用しているエージェント CLI とモデルを特定します。
  3. フッターがない場合は、自分のエントリーだけを記載して追加します。すでに 1 つ以上のエージェント/モデルのエントリーがある場合は、既存の重複しないエントリーをすべて保持し、自分のエントリーがまだなければ追加します。出現順にカンマで区切ります(例:**Agents:** codex (gpt-5), claude-code (claude-sonnet-5))。
  4. これにより、この課題に関わったすべてのエージェントとモデルがフッターに蓄積されます。別のエージェントやモデルが作業途中の下書きを引き継ぐ際に重要です。

修正を実装する

  1. 可能であれば、報告された動作を再現するか、別の方法で検証します。
  2. 関連するコードと履歴を調べ、リポジトリの規約に沿った、完全な修正のうち最小のものを実装します。
  3. リポジトリに関連するテストフレームワークがある場合は、修正がなければ失敗する、対象を絞ったテストを追加または更新します。
  4. 既存の変更履歴を、大文字小文字を区別せずにプロジェクト固有のパスや名称も含めて探します。現在の未リリースセクションに、ユーザー向けの簡潔な説明を追加し、その形式に従います。プロジェクトに変更履歴がない場合は作成せず、この手順を完全に省略し、プロジェクトに変更履歴がないため追記しなかったことを PR 本文に記載します。ユーザーに見える変更に限って変更履歴に追記し、内部向けの説明は追加しません。未リリースの別の変更履歴項目を修正する場合は項目を追加しません。次のいずれかの方法で変更履歴を追加しないよう指示されている場合は、この手順を完全に省略し、変更履歴には何も追加しません。検証からの and no changelog というディスパッチ上の助言がある場合、または課題本文やコメントのどこかに、この実行に宛てた @/glorp:<ID> の指示を含め、今回の修正では変更履歴を省略する、変更しない、あるいは無視するよう求める記述がある場合が該当します。変更履歴を意図的に省略したことと、その理由を PR 本文に記載します。
  5. 開発中、作業ツリーに変更がある場合は、少なくとも 5 分ごとにチェックポイントコミットを作成してプッシュします。Checkpoint issue #<ISSUENUMBER> progress [skip ci] のようなメッセージを使用し、未完了の作業で CI を実行しないよう [skip ci] マーカーを残します。次のチェックポイントを公開する前に実装やテストの完了を待ってはいけません。シークレット、生成されたビルド成果物、無関係な変更は決して含めないでください。チェックポイント時に変更がない場合は空のコミットを省略し、次の開発間隔後に再確認します。
  6. まず対象を絞ったテストを実行し、その後、リポジトリで必須とされる広範なチェックを実行します。変更が原因の失敗は解消します。既知の不具合がある修正をレビュー可能にしてはいけません。
  7. 状態と差分全体を確認します。課題、そのテスト、変更履歴の追記に必要なファイルだけを含めます。

UI スクリーンショットと画面録画のキャプチャ

実装が完了した後に限り、変更したファイルが UI に影響するかどうかを判断します。影響する場合は、次の手順を実行します。

  1. 完成した UI の変更を、代表的な最終状態で示すスクリーンショットをキャプチャします。変更にアニメーション、インタラクション、または状態遷移が含まれる場合は、スクリーンショットの代わりに、または追加で、動作を示す画面録画をキャプチャします。アニメーションの場合は、エラー処理などの二次的なユースケースも含め、すべての機能を余すところなく「使用」する一連の操作を計画します。
  2. ブラウザーを使うインターフェースでは、UI を起動し、CDP やブラウザー自動化など、利用可能なブラウザーツールを使ってスクリーンショットまたは画面録画をキャプチャします。
  3. ターミナルベースのインターフェースでは、視覚的な変化、アニメーション、状態変化がない場合は、出力をテキストとしてコピーします。
  4. それ以外のブラウザー以外のインターフェースでは、利用可能なローカルアプリケーションまたはプラットフォームのキャプチャツールを使用します。適切なキャプチャツールがインストールされていない場合は、Loom をインストールして画面録画を作成します。
  5. ネイティブウィンドウをキャプチャする場合(デスクトップアプリやプラットフォームのキャプチャツールなど、ブラウザー以外でのキャプチャ)、スクリーンショットまたは録画を対象ウィンドウの範囲にトリミングします。キャプチャ時にアプリ自体が本当に全画面表示でない限り、画面全体またはディスプレイ全体の解像度のキャプチャは決して残さないでください。
  6. 各スクリーンショットまたは画面録画をアップロードし、返された URL を Markdown としてプルリクエスト本文に直接埋め込みます(例:![Dashboard after refresh](https://github.com/user-attachments/assets/...))。UI のスクリーンショットや画面録画をリポジトリのアセットに追加したり、ブランチにコミットしたりしないでください。

GitHub には、課題、プルリクエスト、コメントにファイルを添付するための公開 API が文書化されていませんが、Web UI のドラッグ&ドロップと同じエンドポイントは、ベアラートークンを使って非対話的に利用できます。次のコマンドでアップロードします。

REPO_ID=$(gh api repos/<OWNER>/<REPO> --jq .id)
curl -sf -X POST "https://uploads.github.com/user-attachments/assets?name=<FILENAME>&content_type=<MIME_TYPE>&repository_id=$REPO_ID" \
  -H "Authorization: Bearer $(gh auth token)" \
  -H "Accept: application/json" \
  --data-binary @<LOCAL_FILE_PATH>

レスポンスは url フィールド(https://github.com/user-attachments/assets/<uuid>)を含む JSON です。その URL をプルリクエスト本文に埋め込みます。このエンドポイントは文書化されておらず、非公式であるため、失敗または予期しないレスポンスがあった場合は、際限なく再試行するのではなく、以下のキャプチャエラーのいずれかとして扱ってください。

完成した差分が UI コードにまったく影響しない場合に限り、このセクションを省略します。 キャプチャまたはアップロード中に 2 件以上のエラーが発生した場合は省略し、その旨をプルリクエストで説明してください。

コミットとプッシュ

ローカルチェックに合格した後、最後の実装コミットを作成します。[skip ci] は付けず、簡潔な命令形の件名にし、本文にはクロージングキーワードを独立した行に記載します。最新のチェックポイントに最終変更がすべて含まれている場合は、チェック済みの実装を明確に完了するコミットとして、空のコミットを使用します。

Fix <concise issue summary>

Closes #<ISSUENUMBER>

たとえば、git commit -m "Fix parser handling of empty input" -m "Closes #123" を実行すると、必要な独立した本文行が作成されます。対象の課題番号を正確に使用し、例のとおり Closes の先頭を大文字にします。

GitHub は、件名を含むコミットメッセージのどこかにスキップマーカーが含まれるコミットの CI をスキップします。また、スカッシュマージでは、プルリクエストのタイトルと本文がデフォルトブランチ上のコミットにコピーされます。最終実装コミット、CI 修正コミット、プルリクエストのタイトルまたは本文には、変更がそれらのマーカーに関するものであっても、GitHub が認識するスキップマーカー([skip ci]、[ci skip]、[no ci]、[skip actions]、[actions skip]、または skip-checks: true のトレーラー)を文字どおり記載しないでください。代わりに、「CI スキップマーカー」などの言葉で説明してください。

最後にプッシュする前に、ブランチに意図したコード、テスト、変更履歴の記述が含まれていること、最終実装コミットに独立した Closes #<ISSUENUMBER> 行がありスキップマーカーが含まれていないこと、作業ツリーがクリーンであること、ローカルチェックに合格していることを確認します。通常どおりプッシュしてください。強制プッシュは決して行わないでください。

プルリクエストをレビュー可能な状態にする

  1. ドラフト PR のタイトルと本文を更新し、根本原因、変更内容、ユーザーへの影響、変更履歴の項目、テスト、必要な UI スクリーンショットや画面録画を含めて、完了した修正を説明します。Closes #<ISSUENUMBER> は単独の行に残し、前述の説明に従って **Agents:** のフッターを更新してください。削除したり上書きしたりしないでください。「Commit and push」に記載されているリテラルのスキップマーカーは、タイトルと本文に含めないでください。
  2. ヘッドブランチ、ベースブランチ、変更ファイルの範囲が正しいことを確認します。スタックされたプルリクエストの変更ファイルには、ブロッカーのブランチを基点とする、この課題の変更のみが含まれている必要があります。
  3. 実装、ローカルチェック、最終プッシュ、必要な UI スクリーンショットや画面録画がすべて完了してから、ドラフト PR をレビュー可能な状態にします。

CI を完了まで進める

必要なチェックがすべて成功するまで続けます。

  1. 成功を評価する前に、想定されるチェック一式が PR に登録されていることを確認します。PR 作成直後に一時的にチェックリストが空でも、ビルドが成功したことにはなりません。設定済みまたは必須のチェックが表示されるまで待つか、リポジトリに該当する CI が実際に存在しないことを確認してください。
  2. 単一のステータススナップショットだけで判断せず、PR のチェックを監視します。gh pr checks <PR> --watch --interval 10 を優先し、長時間のビルド中にユーザーへ定期的に進捗を知らせるため、製品の継続的な待機機能を使用してください。glorp がこのワークフローを実行するような非対話型の実行では、フォアグラウンドで監視をブロックし、バックグラウンドタスク、モニター、予約された再開処理を待ったままターンを終了しないでください。ターンが終了するとプロセスも終了し、待機が中断されます。
  3. GitHub Actions のチェックが失敗した場合は、必要に応じて gh pr checks、gh run view、ジョブログ API を使い、該当する実行と失敗したジョブのログを調査します。コードを変更する前に、チェック名、実行 URL、失敗したコマンド、有用なエラーの詳細を記録してください。
  4. 外部チェックについては、チェック URL を開き、プロバイダーが提供するログやツールを使用します。ログにアクセスできない場合は、推測せず、アクセス上の阻害要因を報告してください。
  5. 各失敗を分類します。
    • PR が原因の失敗は、実用的であればローカルで再現し、最小限かつ正しい修正を行い、関連するローカルチェックを実行します。「Commit and push」に記載されたスキップマーカーを含めずに修正をコミットし、通常どおりプッシュしてください。
    • マージコンフリクトの場合は、強制プッシュを使わず、最新のデフォルトブランチからブランチを更新して競合を解決し、影響を受けるチェックを再実行してからコミットし、プッシュします。スタックされたプルリクエストの場合は、代わりに「Stack on an open blocking issue」の説明に従い、ブロッカーのブランチから更新してください。
    • 明らかな一時的なインフラストラクチャ障害または不安定なテストによる失敗は、失敗したジョブを一度再実行し、再発した場合は調査します。
    • 明らかに無関係な継続的失敗については、診断情報を収集し、安全に対応できる場合に限り、スコープ内での修正を試みます。それ以外の場合は、実際の外部阻害要因の段階で停止してください。
  6. プッシュまたは再実行のたびに、新しいヘッド SHA のチェックを保留中から完了まで監視します。以前の SHA の古い結果は無視してください。
  7. 対応可能な CI の失敗がなくなるまで、診断、修正、ローカルでの検証、コミット、プッシュ、監視を繰り返します。成功結果を得るために、アサーションを弱めたり、テストをスキップしたり、カバレッジを下げたり、CI を変更したりしないでください。

マージが保留された場合はプルリクエストを保留する

検証時にマージ禁止の指示が記録されていた場合、実行は、準備完了状態でマージされていないプルリクエストを残して終了します。それ以前の作業に変更はありません。修正、そのテスト、変更履歴の注記、最終プッシュ、プルリクエストをレビュー可能な状態にすること、CI の完了までの実行はすべて行います。マージと、その後のイシューだけは行いません。

  1. プルリクエストをマージせず、ブランチを削除せず、元のイシューをクローズしないでください。CI が成功している、または修正が完了しているように見えるという理由で、保留を無視してマージしてはいけません。
  2. 実行自体の出力に判断を記録してください。マージを保留したラベルの名前、またはその指示の文言を引用し、プルリクエストは人間がマージできるよう意図的にオープンのままにしたことを明記してください。
  3. プルリクエストには、完了状況を報告するコメントをちょうど 1 件投稿してください。チケットが Ready であることを伝え、修正、テスト、CI の結果を要約し、マージを保留したラベル名、または指示文を引用して、マージが保留されたことを伝えてください。
  4. 保留された実行では、フォローアップイシューを作成、再利用、割り当てしないでください。マージされていない作業はレビュー中に変更される可能性があるため、「フォローアップイシューを作成」は適用されません。代わりに、フォローアップイシューになるはずだった項目をすべて、同じプルリクエストコメント内の Follow-ups (not filed) 見出しの下に記載してください。同等の既存オープンイシューがあれば、新たに作成するのではなくリンクしてください。これにより、マージする人がイシューを作成できます。それらの項目は「フォローアップイシューを作成」の説明に従って分類してください。手作業のみの項目は Follow-ups (not filed) に含めず、同じコメント内の独立した Manual verification 見出しの下に、セットアップ手順と正確な確認項目を記載してください。
  5. そのコメントを投稿したら実行を終了し、失敗やブロッカーではなく、保留を結果として報告してください。

マージと検証

イシューによってマージの許可が保留されている場合は、このセクション全体を省略し、代わりに「マージが保留された場合はプルリクエストを保留する」に従ってください。

  1. マージする前に、最新の PR の状態を取得し、元のイシューと PR がどちらもまだオープンであることを確認してください。どちらかがクローズされている場合はマージしないでください。イシューがクローズされている場合は作業を中止し、マージされずにクローズされた PR はその試みが却下されたことを意味するため、再オープンしたり再利用したりしてはいけません。次に、ベースがデフォルトブランチであること(積み上げ式のプルリクエストは、ブロッカーが先にマージされるまで待ちます)、少なくとも 1 件の CI 実行がヘッド SHA に登録されていて、その SHA 上の必須チェックがすべて成功していること、PR がマージ可能であること、必須レビューや未解決の会話が妨げになっていないこと、必須の UI スクリーンショットまたは画面録画が揃っていること、ヘッド SHA が CI に合格した SHA であることを確認してください。ヘッド SHA のチェックリストが空のままでは合格とはみなせません。リポジトリで CI を使用している場合は、ヘッドコミットのメッセージと PR のタイトルおよび本文にスキップマーカーがないか確認し、見つかった場合は削除して新しいコミットをプッシュし、マージ前に CI を実行してください。
  2. リポジトリで必須または確立されているマージ方法を使ってください。リポジトリで複数の方法を選べる場合は、スカッシュ、マージ、リベースの順に優先してください。スカッシュする場合は、上書きせずに PR のタイトルと本文をスカッシュコミットメッセージとして使用してください。本文にはすでに単独行の Closes #<ISSUENUMBER> が含まれています。マージまたはリベースしか利用できない場合は、その方法を使い、方法にかかわらずクローズ参照を単独行のまま保持してください。
  3. リポジトリのポリシーで許可されている場合、マージが成功した後にリモートのイシューブランチを削除してください。
  4. PR がマージ済みであること、マージされたコミットがリモートのデフォルトブランチから到達可能であること、GitHub がイシュー #<ISSUENUMBER> をクローズしたことを確認してください。GitHub の処理に多少時間がかかる場合は待ってください。ただし、確認せずにクローズ済みと報告してはいけません。

フォローアップイシューを作成する

失敗または停止した実行の直前(プルリクエストの有無を問いません)と、プルリクエストのマージ後の両方の終了時点で、未解決のフォローアップ作業がないか確認してください。元の Issue、プルリクエストの本文とコメント、現在の会話を読み、明示されたブロッカー、TODO、既知の問題をすべて確認してください。実行を停止する直前の場合は、マージを待たないでください。このセクションは、「Hold the pull request when merging is withheld」に従って終了した実行には適用されません。保留中のプルリクエストでは、フォローアップ Issue は一切作成せず、代わりに同じ項目を完了状況のコメントで報告します。

項目をすべて分類してから起票してください。 受け入れ可否を人が確認する以外に方法がない項目は、手動のみです。たとえば、サードパーティ製の GUI アプリケーションやホストの実行、物理ハードウェアや周辺機器の使用、実機やアカウントの使用、リポジトリでテストできない主観的または視覚的な判断が該当します。手動のみの項目は、絶対に Issue として起票しないでください。glorp が作業できないエージェント枠に割り当てることになり、どのエージェントも解決できない Issue でバックログが埋まってしまいます。

  • 手動のみの項目は、Manual verification チェックリストを含むコメントを1件だけ投稿してください。プルリクエストがある場合はそこに、プルリクエストを作成せずに実行が停止する場合は元の Issue に投稿してください。プルリクエスト作成前に実行が停止する場合は、チェックリストを、その実行がすでに投稿する説明コメント1件に含め、コメントを追加しないでください。各項目について、セットアップ手順と具体的な確認内容を記載し、CI では確認できないことを明記してください。以前の実行が同じチェックリストをすでに投稿している場合は、再投稿しないでください。
  • スクリプト、テストハーネス、ドキュメント、パッケージングなど、自動化可能な作業と手動確認が混在する項目の場合は、自動化可能な部分だけをフォローアップ Issue として起票し、手動確認の内容はコメントに記載してください。
  • 以下の手順は、手動のみではない項目、またはその一部にのみ適用されます。
  1. 実行可能な項目は、それぞれ個別の課題として同じリポジトリに作成してください。完了済みの作業、曖昧な所見、または同等の未解決課題がすでにある項目については課題を作成せず、既存の課題にリンクしてください。
  2. 新しい課題には、焦点を絞ったタイトルと、プルリクエストを読み直さなくても対応できるだけの背景情報および受け入れ条件を記載してください。
  3. 新しい課題はすべて、元の課題と、ブロッカーまたは残作業が見つかったプルリクエストがある場合はそのプルリクエストに関連付けてください。対応している場合は、リポジトリまたはプロジェクトの関連メタデータを優先してください。対応していない場合は、課題本文に Addresses #<ISSUENUMBER> を記載し、プルリクエストがある場合は and #<PRNUMBER> も加えてください。
  4. 元の課題に未解決の課題依存関係があり、フォローアップがその依存関係に対応する場合は、フォローアップを関連するブロッカー課題のサブ課題にしてください。依存関係と新しい課題の GitHub 課題 ID を確認したうえで、GitHub のサブ課題 API を使用してください。Markdown でブロッカーに言及するだけでは不十分です。ブロッカーが複数ある場合は、フォローアップを、対応する特定のブロッカーだけに関連付けてください。関係が曖昧な場合は推測せず、指示を求めてください。同等の未解決課題を再利用する場合も、すでにそのブロッカーのサブ課題でない限り、同じ関連付けを適用してください。
  5. 新しいフォローアップ課題のラベルは、元の課題からコピーせず、フォローアップ自体に基づいて設定してください。まずリポジトリで使用可能なラベルを確認し(gh label list)、フォローアップの内容に合った種類のラベルを適用してください。たとえば不具合には、このリポジトリで不具合を表すラベル(bug、bugreport、defect)を、新しい作業には機能を表すラベル(enhancement、feature、Feature)を使用します。リポジトリで実際に定義されているラベル名を、大文字小文字を区別せずに照合し、定義されていないラベルを作らないでください。該当するラベルが定義されていない場合は、近似ラベルを使わず、種類を示すラベルなしにしてください。
  6. 元の課題のラベルは、フォローアップにも当てはまる場合に限り引き継いでください。フォローアップと元の課題で共通する内容(領域、コンポーネント、リリーストレイン、優先度、milestone123 のようなグループ分け)を示すラベルは引き継ぎます。元の課題自体を示し、フォローアップと矛盾する可能性のあるラベルは引き継ぎません。具体的には、種類を示すラベル(フォローアップが機能リクエストの場合の元の課題の bug、およびその逆)や、トリアージまたはワークフローの状態(needs-triage、duplicate、wontfix、good first issue)です。引き継いだラベルが、上記の方法で選んだ種類を示すラベルに優先することはありません。両者が一致しない場合は、フォローアップ自身の種類を示すラベルを優先し、元の課題のラベルは引き継がないでください。
  7. 元の課題のマイルストーンと担当者を、すべての新しいフォローアップ課題にそのまま引き継いでください。元の課題から値を確認し、フォローアップの作成時に、上記で決定したラベルと合わせて設定してください(gh issue create --label ... --milestone ... --assignee ...)。または、作成直後に gh issue edit で追加してください。リポジトリで受け付けられない値(存在しなくなったラベル、終了済みまたは存在しないマイルストーン、割り当てできないユーザー)だけを省略し、どの値を省略したかを明記してください。この手順全体を省略しないでください。元の課題に設定されていないマイルストーンや担当者を作り出さないでください。
  8. 元の課題のプロジェクト項目を確認してください。GitHub Projects に1つ以上含まれている場合は、新しいフォローアップ課題をすべて同じプロジェクトに追加し、それぞれの新しい項目の Status をそのプロジェクトの Todo オプションに設定してください。Todo は大文字小文字を区別せずに照合しますが、別のステータスを黙って選ばないでください。失敗または停滞した実行を終了する前にも、マージ後にも、この振り分けを適用してください。
  9. 元の課題にプロジェクト項目がなく、実行時のディレクトリに .glorp.json があった場合は、上記で引き継いだ担当者に加えて、すべての新しいフォローアップ課題を認証済みユーザーに割り当ててください。Glorp が処理を割り当てられるよう、gh issue edit <NEWISSUENUMBER> --repo <OWNER/REPO> --add-assignee @me を使用してください。クローンの前に記録したファイルの有無を使用し、隔離されたチェックアウトに無視対象の状態ファイルが存在すると想定しないでください。プロジェクトに属するフォローアップには認証済みユーザーを追加しないでください。引き継いだ担当者は引き続き適用してください。
  10. 同等の未解決課題を再利用する場合も、すでに正しく振り分けられている場合、または現在のプロジェクトステータスから作業が開始済みもしくは完了済みとわかる場合を除き、同じプロジェクトステータスまたは担当者の振り分けを適用してください。再利用する課題には、決定したラベルに加え、引き継いだマイルストーンと担当者を、それぞれの項目に独自の値が設定されていない場合に限り追加してください。既存のトリアージを上書きまたは削除してはいけません。
  11. 新規作成または再利用したフォローアップ課題の URL をすべて最終報告に記録してください。該当する項目がない場合は、フォローアップ課題が不要だったことを明記してください。手動確認が必要な項目は、該当項目を列挙したコメントの URL とともに別途記録してください。
  12. 課題の作成、元の課題との関連付けまたは必須のサブ課題関係の設定、フォローアップへのラベル付けまたは元の課題のマイルストーンや担当者の引き継ぎ、必須ユーザーの割り当て、プロジェクトへの追加、または Todo ステータスの設定に失敗した場合は、実行可能なエラーとして扱い、再試行してください。必須のフォローアップ課題作業が未完了のまま、失敗または停滞した実行を終了したり、マージ済みのワークフローを完了として報告したりしないでください。

結果を報告する

統合した結果を最初に記載してください。課題とプルリクエストの URL、ブランチ名、最終コミットまたはマージの SHA、クローンのパス、変更履歴ファイル、ローカルテスト、完了した CI チェック、フォローアップ課題の URL(または不要だった旨)、手動検証項目とそのコメント URL(フォローアップ課題とは別に記載するか、該当なしと明記)、UI のスクリーンショットまたは画面録画(または該当しない旨)を含めてください。プルリクエストのマージと課題のクローズの両方を確認してください。実際にブロックされている場合は、失敗した正確な手順、関連する URL またはログの詳細、残っている要件、そのために作成または再利用したすべてのフォローアップ課題を示してください。続行できるよう、分離したクローンとブランチはそのまま残してください。マージが保留され、プルリクエストを保留した状態で実行が終了した場合は、マージではなくその旨を最初に記載してください。プルリクエストが準備完了だが未マージであることを報告し、マージを保留したラベルの名前、または保留を示す文言を引用して、完了状況を報告したコメントの URL を示してください。そこで報告したフォローアップ項目は、課題 URL ではなく、未登録の項目として列挙してください。スタックされたプルリクエストが、未解決のブロッカーを理由に保留された状態で実行が終了した場合は、その旨を最初に記載してください。プルリクエストが準備完了だが未マージであること、待機中のブロッカーのプルリクエストを示し、保留を報告したコメントの URL を記載してください。課題がトラッキング課題であるために実行が終了した場合は、プルリクエストを作成していないこと、作成済みまたは既存のサブ課題とその URL および状態、親課題をクローズしたか、未解決のサブ課題を待っている状態かを報告してください。プルリクエストを作成せずに検証中にワークフローが停止した場合は、プルリクエストを作成していないこと、理由を引用し、作成または再利用したすべてのフォローアップ課題と、課題に投稿した説明コメントの URL を記載してください(課題が存在しない場合は、不要だった旨を確認してください)。

クローンをクリーンアップする

分離したクローンのディレクトリと一時ファイルを削除してください。ワークフローがブロックまたは失敗した場合は、調査を続けられるようクローンを残し、その場所をユーザーに報告してください。

コメント