pdlc-skills は AI に書かせたコードの品質をどう守るのか
目次
前回はループを自律的に回す方法を書きました。速く回るほど、古い問題が際立ってきます。AI が出してくるものの品質は、誰が保証するのか。 AI は疲れません。午後のあいだに書き上げるコードの量は、人が数日かけて読む分に相当します。今回は、これを pdlc の中でどう受け止めているかを書きます。一つの関門ではなく、七つの環をつないだ一本の鎖で受け止めます。
なぜ AI がコードを書くと、品質がいっそう重要になるのか
以前のコードの品質は、二つのことに支えられていました。一つは、書いた本人が「これで合っている」という感覚を持っていたこと。もう一つは、量が限られていて、レビューが追いついていたことです。AI が入ると、この二つの前提が同時になくなります。
AI に「自分で分かっている」感覚はありません。 自分の仕事を採点させると、体系的に甘くつけます。嘘をついているのではなく、本当にうまくやったと思っているのです。だから pdlc では、モデルの自己チェック結果は独立した欄に記録するだけで、「止めるべきかどうか」の判断には一切使いません。
量も変わりました。 前回の無人実行では、午後の一回で三期分のイテレーションが終わりました。バックエンドの API グループが四つ、フロントエンドのページが三つ、通知ルール一式。以前なら数日かかった仕事です。アウトプットは速くなりましたが、「正しいかどうかの判断」は速くなっていません。同じ目、同じ時間のままです。
この差そのものがリスクです。速く走るほど、間違いは気づかれる前に遠くまで進みます。だから品質保証は速度の足を引っ張る負担ではなく、速度をまともに使えるようにするブレーキとハンドルです。ただし、人がコードを一行ずつ読むわけにはいきません。それでは浮いた時間をそのまま返すことになります。
先に結論:七つの環を一本の鎖に
私は品質保証を七つの環に分けています。
要件 → 設計 → TDD → 実装 → ユニットテスト → E2E → 別の AI がレビュー
最初の二つは AI が書き、AI がレビューし、最後に人が一度確認します。中の四つは機械が強制的にチェックし、交渉の余地はありません。TDD で赤を立て、実装は終了コードで判定し、ユニットテストは十分な厚みを持たせ、E2E はコアの流れだけを守ります。最後の環は、別の AI にレビューさせます。七つは並列ではなく直列です。どれか一つが崩れると、その前の環が保証していたものの価値も下がります。要件を間違えれば、後ろでどれだけ厳しくテストしても、間違ったものをより頑丈に作るだけです。

順番に一つずつ説明します。
環 1・環 2:要件と設計。AI が書き、AI がレビューし、人が確認する
要件と設計を品質管理に数えるのは意外に思えるかもしれません。しかしこの二つは最上流にあって、後ろのすべてのテストが何を検証しているのかを決めています。
この二つの文書は AI が書きます。PRD の段階には八項目の自己チェックがあります。背景と目標は明確か、ユーザーストーリーは足りているか、受け入れ基準は測定可能か、機能一覧に優先度が付いているか、など。チェックを通らなければ次の段階に進めません。最後の項目はいちばん地味に見えますが、見せかけのグリーンの話まで来ると、これが最も効いてくることが分かります。
書き終えたら、まず別の AI がレビューし、最後に人が一度確認します。この順番は逆にできません。要件と設計を人がゼロから書いて一字ずつ確認するなら、AI のアウトプットが速くなるほど人がボトルネックになり、冒頭の差に戻ってしまいます。人の役割は確認であって、実行ではありません。
ただし、その確認は省けません。作るべきかどうか、境界をどこに引くか、いくつに分けるか。これらは判断の問題で、終了コードを返してくれるコマンドは存在しません。だから第 5 回の自律ループはこの二つの環には触れず、TDD → 実装 → レビュー だけを引き受けます。機械が自動で見つけられる誤りは機械に、見つけられないものは人に残す。この線引きです。
環 3:TDD。先に失敗するテストを書く
コードを書く前に、必ず失敗するテストをひとまとまり書きます。「テストを先に書くことを推奨します」という柔らかい要求ではなく、硬い要求です。これには具体的な利点があります。この時点から「終わったかどうか」に、モデルと無関係な答えができます。テストを一回走らせ、終了コードが 0 なら終わり、0 でなければ終わっていません。
この門が成り立つ前提は、前回の test-commands.yml が整備されていることです。判定は実際にコマンドを走らせた結果だけで決まります。モデルが「うまくできたと思う」と言っても、ここでは数に入りません。
環 4:実装。終了コードだけを見る
ここでようやくコードを書きます。この段階は管理できないと思われがちです。AI が書くのだから、一行ずつ見張るわけにはいかない、と。実際には最も厳しく管理されている段階です。入る前と出た後に、それぞれ検査があるからです。
入口で見るのは一つだけです。関連するテストが存在し、しかも今この時点で赤であること。 これは pdlc の鉄則に書かれています。テストが見つからなければ実装コマンドは実行を拒否し、TDD に戻すよう促します。「先に書いて、テストは後で足す」というやり方は受け付けません。
コードを書くときの規則は一つです。テストを緑にする最小限のコードを書き、その後でテストに守られながらリファクタリングする。この規則が狙っているのは、AI がいちばん楽をしようとする経路です。テストが通らないとき、テストを直すほうがコードを直すより常に簡単です。だから実装段階ではテストファイルを触ることを許しません。pdlc の自動受け入れテストには、そのためのアサーションが一つ入っています。テストファイルが変更されていれば、それだけで失敗です。
出口では三つを検査します。ユニットテスト、カバレッジ、lint。三つとも実際にコマンドを走らせて終了コードを見ます。lint はゼロ警告が条件で、「前回より減っていればよい」ではありません。結果は状態ファイルに書き込まれ、pdlc はこの三つのフィールドにはコマンドの終了コードしか入れてはならない、モデル自身のチェック結果で代用してはならないと明記しています。一つでも通らなければ、この段階は完了扱いにならず、流れは先に進みません。

