Skip to content

Fix worktree-bound Codex app-server startup#568

Merged
baron merged 26 commits into
repoprompt:mainfrom
mplibunao:bugfix/codex-worktree-app-server-start
Jul 22, 2026
Merged

Fix worktree-bound Codex app-server startup#568
baron merged 26 commits into
repoprompt:mainfrom
mplibunao:bugfix/codex-worktree-app-server-start

Conversation

@mplibunao

@mplibunao mplibunao commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • separate the Codex app-server process launch directory from the thread/turn execution directory
  • launch each session-owned app-server from the selected worktree's logical repository root while keeping thread, turn, sandbox, logs, and diagnostics bound to the linked worktree
  • key controller reuse on the complete launch/execution path pair and scope worktree selectors to the declared repository
  • preserve bounded startup stderr and structured exit status while enforcing one destructive child reaper, bounded teardown, and missed-exit self-healing

Fixes #554

Validation

  • AgentRunWorktreeStartTests: 47/47
  • CodexNativeSessionControllerGoalConfigTests: 19/19
  • CodexNativeSessionControllerTurnDispatchTests: 9/9
  • MCP bootstrap/routing readiness: 7/7
  • process termination and Codex app-server exit lifecycle: 26/26
  • three fresh 64-live/80-early-exit saturation passes completed before the temporary harness and ledger row were removed
  • SwiftFormat: 0/1,458 files require changes
  • strict SwiftLint passed
  • authoritative root/provider test lists and exact 3,345-ID ledger reconciliation passed
  • clean-HEAD packaged product build passed; preserved artifact provenance is commit f65e925d, dirty: false, with deep strict codesign verification
  • the earlier clean-branch pr-ready lane completed 3,321 root tests with zero failures
  • the post-rebase full-root lane hit two unrelated durable-artifact/codemap timing flakes; both exact cases passed in fresh-process isolation, and every rebased overlap/fix-specific suite is green

Packaged evidence

Using the same wizyemm-infra workspace, linked worktree, selector target, and Codex model:

  • preserved v1.0.29 baseline failed for both worktree_id and @branch:demo/rpce-554-worktree-start-evidence with Codex native start failed: Codex app-server process is not running.
  • patched sessions completed for both selector forms
  • live launcher/native process pairs reported launch cwd /Users/mp/Projects/wizy/wizyemm/wizyemm-infra
  • both agents reported execution cwd in the linked demo/rpce-554-worktree-start-evidence worktree and made no edits

The accepted baseline failure screenshot is attached in a PR comment. macOS Screen Recording authorization did not survive the ad-hoc signature change, so no patched screenshot is claimed; the patched result is backed by RepoPrompt session results plus the independent process-cwd observations.

