Compaction resume incorrectly presents stale latest user prompt as current active instruction

Open 💬 3 comments Opened Jun 12, 2026 by winnal
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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:

  1. User sends prompt A.
  2. Codex performs substantial work after prompt A.
  3. Context compacts.
  4. The resumed model sees prompt A as the latest/current user instruction.
  5. 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.

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 2 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #27588

Powered by Codex Action

JulianAdamek · 1 month ago

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:

  1. I submit user prompt A.
  2. Codex processes prompt A and completes that turn in full.
  3. I then submit prompt B, which establishes a longer-running goal.
  4. Codex performs work toward the goal established by prompt B.
  5. Automatic context compaction occurs while that goal is in progress.
  6. After compaction, Codex incorrectly returns to prompt A—the turn immediately before the goal-setting prompt—and processes it a second time.
  7. Once that duplicated turn is complete, Codex resumes its work toward the current goal from prompt B.

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:

  • the current ongoing goal and enough state to resume it; and
  • an incorrect indication that the preceding historical user turn is still pending.

This produces a duplicated response or duplicated work for the previous turn, followed by continuation of the actual current goal.

Environment:

  • Client: Codex VS Code extension
  • Extension version: 26.721.41059
  • VS Code version: 1.130.0
  • Model: GPT-5.6 Sol Ultra
  • OS: Ubuntu 24.04.4 LTS
  • Frequency: reproduces after automatic compactions when 'pursuing goal' is active

I can provide a sanitized transcript showing the turn ordering and the compaction boundary.

luvs01 · 23 days ago

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:

  • Each admitted user submission gets a durable UUIDv7 item identity; the owning thread and active turn are persisted with the legacy projection.
  • A request ledger reconstructs only from matching canonical response items plus lifecycle evidence, and fails closed on duplicate, missing, or conflicting IDs; terminal turns; rollback or abort; mixed history modes; and unknown owners.
  • Local compaction preserves the exact tracked request ID only when its content survives deterministically, and persists an explicit summary item ID rather than recognizing summaries by text.
  • Continuation prompts receive a bounded structural marker immediately before the exact active request part. The marker contains no request text and is never sent to the compaction request.
  • Legacy and paginated resume paths preserve the same canonical user item ID.

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?