Codex CLI: add a bounded native recovery loop for failed tool workflows

Open 💬 0 comments Opened Aug 21, 2026 by defin85

What variant of Codex are you using?

Codex CLI / TUI and app-server.

What feature would you like to see?

Summary

Add an opt-in, bounded native recovery loop for eligible tool failures inside the current Codex thread.

When an ordinary project workflow fails, Codex should be able to preserve a small host-owned incident record, ask the model for a diagnosis, apply an owner-scoped repair through the existing tool and approval system, verify the original operation, and either resolve the incident or stop safely.

This should be runtime state, not only prompt guidance or a skill. The host must own attempt limits, evidence binding, persistence, retry safety, and stop conditions so compaction, resume, or model behavior cannot silently bypass them.

Problem

Codex can often diagnose and repair a failed command when the user explicitly asks it to continue, but there is no native lifecycle tying together:

  1. the exact failed tool call and typed completion facts;
  2. a bounded diagnosis and repair attempt;
  3. the exact repair call and its committed project effects;
  4. verification against the original failure;
  5. a durable resolved, dismissed, awaiting-user, or stopped outcome.

Prompt-only recovery is fragile across compaction and resume. Parsing rendered tool output is also ambiguous: text containing "error" may be a successful diagnostic result, while a process may exit nonzero, time out, remain running, be blocked by a hook, or be aborted without a reliable textual convention.

Proposed behavior

For an eligible root thread and a normal project tool failure:

failed tool call
  -> persist bounded incident snapshot
  -> triage or dismiss
  -> pre-register one owner-scoped repair action
  -> observe the exact finalized repair call and committed effects
  -> pre-register verification
  -> verify the original failure
  -> resolve, request an explicit retry decision, or stop

The model would receive a bounded contextual fragment and narrow transition tools such as triage, progress, and resolve. The runtime, rather than the model, would validate every transition against canonical history and typed tool-result facts.

Required safety properties

  • Experimental and disabled by default.
  • Preserve existing sandbox, approval, hook, and collaboration-mode policies.
  • Never classify control tools, user-interaction tools, or the recovery tools themselves as repair candidates.
  • Do not infer success or failure by parsing rendered output.
  • Bind repair and verification transitions to exact call IDs, payload kind, tool name, environment, and canonical history.
  • Accept project-change evidence only for normalized paths inside the selected environment root.
  • Do not cache tool arguments, output, patches, or command payloads in the incident snapshot.
  • Retry automatically only when the host classifies the action as safe; otherwise require an explicit user decision.
  • Limit an incident to two attempts and stop early on repeated evidence.
  • Fail closed after resume if an action was in flight and its completion cannot be proven.
  • Keep incident records internal: persist them for continuity, but omit them from ordinary model context, thread history projections, search, memories, and child-thread inheritance.
  • Never rewrite existing conversation history.

Why this should be native

A skill can teach the model a useful debugging procedure, but it cannot reliably guarantee atomic persistence, exact evidence binding, retry classification, fork isolation, or stop-on-resume semantics. Those controls need host-owned lifecycle hooks and durable internal state. Skills can still supply domain-specific diagnosis after the native loop establishes the safety envelope.

Acceptance criteria

  1. A typed tool lifecycle distinguishes exited, signaled, timed out, running, aborted, hook-blocked, and pre-handler failures without parsing output text.
  2. A failed ordinary tool creates at most one active incident for the thread.
  3. Repair and verification calls are accepted only when they match the pre-registered intent and canonical history exactly.
  4. Successful verification resolves the incident; repeated evidence, attempt exhaustion, ambiguous resume, or policy refusal stops it.
  5. Unsafe retry pauses for an explicit user decision and cannot be approved for a different call or incident revision.
  6. Compaction and cold resume regenerate at most one bounded steering fragment without replaying actions.
  7. Forks, projections, memory extraction, and ordinary model reconstruction do not expose or inherit internal incident snapshots.
  8. Disabled mode adds no tools, context, persistence, or tool-lifecycle work.

Additional information

Related but distinct requests:

  • #32993 proposes persistent monitor workflows that wake a thread for long-running background jobs. This proposal handles an already observed tool failure inside an active thread and does not add scheduling or monitoring.
  • #36503 demonstrates why recovery must have runtime-owned circuit breakers and an out-of-band fail-closed stop path rather than unlimited model retries.

I built a default-off prototype to validate that this can compose with the existing extension, rollout, tool-lifecycle, app-server, compaction, and approval seams:

https://github.com/defin85/codex/tree/add-native-self-improvement-loop

The prototype is implementation evidence, not a request to bypass the invitation-only contribution process. I am happy to reshape or split the approach if the maintainers consider the workflow useful and want to align on a narrower first stage.

View original on GitHub ↗