## Why
Reloading an evicted sub-agent disabled its rollout tracing, leaving later turns out of the trace. Replacement Code Mode sessions could also reuse cell IDs from earlier sessions.
## What changed
- Reattach reloaded children to the root rollout trace and emit `ThreadResumed` without duplicating `ThreadStarted`.
- Reopen existing threads during replay, preserving their identity and history while clearing stale runtime cell and terminal process mappings.
- Allocate Code Mode cell generations across sessions for both gRPC and stdio hosts to prevent ID reuse after reload.
- Record an aborted trace when session startup fails before the session loop begins.
## Testing
Add regression coverage for child eviction and reload, including a failed reload, continued inference tracing, distinct cell IDs, and preserved mail and follow-up context. Extend replay tests for history preservation and reused runtime handles, and host tests for cell IDs across session replacement and reconnection.
GitOrigin-RevId: 6c146c04b5cda9295afb7d973c0d5474b363a822
## What changed
Add session options for client- or server-owned output truncation and optional `max_output_tokens` budgets for wait and terminate observations. Introduce `TerminateRequest` and update session implementations and callers to use it.
Extend the stdio and gRPC schemas with optional truncation settings and budgets, and define the `bounded-output-v1` capability. Existing sessions retain client-side truncation; providers reject server mode by default. This change defines the contracts without enabling server-side truncation.
## Testing
Extend protocol serialization coverage for `outputTruncation: "server"` while preserving existing wire shapes when optional fields are absent.
GitOrigin-RevId: 22145897ea16d385c5ba9e7549109f7a669fceb4
## Why
Callbacks from the shared stdio host need to retain each execution's trace context after it yields, without keeping the execution span open until its background cell closes.
## What changed
Capture a W3C trace-context snapshot for each execution and restore it as the parent of tool callback and notification spans. Instrument delegate invocation and its returned future so the context is available on entry and across awaits.
## Testing
Add an integration test with overlapping yielded cells completed in reverse order. Cover sampled, unsampled, and untraced callers, trace isolation, callback and notification parentage, and execution spans finishing while callbacks remain blocked.
GitOrigin-RevId: 57924123d2c2f31bcfaf725688d8bba775235fa0
## What changed
Add an optional `preempt` signal to `CodeModeSession::execute` and `CodeModeSession::wait` so callers can end an observation early while the cell continues running and remains available for later waits.
Support the signal in the in-process runtime and across both remote transports: `operation/yield` with the negotiated `yield-observation` capability for stdio, and `YieldObservation` for gRPC. Preserve signals received before gRPC observation registration, and retain normal timeout behavior for older hosts that lack support.
## Testing
Add runtime and transport tests covering early execute and wait yields followed by successful cell completion, yields before observation registration, and suppression of yield frames for older stdio hosts.
GitOrigin-RevId: 3f8049d8f0582be6b8f0832cc03f2d974a0b8f18
## Why
A delegate bound at session creation cannot provide different callbacks for cells sharing that session. Each execution needs to retain its own delegate across yields and release it when the cell is cleaned up.
## What changed
- Pass `CodeModeSessionDelegate` to `execute` instead of session creation.
- Route tool calls, notifications, and cell closure callbacks through the execution's delegate in the in-process runtime and the gRPC and stdio transports.
- Retain delegates with pending executions and live cells, releasing them through closure and cancellation cleanup.
## Testing
Add coverage for distinct delegates across yielded cells, gRPC callbacks before cell admission, and delegate release after completion or abandoned execution cleanup. Update transport tests to verify callbacks reach the owning cell's delegate.
GitOrigin-RevId: 7469f52104b993e790a40c65fb800ad02b7fd606
## What changed
- Accept only `http://` and `https://` gRPC endpoints for app server
`--code-mode-host` connections.
- Limit the standalone code-mode host to stdio and gRPC listeners.
- Remove the WebSocket session provider, dual-WebSocket negotiation, transport
lanes, and related dependencies and tests.
- Keep coverage for shared and prewarmed gRPC hosts and reject WebSocket host
URLs in CLI parsing tests.
GitOrigin-RevId: 8792604e79ffd54ce776074a4dc3f7d55e63752a
## What changed
- Add the opt-in `code_mode_prewarm` feature to establish the code-mode host session during startup, before the first turn.
- Make in-progress host initialization cancellable so a stalled prewarm does not block shutdown.
- Share a failed connection attempt with concurrent callers instead of immediately starting another attempt.
## Testing
- Verify app-server contacts the configured host before the first turn and can shut down while that connection is stalled.
- Exercise shared remote-host behavior with prewarming enabled.
GitOrigin-RevId: 3cfde5509be7b4aba80112c36c5616b9a9b632c6
## What changed
- Add `GrpcCodeModeSessionProvider` for opening code-mode sessions over HTTP/2 or an existing `tonic` channel.
- Support execution, waiting, termination, per-session limits, cell-closure callbacks, and graceful shutdown over the gRPC protocol.
- Bound transport waits and error messages, validate host identifiers and responses, and clean up abandoned executions and observers.
## Testing
- Add end-to-end TCP tests covering session persistence, cancellation, concurrent waits, shutdown, cell cleanup, and independent yield limits.
- Add unit coverage for protocol conversion, deadlines, and session lifecycle state.
GitOrigin-RevId: d4729ce608ad4b42a99744b07e1f230e46cb24ec
## What changed
- Add `create_session_with_limits` and session-scoped cell execution limits.
- Clamp execute and wait yield times to the session's `max_yield_time_ms`
without terminating the running cell.
- Negotiate support with remote code-mode hosts and include non-default limits
in `session/open`, while keeping unlimited sessions compatible with hosts and
providers that do not support limits.
## Testing
- Cover yield-time clamping, zero-timeout behavior, and isolation between
sessions.
- Cover wire serialization, capability negotiation, unsupported hosts, and
shared process-host execution.
GitOrigin-RevId: 9517321cd605bb87f93eeaa6ba331cc2e346e582
## What changed
- Move the V8 implementation into a dedicated `codex-code-mode-runtime` crate used by `codex-code-mode-host`, removing the embedded runtime fallback from the Codex process.
- Resolve the host executable from the active installation layout and check its availability before selecting tools.
- Fall back to direct tools with a one-time warning when optional code mode is unavailable. Keep `code_mode_only` and `disable_in_process_fallback` configurations fail-closed.
## Testing
- Cover host discovery for standalone and package layouts, including missing hosts and symlinks.
- Verify direct-tool fallback, one-time warnings, and fail-closed code-mode-only behavior.
GitOrigin-RevId: 5aa3c6f1db148b2231fc24089a2ee0e2b00dbddb
## What changed
- Allow `features.code_mode_host` to use a configuration table with
`disable_in_process_fallback`. When enabled, failure to start the standalone
host is returned as tool output instead of falling back to embedded V8.
- Preserve the existing fallback behavior by default and continue accepting the
boolean feature toggle.
- Limit displayed host paths in spawn errors to 512 bytes while retaining the
executable-bearing suffix and valid UTF-8 boundaries.
## Testing
- Cover boolean and table-based feature configuration, fallback-disabled host
failures, and bounded ASCII and UTF-8 error paths.
GitOrigin-RevId: ab3d014e79054c2f8beef9a658915f01cca197b2
## What changed
- Add `--code-mode-host ws://...` and `wss://...` support to `codex app-server`, gated by the `code_mode_host` feature. When omitted, app-server continues to start a local host.
- Share one remote WebSocket connection across the process's threads, using the configured HTTP client's proxy and TLS policy and preserving the existing framed host protocol.
- Reject invalid host URLs, bound WebSocket frame sizes, close connections cleanly, and return an error when a connection exceeds 1,024 pending delegate calls without disconnecting it.
## Testing
- Cover CLI validation, WebSocket protocol execution and shutdown, connection sharing across app-server threads, and delegate-call capacity recovery.
GitOrigin-RevId: 715e82d4d9db1e7e2f91b754a777dcab504e2ae4
## Why
Not every Codex distribution currently includes the
`codex-code-mode-host` companion binary. Enabling the process-host
feature should not make code mode unavailable on those surfaces while
packaging support is being completed.
## What changed
- Fall back to an in-process code-mode session only when spawning the
companion binary returns `io::ErrorKind::NotFound`.
- Keep permission, handshake, timeout, and other host failures visible
instead of silently falling back.
- Store the provider's owned-process/in-process choice as one
enum-backed state so later sessions reuse the fallback decision.
- Preserve the underlying spawn `io::Error` while retaining the host
path in the displayed error.
- Update provider, `CodeModeService`, and end-to-end coverage to verify
successful fallback execution.
## Test plan
- `just test -p codex-code-mode`
- `just test -p codex-core missing_process_host`
## Summary
- add the `code_mode_host` feature flag and select
`ProcessOwnedCodeModeSessionProvider` in `CodeModeService` when enabled
- initialize code-mode sessions lazily so a missing host reports a tool
error without failing thread startup
- resolve `codex-code-mode-host` beside the running Codex binary by
default while preserving `CODEX_CODE_MODE_HOST_PATH` as an override
- add unit and end-to-end coverage for host resolution and graceful
missing-host behavior
## Why
This wires the process-owned session client from #30112 into the core
service behind an opt-in rollout gate. Packaged Codex installations can
place the helper in the same `bin` directory as the main executable
without relying on `PATH`, while development and custom installations
can continue to override the helper path.
## Stack
- Depends on #30112
- Base branch: `cconger/process-owned-session-runtime-4-client`
## Validation
Build `codex` and `codex-code-mode-host`
`CODEX_CODE_MODE_HOST_PATH="$PWD/target/debug/codex-code-mode-host"
./target/debug/codex --enable code_mode_host`
## Summary
- add `ProcessOwnedCodeModeSessionProvider` and logical session
generation/rebinding state
- add the supervised child-process connection, reader/writer tasks, and
driver state machine
- make dropped execute/wait/open callers cancellation-safe with explicit
ownership handoff and durable cleanup
- validate cell/delegate lifecycle state and reject invalid protocol
transitions
- add end-to-end stdio coverage for delegates, cancellation, frame
limits, child loss, stale generations, replacement, and long-lived
sessions
## Why
This final stage exposes the process-owned client only after the wire
protocol, host-safe runtime, and standalone host are independently in
place. Transport failure is fail-stop: the client closes local state,
cancels callbacks, reaps the child, and lazily rebuilds a fresh host
generation rather than transactionally recovering the old connection.
## Stack
This is **4 of 4** in the process-owned code-mode session stack.
- Depends on #30111
- Full stack: #30108 → #30110 → #30111 → this PR
## Validation
- `just test -p codex-code-mode -p codex-code-mode-host` — 86 passed
- `just fix -p codex-code-mode`
- `just fix -p codex-code-mode-host`
- `just bazel-lock-update`
- `just bazel-lock-check`
- `bazel test //codex-rs/code-mode:code-mode-unit-tests
//codex-rs/code-mode-host:code-mode-host-unit-tests
//codex-rs/code-mode-host:code-mode-host-stdio-test
//codex-rs/code-mode-protocol:code-mode-protocol-unit-tests` — 4/4
passed
- `just fmt`