Skip to content

rescue.md promises a background-subagent re-invocation that status.md says has been observed not to arrive #99

Description

@patriyang

Observation

Two command docs make incompatible claims about the same mechanism.

plugins/codex/commands/rescue.md:21 states it as a guarantee:

Claude Code re-invokes you when a background subagent finishes; that re-invocation is the rest of this command. Present the subagent's output verbatim then, in the same turn.

plugins/codex/commands/status.md:36 records the opposite from observation:

A foreground Bash call that returns always continues the current turn, so this bounded-wait pattern never depends on Claude Code re-invoking a stopped caller. That re-invocation has been observed not to arrive for subagent callers, leaving a completed Codex result unread with no signal.

These are executable instructions, not prose: rescue.md is what drives /codex:rescue. So /codex:rescue --background is told to end its turn and wait for a callback that the project has already documented as unreliable for exactly this caller shape. When it does not arrive, the subagent's foreground task has finished and persisted a full job record, but nothing presents it and the command has no recovery step to fall back on.

rescue.md:20 compounds it slightly: "There is no job to poll and nothing to fetch afterwards." That is true of the dispatch contract — the subagent's report is Codex's full output, so there is nothing to wait on — but a rescue's foreground task call does persist a task-… record, so there is in fact something to fetch when the report never gets presented.

Scope

Pre-existing: rescue.md:21 and status.md:36 have contradicted each other since #94 added the latter. Surfaced by Codex deep review round 2 on #97, which corrected the README's version of the same claim (#93) and thereby made the inconsistency visible.

Left out of #97 deliberately. That PR's scope was documentation accuracy in README.md; changing rescue.md changes how /codex:rescue actually behaves at runtime, which deserves its own change and its own review rather than a round-2 addendum to an unrelated PR.

Impact

A background rescue can complete successfully and never be shown to the user, with the command doc offering no recovery path — the same failure class #94 removed from the review and implement flows, still live in rescue.

Suggested direction (non-prescriptive)

Two shapes worth weighing:

  1. Document the recovery path. Keep the callback as the happy path, but drop the guarantee and add an explicit fallback: when the re-invocation does not arrive, recover the tracked task-… record with /codex:status and /codex:result.
  2. Give rescue the same wait contract as reviews. Give the background Codex flows a wait contract that does not depend on harness re-invocation #94's whole point was that a foreground Bash call that returns always continues the current turn. If the rescue flow can be restructured to block in bounded foreground steps rather than end its turn, the failure mode disappears rather than being documented.

Option 2 is the real fix if the subagent boundary allows it; option 1 is the cheap mitigation if it does not.

Whichever is chosen, rescue.md:20's "nothing to fetch afterwards" should be reworded, since a job record does exist.

Related

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions