Add an atomic handoff primitive for token-budget context rollover
Add an atomic handoff primitive for token-budget context rollover
Related to #33255.
The new fallback phase gives the model a final opportunity to preserve state before context rollover. However, the model still has to choose an external persistence mechanism, write the handoff there, call new_context, and recover that state in the next window.
Would you consider making this transition atomic by allowing the model to provide a structured handoff as part of the context-window transition itself?
I implemented a downstream prototype here:
https://github.com/0xdeafbeef/codex/commit/542dea6afedd3b64ecace39731768166b28a0095
The prototype introduces:
checkpoint_stage(
completed_stage,
handoff,
next_stage,
)
The host starts a fresh context window after the tool call and injects the model-authored handoff into the new window alongside the normal world state.
The tool is guarded:
- available only after substantial reclaimable context has accumulated;
- unavailable while descendant agents are active;
- usable only once per context window;
- handoff size is bounded;
- the completed and next stages must be distinct.
The handoff is expected to preserve the active objective, decisions and invariants, changed state, verification status, open risks, active skills, and the next completion criterion.
The main difference from the fallback prompt is reliability: preserving and restoring the handoff becomes one host-controlled operation rather than a model-coordinated sequence involving an external storage mechanism.
The exact tool shape is not important to me. For example, this could instead be expressed as:
new_context(handoff: String)
I mainly wanted to share the working prototype as a concrete design reference.
@bolinfest, does this fit the intended direction of the token-budget/context-window work, or is external persistent storage deliberately required here?
I've played with this using sol ultra as the coordinator, and it has already been running for 50 hours. Compaction triggers once every few hours, and the model keeps a compact context and an action ledger in Markdown files.
It looks much more token-efficient than triggering compaction at the end of the context and hoping it saves the stuff that actually matters.
2 Comments
This is very closely aligned with a pain point I have been hitting in real long-running Codex workflows.
I built a user-land Codex skill for this pattern here:
https://github.com/pplong-15/thread-reincarnation-skill
It does not replace the host-level atomic primitive proposed in this issue, but it addresses the same continuity problem from the workflow side: when a Codex thread becomes overloaded, repeatedly blocked, or starts forgetting P0 rules, the skill creates a compact successor handoff instead of continuing the old context indefinitely.
The handoff preserves:
One important piece is that the successor thread must pass a memory check before continuing. In practice, this helps keep the new thread fast while reducing dangerous forgetting.
So I think this issue is pointing at the right host-level primitive. The skill above is a downstream/user-land version of the same idea, and may be useful as a reference for what structured handoff fields and successor validation should look like in real Codex use.
I think the core primitive proposed here is valuable, but the first-principles reason is narrower than “a fresh thread has more room.”
Repeated compaction is recursive lossy compression. If (S_0) is the full operational state and each compaction is a lossy transform (C), then after several passes the model is effectively continuing from (C^n(S_0)). The most damaging loss is often not the broad objective; it is the execution frontier: completed effects, pending work, the latest correction, rejected paths, evidence, and the exact terminal condition. This is consistent with the reports in #29356 and #34095.
A fresh context helps only if it breaks that recursive-compression chain using a checkpoint with higher fidelity than the latest compacted summary. It cannot recover information that was already discarded. This is why “create a visible replacement thread after N compactions” by itself is not sufficient, and it also explains the metadata/UI concerns raised when #22641 was closed.
I would refine the requested core capability as an atomic verified continuation epoch, preferably within the same user-visible thread by default:
Silent fallback to current defaults should be reported as a mismatch, not described as inheritance.
This complements rather than replaces thread context pins (#26889): pins preserve selected durable facts, while an atomic continuation envelope preserves the current execution frontier and proves restoration.
A minimal API could remain close to the proposal here:
It does not need to create another visible thread. Internally starting a clean context epoch while preserving the same thread identity would obtain the main benefit—stopping recursive summary degradation—without requiring users to manage duplicate conversations.
Suggested acceptance tests:
User-land handoff files, hooks, persisted goals, and context pins can reduce the risk today, but they cannot make persistence + restoration + context transition atomic. That is the part that appears to justify a core runtime primitive.