Goal mode replays the last manual steer on later continuation turns

Open 💬 4 comments Opened Jun 12, 2026 by Galuisss

What version of the IDE extension are you using?

26.5602.40724

What subscription do you have?

Pro 5x

Which IDE are you using?

VS Code

What platform is your computer?

Linux 6.18.33.1-microsoft-standard-WSL2 x86_64 x86_64

What issue are you seeing?

During an active /goal, if I manually steer the agent once, that steer can be handled correctly in the current active turn but then become salient again on later goal continuation turns.

The user-visible behavior is that Codex treats the last manual steer entered during the goal as if it were fresh work again, instead of treating it as already consumed by the active turn. This seems especially likely around compaction / resume boundaries, where the preserved history can make the old steer look like the latest real user request.

I originally framed this as hidden goal continuation context being persisted and replayed. After looking through #21291, #19910, #22045, and #22174, I think the broader issue is that manual steer input during an active goal lacks explicit consumed / turn-scoped lifecycle semantics, while goal continuation context also needs clear transient / reattachment semantics.

What steps can reproduce the bug?

  1. Start an active /goal.
  2. While the goal is running, manually steer the active turn with a short instruction.
  3. Let Codex handle that steer.
  4. Allow the goal to continue across later turns and/or compaction.
  5. Observe that the same manual steer can become salient again and be treated as fresh work.

A related core-level repro is to simulate resumed / compacted history containing a normal user steer plus goal continuation context. If fresh goal context is dropped or not reattached correctly, the older real user steer can remain the last preserved user message and regain salience as if it were the current request.

What is the expected behavior?

Manual steer input entered during an active goal should be visible to the model for the active turn, but once handled, it should not keep dominating later goal continuation turns as the latest real user request.

Goal continuation context should be regenerated or reattached from the persisted ThreadGoal at goal continuation / compaction boundaries. Hidden runtime context should not become stale durable replay history, but the active goal should still remain available to the model when continuation resumes.

Additional information

This seems closely related to #21291 and #19910, especially the #21291 failure mode where the last manual steer entered during an active goal becomes salient again after compaction and is treated as fresh work.

My reading is that #22045 improved one part of this by moving goal continuation / budget-limit steering from hidden developer context to hidden user context. However, the review discussion for that PR noted that hidden GoalContext could still be dropped by collect_user_messages() during compaction, leaving an older ordinary user steer as the last preserved user message. The follow-up discussion also acknowledged that compaction would need additional work.

That follow-up appears to have been #22174, which explicitly targeted the #21291 failure mode by preserving goal context during compaction, but it was closed as an unmerged draft. As a result, although #21291 and #19910 are now closed, this behavior appears not to be fully addressed: around goal continuation / compaction boundaries, the model can fall back to an older ordinary user message or manual steer and treat it as fresh work.

This suggests two complementary areas to check:

  1. Goal continuation context should be generated fresh from the persisted ThreadGoal at goal continuation / compaction boundaries, rather than relying on stale hidden context persisted in replay history.
  1. Manual steer input entered during an active goal should have an explicit consumed / turn-scoped lifecycle, so once it has been handled in the active turn, it does not continue to dominate later goal continuation turns as the latest real user request.

These directions seem compatible with the issue described here: consumed manual steers should not dominate later goal turns, while hidden goal runtime context should have a clear transient / reattachment lifecycle instead of being relied on as stale durable replay history.

I locally explored a small patch direction that cleans up stale hidden goal internal context from replay history. I think that direction is compatible with the desired architecture, but it is not sufficient by itself: the user-visible stale-steer behavior also needs explicit consumed / turn-scoped semantics for manual steer input.

View original on GitHub ↗

4 Comments

Jc-Cloete · 1 month ago

Adding corroborating macOS evidence and a current-source check. I initially opened #32627, but after following the issue cluster I agree this older report is the right canonical thread. I will close #32627 in favor of this one.

The important new point from my local traces is that an active /goal is not required. Goal continuation appears to amplify the defect, but I found the same handled-steer replay during an ordinary active task.

Redacted trace from Codex Desktop:

| Offset | Event |
|---:|---|
| T+0s | User steers an active task with an integration, verification, and publish instruction. |
| T+15s | Assistant acknowledges the steer and begins that work. |
| T+45s | context_compacted |
| T+50s | With no new user message, the assistant again announces the same integration, verification, and publish plan and restarts with repository checks. |

The two assistant updates have cosine similarity 0.605. A second manually verified trace had the same shape for a request to set date defaults: acknowledgement, compaction 24 seconds later, then a second acknowledgement with no intervening user input. Similarity was 0.516.

Corpus check:

  • 3,128 local rollout files from 2026
  • 264 rollout files containing context_compacted
  • 82 unique root tasks with an active-task steer before a later compaction
  • zero JSON parse failures

I used similarity only to rank candidates, then manually checked event order. Prompt text, repository names, paths, and thread IDs are withheld.

Current source at 9e552e9 still has the history shape described in this issue:

