自作のagentオーケストレーターからCodexを呼び出して開発している。2026年10月中旬から、reworkを完遂できず、一度行った編集を元に戻して終了するケースが目立つようになった。

実際に観測した流れは次の通り。

reviewerが修正を要求
        ↓
Codexがreworkを開始
        ↓
実際にファイルを編集する
        ↓
修正を完遂できない
        ↓
Codex自身が変更を元に戻す
        ↓
HEADは変わらず、worktreeもclean
        ↓
Codexは「今回は完了できなかった」と報告
        ↓
プロセス自体はexit 0

自分のオーケストレーターでは、exit 0 + HEAD変更なし + worktree cleanを正常なzero-changeとして扱っていた。そのため、変更不要と判断したケースと、修正に失敗してrevertしたケースを区別できず、後者もそのままreviewerへ進んでいた。

最終Git状態だけでは2つの経路を区別できない

最終状態は同じでも、内部の経過は異なる。

状態Codex内部の経過最終Git状態
正常なzero-change確認した結果、変更不要と判断したHEAD変更なし / clean
失敗後のrevert一度編集したが完遂できず、変更を元に戻したHEAD変更なし / clean

最初にオーケストレーター側を確認した。

  • Git差分の検出ミスではない
  • commit漏れではない
  • 直前に入れたorchestrator変更によるregressionでもない

Codexは実際に一度ファイルを変更しており、その後、自分で変更を元に戻していた。

exit 0は以前と同じだった

自分の環境では、Codexがexit 0で終わること自体は以前から変わっていない。

差が出ていたのは、exit 0に至るまでの作業経路だった。

以前は実質的に、次の流れで使えていた。

Codexが作業
    ↓
変更を完了、または変更不要と判断
    ↓
exit 0

今回観測した経路は次の通り。

Codexが作業
    ↓
一度編集
    ↓
完遂できない
    ↓
自分でrevert
    ↓
未完了を報告
    ↓
exit 0

exit 0だけでは、この2つを区別できない。

10月上旬には近い挙動の公開Issueが続いている

2026年10月上旬には、作業完了前にターンを終了する近い報告が複数出ている。

10月4日に作成されたOpenAI CodexのIssue #50771では、Codexが「続ける」「修正する」と説明したあと、実際の作業をせずにターンを終了するケースが報告されている。修正内容を説明しただけでtool callを行わず、turn自体はerrorなしでcompleteになった例も含まれている。

Issue #51552ではcodex execが未変更のままexit 0で終了している

10月7日のIssue #51552では、headlessなcodex execで小さなcoding taskを100回実行し、4回でファイルが一切変更されないままexit 0になったと報告されている。

3回は最終メッセージで「変更した」と報告しており、残り1回も「これから実装する」という内容を出した直後に終了している。成功したrunには存在したfile_changeイベントが、失敗したrunにはなかったことも確認されている。

このIssueに対してOpenAI contributorは10月11日、harness側ではなくmodel behaviorとして扱い、model training側へ共有するとコメントしている。

使われているモデルや実行環境は自分のものと異なる。ここでは、codex execがタスク未完了のままexit 0で終了した事例として参照している。

一時的な編集がrevertされ、最終的にHEADと同一になるケースもある

10月10日のIssue #52888では、1つのCodexタスク中に存在した一時的な編集が後からrevertされたにもかかわらず、VS CodeのCodex Diffがその変更を最終差分として数えてしまう問題が報告されている。

#52888の主題はCodex Diff表示だが、タスク中に一度存在した編集が、完了時にはHEADと同一の状態まで戻る経路を確認できる。

自分の環境で見た「一度変更したあと、最終的には元の状態へ戻って終了する」という動きとも、この点で共通している。

これらは個別の報告であり、Codex全体の失敗率を示す統計ではない。ただ、2026年10月上旬に、タスク完遂前の終了や最終状態と作業報告の不一致に関する報告が続いていることは確認できる。

自作オーケストレーターでは成功判定の不足が表面化した

自分の環境では、これまで正常なzero-changeとして扱っていた条件に、失敗後のrevertも入るようになった。

問題だった判定は次の部分だ。

exit 0
AND
HEAD変更なし
AND
worktree clean

=> valid zero-change

この条件では、最終Git状態しか見ていない。rework中に一度変更したか、修正を完遂したか、変更不要と判断したかは区別できない。

zero-changeを複数の状態に分ける

オーケストレーターでは、zero-changeを1種類として扱わないように修正する。

exit 0はCodexプロセスが正常に終了したという情報として使い、タスクの完了状態は別に判定する。

reworkの状態は次のように分ける。

exit code != 0
  -> process_failed

final diffあり
  -> changed

途中でfile_changeあり + 最終diffなし
  -> reverted_or_ambiguous

最終diffなし + 「変更不要」を明示的に確認できた
  -> valid_zero_change

最終diffなし + それ以外
  -> no_change_unverified

これは状態分類を説明するための例で、実装ではfile_changeイベントだけを唯一の判定材料にはしない。

reviewerから具体的なfindingを受けてreworkを開始し、最終diffがゼロだった場合は追加判定を入れる。

review findingあり
        ↓
rework
        ↓
final diffなし
        ↓
変更不要 / revert / 途中終了を判定

判定には次の情報を使う。

  • Codexプロセスの終了状態
  • JSONL上のfile_changeなどのイベント
  • HEADとworktreeの最終状態
  • reworkを発生させたreview finding
  • Codexが返したoutcome

Codex自身にno_change_requiredのようなoutcomeを返させる場合も、最終メッセージだけでは判定しない。Issue #51552では、最終メッセージと実際のファイル状態が一致しないケースが確認されているためだ。

agentの終了とタスク完了を分けて持つ

今回見直したのは、自作オーケストレーターの状態モデルだ。

次の3つを別の情報として扱う。

  • Codexプロセスが正常終了したか
  • Gitに最終差分があるか
  • 依頼されたタスクが完了したか

workflowの次へ進むかどうかは、この3つとreworkの途中経過を組み合わせて判定する。