Skip to content

fix: run foreground tasks detached-worker-first so a timed-out wait hands back a resolvable task id - #590

Open
daniel3303 wants to merge 1 commit into
openai:mainfrom
daniel3303:fix/foreground-task-detached-worker
Open

fix: run foreground tasks detached-worker-first so a timed-out wait hands back a resolvable task id#590
daniel3303 wants to merge 1 commit into
openai:mainfrom
daniel3303:fix/foreground-task-detached-worker

Conversation

@daniel3303

Copy link
Copy Markdown

Summary

A foreground task runs the whole Codex turn in-process with no internal deadline. Agent harnesses cap shell calls (Claude Code's Bash tool at 600s); when that cap fires, the CLI's stdout is lost and the id the harness reports back comes from its own background-command namespace — status/result cannot resolve it, so a long run's outcome looks unrecoverable even though the companion's state store holds it. (Observed in practice: a 13-minute verification run whose result had to be dug out of the state directory by hand.)

Code changes

  • plugins/codex/scripts/codex-companion.mjs — the foreground path now spawns the same detached task-worker the --background path uses and only WAITS in-process, inside --wait-budget-ms (default 540000, deliberately below the common 600s harness ceiling):
    • completion emits the worker's stored payload/rendered output and exit status byte-compatibly with the old in-process path; thrown worker errors (auth rejection, missing prompt) are rethrown so they still land on stderr with a non-zero exit; unresolvable --resume-last still fails fast before any worker is spawned;
    • timeout prints the companion's REAL task-* id plus the retrieval command, and the run simply continues in the worker — nothing is lost even if the harness kills the CLI afterwards;
    • progress still streams to stderr by tailing the worker's log, with a settle pass so the closing lines (including failure text) are carried.
  • Version bumped to 1.0.7 via npm run bump-version.

Tests

  • New regression: a task outliving a 1ms wait budget hands back a task-* id that status --wait and result both resolve once the detached worker finishes.
  • Full suite: 89 pass, 3 fail — the same 3 failures reproduce on a clean checkout of main in this environment (status/result fixture expectations), i.e. no regressions from this change.

…ands back a resolvable task id

A foreground task ran the whole Codex turn in-process with no internal
deadline. When the invoking agent harness (Claude Code's Bash tool caps
a call at 600s) timed the CLI out, the process's stdout was lost and
the id the harness reported came from its own background-command
namespace — which codex-companion status/result cannot resolve, so the
run's outcome looked unrecoverable even though the state store had it.

The foreground path now spawns the same detached task-worker the
--background path uses and only WAITS in-process, inside a budget that
defaults below the 600s ceiling (--wait-budget-ms, default 540000). On
completion it emits the worker's stored payload/rendered output and
exit status byte-compatibly with the old path (thrown worker errors are
rethrown so auth failures still land on stderr, and unresolvable
--resume-last still fails fast before a worker is spawned); on timeout
it prints the companion's REAL task id with the retrieval command, and
the run simply continues in the worker. Progress streams to stderr by
tailing the worker's log, with a settle pass so the closing lines
(including failure text) are carried.

Regression test: a task outliving a 1ms wait budget hands back a
task-* id that status --wait and result both resolve once the detached
worker finishes.
@daniel3303
daniel3303 requested a review from a team August 4, 2026 17:56

@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: 43661cc873

ℹ️ 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".

jobId: job.id
});
const { payload } = enqueueBackgroundTask(cwd, job, request);
const waitBudgetMs = Math.max(0, Number(options["wait-budget-ms"]) || DEFAULT_TASK_WAIT_BUDGET_MS);

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 Honor the stop-gate timeout for JSON task callers

When the stop-review gate runs, stop-review-gate-hook.mjs invokes task --json with its own 15-minute spawnSync timeout and then parses payload.rawOutput; with this new default budget, any stop-gate review that runs for 9–15 minutes now returns a successful wait-timeout payload with no rawOutput, so the hook blocks as “no final output” even though it was configured to wait longer and could have produced an ALLOW:/BLOCK: verdict. Please let that internal caller wait for the full stop-gate timeout (or otherwise opt out of the 540s foreground handoff).

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