Repository navigation
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Use the Codex provider and finish a normal turn, so it has a native turn boundary.
- Start another request in the parent thread and leave it running.
- Fork the conversation from the earlier completed turn.
- Send a different request in the fork before the parent finishes.
Expected behavior
The fork copies the native Codex conversation through the selected completed turn, excluding later activity, while the parent continues running. This allows two independent requests to use the same prior context.
Actual behavior
T3 starts a fresh native session with a bounded portable handoff instead. The timeline shows a Codex-to-Codex Context handoff even though the provider and model have not changed. The model receives selected visible history; native reasoning and tool state are not replayed.
In the observed fork, the handoff recorded:
Title: Fork context
Selected 5 intact items; omitted 41 items.
Attached files and native tool/reasoning state are not replayed.
The full T3 history remains stored and readable; the problem is the context transferred into the fork.
Impact
Major degradation of context for parallel requests. Whether a fork retains native history depends on whether the parent happens to be running when the fork's first message is dispatched.
Version or commit
Confirmed in upstream 47f2c8d29e981c7723467efe137ee19e91df924e. The blanket busy-source fallback was introduced by 50c1c5dc53 in #26901. The original observation was in a personal fork; its exact installed release version was not recorded.
Environment
Windows, Codex provider. Native protocol verification used Codex CLI/app-server 0.166.0 with an isolated home/workspace and a local mock Responses endpoint, without real model calls.
Diagnosis and evidence
The dispatch policy excludes every busy source from native forking. Startup rechecks the source and applies the same fallback. #26901 describes the restriction for Claude, OpenCode and Pi, and notes that Codex previously forked natively in this situation.
Codex supports this case: its app-server API accepts a completed lastTurnId while a later source turn runs. Only an in-progress explicit boundary is rejected. The isolated native check produced:
Source before fork: active, second turn running
thread/fork(lastTurnId = completed first turn): succeeded
Fork history: first turn and its marker retained; second turn excluded
Source after fork: still active
Prepared fix and validation
A prepared proposal is available in #29239 at c38a7d4d9fc1efdf6a1e3f7a9957783aafa0be5a: branch, comparison with upstream main.
It permits busy native forks only when the provider advertises support and the selected turn has a usable native reference. Other providers, synthetic replies such as /goal, and missing cursors retain the portable fallback. Both dispatch planning and startup enforce the restriction.
- Original native-fork regression cases failed before the fix. Three additional missing-boundary cases also failed before the review correction; all nine selected fork cases pass afterward.
- Changed-file validation passed formatting, lint, unused-code, GraphQL and typechecks for all 35 affected packages. Tests: 218 passed and four Windows worktree-recovery failures, each independently reproduced on unchanged upstream at the commit above.
- The prepared PR's required hosted checks passed on
c38a7d4d9f. Codex and CodeRabbit's findings were corrected and their review threads resolved.
Maintainer confirmation of the intended Codex behavior is still pending. The prepared fix is available for maintainers to consider; they may choose this implementation or another approach.
Workaround
Wait for the parent to be idle before sending the fork's first message.
Filed by GPT-6.1 Sol through the Codex harness.
Activity
Alb11747 commentedon Nov 2, 2026
Prepared fix and validation: #29239.