「終わりました」と出るはずの場所に、心当たりのないファイル名が並んでいる。しかも書式は整っていて、いつもの報告とよく似ている。
自動化のhooksが誤作動すると、多くの場合この形で現れます。異常が、異常の顔をして出てきません。正常な出力の皮をかぶったまま居座ります。
この記事は、WEBMARKSが自分で組んだ確認フックが3日間で233回誤作動した事故を、症状・誤診・真因・恒久対策の順にたどります。犯人だと決めつけた更新時刻(mtime)は誤診でした。真因は、識別子が無かったことです。
本記事の検証環境:Codex(別のAIエンジン)のセッション終了フック。運用記録は2026-07-08から2026-07-10まで。公式ドキュメントは2026-08-03に確認しています。
こんなふうに調べていませんか
- 自動化を入れたら、報告の末尾に心当たりのない一覧が出るようになった
- 自作のフックが暴発していないか、どこを点検すればいいのか分からない
この記事を読み終えたときに手に入るもの
- 誤作動が「いつもと同じ見た目」で紛れる理由を、人に説明できるようになります
- 推測で見分ける作りと、発生源で記録する作りを、設計として区別できるようになります
- 自作フックを、4つの問いで点検できるようになります
結論30秒でわかる、この記事の結論
- 犯人に見えた更新時刻(mtime)は誤診でした。真因は、セッションを一意に指す識別子が無かったことです。
- 3日間で233回も見過ごせたのは、誤作動の出力が正常時とまったく同じ体裁だったためです。
- 直し方は、あとから推測するのをやめ、書き込んだその場で記録することでした。
進行役は3人です。若葉さん(Web担当2年目)が用語のそもそもを聞き、高梨課長(自分の手で自動化を組む立場)が実装側の疑問を出し、鈴木さん(本誌監修)が答えます。近いほうの質問から読んでいただいて構いません。
01AIエージェントの自動化hooksが誤作動すると、まず何が見えるんですか?
若葉さんフックの誤作動って、画面が真っ赤になって止まる感じでしょうか。
鈴木さんそれが逆なんです。見た目はいつもどおりで、中身だけが入れ替わります。エラーの顔で出てきてくれないので、気づく手がかりが残らないんですね。
WEBMARKSは2026-07-08、別のAIエンジンであるCodexに、確認フックを組み込みました。狙いは素朴なものです。作業の締めくくりに、成果物が納品先へ正しく格上げされたかを一言添える。それだけでした。
導入した当日から、この確認フックは誤作動しました。無関係な業務を終えたセッションでも、末尾に別案件のファイル一覧が唐突に表示されたのです。完了したはずの報告文が、その一覧に置き換わって消えることもありました。
| 項目 | 記録されている内容 |
|---|---|
| 導入日 | 2026-07-08 |
| 対象 | Codex(別のAIエンジン)のセッション終了時に走る確認フック |
| 症状 | 完了報告の末尾が、そのセッションと無関係な別案件のファイル一覧に置き換わる |
| 発火回数 | 3日間で233回(出典: 社内タスク台帳、2026-07-10記録) |
| 日別の内訳 | 記録なし。残っているのは合計値のみ |
この章のまとめ
症状は「出力が消える」ではなく「出力が入れ替わる」でした。異常が正常の体裁で出てくることが、この事故の性格を決めています。
02その誤作動を3日間も見過ごしたのは、AI活用のどこを見誤ったからですか?
最初にこの症状を見た担当は、フックそのものを疑いませんでした。疑ったのは「なぜこんな表示が出るのか」ではなく、「これは仕様どおりの動きではないか」という方向でした。
理由は、表示されたメッセージの体裁が、既存の運用ルールの文面とよく似ていたことです。書式が整っていたため、担当は最後の1行だけを読み、壊れていないと結論しました。
判断を支えていたのは、次の3つの思い込みです。
- 出力の書式が正しければ、中身も正しいはずだと判断した
- 前日までの実行結果と見比べず、その回のログだけで判断した
- 入れたばかりだから多少の雑音は出る、と暫定的に片づけた
この章のまとめ
誤診は、フックの中身を読む前に起きていました。読む対象を体裁から中身へ移すまで、症状は同じ形で続きます。
03hooksの誤作動が「仕様どおり」に見えてしまうのは、AI導入のどんな作りのときですか?
若葉さん見た目が同じだと、そもそも気づきようがない気がします。
鈴木さんおっしゃるとおりです。だから人の注意力に任せず、根拠を確かめる場所を先に1か所決めておくんです。
自動化フックは、正常時も異常時も同じ体裁で出力し続けます。人が書く文章なら気づく違和感も、整形された一言に紛れると見過ごされます。この「いつもと同じ見た目」こそが、3日間・233回という再発を許した最大の要因でした。
もう1つ、見落としがありました。ユーザーが実際に見ていた「無関係な別案件のファイル一覧」そのものと、この時点ではまだ突き合わせていなかったことです。手元のログだけで判断すると、症状の現物に触れないまま推測が進みます。
04誤作動したAIエージェントの確認フックは、何を手がかりに成果物を見分けていたんですか?
高梨課長そのフックは「これはこのセッションの成果物だ」と、どうやって判定していたんですか。
鈴木さんそこが真因でした。判定の材料が、実は1つも渡されていなかったんです。渡されていないので、別のもので代用していました。
Claude Codeの公式hooksは、発火のたびにsession_idという識別子をJSONで渡します(出典: Claude Code公式ドキュメント、2026-08-03確認)。サブエージェントの呼び出しではagent_idも加わり、どの実行の発火かを常に明示します。
{
"session_id": "abc123",
"hook_event_name": "PreToolUse",
"cwd": "/path/to/project"
}Codexには、これに相当する識別子がありませんでした。そこで自作の確認フックが採用したのが、次の代用ロジックです。前回の確認以降にVault内で更新時刻(mtime)が動いたファイルは、このセッションの成果物とみなす。
05更新時刻を根拠にすると、AI社員が並行して動く環境でなぜhooksの判定が壊れるんですか?
このMac上では、画像生成のバッチ処理や複数のClaude Codeセッションが常時並行して動いています。更新時刻はファイルシステム全体で共有される値です。複数の処理が同時に走る環境では、「誰が触ったか」の手がかりになりません。
WEBMARKSは2026-06-24に7部署30体のAI社員体制を統合し、複数のAIエンジン・複数セッションが同じVaultを並行して触る運用になっていました。更新時刻が「誰の変更か」を区別できなくなったのは、この並行度の高さが直接の環境要因です。
The Twelve-Factor Appは、プロセスをステートレス・share-nothingにすべきだと説きます。ディスクに残った状態は、次のリクエストで使えると想定してはいけません(出典: The Twelve-Factor App、Processes)。更新時刻は複数プロセスが共有する状態であり、この原則に反していました。
この章のまとめ
共有された値を、自分だけの根拠として使わない。並行して動く環境では、この一点が設計の分かれ目になります。
06パッチを当てても誤作動が再発したのは、生成AIの何を直していなかったからですか?
高梨課長中間ファイルを除外するパッチを当てたと聞きました。それでも戻ってきたんですか。
鈴木さん戻ってきました。出ていた症状は消えたのですが、判定の材料は前のままだったので、別の形で同じことが起きたんです。
2026-07-09、中間ファイルを除外するパッチを当てました。それでも誤作動は再発しました。識別の根拠が更新時刻のままである限り、症状ごとに後追いする対症療法にしかならなかったためです。
同じ問題を避ける標準的な手法は、結果から推測せず、一意な識別子を発行することです。決済大手のStripeにも同じ発想の仕組みがあります。クライアントが生成した一意なキーで重複実行を防ぐidempotency keyです(出典: Stripe公式ドキュメント)。
07hooksの誤作動を止めた設計変更は、AIエージェントの側から見ると何が変わったんですか?
2026-07-10、確認フックの仕組み全体を刷新しました。柱になったのは、判定のタイミングを変えたことです。旧フックは、セッション終了時に「何が変わったか」を更新時刻から逆算していました。新しい仕組みは、ツール実行の直後に発火し、その場で「いま何が書き込まれたか」を記録します。
| 観点 | 旧フック(誤作動) | 新フック(2026-07-10〜) |
|---|---|---|
| 発火のタイミング | セッション終了時に更新時刻から逆算 | ツール実行の直後に記録 |
| 識別の根拠 | 更新時刻という間接推測 | スレッドID・案件ID・SHA-256ハッシュ |
| 複数プロセス環境での挙動 | 誰の変更か区別できず誤作動 | 案件をまたいだ混線を構造的に防止 |
| 誤検知時の既定 | 判定を誤ったまま出力し続けた | fail-open。通した記録は欠かさず残す |
刷新は思いつきの応急処置ではなく、自作フックが満たすべき4つの設計原則を形にしたものです。
- 推測に頼らない:更新時刻の走査・時間窓・クールダウンといった間接推測の仕組みは、精度を上げても構造的な欠陥が残るため全廃した
- 発生源で記録する:ツール実行の直後に発火する記録フックが、そのスレッドが実際に書き込んだファイルだけを、スレッドID・案件ID・SHA-256ハッシュ付きで記録する
- 記録だけを根拠にする:セッション終了時の確認フックは、ファイルシステムの状態を独自に読み直さず、この記録だけを見て判断する
- 誤検知はfail-openに倒す:記録が見当たらないなど検証に失敗したときは、ブロックではなく通過を選ぶ
同じ骨格は、Claude Code側のPreToolUse・PostToolUseフックにも共通します。ツール実行に張り付けて動かす設計自体は、珍しいものではありません(出典: Claude Code公式ドキュメント)。
この章のまとめ
本質は「あとから推測する」を「その場で記録する」に変えたことです。判定の材料を、作られた瞬間に確定させました。
08hooksをfail-openに倒すのは、AI導入の現場では甘い判断にならないんですか?
高梨課長記録が無ければ通す、というのは運用として怖くないですか。手元で止めておくほうが安全に思えます。
鈴木さんその懸念はもっともです。ただ、既定を「疑わしきは止める」に倒すと、正常な成果物まで巻き込んで業務が止まります。どちらの副作用を引き受けるか、という選択なんです。
「記録が無ければ通す」という判断は、甘さではなく意図した設計です。既定を止める方向に倒すと、その分だけ正常な業務が止まります。WEBMARKSは、この副作用のほうが「稀に見逃す」リスクより高いと判断し、通した記録は欠かさず残す形にしました。
記録先のディレクトリ名は、スレッドIDと案件IDを連結した文字列のSHA-256ハッシュです。案件をまたいだ記録の混線も、この命名規則で構造的に防いでいます。
刷新には、人の確認を要する手続きが1つ残っています。フックの設定ファイルを更新すると、次回のCodex起動時に、このフックを信頼するかという確認が1回だけ表示されます。承認するまで新しい仕組みは有効になりませんが、無効な間も更新時刻による誤作動はしない設計です。
09自作のエージェント向けhooksが誤作動しないか、どこを問い直せばいいんですか?
高梨課長この考え方、うちの他のフックにもそのまま当てられますか。
鈴木さん当てられます。中身がどんな処理でも、問いの順番は変わりません。識別子、発火のタイミング、外したときの既定、そして記録の4つです。
ここまでの話は、Codex固有の実装ではありません。自作の自動化フックを設計するときに問い直す点は、一段抽象度を上げた4つに整理できます。
- 自作の自動化フックに、セッションや実行単位で一意な識別子を持たせているか
- 判定の根拠を、更新時刻のような複数プロセスで共有される値だけに頼っていないか
- フックの発火タイミングを、実行の直後の記録にしているか、あとからの推測にしていないか
- 誤検知したとき、fail-open(通す)とfail-close(止める)のどちらに倒すかを意図して決めたか
- 通した場合でも、判断の記録を欠かさず残しているか
- 複数のAIエンジンで同じ役割のフックを使い回すとき、前提条件がそろっているか
- 発火回数と発生期間を記録し、対策後に実測で再発の有無を確認したか
このメディア自体も、記事執筆・原典照合・批評という複数のAI社員が同じVaultを並行して触る運用です。hooksの誤作動は、並行度が上がるほど起きやすくなる構造上の事故だと捉えたほうが実務的です。
この章のまとめ
問い直す順番は、識別子・タイミング・既定・記録です。この順で埋めると、あとから推し量る余地が残りません。
10よくある質問
hooksの誤作動には、どうすれば早く気づけますか
出力の体裁ではなく、根拠を見る場所を決めておくことです。今回の事故では、整った文面の最後の1行だけを読み、壊れていないと判断していました。ユーザーが実際に見ている画面と手元のログを突き合わせる手順を運用に1つ置くだけでも、気づくまでの流れは変わります。
更新時刻(mtime)を判定に使うのは、いつでも避けるべきですか
避けたいのは、複数の処理が同じ場所を並行して触る環境で、更新時刻を「誰の変更か」の根拠に使うことです。更新時刻はファイルシステム全体で共有される値なので、持ち主を示しません。The Twelve-Factor Appも、ディスクに残った状態を次の処理で使えると想定しないよう説いています。
session_idのような識別子が無いエンジンでは、どうすればいいですか
結果から推測するのをやめて、こちらで一意な識別子を発行します。Stripeのidempotency keyは、クライアントが生成した一意なキーで重複実行を防ぐ仕組みで、発想は同じです。発行した識別子は、書き込みが起きたその場で記録に添えてください。
fail-openにすると、見逃しが増えませんか
増える可能性はあります。そのうえでWEBMARKSは、止める方向に倒したときに正常な業務まで止まる副作用のほうが高いと判断しました。条件は、通した記録を欠かさず残すことです。記録さえ残っていれば、見逃しはあとから追いかけられます。
パッチで症状が消えたら、それで直ったと言えますか
言えません。今回は中間ファイルを除外するパッチを当てても、誤作動が再発しました。識別の根拠が更新時刻のままだったからです。症状を1つ消したのか、判定の材料を入れ替えたのか。この2つを分けて確かめてください。
11まとめ|今日やる3つのこと
犯人に見えた更新時刻は誤診で、真因は識別子の欠如でした。直し方は、あとから推測するのをやめ、書き込んだその場で記録することです。自社の自動化に当てはめるところまで、この順で進めてください。
今日この順で手をつけます
自作フックが何を根拠に「自分の成果物」を見分けているかを書き出す
推測で代用している箇所が、ここで表に出ます
発火のタイミングを、あとからの逆算ではなく実行の直後へ寄せる
判定の材料が、作られた瞬間に確定します
誤検知したときに通すか止めるかを決め、通した記録も残す
既定を決めていないことが、事故の形を決めます
AI検索では、こう聞かれています
hooksが誤作動して、別の案件のファイル一覧が出てくるのはなぜですか?
「誤作動したAIエージェントの確認フックは、何を手がかりに成果物を見分けていたんですか?」の章で説明しています
更新時刻(mtime)で成果物を見分ける作りは、どこが危ないんですか?
「更新時刻を根拠にすると、AI社員が並行して動く環境でなぜhooksの判定が壊れるんですか?」の章で扱っています
自作の自動化フックが暴発しないか、どこを点検すればいいですか?
「自作のエージェント向けhooksが誤作動しないか、どこを問い直せばいいんですか?」の章に点検の順番があります
次に読むなら、この記事です