Context
Release classification: post-release Agent Harness wake hardening; boardless unless the operator promotes it.
Parent / residual lane: #13287.
After #13350 / PR #13351 migrated @neo-gpt wake subscriptions to harnessTargetMetadata.adapter: codex-app-server, the live wake daemon surfaced a new route blocker instead of the prior osascript submit ambiguity. The wake log showed WAKE_SUB:7648b86c-2f1e-43a8-95a6-cc399f66a938 failing repeated codex-app-server delivery attempts with spawn codex ENOENT, then dropping the wake.
Local falsifier: this Codex Desktop session resolves the executable as /Applications/Codex.app/Contents/Resources/codex, but the long-lived daemon environment does not have bare codex on PATH.
The Problem
The Codex app-server adapter currently assumes codex is discoverable from the daemon process environment. That assumption is false for at least the live macOS daemon path: interactive shells can find Codex Desktop's bundled CLI, while the daemon's reduced environment cannot.
This blocks #13287's migrated-route validation. The subscription now selects the intended submit-capable route, but the route cannot reach the Codex CLI process at all, so no L4 prompt-submit/start-turn matrix can be collected on the migrated path.
The Architectural Reality
ai/daemons/wake/daemon.mjs owns live wake delivery for durable WAKE_SUBSCRIPTION rows.
ai/scripts/lifecycle/resumeHarness.mjs owns fresh-session harness resume and already has a sibling Codex app-server route.
- Both surfaces resolve the Codex CLI through a bare
codex default when CODEX_CLI_PATH is unset.
CODEX_CLI_PATH must remain the highest-priority explicit override for tests, custom installations, and cloud deployments.
- The macOS Codex Desktop bundled CLI path is an app-local fallback, not a replacement for explicit config. Non-mac/cloud deployments should continue to use explicit
CODEX_CLI_PATH or the existing bare codex command contract.
- The
codex-app-server route must fail visibly if the CLI cannot be found; it must not silently fall back to osascript, because that would reintroduce the GUI focus/Enter path this adapter is meant to bypass.
The Fix
Update both Codex app-server entry points to resolve the CLI in this order:
CODEX_CLI_PATH when explicitly set.
- On macOS, an executable Codex Desktop bundled CLI path, with a test/relocation override for the Desktop path.
- Bare
codex as the existing cross-platform fallback.
Add focused unit coverage proving both the wake daemon and resume harness can dispatch through a mocked Desktop-bundled CLI when PATH intentionally lacks bare codex.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
Wake daemon codex-app-server adapter |
#13287 live wake log + ai/daemons/wake/daemon.mjs |
Resolve explicit CODEX_CLI_PATH, then macOS bundled Codex Desktop CLI, then bare codex |
If no executable exists, delivery fails visibly; no osascript fallback |
Resolver JSDoc names PATH-risk rationale |
Focused daemon unit test with PATH lacking bare codex |
Resume harness codex-app-server adapter |
ai/scripts/lifecycle/resumeHarness.mjs sibling route |
Use the same explicit-first / Desktop-fallback / bare-command resolution |
Live-host guard remains; tests use mock opt-in |
Existing live-host guard docs updated |
Focused resume-harness unit test |
| Cloud / non-mac deployments |
Existing explicit env contract |
CODEX_CLI_PATH stays authoritative; bare codex fallback remains |
No macOS app-path dependency outside darwin |
Ticket and PR body call out boundary |
Source review + existing mock coverage |
Decision Record impact
Aligned with ADR 0002 / wake-substrate route separation. This is a route-resolution bug fix, not an architecture change.
Acceptance Criteria
Out of Scope
- Completing the #13287 L4 matrix.
- Changing wake subscription identity templates or migration behavior from #13350 / PR #13351.
- Reverting to
osascript for Codex wakes.
- Electron shell/build-root work; that remains #13033.
- Cloud deployment authentication or installing Codex CLI on remote hosts.
Avoided Traps / Gold Standards Rejected
- Auto-closing #13287: rejected. The matrix remains open after this route fix.
- Silent
osascript fallback: rejected. It would hide the configured-route failure and revive the old focus-sensitive path.
- Hardcoding macOS for all deployments: rejected. The bundled path is darwin-only and explicit
CODEX_CLI_PATH remains authoritative.
- Fixing only wake delivery: rejected. Resume harness has the sibling Codex app-server resolver and would drift if left unchanged.
Related
Duplicate / Claim Sweep
Live latest-open sweep: checked the latest 20 open GitHub issues on 2026-06-15T16:50Z. Relevant live hits included #13287, #13012, #13033, #13289, #13362, and H2 follow-ups, but no dedicated spawn codex ENOENT / Codex Desktop CLI resolver ticket.
Targeted live GitHub searches for "spawn codex" ENOENT and "Codex Desktop CLI" "codex-app-server" returned no open duplicate.
A2A in-flight sweep: native list_messages / add_message tools are not exposed in this Codex Desktop surface (tool_search returned no A2A tools earlier in this turn), so private in-flight claim visibility is unavailable. The public GitHub state and repo/content sweep found no duplicate.
Semantic KB sweep: attempted ask_knowledge_base(query='spawn codex ENOENT codex-app-server CODEX_DESKTOP_CLI_PATH wake daemon duplicate ticket', type='ticket'), but the KB MCP is currently unhealthy (knowledgeBase:null, Failed to access collections). This failure is recorded as a live substrate limitation rather than silently omitted.
Exact repo/content sweep: rg "spawn codex|codex-app-server.*ENOENT|Codex Desktop CLI|CODEX_DESKTOP_CLI_PATH" resources/content/issues resources/content/discussions ai learn .agents/workflows found only the implementation branch edits in ai/, not an existing issue/discussion duplicate.
Origin Session ID: unavailable in this Codex Desktop surface.
Retrieval Hint: "Codex app-server spawn codex ENOENT wake daemon CODEX_DESKTOP_CLI_PATH bundled CLI"
Context
Release classification: post-release Agent Harness wake hardening; boardless unless the operator promotes it.
Parent / residual lane: #13287.
After #13350 / PR #13351 migrated
@neo-gptwake subscriptions toharnessTargetMetadata.adapter: codex-app-server, the live wake daemon surfaced a new route blocker instead of the priorosascriptsubmit ambiguity. The wake log showedWAKE_SUB:7648b86c-2f1e-43a8-95a6-cc399f66a938failing repeatedcodex-app-serverdelivery attempts withspawn codex ENOENT, then dropping the wake.Local falsifier: this Codex Desktop session resolves the executable as
/Applications/Codex.app/Contents/Resources/codex, but the long-lived daemon environment does not have barecodexonPATH.The Problem
The Codex app-server adapter currently assumes
codexis discoverable from the daemon process environment. That assumption is false for at least the live macOS daemon path: interactive shells can find Codex Desktop's bundled CLI, while the daemon's reduced environment cannot.This blocks #13287's migrated-route validation. The subscription now selects the intended submit-capable route, but the route cannot reach the Codex CLI process at all, so no L4 prompt-submit/start-turn matrix can be collected on the migrated path.
The Architectural Reality
ai/daemons/wake/daemon.mjsowns live wake delivery for durableWAKE_SUBSCRIPTIONrows.ai/scripts/lifecycle/resumeHarness.mjsowns fresh-session harness resume and already has a sibling Codex app-server route.codexdefault whenCODEX_CLI_PATHis unset.CODEX_CLI_PATHmust remain the highest-priority explicit override for tests, custom installations, and cloud deployments.CODEX_CLI_PATHor the existing barecodexcommand contract.codex-app-serverroute must fail visibly if the CLI cannot be found; it must not silently fall back toosascript, because that would reintroduce the GUI focus/Enter path this adapter is meant to bypass.The Fix
Update both Codex app-server entry points to resolve the CLI in this order:
CODEX_CLI_PATHwhen explicitly set.codexas the existing cross-platform fallback.Add focused unit coverage proving both the wake daemon and resume harness can dispatch through a mocked Desktop-bundled CLI when
PATHintentionally lacks barecodex.Contract Ledger Matrix
codex-app-serveradapterai/daemons/wake/daemon.mjsCODEX_CLI_PATH, then macOS bundled Codex Desktop CLI, then barecodexosascriptfallbackPATHlacking barecodexcodex-app-serveradapterai/scripts/lifecycle/resumeHarness.mjssibling routeCODEX_CLI_PATHstays authoritative; barecodexfallback remainsDecision Record impact
Aligned with ADR 0002 / wake-substrate route separation. This is a route-resolution bug fix, not an architecture change.
Acceptance Criteria
codex-app-serveradapter keepsCODEX_CLI_PATHas the highest-priority override.CODEX_CLI_PATHis unset, the wake daemon can resolve an executable Codex Desktop bundled CLI path before falling back to barecodex.PATHlacks barecodex.PATHlacks barecodex.osascriptfor a configuredcodex-app-serverroute.Out of Scope
osascriptfor Codex wakes.Avoided Traps / Gold Standards Rejected
osascriptfallback: rejected. It would hide the configured-route failure and revive the old focus-sensitive path.CODEX_CLI_PATHremains authoritative.Related
Duplicate / Claim Sweep
Live latest-open sweep: checked the latest 20 open GitHub issues on 2026-06-15T16:50Z. Relevant live hits included #13287, #13012, #13033, #13289, #13362, and H2 follow-ups, but no dedicated
spawn codex ENOENT/ Codex Desktop CLI resolver ticket.Targeted live GitHub searches for
"spawn codex" ENOENTand"Codex Desktop CLI" "codex-app-server"returned no open duplicate.A2A in-flight sweep: native
list_messages/add_messagetools are not exposed in this Codex Desktop surface (tool_searchreturned no A2A tools earlier in this turn), so private in-flight claim visibility is unavailable. The public GitHub state and repo/content sweep found no duplicate.Semantic KB sweep: attempted
ask_knowledge_base(query='spawn codex ENOENT codex-app-server CODEX_DESKTOP_CLI_PATH wake daemon duplicate ticket', type='ticket'), but the KB MCP is currently unhealthy (knowledgeBase:null,Failed to access collections). This failure is recorded as a live substrate limitation rather than silently omitted.Exact repo/content sweep:
rg "spawn codex|codex-app-server.*ENOENT|Codex Desktop CLI|CODEX_DESKTOP_CLI_PATH" resources/content/issues resources/content/discussions ai learn .agents/workflowsfound only the implementation branch edits inai/, not an existing issue/discussion duplicate.Origin Session ID: unavailable in this Codex Desktop surface.
Retrieval Hint: "Codex app-server spawn codex ENOENT wake daemon CODEX_DESKTOP_CLI_PATH bundled CLI"