はじめに
AIがコードを書くようになって、レビューを誰が担当するかという話も変わってきました。
例えば、次のような進め方があります。
- AIが実装して、人間がコードレビューする
- AIが実装・レビューして、最後に人間が確認する
- AIが実装からレビューまで担当し、人間は例外的な判断だけを行う
どれか一つが常に正しい、という話ではありません。製品や組織によって採用する形は違うと思います。
ただ、ここで少し気になったことがあります。
「人間が最後に確認する」とは、何を確認すれば終わりなのでしょうか。
また、人間がコードを読まない運用なら、AIはどの時点でレビューを終えてよいのでしょうか。
誰がレビューしたかではなく、何をもってレビュー完了と判断するのか。
今回は、この問いについて実際に詰まった話です。
前回の『次のボトルネックは「検証」』では、PRを1本作る単価ではなく、子PRを合わせた最終版が検証を通るまでのtoken、cost、latencyを測りたいと書きました。この最終版を、以下では統合headと呼びます。
その後、家計簿アプリでHuman-on-Exceptionを使い、子Issueから統合PRまで進めました。実装は進みましたが、レビューは終わらず、統合headに必要な検証をすべて完了することはできませんでした。
前回予告したA/B/Cの定量比較は、まだ実施できていません。今回は、何が起きたかと、その後に変更したレビュー契約を整理します。
今回の前提
手順の詳細は最初の記事にあります。今回は、その方針で家計簿を開発した結果を扱います。
今回やったこと
対象は、ログイン、共有する家計、手入力の記帳、レシート・カード明細の取り込み、月次の収支・残高を持つ家計簿アプリです。
AIがQuestionsを作成し、人間が製品の意味を回答しました。受諾したQ1〜Q19をもとに、AIがIssueと実装を進めています。
例えばレシートについては、単一の支出ではなく、親レシートと子明細を持つ形を選びました。商品ごとにカテゴリを持てますが、その分、親の合計と子の合計を一致させる条件が必要になります。
つまり、人間が決めた製品の意味が、そのままテストとレビューで確認する対象になります。
子PRのtargeted検証が成功しても、その証拠だけで統合headをcleanとは判断しません。統合後に初めて発生する不整合があるためです。

※別のリポジトリで検証しているため、Questionsの内容は異なります。
レビューにはどんなルールを使ったか
今回のレビューは、単にPRに @codex review と書いて、出てきた回答をそのまま採用するものではありません。
Human-on-Exceptionのレビュー契約では、次のように扱います。
| 項目 | ルール |
|---|---|
| レビュー担当 | 実装AIとは別セッション・別コンテキスト。実装者の自己レビューは代替にならない |
| 確認対象 | Issue AC、受諾済みAnswers、concept・ADR・Policy、適用ルール、diff、tests |
| 見る範囲 | 不具合や回帰だけでなく、認可、データ整合性、トランザクション、UI、API、テスト、仕様文書の更新漏れ。diffに載っていない対応ファイルも必要なら調べる |
| 指摘の扱い |
valid、false positive、decision required に分類。妥当な指摘はAIが修正し、検証をやり直す |
| 完了の証拠 | 対象base/head、確認した範囲、指摘と解消状況を記録。未解決・未判定や未確認範囲はpending |
| テスト | レビューとは別ゲート。レビューが済んでも、必須チェックの未実行は成功にならない |
例えばレシートの親子合計は、一般論として良い実装かどうかだけではなく、その家計簿で合意した振る舞いに合っているかを確認する対象です。
今回の家計簿では、PR上でCodexにレビューを依頼しました。CodexやCursor Bugbotは別々の品質基準を持つのではなく、共通のレビュー契約に従う入口として位置づけています。
ただし、上の表は現在公開されているルールの概略です。家計簿を試したあとにPR #23で追加した「統合headの初回は全面、その後は独立した影響判定に従って証拠を再利用する」という規則も現在の契約には含まれています。これは当時のレビューに最初から適用できていたものとして扱わず、後半で変更内容として説明します。
ここまで定義しても、レビューする観点を列挙しただけで未知の欠陥がなくなるわけではありません。その点は契約でも保証していません。
レビューで実際に指摘されたこと
統合PR #10では、Codexのレビューから具体的な指摘が出ました。
| 指摘 | 内容 |
|---|---|
| 確定レシートの子明細削除 | 親600円、子200円+400円で確定したあと、200円の子明細を削除できると、親と生きた子の合計が一致しなくなる |
| カード明細を収入へ変更 | 支出として確定した明細を汎用編集から収入に変更できる |
| カテゴリ削除の競合 | 参照確認と削除をatomicに扱わないため、並行した記帳作成との競合で不整合や500エラーが起こり得る |
| ロック順の不一致 | 競合への修正後、記帳更新とマスター削除でロック順が逆になり、デッドロックが起こり得る |
これは「AIがAIをレビューして、問題ありませんと返した」という結果ではありませんでした。
ロック順の不一致は、最後にレビューを依頼したhead b322832 への指摘です。
ここで追加の修正・再レビューを打ち切り、レビューは未完了として記録しました。
特にレシートの子明細削除は、先に決めた「親と子で合計が一致する」という製品の条件に関わります。
また、ある競合を直したあとに、別の処理経路について新たな指摘が出たものもあります。
レビューが機能しているから指摘が見つかる。一方で、指摘が出るたびに修正と再検証が必要になります。
「Reject deletion that breaks a confirmed receipt total」