この門を出ても終わりではありません。コードは次にレビューへ送られますが、レビューにも入口条件があります。テストが全部緑でなければ、レビューは受理されません。実装とレビューのあいだに挟まっているのが、次の二つの環です。
環 5:ユニットテストは厚くする。ただし部品しか証明しない
前の二つの門ができたら、次はユニットテストを厚くします。私の比較的大きなプロジェクトでは、ユニットテストが四千件以上、カバレッジは 90% を超えています。ただ、この規模まで積んだからこそ、限界もはっきり見えています。ユニットテストが証明するのは、個々の部品を単体で取り出せば正しいということです。それだけです。
保険と勘違いされやすい数字があります。カバレッジです。これは「この行が実行された」を測るものであって、「このロジックは正しい」を測るものではありません。次のテストは、ある関数のカバレッジを満点にできます。
it('注文合計を計算する', () => {
expect(calcTotal(order)).toBeDefined();
});
関数は動き、分岐も通り、レポート上のこの行は緑です。しかし計算が合っているかどうかについて、このテストは一言も言っていません。誰かがずるをしているわけではなく、カバレッジは生まれつき実行しか見えず、アサーションが見えないのです。これを受け入れ基準に使うほど、「数字を良く見せる」方向へ流れていきます。
だから 90% という数字は書きますが、それが証明するのは「テストが広く敷かれている」ことで、「品質が高い」ことではありません。後者に答えるには、次の環が要ります。
環 6:コアの流れは E2E に任せる
同じプロジェクトで、コア業務フローの E2E は百件あまりです。四千対百。この比率そのものが、二つの分担を語っています。
本番で起きる障害は、ある関数の計算が間違っていた、というものは少数です。多くは、それぞれ正しい部品をつないだら合わなかった、という形です。状態が渡っていない、順序が逆、境界の解釈が両側で違う。こうした問題はユニットテストには構造的に見えません。依存をすべてモックしてしまうからで、問題は依存と依存のあいだにあります。
だからコアの流れには E2E を置きます。私は Playwright で Chrome を動かし、本物のページを走らせます。実際にクリックし、実際に API の応答を待ち、実際に描画結果を確認する。遅いし、不安定にもなりやすい。それでも「この業務フローは今日も通るのか」に答えられる手段は、これしかありません。

/pdlc-quality の E2E の照合は単純です。すべてのコアフローについて、対応するテストがマッピングファイルに存在し、かつ今回の実行結果で通過していることを確認する。一件でも欠ければ赤です。「この流れは別のテストでカバーされているはず」で穴を埋めることは認めません。それこそが、取り除きたい主観的判断です。
環 7:段階ごとに、別の AI にレビューさせる
最後の環はレビューです。しかも一回ではありません。要件レビュー、設計レビュー、コードレビュー、それぞれが一つの関門です。
要は「別の」という点です。冒頭で書いたとおり、AI は自分を甘く採点します。設計を考え出したばかりの AI に、続けてその設計を評価させても例外ではありません。だからこの数回のレビューは、それぞれ別に起動します。セッションを変える、subagent で別の AI を立ち上げる、あるいはモデルごと変える。コンテキストがきれいなレビュアーだけが、作者に見えないものを見つけられます。作者の頭の中にある「ここはこう考えたから」という補足は、新しいセッションには存在しません。設計文書に本当に欠けている部分は、そこで初めて表に出ます。

