Skip to content

fix: keep rescue Bash attached to Codex - #738

Open
fscfede-beep wants to merge 2 commits into
openai:mainfrom
fscfede-beep:fix/rescue-foreground-bash-432
Open

fix: keep rescue Bash attached to Codex#738
fscfede-beep wants to merge 2 commits into
openai:mainfrom
fscfede-beep:fix/rescue-foreground-bash-432

Conversation

@fscfede-beep

Copy link
Copy Markdown

Summary

Fixes #432 and #324.

The current /codex:rescue command already owns execution mode at the Agent layer: --background backgrounds the rescue subagent, while --wait / default runs it in the foreground. However, the rescue subagent still contained an independent heuristic telling itself to prefer background execution for complicated work.

That leaves the single inner Bash call free to use Claude Code's run_in_background behavior. In that mode the Bash-owned companion/process tree can be reaped independently, and the thin forwarding subagent can return only a background-job acknowledgement instead of Codex's final output.

This patch makes the ownership boundary explicit:

  • the outer /codex:rescue command is the only layer that decides background vs foreground
  • the rescue subagent always runs its one Bash call in the foreground
  • the inner companion task call never receives --background
  • therefore the Bash call remains attached until Codex returns final stdout, even when the rescue Agent itself is backgrounded

No runtime implementation changes are needed: task without --background already executes synchronously through runForegroundCommand.

Current-vs-historical behavior

Part of #324 predates the current rescue routing. The present command already backgrounds the Agent itself rather than requiring the task runtime to own that choice. The remaining defect on current main is the contradictory subagent guidance that can background the Bash call inside that Agent. This PR fixes that current, still-reproducible boundary rather than reintroducing the historical --wait design.

Validation

Against current main (db52e28):

  • test-first rescue contract: RED because the subagent did not prohibit background Bash and explicitly required a prefer background execution heuristic
  • after patch, focused rescue tests: 2 passed, 0 failed
  • full tests/commands.test.mjs: 8 passed, 0 failed
  • negative scan across rescue command/agent/runtime skill: no remaining prefer background execution guidance
  • git diff --check: pass

Fresh collision checks immediately before publication found no open PR for #432 or #324 implementing this execution-boundary fix.

Scope

Four files only:

  • plugins/codex/agents/codex-rescue.md
  • plugins/codex/commands/rescue.md
  • plugins/codex/skills/codex-cli-runtime/SKILL.md
  • tests/commands.test.mjs

This intentionally does not add polling, a second process supervisor, or a new task execution mode.

@fscfede-beep
fscfede-beep requested a review from a team September 5, 2026 01:33

@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: 19810b45ba

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/codex/agents/codex-rescue.md Outdated
Comment on lines +24 to +25
- Use the single `Bash` call in the foreground. Never set `run_in_background` on the Bash call.
- Call `task` without `--background` so the Bash call stays attached until Codex returns its final stdout, even when this subagent itself is running in the background.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve a detached execution path for long rescues

When a Codex rescue exceeds Claude Code's foreground Bash limit, this mandatory foreground call is terminated even if the user selected --background: the Bash tool defaults to a 120-second timeout and caps an explicit timeout at 600,000 ms. The runtime's task --background path is the mechanism that detaches a durable worker, but these lines now prohibit it; because this agent also returns nothing on Bash failure, long tasks—the exact case README.md recommends backgrounding—can silently lose their final result. Keep a detached runtime path for background rescues and retrieve its result instead of holding one foreground Bash call open indefinitely.

Useful? React with 👍 / 👎.

@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: 76f876af2d

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

- Never set `run_in_background` on any Bash call.
- For a forwarded `--background` request, use the durable companion path: first run a foreground Bash call with `node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" task --background --json ...` and read `jobId` from its JSON.
- While that job is `queued` or `running`, use foreground Bash calls to `node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" status "$jobId" --wait --timeout-ms 60000 --json`. Each wait is bounded so no Bash call stays attached for the whole Codex run.
- When the background job is terminal, run `node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" result "$jobId"` in a foreground Bash call and return that stdout exactly as-is.

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 Return only raw Codex output from background rescues

When a completed background job has a thread ID, this plain result call does not return Codex's output verbatim: renderStoredJobResult appends Codex session ID and Resume in Codex lines to the stored raw output (plugins/codex/scripts/lib/render.mjs:405-410). This makes --background violate the command's explicit verbatim-output contract and behave differently from the foreground path; use a raw/JSON result mode and emit only the stored Codex response.

Useful? React with 👍 / 👎.

@sylvesterkaczmarek sylvesterkaczmarek 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.

The updated ownership model makes sense now that background rescue has to survive the host Agent lifecycle: durability belongs to the companion job, while the Agent becomes a waiter/reader instead of trying to keep the Bash process alive. The PDEATHSIG regression is much stronger than a mocked child-process assertion.

One lifecycle edge I would still pin explicitly is cancellation or interruption of the waiting Agent after the detached job has been created. Does that intentionally leave the Codex job running for a later status / result, or should it cancel it? Either behavior can be valid, but it matters because this design deliberately decouples worker lifetime from the Agent.

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

Labels

None yet

Projects

None yet

2 participants