Repository navigation
Support durable delayed Goal continuation and owner-synchronized external state changes #41766
Description
What variant of Codex are you using?
Codex App (desktop).
What feature would you like to see?
Please support durable delayed continuation for Goals, with native desktop-owner semantics.
Why this is needed
Agents frequently reach a state where no useful model work can continue until an external result exists, for example:
- a GitHub Actions CI run is still executing;
- another Codex thread is implementing or reviewing a dependency;
- an external service or user-controlled environment will not be ready for some time.
Keeping the Goal active during such waits can produce continuation turns with no actionable work, consume model tokens and compute, encourage repeated polling, and risk duplicate decisions. Ending the Goal entirely loses the intended continuation. The desired behavior is a goal-aware dormant state: finish the current turn, suppress native continuation while nothing can be done, and resume the same Goal exactly once when the selected condition becomes actionable.
This is not a request for a general background-job scheduler. It is a bounded lifecycle control for one existing Goal.
A useful API could provide either or both of these capabilities:
-
Native delayed or event-driven Goal continuation
- An agent, or a user instruction handled by an agent, can defer the current Goal until
resume_at, a bounded delay, completion of a named CI run, or a response from a named existing thread. - The current turn is allowed to finish normally.
- The dormant interval starts no model turn and performs no model-driven polling.
- No native Goal continuation starts before the time or event becomes due.
- At the deadline or event, Codex reactivates the same Goal and starts exactly one continuation.
- The schedule is durable across app restarts, bound to the exact thread and Goal identity, cancellable, idempotent, and limited to one active schedule per Goal.
- On wake, the continuation reads the current Goal state and the fresh external result before deciding what to do; it does not blindly replay the pre-wait plan.
- An agent, or a user instruction handled by an agent, can defer the current Goal until
-
Owner-synchronized external Goal control
- An external app-server or IPC client can set the Goal state through a supported API.
- A
pausedoractivechange is applied to the loaded desktop owner's in-memory conversation state with the same semantics as clicking the App's Pause Goal or Resume Goal control. - The acknowledgement is returned only after the owner has applied the transition.
- Pending continuation decisions are cancelled or recomputed from the new state, and state notifications propagate across app-server processes.
The key invariant is: once a delayed pause is acknowledged, only the due scheduler or matching event may reactivate the Goal before the deadline.
Additional information
A separate app-server client can persist thread/goal/set as paused while the loaded desktop owner still retains an active in-memory Goal and schedules another native continuation. The UI Pause Goal control does not have this mismatch because it updates both persisted state and the desktop owner's local state.
This makes external durable scheduling unreliable unless tooling drives the visible UI. A native delayed/event-driven continuation API would be the cleanest solution; owner-synchronized external state changes would also make existing integrations reliable.
The intended resource benefit is concrete: while waiting on CI or another thread, Codex should be able to release the current model turn and consume no further model budget until the registered condition changes.
Activity
icekinder commentedon Sep 29, 2026
I tested a local app-server candidate for durable Goal wait/wake and exact-goal identity. The backend behavior works in the checked scenarios. Desktop caller integration still needs a supported build route.
With desktop 26.928.20755 attached through its existing WebSocket override, a local fixture verified quiet unchanged waiting, one changed-state continuation, duplicate rejection, and persisted wait across desktop/server restart. Restart testing used an explicit diagnostic thread resume. This does not prove spontaneous desktop resume or actual window controls.
The current desktop callers do not carry the candidate's goal identity through clear, status changes and cross-window interruption. A delayed action for A can therefore target replacement B. Replaying the exact extracted caller functions against the candidate app-server produced 17 failures in 23 cases. A two-module caller repair passed all 23. Window state and peer transport were simulated in this replay, so this is not a released-UI reproduction.
The proposed caller changes are:
To finish native desktop acceptance, is there a supported Owl development-build route, or can these changes be applied in desktop source and supplied as a properly signed development candidate? The app explicitly rejects stock Electron. A locally repackaged, ad hoc hardened copy passed static signature verification but failed runtime library validation because it had no signing Team ID. I did not remove the Owl check or weaken library validation.
The remaining acceptance is actual local/cross-window goal controls, stale replacement rejection, quiet wait and single wake, plus supported restart/resume in the repaired desktop. The current evidence is local integration proof, not a claim of installed production enforcement.