エージェントが「できませんでした」で止まった日 — 未実施を成功にしない設計

accounting-app の法人決算書類まわりのE2E検証を、Codex のサブエージェントに任せていました。
結果は2回続けて blocked です。PRは1本も上がっていません。
ただ、これは失敗の記録ではありません。止まるべきところで止まった記録です。
何が起きたか
親Issue #1214 から派生した #1215、そこからさらに #1216 という連鎖になりました。
詰まった中身は地味です。
- Docker daemon への接続が権限拒否。実DB・RLS・API・PDF・Chromium が全部動かせない
- npm ci が EPERM。専用worktreeに
node_modulesが作られず、型検査もlintも走らない - 型検査とlintには、そもそも既存のエラーが残っていた
つまり、書いたコードの良し悪し以前に、検証環境が立っていなかった。
止まり方のほうが重要だった
自律エージェントに長い作業を任せると、いちばん怖いのは失敗ではなく 「動かせなかったものを動いたことにして先へ進む」ことです。
今回のIssueコメントには、毎回この一行が入っていました。
未実施を成功扱いしていない。PRは未作成。
これは偶然ではなく、指示側にfail-closedの条件を書いてあったからです。
| 条件 | エージェントの振る舞い |
|---|---|
| 実行できた | 結果を証跡として残す |
| 実行できなかった | 未実施と明記して止まる |
| 判断がつかない | 未実施側に倒す |
「実行できなかった」と「実行して失敗した」を別物として扱わせるのがポイントです。
この2つを混ぜると、レポートの 3/3 passed が何を意味するのか誰にも分からなくなります。
実際、今回残った有効な成果は focused test 3/3成功 だけで、それ以外は全部「未実施」でした。
その内訳がそのまま読めることに価値がありました。
原因のほうは、あっさり片付いた
翌朝、同じ環境で docker info を叩いたら普通に返ってきました。
29.1.3 4cpu 6.2GB
supabase_db_supabase Up (healthy)
supabase_kong_supabase Up (healthy)
...
Docker Desktop 側が落ちていただけです。前日には launchd から実行したときに PATH が足りずDocker未起動と誤判定する別の不具合も直していて、 「Dockerが見えない」に見える状態が複数の原因で起きていました。
node_modules はいまも作られていません。こちらは残っています。
次にどうするか
- worktree側の
npm ciの EPERM を先に潰す。依存が入らない限り型検査もE2Eも意味がない - Docker が生きているうちに
preflight → 型検査 → focused test → workers=1のE2Eを一気に通す - 既存の型検査・lintエラーは、今回の変更と切り離して別Issueにする
環境の不備を、実装の失敗と同じ箱に入れない。 今回いちばん効いたのはこれでした。
止まる条件の具体的な書き方は エージェントが止まるとき に手順としてまとめてあります。