AIが大量に変更を入れる環境で『誰が何を承認したか』を後から追えるようにする
はじめに:承認が、ハンコになっていく
AIエージェントがコードを書き、手順を流し、設定を変える。人間の役割は「アーキテクチャの意思決定と最終承認」に寄っていく。この前提はもう珍しくありません。
問題は、その「承認」が意味を失っていくことです。
エージェントが1日に数十、数百の変更を出すようになると、変更を全部読んでから承認する運用は物量で破綻します。残るのは、中身を見ないまま押される承認のハンコです。git blame をたどると人間の名前が出てきますが、その人はそのコードを書いていないし、よく読んでもいません。署名はあるのに、署名が何も保証していない状態になります。
平常時はこれでも回ります。困るのはインシデントが起きたあとです。
「なぜこの変更が入ったのか」「誰がこれを通したのか」「この判断に責任を持ったのは誰か」。事後にこれを再構成しようとして、初めて証跡が無いことに気づきます。コードを書いた主体(AI)は責任を持てず、責任を負うべき主体(人間)は実態として見ていなかった。このエージェンシーと責任のズレは、AIの稼働量が増えるほど広がります。
本記事のテーマは、そのズレの埋め方です。新しい監査ツールの紹介ではなく、「誰が何を承認したか」を後から追えるように、承認の来歴(provenance)を機械可読に残す運用設計の話をします。後半では、コミットの trailer・ラベルのスキーマ・集計スクリプトまで具体例を載せます。
前提として、AGIがいつ来るかは論じません。予測できない到来を待つのではなく、来た時に間に合うよう今動かせる運用だけ動かす、という立場で書きます。AIの稼働量がすでに人間のレビュー帯域を超え始めているなら、到来とは関係なく今日から効く話です。
物量が監査を壊す、3つの壊れ方
「監査できなくなる」の壊れ方は1種類ではありません。分けて捉えると打ち手も分かれます。
壊れ方1:承認の形骸化
レビュー対象が人間の処理能力を超えると、承認は「読んだ」を意味しなくなります。読まずに承認ボタンを押すことを個人の怠慢として責めても解決しません。物量に対して帯域が足りていない、という構造の問題だからです。
形骸化した承認は、外形的には正常な承認と区別がつきません。承認ログには同じく「承認済み」と並びます。だから「承認されているか」を見ても安全性は分からなくなります。
壊れ方2:来歴の欠落
AIが変更を出すとき、背後には文脈があります。誰がどんな指示を出したのか、エージェントはどんな情報を参照したのか、どの判断をエージェントが自分で下したのか。
人間が手で書いていた時代は、この文脈の多くが人間の頭の中にあり、必要なら本人に聞けました。AIが大量に動く環境では、その文脈はどこにも残らずに消えます。コミットメッセージと diff だけが残り、経緯が欠落する。事後に経緯を再構成しようとしても、参照すべき記録が存在しません。
壊れ方3:エージェンシーと責任の分離
AIは行動(agency)を持ちますが、責任(accountability)を負えません。人間は責任を負えますが、稼働量の差で実態の監督ができなくなります。
この分離を放置すると、「システムがそう判断しました」が免責の言い訳になります。誰も嘘をついていないのに、誰も責任を引き取れない。技術的なログをいくら積み上げても、「最終的に誰がこの不可逆な変更を引き受けたのか」が記録されていなければ、組織として責任の所在を示せません。
この3つは連鎖します。来歴が欠落する(2)から承認が形骸化し(1)、形骸化した承認のもとで責任が宙に浮く(3)。打ち手はこの連鎖を逆からほどく形になります。
設計方針:監査の単位を「全行レビュー」から「来歴+判断の証跡」へ
ここで方針を1つ決めます。「全部読んでから承認する」を諦めます。
品質を落とす話ではありません。物量が帯域を超えた世界で「全部読む」に固執すると、形骸化した承認が量産され、かえって安全性が下がります。固執をやめて、読まなくても後から追える構造に投資を振り替えます。
監査の対象を「コードの中身」から次の2つに移します。
- 来歴(provenance):この変更がどういう経緯で生まれたか
- 判断の証跡(decision record):人間が何を引き受けて承認したか
来歴(provenance)という語と問題圏には、SLSA や in-toto のように成果物の供給経路を検証する先行標準があります。本記事はそれらを置き換えるものではなく、ビルド成果物の検証とは別に、組織の「承認判断」に寄せた最小運用を論じます。両者は補完関係にあります。
中身を100%理解していなくても、来歴と判断の証跡が残っていれば、「なぜ入ったか」「誰が引き受けたか」は事後に再構成できます。監査が答えるべき問いは「このコードは正しいか」だけではありません。「誰がどういう判断のもとで、これを世に出すと決めたのか」のほうです。後者は中身を全部読まなくても記録できます。
以下、この方針を半年で仕込む3つの設計パターンを書きます。特定のツールに依存しない形で書くので、自分の環境に読み替えてください。
半年で仕込む3つの設計パターン
パターン①:承認を分解して、機械可読にする
「承認」は単一の行為ではありません。少なくとも次の3つが混ざっています。
- 可逆性の判定:この変更は戻せるのか、戻せないのか
- 影響範囲の判定:この変更はどの境界の外まで影響するのか
- ロールバック責任:問題が起きたとき、誰が戻す判断をするのか
「全行を読む」が無理でも、この3つの判定はコードの中身を完全に理解しなくても下せます。「ここはマイグレーションだから戻せない」「これは1サービス内に閉じる」「壊れたら自分が戻す」。これらは構造の判定であって、全行の精読を必要としません。
やることは、この3つをラベルとして承認に添付し、機械可読にすることです。自由記述のレビューコメントではなく、取りうる値が決まった構造化データとして残します。
# 承認ラベルのスキーマ(取りうる値を固定する)
reversibility: reversible | irreversible # 戻せるか
blast_radius: local | cross-service # 影響が境界を越えるか
rollback_owner: <承認者の識別子> # 壊れたとき戻す判断をする人
値を自由記述にしないことが肝心です。reversibility が たぶん戻せる 半分くらい可逆 のような文字列になった瞬間、後述の集計ができなくなります。enum に倒します。
機械可読にする利点は2つあります。1つは、ラベルの分布を集計できること。「不可逆かつ越境」の変更が承認にどれだけ混ざっているかを数えられれば、形骸化の兆候を定量的に掴めます(具体的な集計は後述)。もう1つは、ラベルに応じて承認の重さを変えられること。可逆でローカルな変更はエージェントの自己申告+軽い承認で流し、不可逆で越境する変更だけ人間の精読を要求する、という重み付けをラベルを軸に設計できます。
承認の核を「読んだ」から「この変更の不可逆性と影響範囲を判定し、ロールバック責任を引き受けた」に置き換える。物量ではなく構造で承認を切り分けます。
パターン②:変更の来歴メタデータを残す
変更ひとつひとつに、最低限これだけは紐づけたい来歴があります。
- 生成主体:どのエージェント/どのモデルが生成したか
- 指示の出どころ:誰の、どんな意図の指示から始まったか
- 人間の承認スコープ:人間が承認したのは「全体」なのか「不可逆な部分だけ」なのか
これらを①のラベルと一緒に、変更の正本に同居させます。git 運用なら、コミットメッセージ末尾の trailer に置くのが手軽です。
# コミットメッセージ末尾の trailer(変更の正本にメタデータを同居させる)
Change-Agent: claude-opus-4-x # 生成主体(モデル)
Change-Intent: レート制限を 10→50rps に緩和 # 指示の意図(全文ではなく要約)
Approved-By: k.ikegami # 承認者
Approval-Scope: irreversible-only # 全体承認か、不可逆部分のみか
Reversibility: irreversible # ←①のラベル
Blast-Radius: cross-service # ←①のラベル
Rollback-Owner: k.ikegami # ←①のラベル
これはゼロから作る慣習ではありません。AIエージェントが書いたことを示す帰属 trailer はすでに広く使われていて、Claude Code・Copilot・Cursor は Co-Authored-By をデフォルトで付けます。OSS界隈ではAIをツールと位置づける Assisted-by:、Apache 財団では機械可読な provenance 向けの Generated-by: も使われています。ただしこれらが答えるのは「誰(どのAI)が書いたか」までで、「誰がどう承認したか」は空いています。本記事のラベルは、その既存の帰属 trailer に承認判断の層を足すものだと捉えてください。
trailer にする理由は、別システムのチャットログに散らばらせないためです。来歴を AI ツール側の対話履歴に頼ると、そのツールの保持期間が切れた瞬間に消えます。変更の記録(コミット、PR、課題チケットなど、自分の環境で「変更の正本」になっている場所)に、同じ寿命で添付します。
Change-Intent はプロンプト全文ではなく意図の要約(単一行)にします。trailer はコミットメッセージ末尾の連続ブロックを Key: value 形式でパースする仕組みなので、途中に空行や複数行が入ると壊れます。要約に絞る判断は、この制約とも噛み合います。全文や対話の全履歴を残そうとすると、次に書くログ保全のリスクに正面からぶつかります。「どのモデルが・誰の意図で・どこまでの承認スコープで入ったか」が辿れれば、来歴としては機能します。
trailer に揃えておくと、集計は git log だけで完結します。
# 直近の変更で「不可逆性 × 影響範囲」がどう分布しているかを数える
git log --format='%(trailers:key=Reversibility,key=Blast-Radius,valueonly,separator=%x20)' \
| sort | uniq -c | sort -rn
# 出力例:
# 142 reversible local
# 38 irreversible local
# 11 irreversible cross-service ← ここが膨らんでいたら、承認の重み付けが効いていない
%(trailers) は値ごとに改行を付けるため、%(...) %(...) と2つ並べると値が別行に割れて uniq -c が壊れます。1つの %(trailers) 内に key= を複数並べ、separator=%x20(空白)で連結すると、1コミット1行に揃います。
「不可逆かつ越境」が承認全体のどれだけを占めるかを、定期的にこの一行で確認できます。比率が想定より高ければ、本来は精読すべき変更が軽い承認で流れている兆候です。Approved-By 単独で同じ形にすれば、特定の承認者にハンコ承認が偏っていないかも見えます。
パターン③:事後再構成できる、最小限のログ保全
監査の話をすると「全部ログに残そう」に流れがちですが、ここは逆に振ります。
AIとの対話ログには、機密情報・認証情報・個人情報・内部構成が混ざり込みます。それを無制限に保全すると、監査のための記録そのものが最大の情報漏えいリスクになります。守るために残したログが、攻撃者にとって最良の地図になります。
設計の力点は「何を残すか」ではなく「何を残さないか」に置きます。
- 残すのは、来歴の再構成に必要な構造化メタデータ(パターン②)と、判断の証跡(パターン①のラベル)
- 残さない/マスクするのは、対話の生ログに含まれる機密・認証・個人情報
- 保全期間は無期限にせず、事後再構成に必要な期間で区切る
「全部読まないが、後から追える」を成立させるのは、全ログの保全ではなく、選んで残した証跡です。残す量を増やすほど監査が強くなるわけではない、というのがこのパターンの肝です。
陥りやすい罠
仕込む過程で踏みやすい穴を2つ挙げます。
罠1:監査の自動化が、監査の形骸化を生む。 ラベル付けや承認を自動化しすぎると、今度は「自動でラベルが付いて自動で承認される」状態になり、形骸化が一段深いところで再発します。自動化してよいのは可逆・ローカルな変更の処理までです。不可逆・越境の判定は自動化せず、人間が引き受ける一線として残します。
罠2:来歴を残すこと自体が新たな攻撃面になる。 trailer やラベルが改ざん可能なら、「承認されたように見せかける」攻撃が成立します。ここで注意したいのは、パターン②で来歴を置いたコミットの trailer は、それ単体では改ざん耐性を持たないことです。commit --amend や rebase、force-push でいくらでも書き換えられます。つまり「来歴の運搬」と「完全性の担保」は別レイヤとして設計する必要があります。
trailer は来歴を変更の正本に運ぶ役割に割り切り、完全性は別の層で担保します。具体的には、署名コミット(GPG/SSH)+ protected branch(force-push 禁止)+サーバ側の追記専用監査ログ(VCS ホスティングの audit log など)の併用です。ただし署名は「そのコミットが改ざんされていないこと」は示せても、「履歴を別の署名済みコミットに丸ごと書き換えること」自体は防げません。だから force-push を止める運用と、書き換えできない場所への追記が要ります。誰がいつ何を記録したかが改ざんできないこと(証跡の完全性)が崩れると、監査の前提ごと崩れます。
どちらの罠も、「監査を仕組みにした」こと自体に安心して、その仕組みの健全性を監査しなくなる点が共通しています。監査の仕組みもまた、定期的に「形骸化していないか」を点検する対象です。
おわりに
AIが大量に変更を入れる環境で守るべきは、コードの正しさだけではありません。「誰がどういう判断で、これを世に出すと決めたのか」を後から示せること、つまり説明責任のトレーサビリティです。
この記事で書いた3つは派手な技術ではありません。承認を分解してラベルにする、来歴メタデータを変更と同じ場所に残す、ログは選んで最小限だけ保全する。それでも、物量が承認をハンコに変えてしまう前に仕込む価値があります。
これは信頼モデルの話でもあります。ネットワーク的にゼロトラストを敷いても、変更の承認が「中身を見ないハンコ」なら、内部からの信頼は担保されていません。誰が何を承認したかを追えること自体が、AI駆動環境における信頼の土台の一つです。
AIの稼働量が人間のレビュー帯域を超えるのは、連続的な変化です。超えてから証跡を作るのは間に合いません。まだ全部読めているうちに、全部読まなくても追える構造へ移しておく。本記事の趣旨はそれに尽きます。
Discussion