三つのうち、コードレビューが最も細かく見ます。設計文書と照らし合わせて一項目ずつ確認します。API のパラメータと戻り値の形は一致しているか、エラー処理は統一されているか、文字列連結の SQL はないか、認可チェックの抜けはないか、一覧 API にページングはあるか、N+1 クエリはないか。その場で直せるものは直します。直せないもの、たとえばアーキテクチャ上のトレードオフや業務ロジックの解釈が分かれる点は、レポートに書き、人が判断する項目として印を付けます。
レビューするのはあくまで AI であって、人ではありません。人の時間を「全体を通読して問題を探す」ことに使うべきではなく、それは AI がこなせる仕事です。人が扱うのは、AI が報告してきて、AI 自身も判断に迷っている数点だけです。レビューが人の判断を要する事項に当たれば、pdlc は停止して blocked を書き、人に戻します。第 5 回の「設定フィールドが三つ、どのバックエンドからも参照されていない」件は、まさにこうして止まりました。
七つそろっても、見せかけのグリーンには備える
鎖がそろい、レポートが全部緑。これで信じてよいでしょうか。まだ一段足りません。危険なのは赤ではありません。赤は少なくとも正直です。危険なのは見せかけのグリーンです。表面は問題なさそうで、下ではすでに壊れている緑です。
これには二種類あり、どちらも「もっと頑張る」では防げません。
一つ目は、一覧の陳腐化です。 E2E のカバレッジ行列は「コアフロー一覧」と照合します。その一覧は、人が覚えていて更新するものです。コアフローを一つ追加したのに、誰も一覧に足さなければ、行列は緑のままです。「分かっていない」を「カバーしている」に見せてしまう。これはチェックがないより悪い。緑のレポート付きで、安心して間違い続けられるからです。対策は、実行のたびに PRD と強制的に突き合わせることです。PRD にあって一覧にない項目は、即座に赤にします。
二つ目は、「判定不能」を「問題なし」と読んでしまうことです。 PRD 自己チェックの中でいちばん地味だった項目を覚えているでしょうか。機能一覧に優先度を付けること。突き合わせはこの P0/P1 の印を手がかりにします。ある PRD にそもそも印がなければ、抽出結果は空集合です。それを一覧と比べれば差分はゼロで、レポートは「突き合わせ通過」と書きます。実際には、その PRD 全体が一度もチェックの範囲に入っていないのに。古い PRD ほどこの問題を起こしやすく、そして古い PRD こそ、すでに本番で動いている主要な流れを担っています。

そこで規則を変えました。優先度がないために突き合わせに参加しなかった PRD は、必ず別枠で警告として列挙し、突き合わせの項目は「通過」にできません。書けるのは「⚠️ 差分なし。ただし判定不能の PRD が N 件」だけです。第 3 回の「走らせるコマンドがなければ欄を空けておき、通過とは書かない」と同じ原則です。測れないなら「未測定」と正直に書き、空白を緑に見せかけない。
この仕組みで防げないもの
七つの環と見せかけのグリーン対策をそろえても、届かないところは残ります。
要件そのものが間違っていれば、やはり全部緑です。 この鎖が保証するのは「作ろうとしたものが、堅く作られた」ことであって、「それを作るべきだった」ことではありません。
本当に全部そろえたかどうかも保証しません。 私自身に反例があります。もう少し小さな別のプロジェクトでは、ユニットテストも E2E も動いているのに、カバレッジのツールがそもそも設定されていませんでした。環が一つ欠けていれば、「品質は保証されている」とは言えません。pdlc を入れれば自動的に基準を満たすわけではなく、やるべきことを目の前に並べてくれるだけです。
最後に承認するのは、やはり人です。 /pdlc-quality がするのは、実測データを検証可能なレポートにまとめることまでです。基準を満たしたかどうかの結論は出さず、リリースするかどうかは人が決めます。コードを書く側が同時に結論を出す側でもあるなら、機械に判定させるために組んだ仕組みは意味を失います。
この仕組みで得られたもの
冒頭の差に戻ります。AI でアウトプットは速くなり、判断は追いついていない。この七つの環がしていることは、突き詰めれば「判断」のほうもアウトプットに追いつく速さにすることです。
私自身について言えば、得られたのは「バグがない」ではありません。それは誰にも保証できません。得られたのは、AI に自分で走らせて構わないと思えることです。前回の無人実行では、午後の一回で三期分が終わり、私が介入したのは三回だけでした。運がよかったのではなく、間違ったものはどこかの環で止まると分かっているからです。本番のユーザーに見つけてもらうまで待つ必要はありません。
AI が犯すはずの間違いは、やはり犯します。この鎖がしているのは、間違いをできるだけ早く表に出すことです。まだ一つのバグで、直すのが安いうちに。事故になってからではなく。
次回
次回は方向を変えて、見えることの話をします。機能同士の依存をどう記録するか、一か所を変えたらどこに波及するか、プロジェクトが今どこまで進んでいるかを一目で見られるか、そして振り返りをどう残すか。
試してみる:
curl -fsSL https://raw.githubusercontent.com/kanfu-panda/pdlc-skills/main/install.sh | bash -s -- --global
リポジトリはこちら:https://github.com/kanfu-panda/pdlc-skills
役に立ったら star をいただけると励みになります ⭐
この七つの環は、私が自分のプロジェクトで落ち着いた構成で、すべてのプロジェクトに合うとは限りません。もっと簡素な組み合わせで回している方や、どれか一つは外せると思う方がいれば、コメント欄で聞かせてください。
コメント