What variant of Codex are you using?
CLI / app-server v2 on current main (e766f7598993ce37cf61b9c26c80cc2ba3a4f2d7).
What feature would you like to see?
An experimental app-server request that atomically starts a turn only when a specific thread is idle.
Today, turn/start is intentionally start-or-steer: if a turn becomes active before Core admits the request, the input can be steered into that turn. A client can read an idle status first, but thread/read → turn/start is not atomic. That makes turn/start unsafe for background or event-driven clients that must never alter an active human-owned turn.
A narrow v2 shape would be:
turn/startIfIdle {
threadId,
expectedCwd,
clientUserMessageId?,
input
}
The admission should happen inside the same ordered Core turn-input path as ordinary input and either:
- start one turn and return the existing
TurnStartResponse with its actual turn ID; or
- reject without steering, interrupting, queuing, applying turn settings, recording input, or making a provider request.
The useful fail-closed reasons are:
- thread is busy;
- pending trigger work exists;
- Plan mode is active for this client admission;
- the effective turn cwd differs from
expectedCwd;
- the thread is not persistence-enabled.
The cwd check must be part of the same reserved admission operation; checking it in app-server before submission would leave another race.
Core now has most of the required primitive: PR 38275 added ordered CodexThread::start_turn_if_idle / TurnInputMode::StartIfIdle. The remaining work is a small precondition extension plus the experimental app-server protocol/processor surface, schemas, docs, and focused fake-provider regressions.
This does not require a new delivery queue, retry loop, fallback to turn/start, approval response, or replacement client.
Additional information
We ran into this while building a small resident app-server integration at @clevvi: inbound work should wake an idle Codex thread, but must leave an active TUI turn completely alone.
Related, but not duplicates:
- #20312 asks for a broader native event-driven wake facility.
- #36866 documents the existing start-or-steer behavior and turn-ID consequences of
turn/start.
- #34767 shows why multi-client admission needs a single authoritative turn boundary.
I have a focused current-main patch and deterministic no-real-model tests in progress. Happy to open the PR if this API shape is welcome.
What variant of Codex are you using?
CLI / app-server v2 on current
main(e766f7598993ce37cf61b9c26c80cc2ba3a4f2d7).What feature would you like to see?
An experimental app-server request that atomically starts a turn only when a specific thread is idle.
Today,
turn/startis intentionally start-or-steer: if a turn becomes active before Core admits the request, the input can be steered into that turn. A client can read an idle status first, butthread/read → turn/startis not atomic. That makesturn/startunsafe for background or event-driven clients that must never alter an active human-owned turn.A narrow v2 shape would be:
The admission should happen inside the same ordered Core turn-input path as ordinary input and either:
TurnStartResponsewith its actual turn ID; orThe useful fail-closed reasons are:
expectedCwd;The cwd check must be part of the same reserved admission operation; checking it in app-server before submission would leave another race.
Core now has most of the required primitive: PR 38275 added ordered
CodexThread::start_turn_if_idle/TurnInputMode::StartIfIdle. The remaining work is a small precondition extension plus the experimental app-server protocol/processor surface, schemas, docs, and focused fake-provider regressions.This does not require a new delivery queue, retry loop, fallback to
turn/start, approval response, or replacement client.Additional information
We ran into this while building a small resident app-server integration at @clevvi: inbound work should wake an idle Codex thread, but must leave an active TUI turn completely alone.
Related, but not duplicates:
turn/start.I have a focused current-main patch and deterministic no-real-model tests in progress. Happy to open the PR if this API shape is welcome.