openai / openai/codex-plugin-cc
codex-companion: review jobs ignore --background, dead children never reaped, no wall-clock ceiling — jobs stuck 'running' forever
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 33.3k
- Forks
- 2.3k
- PR merge metrics
- No merged PRs in 30d
Description
Context
We run the codex plugin (1.0.6) inside Claude Code as a first-class subagent runtime — codex-companion.mjs supervises implementation and adversarial-review jobs daily in a production monorepo. Three defect classes have each cost us real wall-clock time; all three share one root: a job record can claim running forever with no supervisor path that ever falsifies it.
Defect 1 — dead children are never reaped
When the child process dies (we've seen it after Nx daemon/plugin-worker failures and mid MCP call), the job record stays running with a frozen updatedAt indefinitely. No terminal state, no error. Field incidents: two implementation jobs died silently mid-run (2026-07-28), and a task job's child died while status reported running for another hour until a human polled (2026-08-04).
Expected: the supervisor detects child exit/death (exit event, or process.kill(pid, 0) liveness probe on read paths) and flips the job to failed, preserving partial output.
Defect 2 — adversarial-review accepts --background but ignores it
handleReviewCommand calls runForegroundCommand unconditionally (~line 739 in 1.0.6); --background is parsed but only honored for task runs. A caller that passes --background to a review gets silent foreground behavior — and when the calling harness's tool timeout fires, the run is orphaned and the job wedges permanently.
Notably this is pinned by an existing test (review accepts --background while still running as a tracked review job asserts the full foreground payload), i.e. "accepted but ignored" is encoded as intended. Respectfully: either --background should mean background for reviews, or the flag should be rejected for review commands. Silently accepting a no-op flag is the worst of the three options.
Defect 3 — no wall-clock ceiling
Four adversarial reviews in one session (2026-07-31) each explored 10–40 min and then went permanently silent, status stuck running forever. With no ceiling, every wedge requires a human to notice, mine the job log by hand, and cancel.
Expected: a configurable ceiling (we'd suggest ~45 min default, env/config overridable) after which a still-running job is failed with the tail of its log captured as partial output.
Side finding — test-suite env leak
The suite spreads process.env into its fixtures: with CODEX_COMPANION_SESSION_ID exported (true in any Claude Code session), 3 unrelated tests fail, and test runs create codex-plugin-test-* state dirs under the user's real plugin data directory instead of an isolated tmpdir.
We have a verified patch
We've built and verified a fix against 1.0.6: failStoppedJob()/readJobLogTail() as the single place a stopped job is failed with partial output; reconcileActiveJobs() on job-read paths handling both pid-liveness and the ceiling (default 45 min, CODEX_COMPANION_MAX_JOB_MS/maxJobRuntimeMs); reviews routed through the same background path as tasks with the runner chosen from the stored jobClass; the cancel path deliberately excluded from reconciliation so explicit cancels always see raw state. Plugin suite: 91/91 baseline → 97/97 patched (new coverage for reaping, ceiling, and background reviews; the stale 2026-03-18 active-job fixtures moved to relative timestamps so they don't get reaped mid-test).
Happy to submit it as a PR if maintainers are open to the --background behavior change — flagging the design question here first since a test pins the current behavior.
Report produced by an automated harness investigation (Claude Code) on behalf of the repo owner; incidents referenced are from our real usage telemetry.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with codex-companion.mjs, especially handleReviewCommand near line 739 and the existing background-job tests. Trace failStoppedJob(), readJobLogTail(), and reconcileActiveJobs() across job-read, review, and cancel paths, then run the plugin suite. Done means dead jobs and overlong jobs reach a terminal state, review background behavior is decided and covered, and the suite remains isolated and passing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- backend, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100