## What changed
Expose `Environment::observe_connection_attempts` and `ConnectionAttemptOutcome` to report elapsed time and success, failure, or cancellation for initial connections. Measure from the end of provisioning through client installation, including connection retries.
The first registered observer wins. Past attempts and reconnections are omitted.
## Testing
Extend tests to assert failure followed by success when startup is retried, and a single cancellation notification when an environment is replaced during startup.
GitOrigin-RevId: 88300f38dcf9428b824c5ff36aa1b40d7d466b6f
Use Codex `0.162.1` instead of `0.156.1` for
`exec-server-stable-release-test`, updating the Bazel release archive version,
checksum, and repository reference.
GitOrigin-RevId: 304108b223da1e5506483f53c476a55a8f31ce71
## Why
Remote configuration reads need a bounded wait without disrupting valid in-flight work on connections that cannot reconnect.
## What changed
- Add `read_environment_config_with_timeout` to `ExecServerClient` and `Environment`, bounding RPC sending and receiving after connection establishment. Local reads retain their existing behavior.
- Return a typed `ExecServerError::RpcTimedOut` and classify it as retryable for read-only preparation.
- Share timeout handling with environment-info requests. Close the timed-out transport and request recovery only when a reconnect strategy exists; otherwise, keep the connection open.
## Testing
Add a regression test verifying that a timed-out configuration read preserves an in-flight stdio read and allows subsequent reads on the same connection, including after a late response.
GitOrigin-RevId: 6785d5846f4c3b07a6e7c505e359238609c3a6b6
## What changed
Add `preserve_fork_prefix` to the multi-agent v2 configuration, defaulting to `false`. When enabled, full forks retain the parent's model-visible history, including commentary and tool records, and append the child's instructions. Legacy compaction without a reusable context baseline still rebuilds the child context.
Mark copied history as inherited, complete unfinished tool calls in the fork snapshot, and exclude inherited manual approvals from authorization review while retaining them in model context.
## Testing
Add coverage for preserved request prefixes, child instructions, legacy and paginated histories, Code Mode, missing inherited tool outputs, compaction fallback, and approval isolation across checkpoint replay. Update the noisy helper failure test to read its response before starting cleanup.
GitOrigin-RevId: ce9235dfa111c88d6ce66cb93d564fb63b326489
## What changed
- Add optional `websocketRequestId` to `environment/add` and send it as `X-Request-ID` on direct WebSocket upgrades, including reconnects. It requires a secure transport or a loopback destination.
- Echo a supplied `X-Request-ID` in the exec-server WebSocket upgrade response.
## Testing
Add coverage for `websocketRequestId` serialization and for handshake header forwarding and echoing, both with and without a request ID.
GitOrigin-RevId: 235303ff7e1150405b7e1158d6024223144e0cc3
## Why
Command processes need thread and tool call labels for correlation, without stale values from inherited environments or cached shell snapshots.
## What changed
- Export the originating `exec_command` call ID as `CODEX_TOOL_CALL_ID`; later `write_stdin` calls leave it unchanged.
- Apply executor metadata as `CODEX_THREAD_ID` and `CODEX_TOOL_CALL_ID` after environment policies, overlays, and snapshot replay. Clear omitted fields when metadata is present; without metadata, preserve thread context and remove the call ID.
- Exclude both IDs from newly captured snapshots and omit the call ID from capture and validation helpers.
- Preserve empty call IDs, omit NUL-containing IDs, and handle case-insensitive environment names on Windows. Document that these labels support correlation, not authorization.
## Testing
Add regression coverage for metadata precedence, missing and invalid IDs, snapshot capture and replay, local and remote execution with pipes and TTYs, sandboxed remote execution, and preservation of the originating call ID across later input.
GitOrigin-RevId: 1027212b5d495d8e7cfac0f498c3134e060aa897
## What changed
Wire existing sandbox integrity checks into local command preparation, exec-server process preparation, and sandboxed filesystem helper and file-open operations. Make execution request preparation asynchronous so callers can await the checks.
The checks remain observational: failures and timeouts do not prevent command execution.
## Testing
Add regression tests that launch a real command after checker preparation fails or exceeds its timeout, verifying successful output and exit status.
GitOrigin-RevId: a82399f8aeb8b08f9965e6121b4c7f460552af3f
## What changed
Export `run_integrity_checks` from `exec-server` to check whether the effective filesystem policy permits writing containment dependencies on Linux, macOS, and Windows. Run preparation and checks on a blocking worker, limit waiting to five seconds, and keep results observational without affecting execution.
Skip mismatched sandbox backends, full-disk-write policies, and `EscalatedSandboxWithRestrictions` overrides. Continue checking ordinary configured policies with root write access and deny restrictions.
Record check outcomes, preparation time, and total duration with bounded metric tags that omit filesystem paths.
## Testing
Add coverage for findings, clean results, missing dependencies, preparation errors, eligibility rules, and timeouts. Verify that timed-out workers emit no late results and that metrics contain no filesystem paths.
GitOrigin-RevId: a234f4a2f629f9bb090da622cea352c99456cb00
## What changed
Enable the exec server's `sandbox_integrity` module on macOS and select the Seatbelt backend. Inventory the Codex executable and the system Seatbelt executable as critical dependencies.
Preserve the filesystem sandbox policy unchanged: Seatbelt handles deny globs as native patterns, so no snapshot scan is needed.
GitOrigin-RevId: 78299dd61e168f5ce34454c8b3bb887e67c5f342
## What changed
Add Linux dependency discovery and policy preparation to `exec-server`'s sandbox integrity module. Inventory bundled and system `bwrap` candidates and the deny-glob scanner using the launcher's location and the command's `PATH` and working directory.
Resolve `:tmpdir` and tilde-prefixed deny globs using the command's `TMPDIR` and `HOME`, with account home-directory fallback. Reuse Linux sandbox helpers to expand deny globs in the command's explicit environment.
## Testing
Add Linux tests covering symlinked launchers, relative and empty `PATH` entries, and empty, relative, and tilde-prefixed `TMPDIR` values alongside home-relative deny globs.
GitOrigin-RevId: fe404fa4be77ece677b22d52d77a7234dbf0cffe
## What changed
Add Windows MXC backend helpers to inventory the Codex executable, sandbox
launcher, and available `rg` scanner when deny globs are configured. Prepare
filesystem policies for inspection by reusing MXC temporary-directory and volume
resolution and replacing deny globs with concrete path snapshots.
Allow Windows deny-glob resolution to run its scanner with an explicit command
environment and working directory, including an empty environment. The integrity
helpers are not yet invoked by an execution runner.
## Testing
Add a backend test verifying that deny-glob snapshots replace the original
patterns, including empty snapshots, and affect `FileContentsChecker` results.
GitOrigin-RevId: 409c527663d230d76d65be3bf0a37959f694d77e
## What changed
Move `SandboxOverride` into the shared protocol and carry the controller's selection through tool attempts, execution requests, and exec-server process and filesystem sandbox preparation. Include it as `sandboxOverride` in filesystem sandbox contexts for observation without granting broader permissions or altering sandbox commands.
Default missing values to `NoOverride` and omit that value when serializing to preserve compatibility with existing requests.
## Testing
Extend tests to cover override propagation, wire round-trips for all three variants, and deserialization of requests without `sandboxOverride`.
GitOrigin-RevId: 2f438cf4aef1134e3149959d14aa731682168ae5
## Why
Executor config reads omitted the startup `features.prefer_mxc` override, so clients could not see the CLI sandbox preference.
## What changed
- Include the explicit CLI `features.prefer_mxc` value in `environmentConfig/read` as a `session-flags` layer, above project config and below legacy managed file and MDM config.
- Retain only this preference from startup overrides.
- Expose `windows_mxc_allowed_by_config` to share MXC eligibility checks after callers resolve the active permission profile.
## Testing
Add CLI and remote executor coverage for preference propagation and filtering, plus a unit test verifying that both legacy managed config sources retain precedence.
GitOrigin-RevId: 5ac6f5257f1e807c2f197dcf5dcb2385cedca0ea
## Why
Windows temp grants could fall back to host `TEMP`/`TMP` values and bypass read-only or denied subpaths. Sandbox permissions must match the environment passed to the child process.
## What changed
- Resolve `:tmpdir` from absolute `TEMP`/`TMP` paths in the completed workload environment, preserving access modes and missing-path rules without falling back to host values.
- Deduplicate Windows environment keys case-insensitively in a deterministic order so permission resolution and the child environment select the same value.
- Use the resolved temp policy for elevated sandbox overrides across core execution, exec-server, and direct spawning.
- Launch direct-spawn sandbox wrappers with the supplied Codex executable, materializing an inner helper only when it is that executable.
## Testing
Add Windows regression coverage for temp-only writes, read-only and denied carveouts, mixed-case and duplicate environment keys, unavailable temp paths, and empty or missing write-root overrides. Exercise core execution and direct spawning, and extend exec-server RPC coverage to the elevated backend with temp values set through the environment policy.
GitOrigin-RevId: 16b8bd4702cc434fd743a08c75a3e4515780bff3
## Why
On Windows 10, strict native opens can reject the DOS drive alias itself as a reparse point, preventing no-follow filesystem operations on ordinary drive-letter paths.
## What changed
Retry rejected drive-letter opens relative to a verified local volume root. Require the root to resolve to a physical disk volume directory without reparse attributes, and retain `OBJ_DONT_REPARSE` for paths beneath it so junctions remain blocked.
## Testing
Add Windows tests for file creation and reading through the volume fallback, opening the drive root, and rejecting junction traversal and creation. Validate accepted volume-root names and verify that named pipes are rejected without establishing a client connection.
GitOrigin-RevId: 51ffde4f77d2af45d18dfc4cb026d73a0e69b061
## Why
A stalled rendezvous WebSocket upgrade can prevent reconnects, while short-lived connections reset reconnect backoff too early. Blocked relay writes also prevent received pongs from clearing their heartbeat deadline.
## What changed
- Bound rendezvous WebSocket connection attempts with `DEFAULT_REMOTE_EXEC_SERVER_CONNECT_TIMEOUT`.
- Retain exponential reconnect backoff across short-lived connections, resetting it only after a connection lasts at least 120 seconds.
- Process pongs during blocked data writes while preserving the in-flight send and its independent write timeout. Prefer queued pongs over an expired heartbeat deadline.
- Abort the relay writer when its owning connection task is dropped.
## Testing
Add coverage for pongs arriving during blocked writes, missing and queued pongs, independent write timeouts, and writer cancellation. Extend reconnect tests to cover stalled WebSocket upgrades without re-registration and backoff reset after a stable session.
GitOrigin-RevId: 0efa350c2b4ada9b89e23df8909063fbb69f33dc
## Why
Rendezvous connection warnings report only a generic WebSocket error, while debug logs include raw error text. Structured diagnostics make failures easier to investigate without logging potentially sensitive error payloads.
## What changed
- Generate a request ID for each connection attempt, send it as `x-request-id`, and include it in the connection span and connection, disconnection, and failure logs alongside the attempt count.
- Replace raw error logging with typed error categories, I/O error kinds, HTTP status codes, and allowlisted values from `x-codex-rendezvous-rejection-reason`.
- Ignore unknown rejection reasons and response bodies.
## Testing
Add tests for rejection-header allowlisting, typed I/O failures, and a rejected WebSocket handshake that verifies the request ID header and preserves the HTTP status and known rejection reason.
GitOrigin-RevId: a8274fec965bcf5b8453b047c0bb79396cdf6ba4
## Why
File replay can accommodate shell state larger than the 512 KiB budget used for environment replay.
## What changed
Allow up to 4 MiB of shell state and 8 MiB of capture output for file replay. Keep captured environments capped at 512 KiB and preserve the 512 KiB combined state-and-environment limit for environment replay. Report distinct failures for oversized capture output, state, and environments.
## Testing
Add replay-specific size-limit tests and enlarge the Bash integration-test snapshot to exercise file replay beyond the environment replay budget.
GitOrigin-RevId: 0210848eb398d75426cb8b4b3bfaa0bce25264b8
## What changed
Add `codex.shell_snapshot.command` and `codex.shell_snapshot.wait_ms` metrics for eligible command preparations in the unified exec runtime and exec server. Tag observations with snapshot version, availability state, and whether replay was selected (`used`) or normal shell startup was used (`fallback`). Exclude background prewarming from command observations; `used` measures replay selection, not successful restoration or command completion.
## Testing
Extend snapshot retry tests to verify command counts and wait observations across fallback and recovery, excluding prewarm captures. Extend credential-broker approval tests to verify one `protected` snapshot observation for login-shell commands.
GitOrigin-RevId: d3d9f370b6bbba6dfc930a44044ce09373841799
## Why
Bubblewrap discovery probes executables before confinement. Excluding only the command's current directory leaves candidates in other writable roots eligible to run outside the sandbox.
## What changed
- Filter canonical `PATH` candidates using the filesystem policy and effective user permissions, including writable ancestors, symlinked roots, and full-disk write access. Preserve protected system installations while rejecting replaceable paths.
- Select the launcher with the command's permissions before the proc-mount preflight, retaining the bundled bubblewrap fallback.
- Use the effective permission profile and policy working directory for startup warning probes.
## Testing
Add unit coverage for writable roots, symlinks, read-only carveouts, replaceable parents, and full-disk policies. Add Linux integration tests showing writable `bwrap` candidates are neither probed nor launched, including when the command runs in a workspace subdirectory or uses managed networking with full-disk write access.
GitOrigin-RevId: 188c9f45e727eaace062f5abb1205dc23fdf3c51
## What changed
- Accept per-environment `skills.required` lists through `environment/add` and `environments.toml`.
- Before inference, require each named skill to be enabled and supplied by the selected environment. Missing skills fail the turn before a model request, including when environment setup fails.
- Stop applying an environment's requirements after it is deselected. Exempt isolated Guardian reviewers, which have no skill catalog.
## Testing
Add tests for available, missing, disabled, and wrong-environment skills, failed environment setup, recovery after deselection, and propagation of TOML requirements to the correct environment.
GitOrigin-RevId: 302ced4774697d2f414f745fe0535e71f747eda2
## Why
Remote executors need to recover from confirmed authentication-service outages and spread reconnect attempts after a shared outage. Registration retries must remain limited to confirmed failures before a write, since replaying an ambiguous request can replace a newer registration.
## What changed
- Retry registry responses with HTTP 502 and `authentication_service_unavailable`, alongside the existing HTTP 503 `registration_conflict` retries.
- Accept structured registry errors in `detail`, keeping the canonical `error` authoritative when both are present.
- Randomize reconnect delays between half and all of the current exponential backoff, retaining the 30-second cap.
## Testing
Add coverage for reconnect jitter bounds, authentication-outage retry cancellation, error-envelope precedence, and preservation of Noise identity and initialized sessions across retries. Make the HTTP-header helper cleanup test wait for the helper PID before cancellation and verify process termination when the provider is dropped.
GitOrigin-RevId: 35fdb57732d17b0bbfeca8a4dc557a0988e29a31
## What changed
Advertise `fileWriteStreaming` and support `fs/open` with `mode: "replace"` to create or truncate a file for writing. Implement `fs/writeBlock` with explicit offsets and nonempty chunks of up to 1 MiB, rejecting ranges beyond the signed 64-bit file offset limit.
Apply write sandbox permissions when opening writable handles, including when full-disk reads are allowed. Keep `read` as the default open mode.
## Testing
Add integration coverage for positional writes, chunk and offset bounds, replacement truncation, read/write handle permissions, and sandbox write restrictions. Verify that duplicate handle IDs and exhausted handle capacity reject replacement opens without creating or truncating files.
GitOrigin-RevId: 696ee6437dd5f5b69d5a7667dddea0ff44472094
## Why
The per-connection limit of 128 file read handles was checked only after opening the file, leaving pending opens outside the limit.
## What changed
Reserve a semaphore permit before polling the file-open future, counting pending opens and registered handles against the same limit. Release capacity when an open fails or is cancelled, or when a handle closes, even if a read still retains the file.
Use synchronous handle-table locks that never cross an await, and recheck duplicate IDs after opening to preserve the winning handle during concurrent opens.
## Testing
Add tests for stalled-open progress, pending-open admission limits, permit cleanup after failure or cancellation, capacity reuse while a file remains in use, and concurrent duplicate IDs.
GitOrigin-RevId: caabf38c74dda5951f2fc75234a7149daaa01263
## What changed
- Centralize `windows-sys` at version `0.61.2` in the workspace and migrate dependent crates to it.
- Adapt Windows API calls to the updated handle, boolean, and type definitions. Replace custom handle owners with `OwnedHandle` and use `BorrowedHandle` where ownership stays with the caller.
- Add explicit wrappers for non-owning Windows handles passed between threads.
## Testing
Enable the MCP refresh cleanup test on Windows. Retain process handles to verify that a superseded MCP server stays alive during an in-flight call, exits after cancellation, and leaves the replacement running until shutdown.
GitOrigin-RevId: 86f53d9b300d13edff7154f4a7c32e34dacd2919
## What changed
Add `CODEX_GUARDIAN_DECISIONS_API_KEY` to the non-inheritable environment variables and the HTTP header environment denylist. Case-insensitive filtering removes it from child process environments, including explicit shell policy and command overrides, and rejects its use through `http/request` header `value_env_var`.
## Testing
Extend regression coverage for inherited and overridden variables, mixed-case names, and HTTP header rejection before any network request is sent.
GitOrigin-RevId: 1adeef814fdccb2d6c77dd68f7a5dfcec0b41cc6
## Why
Concurrent Linux test spawns can inherit writable descriptors for executable fixtures, preventing those fixtures from being executed even after the writing test closes its descriptor.
## What changed
Replace direct executable fixture writes and copies across the Rust tests with `codex_utils_cargo_bin::write_executable` and `copy_executable`. These existing helpers complete writes and copies in separate processes on Linux.
Remove the empty temporary inode before creating fake bubblewrap executables, and stage tampered bubblewrap bytes in a separate data file before copying them into the executable fixture. Add the required test dependencies.
GitOrigin-RevId: c875c83088731a4933ef1574e8d79d8cecc12f54
## What changed
- Add `EmaAuthenticatedHttpClient` to cache and renew resource bearers, serialize concurrent renewals, and include authentication time in the request deadline. Confine bearers to the configured MCP endpoint and reject redirects.
- Return authentication-required errors for `401` responses without replaying MCP operations. Preserve a newer cached bearer when a delayed response rejects an older one.
- Add revocable request authority that cancels pending requests and ends response streams.
- Pin enterprise credentials to a persistent version advanced on save or deletion. Use short credential locks and invalidate rejected grants only when their record and version are still current, preserving newer logins.
- Hide keyring account identifiers from enterprise credential errors and traces while preserving authentication failure classification.
## Testing
Add tests for token expiry and renewal, endpoint confinement, redirects, request deadlines, revocation during renewal and streaming, delayed `401` responses, credential replacement and logout races, and credential error privacy.
GitOrigin-RevId: ee3e5cf7ecbba3d09e1ab29ed4fbb2a35eacc60d
## Why
Retaining process output, publishing events, and serving reads cloned the underlying byte buffers. Sharing those buffers avoids copying output bytes when chunks are cloned.
## What changed
Store `ByteChunk` bytes in `Arc<Vec<u8>>` and retain `ProcessOutputChunk` values directly. Add borrowed byte access for the MCP process transport while preserving base64 serialization and owned byte extraction through `into_inner()`.
## Testing
Add a unit test covering base64 serialization, deserialization, and independent owned bytes extracted from shared chunks.
GitOrigin-RevId: 6bba114af48424aa844487aa75163cfc604e0575
## What changed
Add `FsHelperOpenParams` with only a `path` field and use it for the exec-server filesystem helper's `fs/open` requests. Replace reuse of `FsReadFileParams`, removing unused read-file options from the open request type.
GitOrigin-RevId: ca84447d06fbf391cc5ad189ac6c46e6aeaa1f63
## What changed
Register `fs/writeBlock` and require filesystem initialization before handling it. Validate the file handle ID, then return an invalid-request error stating that writable file streams are unsupported.
GitOrigin-RevId: 13440e497a88ca6505ee60d95bbb771d3cae06b8
## Why
Older executors can ignore the file open mode and silently return a read-only handle for a writable open.
## What changed
Add `ExecServerClient::fs_write_block` and require the `file_write_streaming` capability for both block writes and `FsOpenMode::Replace` opens. Return a protocol error before sending either request when the executor lacks support, while allowing read-only opens.
## Testing
Add a WebSocket regression test verifying that unsupported writable opens and block writes are rejected locally and read-only opens still reach the executor.
GitOrigin-RevId: f206e1da80c12af76ead14c75f8ffe71f82cce89
## What changed
Return `Arc<EnvironmentInfo>` from `ExecServerClient::environment_info()` so repeated reads and cloned clients share cached metadata without cloning its contents. Wrap metadata from initialization and lazy RPC fetches in `Arc`, while preserving the owned return value in `LazyRemoteExecServerClient`.
## Testing
Extend the cache test to assert pointer identity across cloned clients for both initialization-provided metadata and lazy fetching after connecting to a legacy server.
GitOrigin-RevId: 3f56f4d51a4aebc0c4821c0b128a70efb23933d4
## Why
Failed shell snapshot captures could leave processes launched by shell startup files running after the capture ended.
## What changed
Run each Unix shell snapshot capture in its own process group and kill that group on failure, timeout, or cancellation. Keep the capture leader unreaped until output and exit status are validated so its process group ID cannot be reused during cleanup. Preserve startup helpers after a successful capture.
## Testing
Add regression coverage for startup child cleanup after nonzero exits, invalid output, cancellation, and timeout, alongside fallback and retry behavior. Verify that successful captures preserve delayed startup output and background services and reuse the cached snapshot.
GitOrigin-RevId: a56ef5d8615325952bdc8bb78727de1559e7e9c7
## What changed
- Add `read` and `replace` modes to `fs/open`, defaulting omitted modes to `read` for existing callers.
- Define `fs/writeBlock` request and response types for offset-based writes, with a maximum decoded chunk size of 1 MiB.
- Add the `fileWriteStreaming` capability, defaulting to `false`. Keep writable streams unsupported in the server and explicitly reject replacement opens.
## Testing
Add a protocol test verifying that legacy `fs/open` requests without a mode deserialize as read-only opens.
GitOrigin-RevId: 4d3997717e821cd1f62df12a03c8eec36332a66d
## What changed
Rename `file_read` to `file_handle` and `FileReadHandleManager` to `FileHandleManager`. Update the filesystem handler field, handle ID validation helper, and related constants to use file handle terminology. File operations, limits, and error messages remain unchanged.
GitOrigin-RevId: 25ad81a917386da23fd42ecff79bd47a482ce430
## What changed
Run direct `read_file` operations in a blocking task with bounded read chunks and cancellation checks. Dropping the async caller cancels further reads between chunks. Preserve the 512 MiB size limit, symlink-following options, and regular-file validation.
## Testing
Add regression coverage for 4 MiB reads and oversized-file rejection with both symlink-following options, cancellation after the first chunk, and FIFO rejection without waiting for a writer.
GitOrigin-RevId: 19f2816de15a03bd89b463de6b002367e6a692a9
## Why
A stuck transport can fill the outbound queue, leaving an `environment/info` request blocked while sending. The timeout must cover sending as well as waiting for a response.
## What changed
Wrap the live metadata RPC in a 30-second timeout. On timeout, close the probed connection and request session recovery, returning the timeout error without retrying the failed request. Document the experimental `environment/info` endpoint and its timeout behavior.
## Testing
Extend the WebSocket session recovery test to cover an unanswered `environment/info` request, checking that it times out, closes the connection, and resumes the same session while retaining the client instance.
GitOrigin-RevId: 9035d2edab3626e780d8bd40ebcdf0ca327bfddb
## Why
Elevated sandbox tests share machine-local Windows accounts. Concurrent setup can rotate account passwords between another test's setup and logon.
## What changed
- Add a shared file-lock guard for elevated sandbox tests in `codex-core`, `codex-exec-server`, and `codex-windows-sandbox`, held through sandbox commands and cleanup.
- Queue these tests in a single-threaded Nextest group before their timeouts start, while retaining the file lock to coordinate other test processes.
- Limit account locking to tests that use elevated accounts and remove the sandbox crate's blanket Bazel `exclusive-if-local` tag.
GitOrigin-RevId: 26d4606cb1fdcac65926d29835bed4eac04c19c0
## Why
Canceled RPC calls could leave entries in the pending request map until further traffic or disconnect. Cleanup should happen when the call is dropped, even if no response arrives.
## What changed
Use a `PendingRequestGuard` to remove each registration when its call completes or is canceled. Protect the pending map with a synchronous mutex so cleanup can run in `Drop`, replacing opportunistic pruning and explicit error-path removals.
## Testing
Add a regression test that drops an in-flight call and verifies that the pending request count immediately reaches zero without further traffic.
GitOrigin-RevId: 82c0629f37a2f4bb89b8d10e167e2a09765b26eb
Replace the three optional fields in `AttachmentState` with `Attached` and
`Detached` variants, making inconsistent field combinations unrepresentable.
Keep the connection ID in both variants and the expiration deadline only in
`Detached`, and update attachment and expiration checks to match on the state.
GitOrigin-RevId: 6a5f05f0ce2f064acc8f5cacd00bc374c4f47986
## Why
Background helpers launched from a detached Windows process can allocate console windows. Job Object launches and containment fallbacks need to preserve console suppression as well.
## What changed
- Add `codex_utils_process::background_command` to set `CREATE_NO_WINDOW` on Windows, and use it across background subprocess launches, including Git, plugins, authentication, diagnostics, and sandbox helpers.
- Centralize console suppression in Job Object launches. Keep `CREATE_NO_WINDOW` when retrying without containment, and clear `CREATE_SUSPENDED` so the fallback child can run.
- Preserve console inheritance for interactive shell launches and interactive AWS authentication refreshes.
## Testing
Add Windows regression tests covering console-free launches from detached parents through standard and Tokio commands, stdout/stderr capture, successful containment, Job Object creation and assignment failures, and sandbox setup refresh helpers.
GitOrigin-RevId: b2c238fa7d4f9fbd868e5adf7d4be9958ff01e6c
## Why
Remote controllers cannot resolve a sandbox-compatible PowerShell executable on the execution host.
## What changed
Apply the existing PowerShell fallback during exec-server request preparation for the `Elevated` and `Mxc` Windows sandbox backends. Match `pwsh` and `powershell` executable names case-insensitively and replace inaccessible Store PowerShell paths when a compatible executable is available.
## Testing
Add Windows RPC regression tests for lowercase and mixed-case PowerShell aliases with a restricted server `PATH`, verifying successful command execution in the `Mxc` sandbox.
GitOrigin-RevId: 365541af2f026a662b1988429f5d182c98e4a236
## Why
Concurrent tests can inherit writable descriptors for executable fixtures, causing `ETXTBSY` when those fixtures launch on Linux.
## What changed
Expose shared `write_executable` and `copy_executable` helpers from `codex_utils_cargo_bin` and adopt them in CLI, exec-server, and MCP tests. On Linux, writes and copies complete in separate processes so sibling test spawns cannot inherit the writable descriptors. Script fixtures receive mode `0o755`, and copied executables retain their source permissions.
Remove the executable-busy retry loop from the program resolver test now that its script uses the shared helper.
GitOrigin-RevId: 61624158190bb1e75c27d9eb9c87a2defc147fb7
## Why
A provisioned executor can still be resuming after readiness is reported. Initial connection attempts can exhaust the ordinary registry retry limits before the executor comes online.
## What changed
Retry `environment_offline` registry responses during initial Noise rendezvous connections for provisioned environments until a fixed five-minute deadline, starting after provisioning succeeds. Keep the existing retry limits for other registry errors and stop on permanent failures.
## Testing
Add tests covering the five-minute deadline, ordinary limits for other errors and stalled requests, and termination on a later permanent error. Verify that readiness and info requests remain pending through an extended offline period and succeed using the same environment handle once the executor comes online.
GitOrigin-RevId: e22211499d9ec2f3590e75224eb39e2e4bf3538d
## Why
Private IP destinations always bypassed inherited upstream proxies, preventing their use for private networks reachable through an upstream VPN proxy.
## What changed
- Add `codex exec-server --proxy-private-ips-via-upstream`, also configurable with `CODEX_EXEC_SERVER_PROXY_PRIVATE_IPS_VIA_UPSTREAM=true`. The setting defaults to disabled.
- Allow permitted RFC 1918, carrier-grade NAT, and IPv6 unique-local destinations to use an applicable upstream proxy. Loopback and link-local destinations retain direct routing, and destination access policy still applies.
- Keep connections direct when no valid upstream proxy applies or `allow_upstream_proxy=false`. Errors after selecting an upstream proxy do not trigger a direct retry.
- Rename `ExecServerRuntimePaths` to `ExecServerRuntimeOptions` and carry the routing setting from executor startup into the managed network proxy.
## Testing
Add routing coverage for private address ranges, special-use addresses, and public targets with the option enabled and disabled. Verify that HTTP and CONNECT requests still enforce destination allowlists and denylists, and update the CLI help snapshot.
GitOrigin-RevId: b7c9cc7da0e0f545694a6521b74c9b36b7b92769
## Why
Sourced snapshots parse options and aliases as a group before restored options take effect. Aliases serialized with `RC_QUOTES` enabled can therefore be misinterpreted by the replay shell.
## What changed
Serialize zsh aliases for sourced snapshots with `NO_RC_QUOTES` in a subshell, preserving the captured shell options and avoiding a dependency on the optional `zsh/parameter` module.
## Testing
Extend regression coverage to execute restored aliases with `RC_QUOTES` enabled and disabled across source and eval replay. Expand macOS zsh concurrent replay tests to cover quoted aliases, preserved options, and blocked descriptor paths with and without a TTY.
GitOrigin-RevId: 48086f380c21318bece9226dfe6486c179c2a440
## Why
Large shell snapshots need a replay path that does not add their state to the child process environment.
## What changed
- Keep captured state cached in memory and give each Bash or Zsh launch an independent, read-only file descriptor to source. Unlink the file before writing shell state, create it under the sandbox-protected daemon directory, and close the carrier descriptor before restoring functions.
- Probe descriptor-path access inside the capture sandbox. Retain environment replay for `sh` and when descriptor paths are unavailable; use normal shell startup if preparing the replay file fails.
- Group options and aliases during capture so sourcing preserves their parsing behavior.
## Testing
Add coverage for concurrent replays with 480 KiB payloads, pipe and TTY execution, stdin preservation, descriptor cleanup, sandbox protection, blocked descriptor-path fallback, and alias/option parsing equivalence.
GitOrigin-RevId: 8103d5c37ce4d1885628a4efba3551549f12bea8
## Why
When a container denies fresh `/proc` mounts, the existing sandbox fallback retains the caller's `/proc` while creating a new PID namespace. Process IDs inside the sandbox can then differ from those exposed by `/proc`, breaking process lookups.
## What changed
- Add `codex exec-server --linux-sandbox-pid-namespace=inherit` to reuse the caller's PID namespace and `/proc` for both process and filesystem helpers. Repository config and command environment variables cannot enable it.
- Keep `isolate` as the default, preserving the existing mount fallback and compatibility with older helpers. Inheritance requires an updated helper and omits `--unshare-pid` and `--as-pid-1`.
- Preserve other sandbox restrictions. With `:minimal`, bind the inherited `/proc` read-only with its container masks and apply explicit filesystem denials afterward.
Inheritance is intended for dedicated environments: it allows sandboxed commands to signal other same-UID processes, including the executor.
## Testing
Add unit and integration coverage for namespace flags, denied proc mounts, consistent process IDs, retained sandbox restrictions, and startup-only selection across process and filesystem helpers.
GitOrigin-RevId: dd13f2b9286d7edcf366b3a42a455f4d78daaf27
## Why
Local `apply_patch` permission checks can treat a macOS system alias and its canonical spelling as different locations, sending writes covered by temporary-directory grants for unnecessary approval.
## What changed
- Normalize trusted top-level aliases in local policy roots and patch targets, reusing a prepared matcher for permission requests and patch safety checks.
- Share alias normalization with Seatbelt and the macOS executor sandbox while preserving mutable symlinks and missing descendants.
- Preserve read-only and deny precedence, protected metadata restrictions, and remote URI matching. Propagate normalization failures from fallible permission checks.
## Testing
Add macOS regressions for multi-file patches with missing parent directories through both direct `apply_patch` calls and shell interception, asserting automatic approval and file contents. Add unit coverage for alias restriction precedence, mutable symlink preservation, missing descendants, and remote permission isolation.
GitOrigin-RevId: 0822ff951eaab728cb1ad91281745fa1b8809f15