メインコンテンツまでスキップ

検証ループ — 「直した」を証明する

修正コードを書いたら終わり、ではありません。/debug のワークフローでいちばん大事なのは、ここからの Verify(検証) です。

「直りました」では完了にしない

ハーネスには「成功を主張するのではなく、証拠を示す」という原則があります。/debug ではこれが反復ループの形で組み込まれています。

SKILL.md 反復プロトコル(抜粋)
フェーズ 1: Investigate → Fix → Verify(深化)
1. Investigate: 原因調査 → 仮説立案 → 修正案出力
2. Fix: 修正を適用(Write/Edit)
3. Verify: 確認方法を実行(テスト、動作確認コマンド)
- 成功 → フェーズ 2 へ
- 失敗 → 仮説を修正して再試行(最大 3 反復)
4. Regression: 関連テストを実行し、回帰がないか確認

今回の fetchUser なら、Verify はこうなります。

証跡を出す
$ yarn test user-service
✓ fetchUser は対象が無いとき null を返す (regression)
✓ fetchUser は対象があるとき User を返す
Test Files 1 passed (1)

このテスト出力こそが「直った」の証拠です。「修正しました」という言葉ではなく、実際にテストを走らせた結果で示します。これは、ハーネスが繰り返し要求する完了条件です。

なぜ証跡にこだわるのか

モデルは「たぶん直った」を「直った」と書いてしまえます。テスト出力という機械的な事実を完了条件にすると、その確率的な楽観をブロックできます。検証できないものを完了とは認めません。これは /debug に限らず、ハーネス全体に通底する姿勢です。

最大 3 回まで反復する

1 回目の修正で直らなければ、仮説を立て直して再試行します。各反復の冒頭には、いまどの段階かを示すヘッダが出ます。

反復時の出力フォーマット
### Debug Pass 2/3
- 状態: verifying
- 現在の仮説: 戻り値の型は直したが、呼び出し側の null チェック漏れが残る
- 直前の検証結果: 失敗(別のテストが落ちた)

反復には品質ゲート上限があります。

  • 品質ゲート: テストがパス、かつ回帰テストもパス
  • 上限: 最大 3 反復。それでも解決しなければ、残課題と次の一手を添えて報告し、無理に「直った」とは言わない

この「上限で正直に止まる」設計が、泥沼化を防ぎます。反復のさじ加減は references/iteration-protocol.md(🔧 自作)という共通プロトコルが定めていて、/debug 以外の skill も同じ枠組みを使い回しています。

直ったら、横展開する(Generalize)

検証が通った後、/debug はもう一歩進みます。同じパターンのバグが他にもないか Grep で探す、Generalize フェーズです。

SKILL.md Generalize(抜粋)
修正が成功した後:
- 同じパターンのバグが他の箇所にないか Grep で確認
- 発見した場合はサマリーに追記(Critical なら修正、それ以外は報告のみ)
- 再発防止策(テスト追加、lint ルール等)を具体的に提案

今回なら「array[0] を素で返している箇所」を横断検索します。fetchUser と同じ書き方が fetchOrder にもあれば、同種のバグが潜んでいる可能性が高い。1 つのバグを直すついでに、仲間を洗い出すわけです。この Generalize の結果が、Ratchet の「学びを仕組みに変える」入口になります。

この章のまとめ

要点は次のとおりです。

  • 完了条件は「直りました」の言葉ではなく、テスト出力という証跡
  • Investigate→Fix→Verify を最大 3 回反復し、品質ゲート(テスト+回帰パス)で収束させる
  • 上限まで試したら正直に止まり、成功を強弁しない
  • 直った後は Generalize で同パターンのバグを横断検索する

次は 応答終了時の Stop hook で、答えを返す瞬間に走る最後の検査群を見ます。