「Keep confirmed statement lines locked to expense」

「Make category deletion atomic」

「Lock categories before creating references」

修正後のレビューをどう扱うか
レビューで指摘が出る。実装AIが修正する。修正するとheadが変わる。改めてレビューすると、別の指摘が出る。
今回の統合PRでは、この繰り返しが起きました。
ここで気になったのは、修正後のheadをどこまで再レビューすべきかという点です。
前のheadで確認した範囲を、修正のたびにすべて見直すとコストがかかります。一方、変更した差分だけを確認すると、既存コードへの影響を見落とす可能性があります。
また、再レビューの範囲を適切に決められたとしても、別の問題が見つかる可能性は残ります。
つまり、今回の問題には二つの側面がありました。
- 再レビューの範囲:以前の証拠をどこまで引き継ぎ、何を確認し直すか
- レビューの終了条件:何をもって、そのheadのレビューが十分だと判断するか
この二つは分けて考える必要がありそうです。
結果として統合headの検証は完了しなかった
家計簿の統合PR #10は、レビューがpendingのままmainへマージしています。
| 項目 | 確認できた状態 |
|---|---|
| 子PRのCIジョブ |
backend-test、frontend-test、lint、docs-consistency、line-endings は成功の記録あり。一方、root-make-test はコンテナunhealthyで失敗 |
| 子PRのtargeted検証 | 各子headで成功の記録あり |
統合PRの修正head bc77e64
|
System 32件・620 assertions、Vitest 9件、make survey 成功とのコメントあり |
統合PRの修正head b322832
|
System 33件・628 assertions、Vitest 9件、make survey 成功とのコメントあり |
統合headのfull make test
|
未実行として記録。部分テストの成功をfull成功には置き換えない |
| 最終対象headのCI全体 | 成功を直接裏付けるActions実行履歴までは今回確認できていない |
| 統合headの独立レビュー | pending |
| mainへのマージ | 人間が実施 |
PR #10の修正・検証記録には、b322832 に対する個別テストとmake surveyの成功、full make testの未実行が併記されています。CIの一部や修正headの個別検証は通っていますが、それだけで最終統合headの必須ゲート完了とは言えません。
full make test を実行できなかった事情には、作業中に別途作成した同名のDockerコンテナとの衝突もありました。これはレビュー終了条件とは別の実行環境上の問題です。
ここは明確に分けておきます。
pendingのままマージしたことと、品質ゲートを通過したことは同じではありません。
b322832 へのコメントには、この版への Codex 依頼を最後にすること、指摘が残っても次は依頼しないこと、検証が揃うまで main へはマージしないこと、を書いています。止めた理由は費用と時間です。合格にしたわけではありません。マージは、そのあとです。未完了だと分かったまま先へ進めています。Human-on-Exception には、この「止める」と「未完了のまま出す」を正式な状態として書く手続きは、まだありません。
今回確認できたのは、開発工程をAI中心に進められたことです。最終的な品質保証まで完了できた、という結果ではありません。
そこで再レビューのルールを変更してみた
この経験から、親のHuman-on-ExceptionにPR #23を追加しました。
内容は、初回の統合headレビューと、それ以降の再レビューを分けるものです。
- 初回の統合headは、子PRのレビュー証拠で代替せず、全体を独立レビューする
- 修正後のheadは、別コンテキストのレビューAIが不変条件と影響範囲を確認する
- 変わらないと独立して判断できた範囲は、以前の証拠を引き継ぐ
- 変更箇所と影響範囲は再レビューする
- 影響を限定できなければ全面レビューに戻す
重要なのは、実装AIが証拠の再利用を確定しないことです。実装AIは差分を示せますが、どこまで確認を省いてよいかはレビュー側が判断します。
また、必須のtestやsurveyは別ゲートのままです。実行していないものをpassedにはしません。
これで、再レビューのたびに無条件で全体を見直す必要は減らせるかもしれません。
ただし、PR #23によるtokenや実行時間の削減効果はまだ測っていません。そして、この変更自体は「何回レビューしたら十分か」という問題の解決ではありません。
それでもレビューの終了条件は残った
PR #23で再レビューの範囲は整理しましたが、その範囲を確認し終えた時点で十分と言えるのかは、まだ分かりません。
今回の変更では、レビューの終了条件までは定義できていません。
Claude Codeチームでも同じ時期に
家計簿の統合PRでレビューの収束に詰まったのと同じ2026年10月15日に、Claude Codeチームから How the Claude Code team does code review という記事が公開されていました。
この記事でも、実装AIとレビューAIのやり取りが長くなる問題が紹介されています。あるPRでは、レビューと修正が50周以上続いたそうです。
対策として、3周後に著者が方針を再考すること、再レビューを差分中心にすること、同じ指摘を繰り返さないことなどが挙げられています。結果として、5周以上必要なPRの割合は8.9%から1.5%に減ったと報告されています。
また、レビューだけでなく、CI、変更のリスクに応じた人間の承認、段階的リリース、ロールバックも組み合わせています。
規模や運用は異なりますが、同じ時期にレビューの収束が課題として扱われていたのは興味深いところでした。
この3周という数字は、3周で問題が残っていても合格にするという意味ではなく、進め方を見直すタイミングです。
レビューの周回数を減らす工夫と、残ったリスクを別の仕組みで扱う設計は、今後の参考になりそうです。
引用:https://claude.dev/blog/solving-code-review-at-anthropic/
ハーネスの先に自動実行を考えると
Human-on-Exceptionは現在、各Promptを人間が起動する形です。自動実行するランタイムはまだありません。
ただ、将来的には、実装、検証、レビュー、修正をランタイムから進め、人間の判断が必要なときだけ止まる形を考えています。
その場合、レビューの終了条件が曖昧だと、次の工程へ進めるかどうかを判断できません。
一定回数で作業を止めることはできますが、それを品質ゲートの通過と同一視することはできません。
レビューの完了判断は、ランタイム化に向けた課題の一つになりそうです。
コストの比較はまだできていない
前回は、子Issueと統合headの検証方式を比較し、clean integrated outcomeまでのtoken、cost、latencyを測りたいと書きました。
今回は統合headがcleanに到達していないため、完了までの総額は測れていません。PR #23による再レビューコストの改善効果も未測定です。
ただし、途中で止まったケースを集計から除くと、実際より安く見える可能性があります。
今後は、消費したコストと、その時点で未実行・pendingだった項目を分けて記録したいと思います。
今のところの結論
今回、Human-on-Exceptionで家計簿を開発し、独立AIレビューを実施しました。
レビューでは実際の問題が見つかり、修正後のheadでも新しい指摘が出ました。最終的には品質ゲートを完了できず、pendingのままmainへマージしています。
その後、再レビューの範囲を整理するルールを追加しましたが、レビューの終了条件そのものはまだ解決していません。
Claude Codeチームの記事でも、レビューと修正の往復をどう収束させるかが扱われていました。
そこで、AIレビューを中心に開発している方に聞いてみたいことがあります。
何をもって、レビューを十分に実施したと判断しているのでしょうか。
人間が最後に確認する場合も、AIだけでレビューする場合も、どこかで完了の判断が必要になります。
レビューの終了条件や、そこで残るリスクをどのように扱っているのか、実際の運用を知りたいです。
※この記事の構成整理・文章の推敲にはChatGPTとCursorを使用しました。実験の事実関係と掲載内容は筆者が確認しています。





