Joifup Blog

Claude Codeのレビューが全部通ったのに残った書き漏れ、原因は差分だった

2026-10-17

この記事は zenn.dev(新しいタブで開きます) にも掲載しています。

Claude Code のサブエージェントにコードレビューをさせていて、レビューが通ったのに「書くべき場所に書いていない」が残っていたことがありました。しかも1回ではなく、実装のステップごとのレビューも、最後のブランチ全体のレビューも、全部通っていました。

なぜ全部通ったのかと、自分のハーネスでどう塞いだかを書きます。持ち帰れるのは、この種類の不備はレビューを何重にしても見えないという構造と、塞ぎ方が1つです。

何が起きたか

自分の事業で動かしているツールに、あるタスクで変更を入れました。その変更で、後続のタスクが定期的に差し替える設定値が1種類から2種類に増えました。後続のタスクを担当するエージェントは、それを知らないと作業の前提を間違えます。

そこで、実装したエージェントは引き継ぎを書きました。作業の記録(ハーネスがタスクごとに残すログ)に、そのタスクの設計書に、PR の本文に。3か所です。設計書には「後続タスクに申し送る」と何か所も出てきますし、PR の本文にも「申し送り先」の行があります。

でも、後続のタスクを担当するエージェントが最初に読むファイルには、書いていませんでした。

レビューはどれも通りました。PR はマージされ、後続のタスクに着手する段で、人(自分)が読んで気づきました。

前提:自分のハーネスの形

ここで初めて構成の話をします。

Claude Code で、superpowers の進め方(brainstorming → writing-plans → subagent-driven-development)を背骨にして、everything-claude-code(ECC) のレビュアーを足して使っています。この組み合わせをどう分担させているかは、ブログに書いた記事があります。

  • 「タスク」は1つずつ Markdown のファイルで持っています。1つのタスクが1本のブランチと1つの PR になり、セッションも変わります。タスクの担当エージェントは、そのタスクの md を最初に読んで作業に入ります。だから後続タスクへの引き継ぎは、後続タスクの md に書くのが正しい場所です
  • 1つのタスクの中は、計画の段で小さな「ステップ」に分けます。実装は、ステップごとに別のサブエージェントがやります。実装したエージェントのコンテキストは、次のステップにも次のタスクにも持ち越されません
  • レビューは、ブランチ全体を見る最終レビューを必ず回します。このときはステップごとのレビューも回していて、それも通りました
  • レビュアーに渡すのは、superpowers の review-package が作るファイルです。中身はコミットの一覧、git diff --stat、git diff -U10 の3つです

要するに、レビュアーが見ているのは差分です。

なぜ全部通ったか

差分には、変わったファイルしか出てきません。

証跡のログ、設計書、PR の本文。この3つは変わったので、差分に入っています。そこには引き継ぎの文があります。レビュアーはそれを読んで、「引き継ぎが書いてある、問題なし」と判断します。嘘は言っていません。差分の中では、引き継ぎはたしかに書いてあります。

後続タスクの md は変わっていません。だから差分に出てきません。レビュアーには、そのファイルを開く理由も指示もありません。そこに書くべきだったことがある、と知る材料が渡っていないからです。

ここが肝で、「ここに書くべきなのに書いていない」は、差分の中に存在しない情報です。レビュアーの能力の問題ではなくて、渡しているものの問題です。レビューを2回にしても3回にしても、別のモデルに変えても、差分を渡している限り同じところで同じように通ります。実際に、ステップごとのレビューと最終レビューの両方が通りました。

差分レビューが検査しているのは「変えたもの」です。「変えるべきだったもの」は、差分には入っていません。

どう塞いだか

渡すものを変えました。CLAUDE.md のレビューの節に、こう足しています。

例外: 「タスクNに申し送った」「ファイルXに反映した」という主張が差分に含まれるときは、その送り先のファイルもパッケージに入れる。 変更されていないファイルは diff に現れないので、「変わるべきだったのに変わっていない」は原理的に検査できない。

差分の中に「◯に書いた」「◯に反映した」という主張があるときは、◯のファイルを、変わっていなくてもレビューの材料に入れます。レビュアーはそのファイルを開いて、「書いてあるはずの文が無い」を見られるようになります。

ポイントは、差分の中の主張を手がかりにしていることです。変わっていないファイルは無数にあるので、全部渡すわけにはいきません。でも「どこかに反映した」と差分が言っているなら、その「どこか」だけは確かめる価値があります。主張があるのに送り先が変わっていなければ、それがそのまま不備です。

材料の側で渡す理由は、こうです。この規則は CLAUDE.md に置いていて、オーケストレーターが review-package を作る段で判断します。レビュアーに「変わっていないファイルも疑って」と頼むのではなく、材料の側で渡します。レビュアーに自由に探させると、今度はコードベースを漁り始めて、差分に集中しなくなるからです。

同じ形の穴が、もう1つあった

同じ出来事で、もう1つ見つかりました。

PR の中に、人に渡す予定の手順書の節が含まれていました。まだ初稿の段階のものです。差分レビューは、その節を「文書として頭から読む」ことをしません。変わった行とその前後を見るだけです。結果として、作業中の覚え書きがそのまま確定の文の中に残っていて、用語の未定義と一緒に見落とされました。

これも同じ構造です。「文書として読むとおかしい」は、差分の中には存在しない情報です。塞ぎ方も同じ発想で、外に出す文書を含む差分では、その節を頭から通して読むレビューを1回別に入れています。想定する読み手(初めて読む、設定を知らない、開発の経緯を知らない人)を明示して渡します。

終わりに

書いてみると、当たり前の話です。差分に無いものは差分レビューには見えないに決まっています。それでも、レビューが通ったときには気づきませんでした。通ったのは、渡したものの範囲で問題が無かった、という意味でしかなくて、渡していないものは誰も見ていません。

おすすめ記事