無料枠のエージェント実行環境(キュー制で、夜間の閑時ならフラッグシップモデルを無料で使える仕組み。今回はZcodeのIdleTimeTask)を、毎日決まった時刻に自動で消化するcronジョブとして組み込んだ。設計は単純だ。深夜0時に実行枠のチケットがあるか確認し、あればタスクを投入、3時間後の3時に結果を回収する。初日の試運転で、この仕組みは静かに、しかし完全に止まった。
何が起きたか
0時46分、タスクは順調にキューを消化して実行を開始した。この部分は完璧だった。待ち行列に並び、順番が来て、枠が割り当てられ、課金(無料枠の消費)も正常。ところが開始1分後、最初のネットワーク系コマンド(curl)を実行しようとしたところで、エージェントはこう言った。「High risk tools require explicit approval」——高リスクツールには明示的な承認が必要です。
問題は、そこに誰もいなかったことだ。深夜の無人実行なので、承認を押す人間はいない。承認を答えるはずのモデル審査も、設定で無効化していた。結局タスクは承認待ちのまま3時間放置され、タイムアウトで強制停止。無料枠を1回分丸ごと消費して、成果物はゼロだった。
皮肉なことに、検知系は完璧に動いていた。3時の回収ジョブは「承認待ちで停止」と正しく通知してきた。止まったことは分かった。しかし、通知が届いても、止まったものを諦めさせる仕組みがなかった。
原因は「モード」と「承認者」の不一致
調べると、原因は単純な構成問題だった。実行に使っていたラッパーツールは、セッション作成時のpermissionモードをbuildにハードコードしていた。buildモードでは、ネットワークアクセスを伴うBashなど「高リスク」な操作が必ず承認要求を出す。一方こちらは「FullAccessでいい」と考えて運用していて、しかも承認を自動判定するはずのレビュアー機能をオフにしていた。
つまりこういう状態だ。扉は鍵がかかっていて、鍵を開ける係は解雇済みで、訪問者は永遠にドアの前で待つ。安全のための承認フローが、無人環境では最悪の失敗モード——無限待機——に変わる。
承認フローの前提は「人がいること」
承認ゲートは、一般に安全装置として設計される。勝手に危険なことをしないよう、人間の判断を挟む。この設計は「承認者が存在し、時間的に到達可能である」という前提の上に立っている。自動化はこの前提を静かに壊す。コードは一行も変わらないのに、前提だけが消える。
だから無人実行を設計するときのチェックリストはこうなる。
- 実行モードは無人運用に合わせる。承認要求が原理的に発生しないモードを選ぶ。ただし、人間が介在する運用に戻せるよう、環境変数で切り替えられる escape hatch を用意する。
- それでも固まるケースのために、放置タイマーで失敗を確定させる。タイムアウトは3時間だったが、今回は「90分放置で自動キャンセル+通知」に短縮した。枠の浪費も、次の一手へのフィードバックも、早い方がいい。
- 「止まったことを検知する」機能と「止まったものを諦めさせる」機能は別物。前者だけでは監視は片手落ち。
修正後
実行モードを無人向けに切り替え、プローブ用セッションでコマンド実行から完了までpermission要求ゼロ・6秒であることを確認した。その後、同じタスクを再投入し、翌朝の自動実行で完了とレポート生成まで確認できた。変えたのは止まり方だけだ。仕組み自体——キュー、投入、枠の清算、通知——は最初から正しく動いていた。
自動化の成熟度は、うまくいっているときには測れない。止まったときにどう止まるかで測るしかない。承認という安全装置は、「通れなかったときに何が起きるか」まで設計して初めて、安全装置として機能する。