ウェブサイトのデプロイ手順を調べていると、共有ツールの一箇所が疑わしく見えた。データが欠けると防護が飛ばされる、というものだ。正式な入口まで遡ると、呼び出し側がすでにその状況を止めていた。この候補はこうして覆された。
今回は、Codexにまずコードの同じバージョンを固定させ、出典だけを読ませた。最後の要約だけを残して反証を省くと、次のレビューで同じ線をもう一度追うことになりかねない。
レビューには、結論の根拠と、それを覆した理由を残す。まだ答えの出ていない問いには、名前と出典と次の一手が要る。
セカンドオピニオンのあとにも仕事がある
〈codexにClaudeの誤りを指摘させた、ただし言いなりにはならない〉では、セカンドオピニオンの独立性をどう守るかを書いた。問いは中立に保ち、生の報告を残し、審査者は問題の指摘にとどめ、採否は全体の文脈を持つ人が決める。
あの経験には限界もあった。完全に空の審査出力なら機械で止められる。しかし、文字の入った報告が本当に実質的な審査を終えているかどうかは、人が判断するしかない。
仕事が増えると、この問題は引き継ぎにまで広がる。数日後に別のウィンドウで引き継ぐ人は、どの結論が確認済みかを知っているか。コードが改版されたあと、古い証拠はまだ有効か。覆された意見に理由が残っているのか、それとも最終要約から消えただけなのか。
セカンドオピニオンを、次の仕事が引き継いで使えるようにしたい。そのためには、チャットの要約より明確な記録が要る。
Cloudflareは未解決の問いをどう残すか
Cloudflareが公開しているsecurity-audit skillが一つの参照になる。候補の発見と再審査を別々のエージェントに担わせ、検証者には反証を探すことを求め、結果を「確認済み」「要検証」「却下」に分ける。審査の範囲は別の台帳で管理され、一つの結果報告が全体の網羅状況の代わりにならないようになっている。
本稿は、Cloudflareの公式記事Build your own vulnerability harness、公開されているsecurity-audit skill、およびその検証ルールを参照している。証拠、反証、要確認の事実を分けるやり方を、筆者自身の作業記録に取り入れた。
借りたいのは、「要検証」の扱いだ。この状態は、未解決の事実を具体的に指し示す必要がある。脆弱性の深刻度は付けず、手がかりが説得力を持って見えても、確認済みと書いてはならない。
たとえば、実際のデプロイ設定を知らなければ判断できないものもあれば、制限された環境で最小限のテストを走らせる必要があるものもある。コードを読むだけでは見えない事実は、記録の中で見える形にしておく。
同じ分け方は、私の日常の仕事にも使える。手がかり、確認待ちの事実、覆された判断を、分けて記録する。会議で提携の方向性が話題になっても、誰に約束する権限があるのかは元のメッセージに戻って確かめる。文書に数字が一つあれば、バージョンと適用日を確かめる。AIは先に手がかりを整理し、人が要る箇所をはっきり書き出せる。
機械による検査はどこまで証明できるか
Cloudflareの検証ルールは限界を明記している。検証器が成功したとき、証明されるのはフォーマットと台帳の整合性だ。脆弱性という事実の判断の代わりにはならない。
新しいエージェントに再審査させれば、元の作者の思考をなぞる偏りは減らせる。だが異なるエージェントでも盲点を共有しうる。何周も回したからといって、「脆弱性の全体のうち何割を見つけた」とは換算できない。Cloudflareはハーネスの作り方を紹介した記事の中で、実在する脆弱性をすべて含む完全なラベル付きデータセットがない以上、再現率は主張できないと指摘している。
第一ラウンドでは、固定したバージョンと出典のフィンガープリントを保存し、別のエージェントが同じ出典に戻って反証を探した。自作の検査器は、記録同士の関連、行番号の範囲、出典の同一性を照合した。このラウンドでは対象のプログラムは実行していない。
出典を再確認できることと、プログラムの挙動を観測したことは、別の層の証拠だ。報告書は、読者がこの違いを見分けられるようにしておく必要がある。
デプロイの手がかりから、修正の検証まで
制御されたローカル再現に進んだのは、第二ラウンドからだ。実際のデプロイの入口、防護、基本機能の確認(smoke)スクリプトはそのまま残し、Gitには本物のバージョン関係を使わせ、サービス、ウェブの応答、ビルドをオフラインの代役に置き換えた。OSが強制するサンドボックスは、ネットワークの遮断と範囲外への書き込みの拒否を確かめるテストを通ってから、各ケースを実行した。
このデプロイ手順は、サイトのページ(Pages)とバックエンドのサービス(Worker)の二つを一度に更新する。旧来の結合デプロイの入口は、混在した台帳から最後の成功した出典を一件だけ取っていた。台帳の後ろにPagesの古い出典の記録が並んでいれば、Workerがすでに使っている新しい出典を見落としうる。
隔離したオフライン環境で、サービスとビルドを代役にして再現したところ、結合デプロイが模擬Workerを古い出典に戻しながら、入口全体は成功と記録する状況が現れた。同じ古い出典をWorker単独でデプロイすると、止められた。レビューの途中でコードは更新されていたが、更新後の出典を固定して再実行しても、同じ結果だった。
ここでいう「台帳の後ろ」は、ファイル内の並び位置を指す。実際のデプロイの時間順の代わりにはならない。
この結果が支えるのは、バージョン比較のロジックを直すことだ。「本番で事故が起きた」ことは支えない。今回検証したのは、このバージョン巻き戻りの経路だけで、脆弱性の判定には至っておらず、深刻度も付けていない。偽のサービスは本物のWorkerを実行していない。実際の機能に影響があったのか、過去の台帳に本当にこの並びが現れたのかは、別の二つの問いとして残る。
第三ラウンドでは、私が同意したうえで、Codexが隔離したコピーでデプロイの入口を修正した。結合デプロイは、PagesとWorkerそれぞれの前回成功した出典を別々に確認するようになり、共有の防護チェックには手を入れていない。新しいテストは、まず古いコードで問題を捉え、次に修正後はそれを止めることを確かめた。完全な入口のケース六件のうち、巻き戻りの四件はサービスのデプロイ呼び出しの前に止められ、通常の更新二件はチェックを終えて成功を記録した。
独立した再審査エージェントは、この範囲を限定した修正を受け入れた。同時に、エラーメッセージがデプロイ対象に応じて切り替わっていないことも指摘し、修正と対照テストを加えた。今回届けたのは、レビューできるパッチとローカルでの検証だ。2026-10-03のこの隔離検証が終わった時点では、パッチは隔離したコピーに置かれたままで、統合も本番デプロイもまだ行っていなかった。本稿は当時の検証の境界を残すもので、その後のデプロイ状況は追跡しない。「レビュー通過」「修正の検証通過」「本番を更新済み」は、分けて記録する必要がある。
証拠と実行の権限を分ける
複数のプロジェクトでAIを使う私の仕事の仕方に合わせて、次の引き継ぎで遡れるようにしておきたい内容を、六つの欄に整理した。
| 欄 | 答える問い |
|---|---|
| 主張 | 今回、何を判断しているのか。 |
| 出典とバージョン | どのコード、文書、元のメッセージに基づくか。 |
| 証拠の状態と理由 | 確認済みか、未確認か、覆されたか。根拠または反証は何か。 |
| 未解決の事実 | 今、どの具体的な答えが欠けているか。 |
| 責任者と次の一手 | 誰が証拠を補えるか、どうやって補うか。 |
| 実行の権限 | 誰がどの操作に同意したか。その権限の元の記録はどこにあるか。 |
今回のデプロイの手がかりを当てはめると、おおよそ次のようになる。これは2026-10-03に隔離検証が終わった時点の記録であり、現在の進捗ではない。
| 欄 | 今回のデプロイの事例(2026-10-03当時の記録) |
|---|---|
| 主張 | 結合デプロイが、Workerがすでに使っている新しい出典を見落とし、バックエンドを古いバージョンに戻す可能性がある。 |
| 出典とバージョン | バージョンを固定したデプロイの入口、対応するオフラインのテスト記録、別に保管した隔離パッチ。 |
| 証拠の状態と理由 | オフラインの経路は再現済み。結合デプロイは巻き戻りつつ成功と記録し、同条件の単独デプロイは止められた。修正後は、入口のケース六件が想定どおりの結果になった。 |
| 未解決の事実 | 本番で同じ台帳の並びと出典の条件が過去にあったか、本物のWorkerの機能に影響があったかは、どちらも未検証。 |
| 責任者と次の一手 | 当時の次の一手:私が今後の範囲と担当者を決め、メインブランチのバージョンを確かめたうえで、パッチの統合と本番デプロイを検討する。 |
| 実行の権限 | 当時は隔離環境での修正とローカルでの検証に同意しており、元の会話に当たって確認できる。パッチの統合と本番デプロイは当時、別に決めることとされていた。 |
最後の欄は特に、独立させておく必要がある。一つの事実を確かめたからといって、修正・送信・公開の権限まで同時に手に入るわけではない。複数のモデルが一致しても、協力相手に対する約束を代わりに引き受けることにはならない。
デプロイのレビューでも同じだ。問題を見つけたあと、修正方針、コードの変更、本番デプロイには、それぞれ別の検収と責任がある。すべてを「完了」にまとめてしまうと、次に引き継ぐ人はもう一度推測し直すことになる。
この記録は、会議やメールの整理にもつなげられる。重要な期限には元のメッセージを添え、提携の約束には確認者を残し、一部の読み取りに失敗したなら、その通りに記す。データの取得失敗と、条件に合うメッセージがなかったことは、「該当事項なし」という同じ一文で済ませてはならない。
維持できる範囲から始める
試行の対象にはウェブサイトのデプロイ手順を選び、日常の要約を一つ残らず何ラウンドものレビューに回すことはしなかった。第一ラウンドでは、ローカルのサブエージェントの呼び出しの計画上限を三回とした。制限しているのは呼び出しの回数であり、トークンや請求額ではない。出典の読み込みと、その後のローカル実行で、それぞれ範囲を記録しておけば、エージェントを一つ増やして何が解決したのかを、あとから判断できる。
覆された候補は残す必要がある。次の審査が先に反証を読み、再確認する価値があるかどうかを判断できるからだ。未検証の手がかりも残し、作業にどの一歩が欠けているかを示す。これらの記録はテストを組む根拠にはなる。人の時間を本当に節約するかどうかは、後の比較を待つ必要がある。
次のラウンドでは、この記録によって再審査が早くなったか、引き継ぎで重複した探し直しが減ったかを見る。最初の試行には比較できる基準がなく、節約の割合を先に書くことはできない。
残しておきたい判断の置き場所は、具体的だ。次に「完了」という文字を見たとき、証拠を辿って遡れること。そして、まだ終わっていない一歩がどれかも分かること。
一次情報
- Build your own vulnerability harness(Dan Jones、Alexandra Godoi、Grant Bourzikas、2026-06-18):skillからリポジトリ横断の社内harnessへ進めた際の設計と限界を説明している。
- cloudflare/security-audit-skill:6段階の単一リポジトリ起点、独立した反証、confirmed / needs_validation / rejectedの区分、coverage ledgerの裏づけとなる。
- VALIDATION-AND-REPORTING.md:形式や記録が整合していても、脆弱性の事実が成立したことにはならないという規則の裏づけとなる。
本稿の配備事例は、筆者が2026-10-03に行った固定ソースの確認、オフライン再現、隔離環境での修正の記録に基づく。裏づけられるのは本文で限定したローカルの結果だけである。


💬 コメント
読み込み中...