Repository navigation
Add wait/wake support for goals without spending tokens #28144
Description
What variant of Codex are you using?
CLI/TUI and app-server goal runtime. This also matters for SDK/app-server integrations that drive long-running goals.
What feature would you like to see?
Add first-class wait/wake support for goals so a goal can stop making model calls while it is waiting for time or an external event, then continue when the wait condition is satisfied.
Current behavior, as I understand it from the goal runtime:
- Active
/goalwork continues automatically when the thread becomes idle. /goal pauseand/goal resumealready let a user stop and restart continuation manually.- Blocked, usage-limited, budget-limited, and complete statuses stop automatic continuation.
- There is not currently a durable "waiting" state that can be resumed automatically by a timer or external signal without spending tokens during the wait.
The missing capability is useful for goals like:
- "Check CI until it finishes, then fix failures."
- "Wait until the deployment completes, then verify it."
- "Poll this external job occasionally, but do not burn tokens while nothing can be done."
- "Resume this goal when another process/webhook tells Codex there is new information."
A good shape might be to separate "goal continuation" from "wait scheduling", similar to how other agent harnesses separate active goals from loop/scheduler primitives:
- A goal can enter a
waitingstate with a bounded reason and optionalwakeAttimestamp. - While
waiting, the runtime must not start another model turn or consume tokens. - A waiting goal can be resumed by user action, an app-server API call, a timer, or a future external-event/channel mechanism.
- Waiting state should be persisted so it survives app/server restart and thread resume.
- Goal update notifications should expose the waiting state and wake metadata to clients.
A small first stage could avoid building every event source at once:
- Add a persisted
waitinggoal status with optionalwakeAt/reason metadata. - Teach the idle continuation path to treat
waitinglikepausedfor token usage. - Add an app-server way for clients/supervisors to wake the goal by setting it active again.
- Optionally add a later scheduler that wakes goals at
wakeAt.
Additional information
I searched existing issues/PRs and found adjacent work, but not an exact request for durable wait/wake semantics:
- goal: pause continuation loops on usage limits and blockers #23094 added blocked/usage-limited statuses so continuation loops pause on blockers and usage limits.
- /goal when blocked doesn't stop but keeps looping consuming tokens and API credits #23177 reported blocked goals continuing to consume tokens; this appears addressed by goal: pause continuation loops on usage limits and blockers #23094.
- /goal: chat "stop" message causes silent token burn until usage limit (autonomous tick ignores LLM-level self-restraint) #24531 discussed active goals continuing despite a chat-level "stop" message; maintainers clarified active goals are intended to keep going and users should pause/clear them.
- codex exec resume should support promptless follow mode for active goals #24016 / Allow promptless exec resume for active goals #24321 cover promptless
exec resume/follow behavior for active goals, which is related to supervising goals but not the same as a no-token waiting state. - /goal runtime includes approval-wait time #22312 covered approval-wait time accounting, which is also adjacent but narrower.
Prior-art note: Claude Code appears to expose this kind of separation through /goal for autonomous continuation, /loop for scheduled prompts, and channels/webhooks for external events. OpenCode appears to support similar patterns mostly through plugins/community tooling rather than a core built-in. The Codex version does not have to copy those interfaces exactly, but the product need seems similar: let long-running goals wait without spending tokens, then wake from time or outside state.
Activity
devansh-jain-18 commentedon Jul 10, 2026
I hit this exact gap in a delegated-work + human-review workflow.
Generic reproduction:
active, the runtime repeatedly starts continuation turns that do little more than check whether the worker finished.In one run this produced 15 automatic continuation turns and increased the goal accounting by roughly 101k tokens while the actual work was proceeding in the separate task.
Neither existing terminal state fits:
completeis false because later reviewed steps remain.blockedis also false because the objective is still making progress and there is no genuine impasse.paused, and manual pause loses the desired automatic callback behavior.This suggests delegated task completion and HITL review are additional concrete wake sources for the proposed
waitingstate:wakeOnThreadCompletion(threadId)wakeOnUserReview/ next user messageWhile waiting, the parent should make zero model calls. A child terminal event should enqueue one continuation turn, and a review gate should then remain dormant until the user responds.
Comparable event-driven patterns exist elsewhere: Claude Code agent teams deliver teammate completion/idle notifications and unblock task dependencies automatically; its async hooks support event-triggered rewake; GitHub Copilot CLI exposes
agent_completedandagent_idlenotifications. Those patterns avoid making the coordinator poll with model turns.This is not a request to let the model abandon an active goal. It is a non-terminal scheduling state that preserves the objective while separating “work is still progressing elsewhere” from “start another model turn now.”
B143KC47 commentedon Jul 22, 2026
+1 — I'm seeing the same on CLI: an active goal keeps emitting placeholder tokens while waiting, instead of waiting silently. A durable waiting state that can be woken by a timer would solve this
vincenthcui commentedon Aug 25, 2026
I implemented a narrower version of the wait/wake separation proposed here:
vincenthcui#1
Instead of adding a new Goal status, it keeps the Goal
activeand persists a separate continuation trigger:onIdleor timer-owned. While timer-owned, the Goal runtime makes zero automatic idle model calls; the scheduler later delivers one explicit turn.The design also adds cross-process CAS using
goalVersion + automationId + generation. This prevents stale timer operations from affecting a replacement Goal or newer schedule generation.@jerryfane, could you review whether this narrower continuation-trigger model preserves the semantics you wanted from a durable waiting state? The PR leaves external-event wake sources for later, but the persisted trigger model can be extended beyond timers.
xxxupeng commentedon Oct 5, 2026
I ran into the same issue with long-running training jobs, so I made a small workaround:
https://github.com/xxxupeng/skills
The
scheduled-autonomyskill is basically Goal-like autonomy with sparse host-side wakeups: Codex keeps working toward the same objective, but when there’s nothing useful to do, it ends the current turn and uses a systemd timer to wake the same thread later instead of polling continuously and burning tokens.Feel free to try it, and issues or feedback are very welcome.
sarinstein-yan commentedon Oct 18, 2026
+1 for a persistent waiting state with event-driven resume. My research workflow needs to wait for queued hardware experiments, then analyze results and iterate automatically. Keeping the goal active wastes inference on waiting; manually pausing and resuming breaks the workflow. Separating waiting from an explicit user pause would be especially useful.