Skip to content

fix(codex): hang protection without coreutils + replace deprecated --enable web_search_cached#2293

Open
smilesjosh007 wants to merge 2 commits into
garrytan:mainfrom
smilesjosh007:fix/codex-timeout-fallback-web-search
Open

fix(codex): hang protection without coreutils + replace deprecated --enable web_search_cached#2293
smilesjosh007 wants to merge 2 commits into
garrytan:mainfrom
smilesjosh007:fix/codex-timeout-fallback-web-search

Conversation

@smilesjosh007

Copy link
Copy Markdown

What

Two fixes to the /codex skill's hardening layer, both hit in the field on a macOS install running codex-cli 0.144.4.

1. Hang protection now works without coreutils. _gstack_codex_timeout_wrapper resolved gtimeout, then timeout, then ran the command completely unwrapped. On a Mac where ./setup never ran (or brew install coreutils failed or was skipped), every codex invocation had zero hang protection, silently. The wrapper now falls back to a pure-shell watchdog: background the command, poll every 5s, TERM at the deadline, KILL 10s later, and report exit 124 like GNU timeout, so the existing _CODEX_EXIT = 124 hang handling (log_event, log_hang, the PIPESTATUS callers in Steps 2B/2C) fires unchanged. gtimeout/timeout are still preferred when present; the watchdog only engages when both are absent.

2. The deprecated web-search flag is migrated, not just dropped. codex-cli >= 0.144 prints deprecated: [features].web_search_cached is deprecated because web search is enabled by default... on every run. The five /codex command templates now pass -c 'web_search="cached"' instead, which is the CLI's own recommended replacement and pins the cached index explicitly rather than relying on the default. Same "pin it explicitly" goal as #2249, but without --search, which codex exec / codex review reject on 0.144.4 (the reason that PR was closed). Related: #2224.

Details worth reviewing

  • Bash prints Terminated: 15 job notices when the watchdog kills a hung command. The fallback runs its job machinery inside a brace group with the shell's stderr routed to /dev/null, while fd 3 carries the command's real stderr through. Call-site 2>"$TMPERR" captures keep working, and both jobs are reaped inside the silenced group, so no notice can surface later and nothing outlives the call holding the caller's pipes open (that last part matters for spawnSync-style callers like the hardening test).
  • Timeout resolution is a 5s poll grid, so a 330s limit fires by ~335s. The skill's limits are 330/600s, both multiples of 5.
  • 143/137 map to 124 only in the no-binary branch; real gtimeout runs are untouched.

Verification

  • test/codex-hardening.test.ts: 29/29 pass. The "executes command directly when neither binary present" test now exercises the watchdog on macOS, inside its 5s spawnSync budget.
  • bash -n clean; no set / trap / IFS / PATH mutations, per the probe's hygiene header.
  • Behavior matrix on macOS 26.5.1 / bash 3.2 with PATH stripped of both binaries: exit 0 and exit 7 pass through; hang maps to 124; hang inside the Step 2B pipeline shape gives PIPESTATUS[0]=124 with partial stdout streamed through; command stderr reaches call-site 2> capture; a timed-out run leaves 0 bytes of junk in the capture file; a fast command through a pipe returns immediately.
  • Live on codex-cli 0.144.4: old flag prints the deprecation warning; -c 'web_search="cached"' runs clean and web search stays enabled.

Scope

/codex only. codex/SKILL.md.tmpl and generated codex/SKILL.md are edited in lockstep; the changed bash blocks pass through generation verbatim. Happy to regen via bun run gen:skill-docs if you prefer. The same deprecated flag also lives in autoplan, ship, review, design-review, design-consultation, office-hours, document-release, the plan-*-review sections, and scripts/resolvers/{review,design}.ts. Left alone here since flag removal is being handled separately per the #2249 closing comment; if you want the same -c migration across the suite instead, glad to follow up.

🤖 Generated with Claude Code

smilesjosh007 and others added 2 commits July 17, 2026 19:20
When neither gtimeout (Homebrew coreutils) nor timeout is on PATH,
_gstack_codex_timeout_wrapper ran codex completely unwrapped, so every
/codex and /autoplan invocation had silent zero hang protection on a
bare macOS install. setup's coreutils auto-install covers most machines
but not ones where setup never ran or brew install failed.

The wrapper now falls back to a pure-shell watchdog: background the
command, poll every 5s, TERM at the deadline, KILL 10s later, and
report exit 124 like GNU timeout so the skills' existing hang handling
(_CODEX_EXIT = 124 checks, including the PIPESTATUS callers) fires
unchanged. Bash "Terminated" job notices are silenced inside a
stderr-swapped brace group while fd 3 carries the command's real
stderr through, so call-site 2>"$TMPERR" captures keep working and no
notice junk leaks into skill output. Both jobs are reaped inside the
group so nothing outlives the call holding the caller's pipes open.

gtimeout/timeout preference is unchanged; the watchdog only engages
when both are absent. test/codex-hardening.test.ts passes 29/29.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…earch

codex-cli >= 0.144 prints a deprecation warning on every invocation:
[features].web_search_cached is deprecated because web search is
enabled by default; set web_search at the top level instead.

Replace the flag with -c 'web_search="cached"' in the five /codex
command templates (review, exec review, challenge, consult, consult
resume) and update the Web search doc note. This follows the CLI's own
deprecation guidance and pins the cached index explicitly rather than
relying on the new default. Verified live on codex-cli 0.144.4: the
old flag warns, the new override runs clean, web search stays enabled.

Unlike the --search replacement proposed in garrytan#2249 (closed: codex exec
and codex review reject --search on 0.144.4), -c is a stable top-level
mechanism accepted by every subcommand.

Scope: /codex skill only (SKILL.md.tmpl and generated SKILL.md edited
in lockstep; the changed bash blocks pass through generation
verbatim). The same flag remains in autoplan, ship, review, design-*,
office-hours, plan-*-review sections and scripts/resolvers, left for
the separate removal effort mentioned in garrytan#2249 or a follow-up PR.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@trunk-io

trunk-io Bot commented Jul 17, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@smilesjosh007
smilesjosh007 marked this pull request as ready for review July 17, 2026 23:33
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