Rebut
プルリクエスト上のAIコードレビューのコメントをトリアージし、厳密に回答します。全ての指摘を実際のコードと照合して検証し、実際のバグは修正し、誤検知は証拠に基づいて反論し、各スレッドに自動トリアージであることを明示して応答します。人間は依然として「Resolve」をクリックします。
これは人間のレビューの補完であり、そのコピーではありません。CodeRabbitやGemini Code AssistなどのAIレビュアーは、はるかに多くの指摘を投稿し、実際のバグと誤検知が混在しており、リポジトリに依存しません。彼らはあなたのリポジトリのローカル設定、規約、ツールを知らないため、あなたのリポジトリでは正しいパターンをバグであると確信を持ってフラグ付けします。ボットの重大度はその正しさではありません: CRITICALは誤検知である可能性があり、些細な指摘に実際のバグが隠れている可能性があります。
AIレビュアーが独自のトリアージを必要とする理由
- リポジトリに依存しない。 ボットはリポジトリのローカル設定(リンター、フォーマッター、型チェッカーの設定、スタックで使用するもの)やハウスルールを読み込みません。あなた自身のツールが必須とするパターンをフラグ付けします。実際の例(ESLintリポジトリ):レビュアーが
meta.defaultOptionsを「間違っている」とCRITICALとマークしましたが、リポジトリのrequire-meta-default-optionsリントルールがそれを強制しています。提案を適用するとビルドが壊れていたでしょう。盲目的な適用は盲目的な却下と同じくらい危険です。 - 高い誤検知率。 多くの指摘は推測またはスタイルのみです。中には人間が見逃した実際のバグもあります。仕事はそれらを証拠に基づいて分離することであり、感覚に基づいてではありません。
- 確信犯的に間違っている。 重大度ラベルはヒューリスティックです。
CRITICALも些細な指摘と同じ方法で検証してください。
レビュアーが人間の場合
パイプラインはすべてのレビュアー(ボットでも人間でも)で同じです:現在のコードに対して検証 → 修正または証拠に基づいて反論 → 属性行付きでスレッド内に応答 → カバレッジを証明。人間のコントリビューターやレビュアーもトリアージループの一部です:人が変更を求めた場合、修正して応答してください。同じ厳密さと、人間のゲートがマージ時に読み取る同じ監査証跡で。変更されるのはトーンだけです。なぜなら、人間はリポジトリを知っており、指摘は少なく信号対雑音比が高く、鈍い反論が脅威となる相手だからです。したがって、レビュアーが人間の場合:
- ボットの枠組みを捨ててください。 彼らのレビューをリポジトリに依存しない、誤検知率の高いノイズとして扱わないでください。通常はそうではありません。
- 協力し、無愛想に反論しないでください。 検証し、正しいものは修正し、間違っているものには技術的な理由で反論してください。決してパフォーマンス的な同意や、同僚に対する無愛想な「誤検知」は行わないでください。理由を、無愛想ではなく技術的に理由付けされた口調で述べてください。
- 自分で応答を投稿し、属性行を付けてください。 ボットスレッドと同じように、人間のスレッドも自律的にトリアージします:トリアージアカウントを通じて投稿し、属性行を開いて、読者がメンテナー自身のピアレビューではなく自動トリアージであると認識できるようにします。コメントをメンテナーから切り離す行こそが、人間のスレッドへの自動投稿を安全にするものです。カバレッジは人間のスレッドもカウントします(ステップ5.5)。そのため、未回答の人間の指摘があるとラウンドは開いたままになります。
以下のステップはボットにも人間にも適用されます。属性マーカーと自動応答は両方に使用されます。レビュアーごとの唯一の適応は上記のトーンです。
事前確認
"${CLAUDE_SKILL_DIR}/scripts/preflight.sh"
preflight.sh は gh が認証されており、リポジトリにGitHubリモートがあることを確認します。前提条件が欠けている場合、stderrに修正方法を出力して非ゼロで終了します。それを中継して停止してください。PRを特定します:[pr-number] 引数、または現在のブランチのPR(gh pr view --json number)。
ステップ1:すべての指摘を収集する
"${CLAUDE_SKILL_DIR}/scripts/gather-review.sh" <pr>
gather-review.sh は、各レビューの著者、状態、本文を含む REVIEWS ブロックと、各インラインコメントの著者、path:line、id=<id>、本文を含む COMMENTS ブロックを、gh の組み込み --jq を介して出力するため、何も発明したりドロップしたりしません。各指摘を、著者、path:line、応答に必要なコメント id、本文とともにリストアップしてください。トップレベルのレビュー要約とすべてのインラインコメントを含めてください。一つも漏らさないでください。各スレッドの著者を、収集された出力に示されている [bot] ログインサフィックスで認識できるボット、または人間としてタグ付けしてください。両方ともステップ4〜6に従い、人間のスレッドはさらに上記「レビュアーが人間の場合」のトーン調整を適用します。
トリアージの前にラウンドが収束するのを待ちます。 レビュアーは非同期で発火します:2番目のボットは最初のボットから数分後にその波を着陸させることがよくあります。そのため、PRが更新された直後の収集実行は、これまでに投稿されたレビュアーのみをキャプチャします。最初の収集後、gh pr checks <pr> --watch || true でラウンドが収束するのを待ちます。これはPRのチェックが完了するまでブロックし、インタラクティブモードとヘッドレスモードで同じように動作し、それが非同期レビュアーが投稿するウィンドウです(|| true はチェックのないPRの非ゼロ終了を失敗として読み取らないようにします)。その後、gather-review.sh を再実行します。新しい指摘が現れた場合、ラウンドはまだ到着中なので、ウォッチして再度収集します。(PRにチェックがない場合、--watch はすぐに戻ります。また、レビュアーのみのボットはチェック実行をまったく登録しない可能性があるため、どちらの場合も一時停止してチェック状態に関係なく再収集します。以下のラウンド間自動化は、この収束後に投稿するレビュアーに対する本当のバックストップです。)再収集で新しいものが何も追加されなくなってから、トリアージを開始してください。これにより、複数レビュアーのラウンドを、レビュアーAの指摘から開始してレビュアーBがまだ投稿中である場合に強制的に2回目のフルパスを行う代わりに、1回のトリアージパスとして処理します。境界はこれが永遠に待つことを防ぎます。最後のセクションのラウンド間自動化は、スキル終了後に投稿するレビュアーに対する耐久性のある回答です。
ステップ2:各指摘を検証する(このスキルの核心)
各指摘について、ボットの枠組みではなく、現在のコードに対して2つの質問に答えてください:
- 問題は再現しますか?
${CLAUDE_SKILL_DIR}/references/debugging.mdの説明に従って再現します:その行でファイルを開き、ロジックをトレースし、ボットが記述した入力を構築し、実際の動作を確認します。バグである場合、実証可能でなければなりません。 - 提案はこのリポジトリにとって正しいですか? リポジトリが定義する関連ゲート(リンター、型チェッカー、テストなど、存在するもの)を実行します。文書化された規約を確認します。ボットのチェックはパスするがリポジトリのゲートは失敗する修正は、ここでは間違っています。
一度に一つのことを変更し、再検証してください。バッチ処理しないでください。
ステップ3:分類
| 評決 | 意味 | アクション |
|---|---|---|
| FIX | 実際のバグ、再現する | 修正する(ステップ4) |
| REFUTE | このリポジトリでは誤検知 | 反証する証拠とともに応答する |
| INTENTIONAL | ボットには見えない意図的な選択 | 意図を説明して応答する |
| MINOR | 表面的、ゲートに影響なし | 注記する;メンテナーの基準に従って修正するかスキップする |
ステップ4:有効なものを修正する
- 指摘に範囲を絞った最小限の変更。バグの場合は、最初に失敗するテストを書き、失敗を確認し、修正し、パスを確認します。
- リポジトリの完全なゲートを実行します。赤いゲートは修正をブロックします。
- ラウンド全体を1つのコミットにまとめてプッシュし、指摘ごとに決してプッシュしないでください。 各指摘をステップ2のように一つずつ検証して修正しますが、すべての修正をステージングして一緒にコミットし、その後一度プッシュします。メンテナーのアカウントで、PRを所有し応答を投稿する同じアカウントです。指摘ごとのプッシュは1つのレビューサイクルを複数に分割します:各プッシュはCIを再実行し、すべてのボットを再トリガーするため、5つの修正は5回のCI実行と5回の再レビュー波になります。ラウンドごとに1つのコミットは1回のCI実行と1回の再レビュー波です。その単一のSHAをキャプチャします。ステップ5のすべての修正応答はそれを引用します。プッシュが、リモートブランチが移動したために非fast-forwardとして拒否された場合(リリースボットのバンプやPRの「ブランチを更新」マージがラウンド中にコミットを追加したなど)、回復し、停止しないでください:
git fetchしてからgit rebase origin/<branch>し、ゲートを再実行し、再度プッシュします。決して--forceは使用しません。リベースはコミットを書き換えるため、新しいSHAを再キャプチャし、ステップ5の応答でそれ(リベース前の古いSHAではない)を引用します。
ステップ5:各スレッドに応答する
元のコメントに応答してインラインでスレッド化します。トップレベルのPRコメントには決して応答しません。
すべてのスレッドにおいて、例外なく、すべての応答を同じ属性行で開きます。 あなたはメンテナーの gh トークンを通じて投稿するため、GitHubは彼らのアバターを表示し、読者は彼らが書いたと想定します。属性行はエージェントを指名し、コメントをメンテナーから切り離すため、自動トリアージがメンテナー自身のレビューと誤解されることはありません:
🤖 Automated triage by Claude Code, posted through the maintainer's account, not a personal review.
リポジトリにボットまたはマシンアカウントがある場合、代わりにそのIDで投稿して著者自身が非個人であるようにします。属性行は個人トークンのためのフォールバックです。
本文をファイルに書き込みます。属性行により本文が複数行になり、インラインの -f body="..." 引用が壊れます。修正応答:
> 🤖 Automated triage by Claude Code, posted through the maintainer's account, not a personal review.
**rebut** fixed in <sha>: <変更の1行説明>.
反論は証拠を述べます:
> 🤖 Automated triage by Claude Code, posted through the maintainer's account, not a personal review.
**rebut** not changing this: <具体的な理由、例:リポジトリのリントルールがそれを必須としている; ゲートはパスする>.
各応答を post-replay.sh で、一度に1つの指摘ずつ投稿します:
"${CLAUDE_SKILL_DIR}/scripts/post-reply.sh" <pr> <comment_id> /tmp/reply.md
post-reply.sh はGitHubのセカンダリレート制限下で投稿のペースを調整し、API応答から作成された応答IDを読み戻して永続化を確認し、投稿がスロットルされた場合はバックオフでリトライします。成功時は応答IDを出力して0で終了します。終了コード1は応答が投稿されなかったことを意味します(次に進まず、修正して再実行)。終了コード2は不正な引数です。生の gh api .../replies 呼び出しをループで手動実装しないでください:連続投稿はレート制限をトリガーして消失します。これこそがこのスクリプトが存在する正確な障害です。1つの指摘、1つの post-reply.sh 呼び出し、順次行います。
応答のみ、決してResolveしません。 APIを通じて応答を投稿します。決して「会話を解決」をクリックしないでください。緑の「Resolve」ボタンは人間のレビュアーのためのものであり、彼らがこのスキルの作業を検証する方法です:各スレッドを読み、応答が存在することを確認し、要約コメントが存在することを確認し、その時点でのみ解決します。スキルが解決すると、人間は自分とエージェントのどちらがスレッドを閉じたかを区別できず、再確認またはトリアージの再実行を引き起こす混乱が生じます。このスキルの出力全体は、応答と1つの要約コメントだけです。「Resolve」ボタンは彼らのものです。
空白のスレッドを残さないでください。 ステップ1で収集されたすべての指摘に応答します:FIX にはそのSHA、または REFUTE / INTENTIONAL / MINOR にはその理由。応答がない指摘は、ボットからのものであれ人間からのものであれ、トリアージされていない作業と区別がつきません。レビュアーはスキルが実行されたかどうかを判断できないため、スキルを再呼び出しし、ラウンドがループします。沈黙は決して評決ではありません。指摘に同意しない場合でも、理由を述べる必要があり、空のスレッドは決して許されません。
ステップ5.5:カバレッジを表明し、CIを再検証し、修正プッシュが引き起こしたラウンドをキャッチする
要約の前に:
-
常にカバレッジを表明します。 投稿後、PRを再クエリし、すべての指摘(ボットと人間の両方)がトリアージアカウントからの応答を受け取ったことを確認します:
"${CLAUDE_SKILL_DIR}/scripts/verify-coverage.sh" <pr>これは指摘ごとに1行(
answered/MISSING)を出力し、次にanswered N / Mを出力します。終了コード0はすべての指摘に応答がある(ラウンドがカバーされた)ことを意味します。終了コード1は各MISSING指摘をリストするため、それらをpost-reply.shで再投稿し、answered N / Nを報告するまで再実行します。終了コード2は読み取り/引数エラーであり、カバレッジではないため、それを表面化します。これは評決が何であれ実行されます。修正がプッシュされなかったすべてREFUTEのラウンドも含まれます。ドロップされた反論応答は、ドロップされた修正応答と同じくらい見えません。いずれかの指摘がMISSINGである間は、ステップ6に決して進まないでください。 -
CIを再検証します。 チェックがまだ収束していない場合は、
gh pr checks <pr> --watchで待ち、次に"${CLAUDE_SKILL_DIR}/scripts/ci-status.sh" <pr>で分類します:ci: green(終了コード0)は問題なし。ci: failing(終了コード1)はブロックするため、デバッグします。ci: none(終了コード3)はCIが設定されていないことを意味し、これは失敗ではなく、注記して次に進みます。これはimplementスキルが処理するのとまったく同じです。ci: pending(終了コード4)は--watchを再実行し、その後再プローブします。読み取りエラー(終了コード2)は「green」ではないため、表面化します。自分の目でgreenを確認してください。スクリプトの証拠なしにそれを断言しないでください。ステップ4で何も変更されなかった場合(すべての指摘がREFUTEまたはINTENTIONALだったため)、新しいプッシュはありません。そのため、このCI再検証と以下のラウンドキャッチは再トリガーするものはありません。上記のカバレッジ表明は依然として実行されます。 -
新しいラウンドをキャッチします。 修正プッシュ…
[以下、翻訳対象外のため省略]