What version of the Codex App are you using (from the About Codex dialog)?
26.721.4979.0
What subscription do you have?
Unknown (API-key-authenticated local setup; no subscription tier is exposed in the available diagnostics).
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
What issue are you seeing?
Using Continue in new chat on an earlier turn can create a child task whose history extends past the selected fork point when one of the later turns was steered.
The residual user message can then survive auto-compaction and be answered again, even though it was sent before the fork and should have been removed from the child task.
The two visible symptoms are:
- The fork boundary includes messages after the selected turn.
- After compaction, Codex responds again to a user message from the rolled-back portion of the parent task.
What steps can reproduce the bug?
- Start a task in the Codex App and complete an initial turn that will be used as the fork target.
- Start another turn.
- While that turn is active, send a steer message before the turn completes.
- Complete at least one additional turn after the steered turn.
- On the initial target turn, choose Continue in new chat.
- Inspect the new task history. Part of the steered turn can remain after the selected fork boundary.
- Continue using the child task until auto-compaction occurs. The residual pre-fork user message can be surfaced and answered again.
The code-level reproduction is to create an app-server turn with both an initial user message and a later turn/steer message sharing the same durable turn_id, add another turn, and then call thread/rollback for the two app-server turns after the target.
What is the expected behavior?
The child task should end exactly at the selected fork point. All later app-server turns should be removed, including every initial and steer message belonging to those turns. Auto-compaction must not reintroduce or replay any removed message.
Additional information
The root cause appears to be a counting-unit mismatch in rollback:
- The app passes
thread/rollback.numTurns as a count of app-server turns after the selected target.
- Core history rollback currently treats each ordinary user message as a separate turn boundary.
- A steered app-server turn persists multiple ordinary user messages with the same non-empty durable
turn_id.
- As a result, rollback can remove too few app-server turns and leave the initial message of the steered turn behind.
A focused fix groups consecutive ordinary user-message boundaries with the same non-empty durable turn_id, while retaining legacy behavior for messages without a turn ID and for inter-agent instruction boundaries:
daizw@315c12e
Validation performed on that commit:
just test -p codex-core drop_last_n_user_turns (7/7 passed)
just test -p codex-app-server thread_rollback (4/4 passed)
just fix -p codex-core
just fix -p codex-app-server
just fmt
What version of the Codex App are you using (from the About Codex dialog)?
26.721.4979.0
What subscription do you have?
Unknown (API-key-authenticated local setup; no subscription tier is exposed in the available diagnostics).
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
What issue are you seeing?
Using Continue in new chat on an earlier turn can create a child task whose history extends past the selected fork point when one of the later turns was steered.
The residual user message can then survive auto-compaction and be answered again, even though it was sent before the fork and should have been removed from the child task.
The two visible symptoms are:
What steps can reproduce the bug?
The code-level reproduction is to create an app-server turn with both an initial user message and a later
turn/steermessage sharing the same durableturn_id, add another turn, and then callthread/rollbackfor the two app-server turns after the target.What is the expected behavior?
The child task should end exactly at the selected fork point. All later app-server turns should be removed, including every initial and steer message belonging to those turns. Auto-compaction must not reintroduce or replay any removed message.
Additional information
The root cause appears to be a counting-unit mismatch in rollback:
thread/rollback.numTurnsas a count of app-server turns after the selected target.turn_id.A focused fix groups consecutive ordinary user-message boundaries with the same non-empty durable
turn_id, while retaining legacy behavior for messages without a turn ID and for inter-agent instruction boundaries:daizw@315c12e
Validation performed on that commit:
just test -p codex-core drop_last_n_user_turns(7/7 passed)just test -p codex-app-server thread_rollback(4/4 passed)just fix -p codex-corejust fix -p codex-app-serverjust fmt