Bug: Mid-goal user steers persist as requirements after /goal clear or new goal (only a new thread clears them)

Open 💬 0 comments Opened Jul 21, 2026 by logicchains

What version of Codex CLI is running?

codex-cli 0.144.6

What subscription do you have?

Pro

Which model were you using?

gpt-5.6-sol

What platform is your computer?

Linux 6.6.87.2-microsoft-standard-WSL2 x86_64 unknown

What terminal emulator and version are you using (if applicable)?

Windows Terminal (WSL)

Codex doctor report

What issue are you seeing?

While a goal is active, if I steer the agent with instructions that are only relevant to a single in-progress task, those instructions keep being treated as lasting requirements on later automatic goal turns. (This is essentially the same issue as https://github.com/openai/codex/issues/27894)

The biggest problem, however (which I don't see an existing issue for): after I clear the goal and set a different goal on the same thread, steers from the previous goal still affect the new one. The only reliable way to clear that “memory” is a full Codex reset / new thread.

Steering from goal A should not persist as requirements for a later goal B.

What steps can reproduce the bug?

  1. Enable goals and start a saved (non-ephemeral) Codex session.
  2. Set a goal, e.g.

/goal Implement feature A end-to-end and verify with tests

  1. While the agent is working on that goal, send a one-off mid-goal steer that is not meant as a permanent objective requirement, e.g.

For now only fix the compile error in foo.rs; ignore the rest of the plan this turn.

  1. Let the turn finish so automatic goal continuation runs again.
  2. Observe that later goal turns still treat that temporary steer as something that must continue to be followed / satisfied.
  3. Run /goal clear.
  4. Set a different goal on the same thread, e.g.

/goal Implement unrelated feature B

  1. Observe that goal B continuations are still constrained or confused by the steer from step 3 (from goal A).
  2. Start a new thread / fully reset Codex, set only goal B, and confirm the stale steer no longer applies.

What is the expected behavior?

• Mid-goal steers should apply to the current goal / current work only.
• When a goal is cleared or replaced, prior goal-scoped steers must not remain as requirements for a new goal.
• The new goal’s continuation should pursue only the new objective (plus any steers given after that new goal was set).
• Users should not need a full session reset just because they gave temporary guidance during a previous goal.

Additional information

Impact

• Temporary “just do X this turn” guidance becomes sticky for the rest of the thread.
• /goal clear + new goal does not restore a clean requirement surface for the new objective.
• Long multi-goal sessions on one thread become increasingly confused after any mid-goal steering.
• Forces abandoning the thread to change goals safely.

Root cause (from open-source code)

  1. _Steers are ordinary thread history, not goal-scoped_

Mid-goal user input is accepted via same-turn steering (Session::steer_input) and recorded as a normal user message (record_user_prompt_and_emit_turn_item → conversation history).
User message / history items have no goal_id, no “ephemeral steer” flag, and no “valid while goal X is active” metadata. Optional passthrough is only things like turn_id. Once recorded, the system cannot tell “this was temporary guidance for goal A.”

  1. _Goal clear/replace only touch goal DB state, not history_

Active goals live in thread_goals (objective, status, usage). /goal clear deletes that row and clears in-memory active-goal accounting. It does not:
• remove prior user steers from history
• mark them superseded
• inject a goal-boundary / supersession context item
Setting a new goal only writes a new objective on the same thread.

  1. _Goal continuation re-elevates historical “user instructions”_

On idle with an active goal, the goal extension injects a hidden continuation prompt (continue_if_idle → continuation_steering_item → try_start_turn_if_idle), from goals/continuation.md.
That template embeds only the current <objective>, but also tells the model to use previous conversation context and, in the completion audit, to derive requirements from the objective and user instructions.
So every automatic goal turn re-promotes earlier user messages—including steers from a previous goal—as open requirements for the current goal.

  1. _Why only full reset works_

A new thread has empty history, i.e. no old steers, which means no bleed-through. Goal clear/set on the same thread leaves history intact, so the bug remains.

View original on GitHub ↗