Compaction resume incorrectly presents stale latest user prompt as current active instruction
Summary
After context compaction, Codex appears to surface the most recent user prompt as if it were newly submitted, even when that prompt is stale and many actions, tool calls, plan updates, or additional compactions have happened since.
This causes the resumed model to treat old instructions as the current user request, which can derail long-running tasks.
Observed Behavior
In long-running threads:
- User sends prompt A.
- Codex performs substantial work after prompt A.
- Context compacts.
- The resumed model sees prompt A as the latest/current user instruction.
- The model acts as though prompt A was just sent, despite it being historical context.
This can repeat across multiple compactions.
Expected Behavior
After compaction, the resume context should distinguish:
- historical user prompts,
- the actual latest active instruction,
- work completed after that instruction,
- current task state,
- whether a prompt is stale/inherited history or newly submitted.
The model should not infer that the most recent user prompt in the compacted transcript is active unless it is actually the latest post-resume instruction.
Impact
This creates serious failure modes for long-running coding/recovery tasks:
- stale instructions override newer completed work,
- old plans are restarted,
- the assistant repeats or reverses prior steps,
- compaction appears to sever task continuity,
- user has to repeatedly re-explain that the prompt is old.
Suggested Fix
The compacted context should include an explicit boundary marker such as:
The following user prompt is historical and was already acted on.
Do not treat it as newly submitted.
Current active task state is: ...
Latest post-compaction user instruction is: ...
Or preserve a durable active-instruction pointer separate from the raw latest user message.
Repro Pattern
Any long-running Codex thread with repeated compactions and substantial work after the last user prompt can trigger this. The issue is easiest to observe when the old prompt contains strong imperative language, because the resumed model treats it as current.
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I am seeing a related but slightly different compaction-resume bug consistently in the Codex VS Code extension while using GPT-5.6 Sol Ultra.
The reproduction sequence is:
Thus, the agent does not simply restart the current goal-setting prompt. It temporarily replays an earlier turn that had already been fully completed before the current goal was established.
The post-compaction state appears to contain both:
This produces a duplicated response or duplicated work for the previous turn, followed by continuation of the actual current goal.
Environment:
I can provide a sanitized transcript showing the turn ordering and the compaction boundary.
I investigated this as an implementation follow-up and reproduced the failure boundary as a state/identity problem rather than a summary-wording problem.
A candidate patch is now implemented and locally verified around these invariants:
Regression coverage includes terminal-before-late-event, same-turn steers, parent/child collisions on turn IDs, hook-shaped literal user input, multimodal flattening, legacy/paginated cold reconstruction, persisted summary-ID readback, and a mocked Responses flow across function call → automatic compaction → continuation. The relevant scoped suites pass.
One limitation: a Windows aggregate integration binary could not be executed locally because an endpoint/security filter held the generated test image open. A smaller library integration exercises the same request path, but I am not treating the aggregate run as passed.
This appears to be a concrete durable-active-request-pointer implementation of the direction discussed here, with overlap with the intent-boundary concerns in #8648 and the replay/redelivery reports in #27894 and #33819. #36866 looks adjacent but separate: it concerns turn/start returning provisional submission S instead of the actual active turn A.
I have not opened a PR because this repository accepts external code contributions by invitation. If this direction matches the intended ownership model, would a focused PR for the durable request identity and compaction-boundary changes be welcome?