Skip to content

feat(rescue): carry the Claude session into a Codex rescue with --session-context - #560

Open
r0han01 wants to merge 1 commit into
openai:mainfrom
r0han01:feat/rescue-session-context
Open

feat(rescue): carry the Claude session into a Codex rescue with --session-context#560
r0han01 wants to merge 1 commit into
openai:mainfrom
r0han01:feat/rescue-session-context

Conversation

@r0han01

@r0han01 r0han01 commented Jul 26, 2026

Copy link
Copy Markdown

Summary

A rescue currently receives only the task text the user typed. Codex reads the same repository, but it has no access to what the user and Claude already discussed, ruled out, or tried and abandoned — so it can spend a run rediscovering a dead end the session had already closed.

/codex:transfer solves the context problem by moving the user into Codex entirely. This PR covers the other half: staying in Claude Code and handing Codex a single task that already carries the session's background.

Add an opt-in --session-context flag to task, surfaced as /codex:rescue --session-context:

/codex:rescue --session-context fix the failing login test
/codex:rescue --session-context                  # task text optional; continues the thread of work
/codex:rescue --session-context --session-context-mode full --background investigate the regression

Design

The brief is assembled in the companion script, not by Claude. It reads the transcript that the existing SessionStart hook already records in CODEX_COMPANION_TRANSCRIPT_PATH, reusing resolveClaudeSessionPath from claude-session-transfer.mjs so the ~/.claude/projects containment check still applies. Claude never has to read or summarize the conversation, so the delegation stays cheap on the Claude side — which is much of the point of delegating.

Assembly mirrors how Claude Code survives its own compaction. The summary written by /compact carries the earlier session, and the turns recorded after the compact boundary close the gap. Running /compact before a rescue therefore produces a denser and cheaper brief than a raw transcript, and frees the user's own context at the same time.

Bounded by construction. Tool calls, thinking blocks, subagent sidechains, meta entries, and injected <system-reminder> blocks are excluded. --session-turns (default 30) and --session-max-chars (default 48 KiB) cap the result; oldest turns drop first and the brief states how many were omitted. The branch and uncommitted file list are attached but diffs are not, so a large working tree cannot balloon the prompt — following the intent of bc8fa66.

Framed as third-party background. The brief opens by telling Codex this is context from a different agent, not its own memory, and that the repository wins if the two disagree. Without that framing Codex reads "I fixed the token refresh" as its own completed work.

--resume narrows auto to recent, since a resumed thread already holds the earlier brief.

Why not --context

--context was the natural name, but #293 proposes --context <text> for pasting extra free-form context into a rescue prompt. That is a different feature and the two are complementary, so this uses --session-context to avoid the collision. Happy to rename if maintainers prefer a different spelling.

--session-context is boolean and --session-context-mode takes the value, so --session-context fix the login cannot misparse the task text as a mode.

Modes

Flag Attaches
--session-context compact summary plus the turns after it (auto)
--session-context-mode summary compact summary only
--session-context-mode recent recent turns only
--session-context-mode full every turn, ignoring the turn cap
--session-context-mode none nothing; same as omitting the flag

Test plan

  • 19 new tests in tests/claude-context-brief.test.mjs covering mode selection, summary/boundary splitting, sidechain and tool-block exclusion, system-reminder stripping, size-based truncation, turn caps, git and non-git working directories, stale-summary detection, partial trailing JSONL lines, path containment refusal, and flag parsing.
  • npm test — 110 tests, 101 pass. The 9 failures (5 setup, 3 status/result, 1 resolveStateDir) reproduce identically on unmodified main in the same environment and are unrelated to this change.
  • npm run build passes.
  • Manual: ran task --session-context against a live Claude Code session with gpt-5.4-mini and confirmed Codex answered questions about the branch, changed files, and prior decisions that appear only in the brief.
  • Manual: confirmed --session-context fix the login keeps the full task text and does not consume fix as a mode.

Note

claude-session-transfer.mjs now resolves the Claude projects directory per call instead of at module load, so transcript path resolution can be tested against a relocated home directory. Behavior is unchanged.

…sion-context

A rescue currently receives only the task text the user typed. Codex reads the
same repository, but it has no access to what the user and Claude already
discussed, ruled out, or tried and abandoned, so it can repeat work the session
already established was a dead end.

Add an opt-in --session-context flag to `task`, surfaced as
`/codex:rescue --session-context`, that attaches the current Claude session as a
handoff brief. The brief is assembled in the companion script from the transcript
the existing SessionStart hook already records, so Claude never has to read or
summarize the conversation itself and the delegation stays cheap on the Claude
side.

The assembly mirrors how Claude Code survives its own compaction: the summary
written by /compact carries the earlier session and the turns recorded after the
compact boundary close the gap. Running /compact before a rescue therefore
yields a denser brief than a raw transcript would.

The flag is deliberately not named --context. PR openai#293 proposes --context <text>
for pasting extra free-form context into a rescue prompt. That is a different
feature, and the two are complementary rather than competing, so this avoids the
name collision.

Details:

- --session-context is boolean; --session-context-mode selects auto (default),
  summary, recent, full, or none, and implies the flag
- --session-turns and --session-max-chars bound the brief; oldest turns are
  dropped first and the brief reports how many were omitted
- tool calls, thinking blocks, subagent sidechains, meta entries, and injected
  system-reminder blocks are excluded
- the branch and uncommitted file list are attached; diffs are not, so large
  working trees cannot balloon the prompt
- the brief is framed as third-party background and tells Codex to verify it
  against the repository rather than trust it
- with --resume, auto narrows to recent, since the resumed thread already holds
  the earlier brief
- a compact summary older than an hour is flagged so the user can re-run /compact
- the task text becomes optional when --session-context is present

Resolve the Claude projects directory per call rather than at module load so
transcript path resolution can be exercised against a relocated home directory.
@r0han01
r0han01 requested a review from a team July 26, 2026 17:23

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 30e78dff29

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

for (let index = bounded.length - 1; index >= 0; index -= 1) {
const turn = bounded[index];
const cost = turn.text.length + 32;
if (selected.length > 0 && usedChars + cost > maxChars) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enforce the character cap for a single oversized turn

When the newest usable transcript turn alone exceeds maxChars—for example, after the user pastes a very large log—selected is still empty, so this condition is skipped and the entire turn is attached. A 1 MB latest turn therefore produces roughly a 1 MB prompt despite the default 48 KiB cap, potentially exceeding model limits or unexpectedly increasing cost; truncate the turn or omit it while keeping the final brief within the configured limit.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant