AI運用の障害が起きたとき、原因切り分けを誤ると同じ現象が何日も再発します。本記事は、更新時刻を犯人だと決めつけて誤診した社内の実際の事故を追い、症状・誤診・真因・恒久対策の4段で切り分ける手順と、証跡から追える記録設計への直し方を共有します。読み終えたら、次に同じ症状が出たときの確認順序が手元に残ります。
01AI運用で起きた障害|原因切り分け前に見えていた症状
WEBMARKSは2026-07-08、Codex(別のAIエンジン)に「成果物が納品先へ正しく格上げされたか」を末尾で確認する仕組みを入れました。導入直後から、業務と無関係な確認メッセージがセッションの最後に毎回出るようになりました。
TASK-048というブラッシュアップ監査を45分かけて実行した回では、完了報告のはずの末尾が「【格上げ確認ゲート】直近で成果物が作られました」という表示に乗っ取られました。列挙されたのは、その回のセッションが一切触っていない別案件のファイルでした。
導入からの3日間で、この確認メッセージは233回発火しました(出典: 社内タスク台帳、2026-07-10記録)。記録に残っているのは次の範囲です。
| 項目 | 記録されている内容 |
|---|---|
| 発火回数 | 3日間で233回 |
| 症状 | 完了報告の末尾が、そのセッションが触っていない別案件のファイル列挙に置き換わる |
| 判定材料 | ファイルの更新時刻(mtime)から担当セッションを推定していた |
| 解消 | thread・case・ハッシュを明示記録する方式へ全面刷新して収束 |
日別の内訳は残していません。ここは正直に書いておきます。合計値だけを記録し、日ごとの推移を取らなかったため、「初日に何回で、修正パッチ後に何回に減ったか」を後から言えません。再発の傾向を見るには日別が要ります。 障害の記録設計としては、この時点で1つ足りていませんでした。
「毎回最後に変なメッセージが出る」「Codexが動いていない気がする」という体感は、あとから振り返ると正確な障害報告でした。ただし、この体感だけでは原因切り分けは進みません。
AI運用の障害がやっかいなのは、業務の完了報告そのものが上書きされる点です。次に何を確認すればいいかが分からないまま、無関係な情報だけが目の前に残ります。
02最初の原因切り分けは、なぜ更新時刻を疑ったのか
最初にこの症状を調べた担当は、セッションログの最後の1行だけを読み、「既存の運用ルールどおりに動いている、壊れていない」と結論づけました。これが誤診でした。
判断の根拠は、確認メッセージの文面が既存ルールの体裁に沿っていたことだけです。ユーザーが実際に画面で見ていたもの、つまり無関係な別案件のファイル一覧とは突き合わせていませんでした。
障害切り分けでもっとも危険なのは、この「文面は正しそうに見える」段階で止まることです。ポストモーテムの実務書は、対応者を個人として断罪しない姿勢を説きます。同時に、システムの脆弱性そのものを特定することへ焦点を当てるべきだとも述べています(出典: Google SRE Book「Postmortem Culture」)。
今回のケースでいえば、脆弱性は担当者の注意力ではありません。検証手順に「実物の画面と照合する」工程が、そもそも入っていなかったことが脆弱性でした。
| 論点 | 誤診(最初の結論) | 真因(実際の原因) |
|---|---|---|
| 何が起きているか | ルールどおりの正常な確認表示 | 旧フックの誤爆バグ |
| 判断の根拠 | セッションログの最終メッセージのみ | 更新時刻で別セッションの成果物を誤って自分の成果物とみなす設計 |
| 突き合わせた対象 | ログの文面だけ | ユーザーが見た画面(無関係ファイル一覧)とは未照合 |
| 結果 | 「壊れていない」と回答 | 3日で233回の誤爆が継続 |
体感が正しく、調査の結論が誤っている。この食い違いは、原因切り分けの現場でくり返し起こります。
03障害切り分けの盲点だった、更新時刻が招いた本当の原因
真因は、旧フック(承認ゲート用の確認スクリプトの旧版)の設計そのものにありました。Codexにはセッションを一意に識別するIDがありませんでした。その代替として「前回の確認以降に更新時刻が動いたVault内ファイルは、このセッションの成果物」とみなす作りにしていました。
このMac上では、画像生成バッチやClaude Codeの並行セッションが常時動いています。更新時刻はファイルシステム全体で共有される値なので、複数の処理が同時に走る環境では「誰が触ったか」の手がかりになりません。2026-07-09に中間ファイルを除外するパッチを当てても再発したのは、更新時刻という方式そのものに欠陥があったためです。この時点で、パッチは症状ごとに後追いする「モグラ叩き」になっていました。
同じ問題は分散システムの世界でも古くから知られています。W3C Trace Context仕様は、高スループット環境では同時刻に複数のリクエストが発生し、タイムスタンプ単独では識別できないと明記しています。だからこそ、ランダム生成した明示的なtrace-idを識別の起点に据えます(出典: W3C Trace Context仕様)。更新時刻に頼った旧フックは、この教科書的な落とし穴をそのまま踏んでいたことになります。
ログだけでは原因追跡に足りない、という指摘も一致します。分散トレーシングの解説では、ログだけでは実行経路を追うのに文脈情報が不足しがちだと指摘されています。根本原因分析には、リクエスト単位の明示的なつながりが要るとも説明されています(出典: OpenTelemetry Observability Primer)。
旧フックが持っていたのは更新時刻という間接的な手がかりだけでした。どのセッションが何を書いたかという明示的なつながりは、どこにもありませんでした。
04AIの運用障害を止めた、原因切り分け後の対処
2026-07-10、WEBMARKSはこの仕組みを全面的に作り直しました。柱は、更新時刻による推測をやめ、書き込みイベントを明示的に記録する方式へ切り替えたことです。
- 更新時刻の走査・時間窓・クールダウンといった間接推測の仕組みをすべて廃止する
- ツール実行の直後に発火するフック(
record-output.py)が、そのスレッドが実際にWrite・Edit・ApplyPatchしたファイルだけを、スレッドID・案件ID・SHA-256ハッシュ付きで記録する - セッション終了時のゲート(
promotion-gate.py)は、この記録だけを見て判断する。他セッションの成果物が混ざる経路自体が無くなる - 検証に失敗したとき(書き込み記録そのものが見当たらない場合を含む)は、ブロックではなく通過を選ぶ設計にした。止める方向に倒すと、正常な成果物まで巻き込んで業務が止まってしまうためだ。その代わり、通した記録は必ず残す
記録先のディレクトリ名は、スレッドIDと案件IDを連結した文字列のSHA-256ハッシュです。案件をまたいだ記録の混線も、構造的に防いでいます。
フックが判断をJSON形式で返し、必要な処理だけを止めるという設計自体は珍しくありません。WEBMARKSはClaude Code側でも同じ仕組みを採用しています(出典: Claude Code公式フックドキュメント)。エンジンが変わっても、この骨格は使い回せます。
この判断は、その場しのぎの妥協ではありません。意図した設計だと、記録に明文で残してあります。原因切り分けでは、判断の根拠が個人の記憶に留まると、あとから検証も再現もできなくなります。設計判断そのものを記録に残す姿勢は、更新時刻のような間接的な手がかりに頼らない運用と、根っこは同じです。
通常のWIP(作業途中の成果物)では、確認メッセージ自体を出さなくなりました。ブロックするのは、承認証跡の無いファイルが納品フォルダへ混入したという構造違反1種類だけです。加えて、フック(機械層)の刷新と同じ日に、指示書側の「毎回質問する」という古い文言も「作業途中は黙って進める」へ書き換えました。片方だけを直すと、直さなかった側から同じ症状が再発するためです。
05原因切り分けの記録を、証跡として残るように変えた
この事故から持ち帰れる教訓は、Codex固有の実装詳細より一段抽象度の高い、原因切り分けの手順そのものにあります。
- 「壊れていない・仕様どおり」と結論する前に、ユーザーが実際に見た画面や出力と照合する
- 並行セッション環境では、更新時刻だけを根拠に成果物の所有者を推定しない。所有の証跡は、書き込みイベントの明示記録でしか成立しない
- フック(機械層)と指示書(文章のルール)は、同じ日にセットで直す。片方だけでは再発を止められない
- 別のAIエンジンへ同じ機能を移植するときは、前提条件(セッションIDの有無など)が崩れていないかを先に確認する
残っている運用上の論点も1つあります。フックの設定ファイルを更新すると、次回Codex起動時に「このフックを信頼するか」という確認が1回だけ出ます。承認するまで新しい仕組みは有効になりませんが、無効な間も更新時刻による誤爆はしない設計にしてあります。
WEBMARKSは2026-06-24に7部署・30体のAI社員体制を統合し、AI社員同士・AIエンジン同士が同じVaultを並行して触る運用に切り替えました。並行稼働が増えるほど、更新時刻のような間接的な手がかりに頼った設計は壊れやすくなります。この事故も、その構造から起きた1件です。
更新時刻を疑う前に、まず証跡の有無を疑う。この順序を守るだけで、同じ種類の誤診はかなり減らせます。
明示記録の仕組みは、送信や公開を人が最終判断する承認ゲートの土台にもなります。ゲート設計全体は『AIエージェントの承認ゲート|送信・公開・削除で止める仕組み』で扱っています。
06同じ失敗を避けるためのチェックリスト
- 「壊れていない」と結論する前に、ユーザーが実際に見た画面と照合したか
- 並行セッション環境で、更新時刻(mtime)だけを根拠に成果物の所有者を推定していないか
- フック(機械層)を直すとき、指示書(指示層)の文章ルールも同じ日にセットで直したか
- 「誰が書いたか」を、推測ではなく明示的な記録(スレッドID・案件ID・ハッシュ値など)で追跡できるか
- 障害の発火回数と発生日を数値で記録し、パッチ後に再発していないかを実測で確認したか
- 新しい検知の仕組みを入れるとき、誤検知は「止める」方向ではなく「黙って通す」方向に倒したか
- エンジンを乗り換えて同じ機能を移植するとき、前提条件(セッションIDの有無など)が変わっていないか確認したか