The issue history also explains why the earlier fix did not close the whole failure mode:

  • #21291 reported the same behavior and was closed after #22045 changed goal continuation from developer context to hidden user context.
  • A review on #22045 said the compaction problem still needed to be solved.
  • #22174 then targeted the exact case where goal context is lost and an older steer regains salience, but that draft was closed automatically without merging.
  • #29811, #30859, and #31099 provide later reproductions of this exact goal/steer/compaction behavior.
  • #28874 describes the corresponding non-goal symptom. #28925 and #31351 show the repeated-compaction loop this can grow into.

#31336 and #8648 report the broader symptom of arbitrary old prompts becoming active again. They may share the same task-ownership/history family, but those reports do not establish compaction or steer retention, so I would not claim one root cause for all of them yet. #30267 looks like stale UI pending-input restoration, and #30767 focuses on stale final-response ownership. Those may be adjacent defects rather than duplicates.

The strongest shared mechanism for the compaction subset is:

  1. A steer is handled.
  2. It is persisted as an ordinary user message without an explicit consumed/closed semantic.
  3. A later compaction retains that recent user message.
  4. The replacement history does not reliably identify the latest completed checkpoint or mark the steer as historical.
  5. The steer becomes actionable again.

A focused regression should process a steer, perform a second compaction, and verify that the next model-visible state distinguishes the completed steer from the current task checkpoint. Merely asserting that the steer appears exactly once in the first post-compaction request does not cover this failure.

joshp123 · 1 month ago

codex generated analysis:

This still reproduces in the Codex App with GPT-5.6 Sol Max.

Feedback ID: 019f48b9-86a4-74e3-abda-5a45bb45f6d2
Second affected task: 019f48b9-7824-7d72-a756-1e0034bd9601
App: 26.707.62119 (5211)
CLI: 0.144.1
Platform: macOS

In the first task, the affected /goal remained one inProgress turn across several later user messages. It underwent three context compactions and emitted a final_answer without the turn completing. After compaction, a completed earlier manual steer was repeatedly treated as the current request, even after newer steering messages.

The second task shows the same lifecycle failure independently. A user prompt was answered once. A later automatic goal continuation crossed contextCompaction and answered that consumed prompt again. The next automatic continuation repeated it once more without a new user message.

This looks like goal/turn lifecycle state being restored incorrectly during compaction, rather than a model-attention failure: a consumed steer regains actionable status while the current goal checkpoint and consumed-steer state do not.

aizuon · 1 month ago

Adding another independently observed reproduction, plus a source-level trace against current main (2e4f55608b4ad26d9c48ea45a6fcd20bfd5e9fe8). This is seriously workflow-breaking in long-running tasks.

Observed sequence in Codex Desktop:

  1. A steering message is delivered during an active turn.
  2. Codex acknowledges and handles the steer, then continues making further progress.
  3. Automatic context compaction occurs.
  4. With no new user message, the post-compaction continuation treats the already-handled steer as fresh input and begins addressing it again.
  5. The same behavior can repeat after later compactions.

This is not merely vague task drift: an already-consumed user instruction is promoted back into actionable state after compaction, despite intervening work and no new user submission.

Current source appears to preserve exactly the history shape that can cause this:

  • steer_input queues the steer as ordinary TurnInput::UserInput.
  • record_pending_input persists it through the ordinary user-prompt path. There is no persisted source=steer, scope, or consumed/handled state; message metadata only carries a turn id.
  • Remote compaction v2 deliberately retains recent real user messages verbatim under a 64k-token budget, filters assistant/tool items from that verbatim retained portion, and then appends the opaque compaction output.
  • should_keep_compacted_history_item drops contextual user messages while retaining real user messages. This can remove fresh hidden goal-continuation context while preserving the older completed steer.

The resulting model-visible shape can effectively be:

[user] exact text of an already-handled steer
[compaction] opaque/lossy account of work performed afterward

That makes the completed steer the most recent exact, explicit user instruction, while proof that it was handled exists only in compressed state. On every subsequent compaction it can regain the same salience, creating a repetition/context-consumption feedback loop.

There also appears to be a regression-test gap. The tests around pending_input verify the first compaction/steer handoff, but not the failing lifecycle:

steer delivered -> steer handled -> more work -> second compaction

A regression should cover that sequence and assert that the next request distinguishes a completed steer from the current task checkpoint. Ideally a steer should have a durable turn-scoped lifecycle (queued / handling / consumed) and a consumed steer should not be retained as an indistinguishable actionable user message. Goal continuation should also be regenerated from current goal state after compaction rather than being dropped.

Related reports contributors may want to consolidate/check: #27731, #28874, #29811, #30859, #31099, and the corroborating duplicate #32627. The older exact report #21291 was closed, but its described failure still matches. PR #22174 explicitly attempted to prevent older real steers regaining salience by preserving goal context during compaction; it was approved but auto-closed for inactivity without merging. PR #22045 addressed adjacent goal-context behavior but its review explicitly noted that the compaction part still needed solving.

This behavior can redo file edits, commands, refactors, verification passes, or potentially destructive/external actions. It also forces users to repeatedly interrupt the agent to explain that the message was already handled. Please treat it as a serious state-restoration/idempotency issue rather than ordinary model forgetfulness.

soupslurpr · 29 days ago

I found a workaround for this issue: make sure that the last message is always "Okay", "Proceed", or similar.