openai / openai/codex

Add a detached effective-context fork for oversized Desktop threads

Open
#38,091 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

app app-server context enhancement performance
Dominant language
Rust
Stars
125k
Forks
19.5k
PR merge metrics
PR metrics pending

Description

What variant of Codex are you using?

Codex App on macOS. The proposed primitive belongs in app-server so the App, CLI, and IDE clients can reuse the same semantics.

What feature would you like to see?

Summary

Add a detached effective-context fork for very long threads.

After a manual or automatic compaction has completed, the user should be able to continue in a new task that inherits the source thread's latest effective model context, but does not inherit or expose the source thread's complete conversation history.

This is a performance and working-set feature, not a request for a new handoff summary or different compaction quality.

Motivation

Very long, tool-heavy Codex App threads can become progressively expensive for the Desktop renderer and app-server to hydrate, parse, serialize, and retain. This can remain a problem after model-context compaction because the persisted/UI-visible transcript is still large even though the model now works from a bounded compacted state.

Existing choices do not provide the desired boundary:

  • A normal fork inherits the conversation history. Paginated reference-backed forks avoid copying the entire parent JSONL, but their logical history still traverses the parent lineage.
  • A new task has a small transcript, but loses the already-computed effective model context.
  • A generated HANDOFF.md or handoff prompt performs another lossy summarization step and is aimed at continuity quality rather than local history hydration cost.

The desired operation is conceptually a shallow/compact fork:

source full transcript
        |
        | latest usable compacted replacement history + surviving suffix
        v
new task with bounded model context and no inherited visible turn history

Proposed semantics

An illustrative app-server request could extend thread/fork with an enum such as:

{
  "method": "thread/fork",
  "params": {
    "threadId": "<source-thread-id>",
    "historyScope": "effectiveContext",
    "excludeTurns": true,
    "deferGoalContinuation": true
  }
}

The exact API name is not important. The important behavior is:

  1. Require the source thread to be idle and use the latest successfully persisted effective model context.
  2. Seed the child with the latest usable Compacted.replacement_history plus the surviving post-compaction suffix needed for the next model request.
  3. Persist that bounded snapshot in the child instead of copying the complete source rollout or retaining a history_base that exposes the parent turns.
  4. Preserve normal fork metadata behavior: forkedFromId, cwd/workspace roots, current configuration and instructions, permissions, environments, and optionally the current Goal.
  5. Leave the source thread unchanged and available for audit.
  6. After switching the App to the child, stop hydrating/subscribing to the source so its renderer/app-server state can be released.
  7. For legacy histories, either migrate to paginated history first or return a clear unsupported result. Do not silently fall back to a full-history copy/read for this mode.

The App could expose this as Continue in compact fork or Continue in a lightweight task after a successful compaction. Automatic rollover is not required for the initial version.

Acceptance criteria

  • The child's first model request receives the same effective conversation state as the source would receive immediately after compaction, apart from intentionally refreshed thread-local context.
  • The child rollout size is proportional to the effective model context, not the full source rollout.
  • thread/turns/list on the child does not traverse or return source turns.
  • Cold resume of the child preserves the same effective context.
  • The source rollout is not rewritten or deleted.
  • Navigating to the child does not require the App to hydrate the source transcript.
Additional information

This appears close to existing app-server building blocks:

Related issues cover different parts of the problem:

  • #25251 reports the Desktop CPU/memory impact of opening a large thread. This proposal adds an explicit escape hatch after successful compaction.
  • #34268 and #35647 cover fork storage amplification. Reference-backed paginated forks address physical duplication, but still retain logical parent history.
  • #36584 proposes a HANDOFF.md workflow motivated by context drift. This proposal transfers the already-effective compacted model state without generating another summary.
  • #22641 proposed an automatic fresh-session handoff prompt. This proposal instead uses normal fork metadata plus the actual effective model context, and is motivated by Desktop/session engineering cost.
  • #30194 covered recovery when compaction fails or cannot reclaim context. This proposal assumes compaction succeeded and detaches the new task from the oversized UI-visible transcript.

The repository accepts external PRs by invitation only. If this direction aligns with the intended thread-storage architecture, would the maintainers consider inviting a focused backend-only PR for the experimental app-server primitive? The Desktop button/navigation could remain an internal follow-up.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with codex-rs/thread-store/src/local/model_context.rs and its load_latest_model_context path, then inspect the existing fork processing in codex-rs/app-server/src/request_processors/thread_processor.rs. Determine how a fork can persist the effective model context without parent-history references. Done means the listed acceptance criteria hold, including bounded child context, no source-turn traversal, preserved source rollout, and cold-resume support.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend-api-design, performance
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.