Context compaction loses operational continuity in long Codex tasks; preserve the last 5 operational steps verbatim
What version of the Codex App are you using (From “About Codex” dialog)?
Version 26.616.51431
What subscription do you have?
PRO
What platform is your computer?
Microsoft Windows NT 10.0.26220.0 x64
What issue are you seeing?
Automatic context compaction in Codex Desktop can lose important task continuity during long-running, complex development sessions.
I am not seeing a normal explicit error message. The issue is a behavioral/task-continuity failure after automatic context compaction.
After compaction, Codex may no longer reliably remember the current operational thread of the task. It can lose or distort subtle agreements, recent decisions, current constraints, rejected approaches, touched files/modules, and the exact next step it was about to take. In practice, the agent sometimes appears to restart reasoning from scratch or continues from an oversimplified summary instead of the actual recent task state.
This is especially damaging in complex projects where the agent must preserve:
- project-specific rules / AGENTS.md instructions,
- current task goal and acceptance criteria,
- recent user corrections,
- what has already been investigated,
- which approach was rejected,
- what files/modules were touched,
- what should not be touched,
- the agreed verification path.
The user impact is severe: I have to constantly supervise Codex after context compaction, because it may confidently continue while missing critical nuance from the pre-compaction work. This makes long-running Codex sessions unreliable for real development work.
Suggested core fix/request:
Please preserve the last 5 operational steps verbatim or structurally losslessly during context compaction.
By "operational step", I mean the recent concrete task sequence, such as:
- the latest user instruction and constraints,
- the assistant's latest intended next action,
- recent tool calls and important outputs,
- files/modules touched or inspected,
- decisions made and alternatives rejected,
- current verification target,
- unresolved blockers or risks.
The older conversation history can be summarized aggressively, but the immediately active operational tail should not be reduced to a vague summary.
What steps can reproduce the bug?
This is not a one-line deterministic code bug, but it is reproducible as a long-session workflow pattern.
Environment:
- Product: Codex Desktop / Codex app
- Platform: Windows
- OS: Microsoft Windows NT 10.0.26220.0 x64
- Model: GPT-5.5 Codex family
- Subscription: [Plus / Pro / other]
Reproduction pattern:
- Open Codex Desktop in a real repository with non-trivial project rules, for example an AGENTS.md file with workflow constraints.
- Start a long-running development task that requires multiple steps, such as debugging a runtime/UI issue, tracing module ownership, editing several files, and verifying with a build or runtime signal.
- Give Codex several important constraints during the task, for example:
- do not make local symptom patches before tracing the real runtime/data path,
- preserve existing user changes,
- verify through a specific build/runtime path,
- do not touch a certain subsystem,
- continue from the already investigated module boundaries.
- Let the session run long enough for automatic context compaction to occur.
- After compaction, ask Codex to continue the same task.
- Observe that Codex may:
- restart reasoning as if the task is new,
- repeat already completed investigation,
- forget a recent user correction,
- choose an approach that was already rejected,
- lose track of touched files or verification requirements,
- continue confidently from a simplified or distorted state.
A minimal synthetic version of the workflow:
Prompt 1:
We are working in this repo. First inspect the module/data/runtime path before editing. Do not make local symptom fixes. Verification must be via [specific command/runtime path]. Keep the current AGENTS.md rules.
Prompt 2:
After investigation, remember that approach A was rejected because [reason]. The correct layer seems to be module B. Do not touch module C.
Prompt 3:
Continue with the implementation and verification.
Then continue the session until automatic context compaction happens.
Prompt after compaction:
Continue from where you left off.
Expected: Codex continues from the exact operational state before compaction.
Actual: Codex may reconstruct the task from a high-level summary, lose nuance, and restart or drift.
I cannot safely provide private project code/logs publicly, but the issue is not tied to one repository. It is a compaction/task-continuity problem that appears during long tool-heavy sessions.
What is the expected behavior?
After automatic context compaction, Codex should preserve enough recent operational state to safely continue the current task without restarting, drifting, or violating recently agreed constraints.
Expected behavior:
- Codex should keep following AGENTS.md / project rules / custom instructions.
- Codex should remember the current task goal and acceptance criteria.
- Codex should preserve recent user corrections and subtle agreements.
- Codex should know what work was already completed.
- Codex should know what files/modules were inspected or changed.
- Codex should remember rejected approaches and why they were rejected.
- Codex should preserve the current verification target.
- Codex should not restart reasoning from scratch unless explicitly asked.
Specific requested improvement:
Please preserve the last 5 operational steps verbatim or structurally losslessly during compaction, separate from the broader summarized history.
A possible compacted-context structure could be:
- Compressed historical summary
- older context summarized aggressively,
- durable project rules,
- long-lived decisions and constraints.
- Lossless recent operational tail
- last 5 operational steps preserved as-is or as structured events,
- latest user instruction,
- latest assistant intent,
- recent tool/action sequence,
- important outputs,
- touched files/modules,
- current blocker/risk,
- current verification path.
This would make compaction a task-continuity mechanism instead of only a summarization mechanism.
Additional information
This is not just a UX inconvenience. It affects project safety and trust.
When Codex loses continuity after compaction, the user may end up with:
- broken systems,
- duplicated work,
- incorrect implementations,
- repeated investigation,
- violated project constraints,
- unnecessary token/time usage,
- a need to constantly supervise the agent.
The current workaround is often to ask Codex to create scratchpads/checklists/handoff notes, but that creates a second problem:
- extra notes consume more context,
- compaction happens more frequently,
- the agent may forget to read the notes anyway,
- the session becomes about maintaining process artifacts instead of solving the task.
So this should ideally be addressed in Codex's compaction/runtime behavior, not pushed entirely onto users as manual note-taking.
Related issues that seem relevant:
- #25792
- #11444
- #14347
- #5957
- #23263
Suggested labels:
- bug
- context
- model-behavior
- app
19 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I reviewed the suggested potential duplicates.
I agree this issue is related to #29354 and #28892, but I do not think it is an exact duplicate.
#29354 describes a repeated pre-write loop where Codex rereads the same files after compaction and never reaches implementation. #28892 focuses on steered follow-ups / mid-turn user input around compaction.
This issue is asking for a more general compaction behavior change: preserve the last 5 operational steps verbatim or structurally losslessly, so Codex can continue the active task after compaction without reconstructing it from a vague summary.
So I see this as related, but distinct.
I would like to add a related product-level suggestion based on a long-running Codex workflow where context compaction became a recurring operational risk.
The issue is not only that compaction can lose the last few operational steps. There is also a missing first-party handoff policy for when a thread has become too large or too valuable to keep compressing safely.
A useful behavior would be for Codex to distinguish between two cases:
If the current thread clearly belongs to a project, repository, workspace, or long-running workflow, Codex should proactively maintain a durable project handoff artifact before risky compaction or before switching to a new phase.
That handoff should include, at minimum:
The goal is that a new Codex thread can resume from project-local state instead of depending on a fragile compressed transcript.
If the current thread is not attached to a durable project or workspace, and the conversation has become too large to keep compressing productively, Codex should explicitly prompt the user to archive the current thread and start a new one.
In that case, Codex should provide a copyable continuation summary before the archive/new-thread handoff, rather than silently continuing until another compaction loses nuance.
Important distinction:
Archive should not be treated as memory. A hidden or archived thread is not a reliable continuity mechanism by itself. If information must be reused later, Codex should first help persist it as a project handoff, workspace file, durable note, or explicit continuation summary.
This would complement the requested “lossless recent operational tail” from the main issue. The recent operational tail protects immediate continuity inside compaction; the handoff policy protects the user when a thread should stop being compressed and should instead transition to a fresh thread safely.
Expected user-facing behavior:
This would make long-running Codex work much safer for research, development, debugging, documentation, and other workflows where losing subtle decisions can invalidate hours of work.
I think this is a useful complementary direction, but I would distinguish it from the core request in this issue.
The "lossless recent operational tail" should be part of the compaction mechanism itself. It protects immediate continuity inside the same active thread: the agent should not lose the latest user instruction, recent tool/action sequence, touched files, rejected approaches, current verification target, and next step.
A project/thread handoff policy solves a different layer: what to do when the thread has become too large, too valuable, or too risky to keep compressing safely.
I would support a handoff mechanism as an escalation path, but not as a replacement for improving compaction.
The risk is that, if implemented as another agent-written scratchpad or summary, it could recreate the same problem in a different form:
So I think the product behavior should be:
In short:
I would not want the handoff mechanism to become "another summary the agent writes and then forgets." It needs to be first-party, bounded, and tied to project/workspace state.
Thanks, Daryll. I really appreciate the careful and professional way you framed this. Your distinction makes sense to me, and it helps separate two things that I had been thinking about together but that probably should not be implemented as one large change.
Based on your feedback, I think the safest path would be to split this into three PR-sized tracks instead of treating handoff as a replacement for compaction improvement:
PR 1: Preserve the recent operational tail during compaction
This should be the core fix for this issue.
The idea would be to make compaction preserve a bounded recent operational tail as first-party structured context, ideally derived from the session/tool event log rather than from another model-written scratchpad.
That tail should preserve, losslessly or near-losslessly:
In other words:
This would keep the active thread coherent immediately after compaction without requiring the user to restate the work or supervise a manual note.
Non-goals for this first PR:
PR 2: Add a bounded first-party project/workspace handoff artifact
This would be a separate escalation path for the case you described: when a thread has become too large, too valuable, or too risky to keep compressing safely.
I agree this should not be another ever-growing agent-written summary. It should be first-party, bounded, structured, and tied to project/workspace state.
It should point to the real sources of truth, for example:
The goal would be safe transition to a new thread or phase, not replacing the active operational tail inside compaction.
PR 3: Project/thread attachment or transition UX
This would be the product-level follow-up related to cases like #24519: when a user starts in a general chat and later realizes the work belongs to a specific project.
This should probably come after the first two pieces, because attaching or moving a thread is much more useful if Codex already has:
So my current understanding is:
Thanks again for taking the time to discuss this so seriously. I appreciate it, and your framing makes the implementation path feel much clearer and safer.
Hi Daryll,
Thanks again for taking the time to think through this so carefully. I really appreciate how seriously and professionally you are engaging with this idea.
Your distinction makes a lot of sense to me. I agree that a handoff mechanism should not be treated as a replacement for improving compaction itself.
Based on your feedback, I split my thinking into three PR-sized tracks and posted that follow-up on the issue:
I think this framing makes the path much safer: fix compaction continuity first, add handoff only as an escalation path, and treat project attachment as a later UX layer rather than mixing everything into one large change.
Thanks again for your thoughtful feedback. It really helped clarify the implementation direction.
原始邮件
发件人:DZRobo @.*>
发件时间:2026年6月22日 14:55
收件人:openai/codex @.*>
抄送:Lee-take @.>, Comment @.>
主题:Re: [openai/codex] Context compaction loses operational continuity in long Codex tasks; preserve the last 5 operational steps verbatim (Issue #29356)
1dZb1 left a comment (openai/codex#29356)
I think this is a useful complementary direction, but I would distinguish it from the core request in this issue.
The "lossless recent operational tail" should be part of the compaction mechanism itself. It protects immediate continuity inside the same active thread: the agent should not lose the latest user instruction, recent tool/action sequence, touched files, rejected approaches, current verification target, and next step.
A project/thread handoff policy solves a different layer: what to do when the thread has become too large, too valuable, or too risky to keep compressing safely.
I would support a handoff mechanism as an escalation path, but not as a replacement for improving compaction.
The risk is that, if implemented as another agent-written scratchpad or summary, it could recreate the same problem in a different form:
more process artifacts,
more context consumed,
more notes the agent may forget to read,
more user supervision.
So I think the product behavior should be:
Compaction always preserves the recent operational tail losslessly or near-losslessly.
When a thread becomes risky to compress further, Codex can create or update a bounded first-party handoff artifact.
That artifact should be concise, structured, and project-aware, not an ever-growing manual note.
It should point to the real sources of truth: files, diffs, tests, logs, reports, artifacts, and next actions.
It should be used for safe transition to a new thread or phase, not as a substitute for preserving the active operational tail.
In short:
Recent operational tail = protects continuity inside compaction.
Handoff policy = protects continuity when the thread should stop being compressed and transition safely.
I would not want the handoff mechanism to become "another summary the agent writes and then forgets." It needs to be first-party, bounded, and tied to project/workspace state.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you commented.
This issue maps closely to a bounded operational checkpoint profile we have now published from the Liminal side.
Artifacts:
The profile separates three mechanisms:
A summary compresses older context. The recent tail preserves up to five structured operational steps. The checkpoint binds that tail to repository identity, Git HEAD, dirty-worktree state, constraints, rejected approaches, touched resources, verification state, and the exact next action.
The main additional boundaries are:
authority: context_only; prior tool approvals do not silently survive compaction or handoff.The fixture covers same-workspace continuation, duplicate resume, changed workspace state, broken lineage, a vague-summary regression, loss of rejected approaches, unverified completion, and invalid authorization carryover.
Core principle:
Would a bounded, workspace-bound checkpoint like this be useful as a conformance target alongside the proposed lossless recent operational tail?
Yes, I think this would be useful as a conformance target alongside the proposed lossless recent operational tail.
The distinction between:
is exactly the boundary I want to preserve.
The core issue remains that compaction itself should not collapse the active task into a vague summary. The recent operational tail needs to survive compaction losslessly or near-losslessly.
A workspace-bound checkpoint seems useful as an additional validation layer: it can decide whether continuation is still safe by checking repository identity, Git HEAD, dirty state, rejected approaches, touched resources, verification state, and next action.
The most important guardrail for me is that this should not become another manual scratchpad system. If the checkpoint is just another agent-written summary that consumes context and may be forgotten, it recreates the same failure mode.
So I would support this if it is first-party, bounded, generated from actual session/tool/workspace state, and used as a conformance target for safe resume/handoff.
In short:
I especially like the invariants around rejected approaches, changed Git HEAD / dirty state, verification evidence, and
authority: context_only.Thanks, safal207. Yes, I think a bounded, workspace-bound checkpoint like this would be useful as a conformance target alongside the lossless recent operational tail.
The part I find especially useful is that it makes the boundary testable rather than only conceptual:
I would map it to the earlier PR-sized tracks this way:
So I would not see the checkpoint as a replacement for the recent operational tail. I would see it as the stricter resumability contract around it: the tail preserves what just happened, while the checkpoint determines whether it is still valid and safe to continue from that point.
The guardrails I especially like are:
authority: context_only, so prior approvals do not silently survive compaction or handoff.Those cases would make a very useful conformance fixture because they directly test the failure modes this issue is about: vague-summary regression, lost rejected approaches, unsafe resume after workspace drift, unverified completion, duplicate resume, and invalid authorization carryover.
So my answer is yes: this kind of checkpoint seems like a strong conformance target, as long as it remains first-party, bounded, workspace-bound, and derived from actual session/tool/workspace state rather than becoming another manual scratchpad the agent may forget to read.
Thanks — I agree with that separation.
A clean conformance target would treat these as three different first-party artifacts with different authority and lifetimes:
The checkpoint should not replace the tail and should not carry execution authority. I would keep its authority explicitly
context_only, so approvals or permissions from before compaction cannot silently survive resume.A minimal checkpoint could bind:
Resume behavior would then be deterministic:
The conformance fixtures I would prioritize are:
That keeps the distinction testable:
historical summary != recent operational tail != resumable checkpointThe tail preserves what just happened. The checkpoint decides whether that preserved state is still valid and safe to continue from.
This issue maps very closely to the recovered-evidence and continuation work in LS.
The central distinction may be:
conversation summary
≠ operational continuation state
A compacted summary may preserve the topic, but safe continuation requires a lossless or typed operational tail containing:
We recently added a small vendor-neutral envelope that separates:
knowledge recovered
→ valid for this trajectory and continuation
→ enforcement decision
Reference:
https://github.com/safal207/LS/pull/651
A possible compaction-tail record could look like:
{
"schema_version": "operational-tail/v0.1",
"trajectory_id": "repo-task-trajectory",
"source_continuation_id": "thread-before-compact",
"target_continuation_id": "thread-after-compact",
"active_goal": "Fix the runtime issue without touching module C",
"active_constraints": [
{
"statement": "Do not apply a local symptom patch before tracing the real data path",
"status": "ACTIVE"
}
],
"rejected_approaches": [
{
"approach": "Patch module A directly",
"reason": "The failure originates in module B"
}
],
"touched_files": [
{
"path": "src/module_b.py",
"last_operation": "EDIT",
"event_ref": "tool-event-184"
}
],
"current_blockers": [
"runtime verification has not yet been completed"
],
"required_next_action": "run the agreed verification command",
"verification_target": "integration test path",
"status": "ACTIVE"
}
The important invariant would be:
«Compaction must not convert active constraints, unresolved blockers, or recent file mutations into vague prose that no longer affects control flow.»
A second useful invariant:
«Resume should preserve the same task trajectory while assigning a new continuation identity.»
That allows the system to distinguish:
same task, resumed after compaction
≠ new unrelated task
A deterministic conformance fixture could test:
This could complement the requested “last 5 operational steps” by making the tail machine-checkable rather than only verbatim text.
Would a small "OperationalTailEnvelope" fixture be useful for testing compaction continuity across CLI, Desktop, and IDE surfaces?
Thanks, this distinction is exactly the core of the issue:
conversation summary != operational continuation stateA summary can preserve what the conversation was about, but safe continuation needs state that still affects the agent's next action.
I agree that a small typed
OperationalTailEnvelopecould be a useful conformance target, especially if it remains first-party and vendor-neutral rather than tied to any external memory system.For Codex, I would see the minimal product requirement as:
The invariant you wrote captures the failure mode well:
I also strongly agree with the conformance fixture idea. The most important tests for me would be:
That would complement the “last 5 operational steps” request by turning it into something testable across Desktop, CLI, and IDE surfaces.
Thanks — this is exactly the boundary I was trying to isolate.
I agree the useful target is a small first-party, vendor-neutral "OperationalTailEnvelope", not an external memory dependency.
The minimal fixture set should prove that after compaction or resume:
The core invariant is:
conversation continuity
!= operational control-flow continuity
I’ll keep the proposed envelope focused on active state that can still change the next action, rather than preserving more narrative context.
This issue's "last 5 operational steps" framing matches the direction I ended up trying as a user-space stopgap, though I agree the real fix should be native.
I put together a small Codex hook package here:
https://github.com/Sakiyary/codex-compact-continuity
It does not preserve the operational tail inside Codex's compacted context. Instead, it externalizes a bounded handoff into the project directory and then forces the resumed agent to read it before continuing:
PreCompactwriteslatest.md,latest.json, snapshots, and a small cumulative rollup;PostCompactmarks the project as needing restore;PreToolUseblocks writes/tests/git/service starts/other normal tools while required reads are still missing;PostToolUseobserves read-only restore tools and clears the gate only after the required handoff/state files have been read.So it is weaker than what you are requesting here: it is not lossless recent tool history, not a native compact tail, and not a structured first-party continuation envelope. It is closer to a lightweight "make the post-compact agent stop and reread the active handoff before doing more work" mechanism.
I am sharing it because it may help people who need a temporary workaround today, especially for long local coding sessions. I would still strongly prefer Codex to have a native structured operational tail / continuation state, because that could preserve recent constraints, touched files, rejected approaches, pending verification, and provenance more reliably than a hook can.
Also, practical caveat: the generated continuity files can contain task/session context and command summaries, so the repo documents adding
.codex-compact-continuity/to.gitignoreand cleaning it up when no longer needed.@Sakiyary this is a useful stopgap, and the boundary you drew is important: it enforces a restore obligation, but it does not turn the handoff into authoritative execution history.
The strongest part of the design is the gate:
PostCompact -> restore required -> normal tools blocked -> required state read -> execution resumesThat is materially safer than merely writing a scratchpad and hoping the resumed agent remembers to consult it.
I would make the handoff envelope carry a few explicit fields so the workaround remains inspectable:
schema_version;The resumed agent should still treat that envelope as continuity evidence, not as authority to claim that an action definitely occurred. Claims such as “this patch was applied” should resolve against git state, diffs, tool logs, or another durable source of truth.
So the separation is:
Thanks for documenting the privacy caveat as well. Project-local continuity files are useful, but they should be local state by default, not accidental repository artifacts.
Thanks, this is a helpful framing. I agree with the separation you described: this hook package can provide a practical restore gate today, while the handoff should remain continuity evidence rather than authoritative execution history. Claims about applied patches, passing tests, or completed commands should still be verified against git state, file contents, tool logs, or fresh command output.
I updated the package in that direction: the handoff now carries a structured envelope with schema version, source project/session, creation reason, bounded recent tail, referenced files/digests where available, pending verification, restore-required files, suggested reads, and a handoff digest.
One small clarification on "local state": I intentionally keep the continuity files project-local and visible, rather than hidden in a global directory, because users should be able to inspect and remove what the tool stores. The package writes a nested
.gitignore, and the README strongly recommends adding the continuity directory to the project.gitignoreas well.We converted the continuity discussion into a vendor-neutral, executable RFC rather than another scratchpad proposal:
RFC-001 — Verifiable Continuation Envelope
https://github.com/safal207/pythiaLabs/blob/main/standards/agent-continuity/RFC-001-VERIFIABLE-CONTINUATION-ENVELOPE.md
Machine-readable contracts:
The key implementation split is:
RESUMABLE.This preserves the issue's requested recent operational tail while avoiding two unsafe shortcuts:
The implementation is transport-neutral, so Codex could store the envelope natively inside its compaction/runtime layer rather than requiring project files or user-maintained notes.
I'd add one more test, aimed at the consumed-not-just-included point.
The fixtures so far mostly check the machinery... envelope present, required reads done, gate blocks until restore. What they can't check is whether the restored state changes the next decision. I've watched an agent re-read a rejection and then propose the rejected thing an hour later anyway, reworded just enough that no pattern-match would catch it. A gate can block "retry A" when A is literally matchable; a re-proposal usually isn't.
So, a behavioral fixture: resume, then put the agent in a spot where the rejected approach looks like the right call. Pass = it declines and points at the rejection. Fail = it re-proposes, however phrased.
In my runs the wording of the stored rejection decided this more than anything about survival. "Rejected: X, because Y. Do not retry X" held. "We went with B after considering X" did nothing.
I want to add a user-facing Codex App workflow case that makes this issue especially difficult to manage.
Observed workflow
A long-running Codex App thread had become reliable at producing art assets after many rounds of user correction. The thread had accumulated both explicit project constraints (MD prerequisites, frozen decisions, visual rules) and implicit working knowledge (accepted/rejected outputs, recurring failure patterns, and the user's preferred production process).
The agent then suddenly drifted from the main direction and failed to follow MD prerequisite requirements. This happened immediately after switching to the 1.5x/Fast setting, although there is not enough evidence to claim that Fast mode caused the context loss. The important point is that the user had no reliable way to know whether the thread had compacted, whether constraints had weakened, or whether the deviation was a temporary model error.
Codex also warns that starting a new thread may lose experience accumulated in the existing thread. This leaves users in a difficult position:
AGENTS.mdis necessary but not sufficient here. It can preserve explicit hard rules, but it does not automatically preserve the full history of accepted/rejected outputs, implicit corrections, current production state, or why previous approaches failed.Requested product behavior
Please add an App-level conversation health and verified continuation workflow:
This is different from simply auto-creating a replacement thread after N compactions (as discussed in #22641). The request is for a visible, user-approved, validated continuation mechanism and an early warning that does not require the user to understand context-window internals.
For non-technical users, deciding when to compact, when to switch threads, and how to write a lossless handoff should be product responsibility, not a manual workflow imposed on the user.