Update 2026-07-22

  • Merged current main (post-Fix Codex app-server tool override policy #603) into the branch: the launch/execution directory split is unchanged; the experimental-steering plumbing removed by Fix Codex app-server tool override policy #603 is gone from this branch too; MCP tool-catalog snapshot hashes refreshed for the merged catalog.
  • The earlier app shard 4 failure (CodemapAutomaticSelectionColdTests.testColdAutomaticSelectionNeverPlansSameNamedDefinitionFromAnotherRoot) no longer reproduces after the CodeMap core rework on main — the suite passes 8/8 post-merge.
  • Post-merge validation: RepoPrompt product build, AgentRunWorktreeStartTests 47/47, CodexNativeSessionControllerGoalConfigTests 19/19, ToolCatalogSnapshotTests 5/5, SwiftFormat + strict SwiftLint clean.
  • Live verification against a machine reproducing Worktree-bound Codex starts fail with “app-server process is not running” while unbound starts succeed #554: on a build without this PR, a worktree-bound agent_run start targeting a repo with cwd-sensitive tooling (mise.toml + repo-local .codex hooks) fails with Codex app-server process is not running — persisted session records show the failure lands ~250 ms after run start, before any Codex thread exists. After including this branch and rebuilding, the identical probe passes; unbound starts and worktree starts on a repo without such tooling pass in both builds as controls.

mplibunao added 13 commits July 17, 2026 09:47
Fence root signaling before the sole destructive reap, retry transient wait failures, and keep TERM-to-KILL cleanup bounded.

Align default launch cwd, fully retire failed controller state, and canonicalize primary repository promotion with deterministic regression coverage.
Persistent kernel wait failures now retry with exponential backoff from
10 ms to a 1 s ceiling instead of a fixed 10 ms loop, while the observer
retains sole destructive-reap ownership until a terminal result.
Five teardown routes each maintained their own checklist of tab-scoped
task cancellations and controller-runtime field clears; new
controller-scoped resources had to be added to every list. The shared
mechanical core now lives in cancelCodexTabScopedControllerTasks and
clearCodexControllerRuntimeState while semantic decisions (reconnect
marking, queue abandonment, interaction settlement, shutdown sequencing,
tracking waits) stay caller-owned.
Both termination origins duplicated the first-claim protocol (same-
generation task reuse, terminal-cause claim, task publication) with
small drift-prone differences. installTransportTermination now owns the
protocol; origins supply only their validation guard, post-claim
capture, and completion strategy.
The controller now retains CodexRuntimeWorkspacePaths as one property so
the launch/execution roles cannot drift through partial initialization.
The observer's signaling flag is named for what it guards
(rootSignalingClosed) since wait-failure retries reopen it before any
reap. Both view-model initializers derive their session projection
closures from one factory.
The post-claim capture now flows through a generic Sendable return value
instead of a mutable unchecked box, so the compiler enforces the
capture-before-publication handoff.
kevent NOTE_EXIT delivery proved non-contractual under saturation (a
64-live/80-early-exit harness stranded one child in roughly a quarter of
runs). Every registration now keeps a 500 ms non-destructive fallback
probe that routes a missed notification through the same token-guarded
sole-reap path; the timer is cancelled at completion.
Copilot AI review requested due to automatic review settings July 17, 2026 02:20

Copilot AI 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.

Pull request overview

This PR fixes worktree-bound Codex Agent Mode startup by separating the Codex app-server process launch directory from the session’s execution directory (thread/turn/sandbox), while tightening worktree repository selection and improving early-exit diagnostics (bounded stderr + structured exit status) with a single destructive child reaper.

Changes:

  • Introduces CodexRuntimeWorkspacePaths (launch vs execution) and updates Codex controller/coordinator/view model plumbing to key controller reuse on the full path pair.
  • Refactors Codex app-server transport lifecycle to preserve typed early-exit evidence (processExited) with bounded stderr capture and observer-owned reaping/teardown.
  • Adjusts worktree selector repository discovery/defaulting to the declared primary workspace root and adds broad regression coverage.

Maintainer-guidance check

  • User impact and invariant: Worktree-bound Codex sessions must start reliably; app-server launch cwd must be stable (logical root) while execution remains bound to the selected worktree.
  • Root-cause confidence: confirmed (launch/execution cwd coupling was the reported failure axis; PR cleanly splits them and adds regression coverage).
  • Authority: Codex CLI/app-server process launch configuration + Agent Mode worktree binding projection are the sources of truth.
  • State-safety risks: medium (provider/controller replacement + teardown correctness); mitigated by typed failure evidence, sole-reaper enforcement, and added lifecycle tests.
  • Scale and observability risks: moderate (new per-child observation registry); bounded probes + nonblocking publication queue help, but correctness/compile safety is critical.
  • Recommended scope: now (fits acceptance criteria for #554).
  • Validation boundary: Agent Mode worktree binding projection + Codex app-server spawn/termination lifecycle (tests added across both).

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Tests/RepoPromptTests/MCP/ToolCatalogSnapshotTests.swift Updates tool catalog snapshot hashes after schema changes.
Tests/RepoPromptTests/MCP/AgentRunWorktreeStartTests.swift Adds regression tests for Codex workspace path projection and worktree selector scoping; adjusts Codex controller fakes.
Tests/RepoPromptTests/Helpers/CodexSessionControllerTestDefaults.swift Adds passive-stub defaults to simplify controller test doubles.
Tests/RepoPromptTests/AI/ProcessTerminationExitStatusTests.swift Expands tests around sole-reaper semantics, teardown ordering, and retry behavior.
Tests/RepoPromptTests/AI/CodexNativeSessionControllerTurnDispatchTests.swift Updates controller construction to use workspacePaths pair.
Tests/RepoPromptTests/AgentMode/Codex/CodexNativeSessionControllerGoalConfigTests.swift Updates config field names and adds tests for launch directory updates and worktree path separation semantics.
Tests/RepoPromptTests/AgentMode/Codex/CodexNativeSessionControllerEventRecoveryTests.swift Updates controller construction to use workspacePaths.
Tests/RepoPromptTests/AgentMode/Codex/CodexMCPBootstrapReadinessTests.swift Updates controller construction/config to use launch directory vs runtime workspace paths.
Tests/RepoPromptTests/AgentMode/Codex/CodexFallbackFIFOTests.swift Updates controller construction to use workspacePaths.
Tests/RepoPromptTests/AgentMode/Codex/CodexAppServerClientProcessExitTests.swift New, comprehensive tests for early-exit evidence, precedence rules, and lifecycle/termination races.
Sources/RepoPrompt/Infrastructure/VCS/GitService.swift Updates to the new beforeReap callback name/semantics for child reaping.
Sources/RepoPrompt/Infrastructure/Process/ProcessTermination.swift Adds process-wide child observation registry + observer-oriented termination APIs; updates reaping API surface.
Sources/RepoPrompt/Infrastructure/Process/CLIProcessConfiguration.swift Centralizes default working directory resolution.
Sources/RepoPrompt/Infrastructure/Process/ChildProcessExitObserver.swift New sole-reaper observer abstraction with bounded retries and signaling window closure.
Sources/RepoPrompt/Infrastructure/MCP/WindowTools/MCPAgentControlToolProvider.swift Clarifies worktree_repo_root default behavior in tool schema.
Sources/RepoPrompt/Infrastructure/MCP/Agent/AgentMCPStartWorktreeCoordinator.swift Scopes worktree resolution to the selected repo; defaults discovery to primary workspace root deterministically.
Sources/RepoPrompt/Infrastructure/AI/Providers/Codex/CodexCLIProvider.swift Improves surfaced error message for typed processExited failures.
Sources/RepoPrompt/Infrastructure/AI/Providers/Codex/AppServer/CodexProcessStderrCapture.swift New bounded stderr tail capture used for typed exit evidence.
Sources/RepoPrompt/Infrastructure/AI/Providers/Codex/AppServer/CodexNativeSessionController.swift Uses runtime launch/execution pair; routes launch cwd to client and execution cwd to thread/turn/sandbox.
Sources/RepoPrompt/Infrastructure/AI/Providers/Codex/AppServer/CodexAppServerClient.swift Adds typed exit evidence, observer-owned termination, and transport-termination arbitration; separates launch directory config.
Sources/RepoPrompt/Features/Diagnostics/AgentMode/Stress/AgentChatStressHarness.swift Updates Codex controller construction to use workspacePaths.
Sources/RepoPrompt/Features/AgentMode/ViewModels/AgentModeViewModel+TabSession.swift Replaces scalar Codex workspace path tracking with launch/execution pair tracking.
Sources/RepoPrompt/Features/AgentMode/ViewModels/AgentModeViewModel.swift Adds shared workspace projection providers and exposes runtime workspace paths for tests.
Sources/RepoPrompt/Features/AgentMode/Services/AgentWorktreeRuntimeWorkspaceResolver.swift Adds Codex-specific projection that validates launch root and keeps execution bound to worktree.
Sources/RepoPrompt/Features/AgentMode/Runtime/Codex/CodexRuntimeWorkspacePaths.swift New type + error for Codex launch/execution directory modeling.
Sources/RepoPrompt/Features/AgentMode/Runtime/Codex/CodexAgentModeCoordinator.swift Keys controller replacement on workspace path pair and consolidates teardown paths for new controller-scoped state.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Sources/RepoPrompt/Infrastructure/Process/ProcessTermination.swift
Comment thread Sources/RepoPrompt/Infrastructure/Process/ProcessTermination.swift
@mplibunao

Copy link
Copy Markdown
Contributor Author

Baseline v1.0.29 packaged failure

Both worktree_id and @branch:demo/rpce-554-worktree-start-evidence failed before the first turn with Codex native start failed: Codex app-server process is not running. This is the accepted visible baseline evidence; the matched patched session and process-cwd evidence are summarized in the PR description.

Baseline v1.0.29 worktree-bound Codex startup failure

@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: 3bfaec2b9e

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…ee-app-server-start

# Conflicts:
#	Sources/RepoPrompt/Infrastructure/AI/Providers/Codex/AppServer/CodexNativeSessionController.swift
#	Tests/RepoPromptTests/MCP/ToolCatalogSnapshotTests.swift
@baron

baron commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

@mplibunao thank you always for your amazing PRs. We're actually going to be bundling the app server and work on general reliability that will hopefully solve most issues with codex involving self-installed clis (like PATH stuff).

@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: 33002fbdfa

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@mplibunao

mplibunao commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@baron Bundling the app-server sounds like a great direction — that should take care of the self-installed CLI/PATH class nicely, and I'm totally fine if this PR ends up covered or superseded by that work. One data point in case it's useful for the bundling design: in the worktree-bound failures here, binary resolution was actually fine (the same binary starts cleanly from the same directory when run manually) — the trigger was launching the app-server with the worktree as its cwd, where repo-local tooling reacts to the directory. Something to keep in mind for wherever the bundled server gets launched from. Meanwhile I'll keep the branch synced and green in case it's still useful.

@baron

baron commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

@mplibunao you make a good point I think this PR merits a separate look to see if we should incorporate it before bundling as it addresses a very specific deficiency.

@baron
baron merged commit 6834a54 into repoprompt:main Jul 22, 2026
8 checks passed
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.

Worktree-bound Codex starts fail with “app-server process is not running” while unbound starts succeed

3 participants