## Why
A temporary exec-server transport loss could emit a thread environment disconnect notification while the session was still recovering.
## What changed
- Add `EnvironmentConnectionState::Recovering` for interrupted transports and pending session recovery.
- Suppress thread lifecycle notifications during recovery, emit a connected notification after successful recovery, and report disconnection when recovery fails.
- Ignore recovery callbacks from retired clients so they cannot overwrite the connection state during refresh.
## Testing
Add coverage for fast and near-deadline recovery, recovery timeout, rejected session resume, and retired-client callbacks. Extend app-server coverage to verify one lifecycle notification per selected thread and usable `environment/info` after recovery.
GitOrigin-RevId: d6dce5cc5264af29b6f993daa209b93102122e40
## What changed
- Build executor skill catalogs from discovery V2 inventories without reopening host paths or falling back to legacy discovery.
- Merge Cloud and executor skills by remote plugin identity and skill name, retaining Cloud metadata and accepted provider read routes. Apply plugin selection and disablement before merging.
- Share a stable catalog across each step's rendering, list/read tools, and explicit and implicit skill invocations.
- Preserve unmatched executor entries when Cloud catalogs are unavailable or partial; only complete Cloud catalogs disable unmatched remote entries.
- Bind discovery caches to captured environments and executor sessions, and refresh MCP when V2 inventories change. Preserve pending invalidations when forced MCP refreshes fail.
## Testing
Add regression coverage for V2 inventory sharing and refresh, environment isolation, catalog merging, partial Cloud results, disabled plugins, and catalog consistency across steps and read routes.
GitOrigin-RevId: 842bdcbc9e19364dd69a9abf9e48330b7425a76c
## What changed
Add `write_file_stream` to `ExecutorFileSystem` and `EnvironmentAccess`, preserving the accessor's captured sandbox permissions. Local and streaming-capable remote filesystems replace files one bounded chunk at a time and return the byte count. Older executors buffer the input before sending a single `writeFile` request.
Close remote handles on completion or failure, perform best-effort cleanup after cancellation, and invalidate pending metadata lookups. Document that failure or cancellation can leave a truncated or partial file and that in-flight I/O may outlive cancellation.
## Testing
Add coverage for sequential writes, binary and empty files across local and remote filesystems, source failures, handle cleanup, metadata invalidation after cancellation, and compatibility with older executors.
GitOrigin-RevId: d3eb44e0ac2f0f336e9e157d686464f4d45a3f26
## Why
Remote credential masking previously supported only Bash commands without login startup or shell snapshots, leaving Zsh commands with unmasked credentials.
## What changed
- Enable masking for Zsh login commands using shell snapshots on Linux and macOS.
- Capture trusted startup profiles per launch, bind the credential broker to the resulting environment, and replace credentials and supported aliases with placeholders before snapshot replay.
- Preserve explicit environment overrides, credential unsets, and launcher-managed proxy settings during replay.
- Warn and fall back to unmasked startup when a snapshot cannot safely replay credentials; stop execution if protected snapshot restoration fails.
## Testing
Extend remote execution tests for inherited and profile-defined credentials, overrides, destination changes, and unsupported-profile fallback. Add a Zsh scenario snapshot showing a credential placeholder in command output.
GitOrigin-RevId: 83193d6cbc05f3deb0d6d0b9ae80974b353ce900
## What changed
Negotiate executor support for `credential_masking` and enable built-in credential brokerage in executor-local network proxies. Supported non-login Bash commands on Linux and macOS receive credential placeholders, with real credentials injected by the proxy for matching destinations.
Retain credential mappings across process launches within the same executor session, scoped by environment, conversation, and broker configuration. Keep credentials and destination context on the executor.
Fall back to unmasked execution for unsupported shells or shell startup, and for configured credential providers. Emit warnings when masking is unavailable, preserving shell profiles and snapshots.
## Testing
Add coverage for capability negotiation, fallback behavior, mapping reuse and isolation, proxy credential injection, and keeping executor credentials out of model-visible request history. Test warning, removal, and rejection modes for credentials left unmasked during preparation.
GitOrigin-RevId: f64e916a5de8350fa0d289d3440ec29761accd75
## Why
Windows MXC needs valid host startup variables, while an empty child environment must remain empty for the SDK to select Windows user-profile defaults.
## What changed
- Replace caller overrides of `SystemDrive` and `LOCALAPPDATA` case-insensitively with nonempty Unicode host values, failing before launch if either is unavailable.
- Track whether the original child environment was empty, ignoring launcher transport keys. Supply host `SystemRoot` for launcher bootstrap in that case, then clear the bootstrap environment before the SDK selects defaults.
## Testing
Extend transport tests to cover host-value replacement and preservation of empty child environments. Strengthen the PowerShell fallback RPC test to require `SystemDrive`, `LOCALAPPDATA`, `USERPROFILE`, and `PATH` in the child.
GitOrigin-RevId: a097e1079069ef897ebb5ba5e63546328c5faeaa
## What changed
- Return qualified skill names such as `team:deploy` and parsed `dependencies` and `policy` instead of a separate namespace and raw metadata file. Share `agents/openai.yaml` parsing and validation between skill loaders and executor discovery.
- Include each standalone skill's search-root ID and path in `discoveryRoot`, while accepting responses from older executors that omit it.
- Add plugin `displayName`, falling back to the manifest name or installation directory.
- Materialize inline MCP declarations in `mcpConfig` with the manifest as their source path, and report incomplete discovery when declared MCP or Apps configuration files have no returned contents.
## Testing
Add coverage for JSON round trips, omitted `discoveryRoot`, optional and invalid skill metadata, qualified names, display-name fallbacks, and inline MCP configuration. Verify standalone search roots survive cached discovery and sandboxed RPC responses.
GitOrigin-RevId: 4124972444ad7c2fb8c6418acbf9a589d797fad2
## What changed
- Register `capabilities/discoverV2` for initialized sessions and expose it through `ExecServerClient` and remote `Environment` APIs, checking executor support before calling it.
- Reuse startup discovery locations and retry failed prewarming on demand. Replay discovery once after executor recovery while preserving the request parameters.
- Track whether all required filesystem watches registered successfully and reload locations and metadata on each request when registration fails.
## Testing
Add coverage for RPC metadata refresh, omission of skill instruction bodies, sandbox isolation, startup scan recovery, disconnect replay, and successful or failed watch registration.
GitOrigin-RevId: 726e8f7e8b4d835b877f31d1d8a9f8eea1ad9c8b
## 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
## 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
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
## 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
## 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
## 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
## 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
## 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
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
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
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
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
## What changed
- Define `capabilities/discoverV2` request and inventory types and advertise `capabilityDiscoveryV2` in executor metadata.
- Prewarm installed plugin and global skill locations at server startup, with nonfatal scan failures.
- Add sandbox-scoped discovery caching with file watcher invalidation and request-time reloads when watching is unavailable.
- Batch metadata reads through the filesystem sandbox helper and bound discovery responses to 4 MiB and 2,048 capabilities.
- Share plugin identity and installed-version selection in `codex-core-plugin-common`, and fall back to `.app.json` when a plugin does not declare an apps configuration.
The V2 discovery manager is not yet wired into RPC request dispatch.
## Testing
Add coverage for inventory metadata, sandbox cache isolation, watcher invalidation, startup scan failures, response limits, and compatibility with older executor metadata.
GitOrigin-RevId: a223a5bc15fdf251023c0c71f468fd92c3b2d847
## What changed
Add `resolve_root_git_project_uri_for_trust` to resolve repository trust roots through `ExecutorFileSystem` using executor path conventions. Share repository and linked-worktree validation with native lookup while preserving native ancestry for paths with opaque URI representations.
Extract `ProjectTrustLookup` to match merged project settings using supplied path spellings and an explicit path convention. Preserve canonical-before-original and cwd-before-repository-root precedence, including cwd entries without a trust level, with ASCII case-insensitive matching for Windows.
## Testing
Add coverage for POSIX, Windows drive and UNC trust roots, project-key precedence and case handling, and native/URI lookup parity. Extend environment-config coverage to verify returned `projects` entries include entries without a trust level.
GitOrigin-RevId: 315434802e86cceee85b14bc1c3767a45e3139f5
## What changed
Expose the shared `--ws-auth` options on `codex exec-server` for direct WebSocket listeners. Support capability tokens configured by token file or SHA-256 digest, and signed JWT bearer tokens. Validate `Authorization: Bearer TOKEN` before each WebSocket upgrade, rejecting missing or invalid credentials with HTTP 401 when authentication is enabled.
Reject listener authentication with stdio, `--remote`, or `forward`. Document the options and connection-time authentication behavior.
## Testing
Add CLI integration tests for all three credential configurations, unauthorized upgrade rejection, authenticated RPC initialization and reconnects, invalid configuration, and incompatible transports.
GitOrigin-RevId: 941fbd3d43e732c910d29b6f8137077b7c332835
## What changed
- Route remote-control enrollment, pairing, client management, and WebSocket connections through the authenticated HTTP client factory. Keep policy denials distinct from authentication failures and wait for policy changes before reconnecting.
- Preserve policy denials through exec-server connection failures so later connection attempts and capability discovery can recover. Keep direct executors running through temporary policy outages while rejecting permanent policy failures.
- Build cached HTTP transports on blocking workers, serialize construction, and retain successful builds after callers time out so request deadlines cover queued construction.
## Testing
Add regression coverage for policy recovery during remote startup, direct registration, accepted WebSocket reconnection, and capability discovery; queued transport construction timeouts; and remote-control WebSocket fallback with invalid custom CA files.
GitOrigin-RevId: c81db18e83de957175bb213d165281ac701089dd
## Why
Filesystem helpers use a `pre_exec` callback to close inherited descriptors on macOS, forcing a fork before execution. Native spawning needs to preserve that isolation and support the socket used for file descriptor transfer.
## What changed
- Launch filesystem helpers through `codex_utils_pty::Command`, using `posix_spawn` with `POSIX_SPAWN_CLOEXEC_DEFAULT` on macOS and returning native launch errors without a fork fallback.
- Extend the shared command wrapper with explicit descriptor and fallback policies, socket-backed stdin, and custom `argv[0]` support.
- Add `Child::wait_with_output` to drain stdout and stderr concurrently, retain kill-on-drop behavior on cancellation, and keep output pipes open until the child exits.
## Testing
Add regression tests for fork-free sandboxed reads, writes, and file descriptor transfers; sandbox denial of outside paths and symlink escapes; descriptor isolation; bidirectional socket stdin; custom `argv[0]`; executable-format errors; and output-pipe lifetimes.
GitOrigin-RevId: d49c00787f30ec0bc196f9e066a0770fc8151152
## What changed
- Remove the private-desktop opt-out from elevated and unelevated Windows sandbox launches.
- Remove `windows.sandbox_private_desktop` and its managed requirement and API fields. Warn users to remove the obsolete setting.
- Require a private desktop name when launching through the Windows sandbox wrapper and command runner.
## Testing
Add coverage for the obsolete-setting migration warning and update wrapper tests to verify a live private desktop is passed and a missing desktop name is rejected.
GitOrigin-RevId: c7135f8d211aac8d812180691c2c1e433d77cde4
## What changed
Add `EnvironmentAccess` and `FileSystemEnvironmentAccessor` to expose filesystem operations with a captured sandbox configuration, without allowing consumers to extract the filesystem or select another sandbox. Include a text-reading helper and an explicit unrestricted constructor.
Provide opaque cache keys that compare filesystem identity and captured permissions without keeping the filesystem alive. Allow opened read streams to outlive the accessor. Export the new APIs through `codex-exec-server` and add `Environment::filesystem_ref()` for borrowing the shared filesystem.
## Testing
Add local and remote coverage for text reads through `EnvironmentAccess`, streams surviving accessor disposal, and cache keys distinguishing changed permissions or a replacement filesystem.
GitOrigin-RevId: 4f6787ed9ba0fb94adea2f31716c4d3132fed07d
## Why
Filesystem reads previously required a sandbox whenever writes were restricted, even with full-disk read permission. This made permitted reads depend on sandbox availability.
## What changed
- Select sandboxing independently for reads and writes, allowing full-disk reads directly while keeping restricted operations sandboxed.
- Use the executor's path convention when evaluating full-disk access, including `:slash_tmp` denials.
- Apply read-specific checks to capability discovery and skill resource reads, allowing unrestricted reads on executors without sandboxed discovery support.
## Testing
Add regression tests for direct read APIs, restricted writes and reads, executor-specific permission rules, and capability discovery without sandbox support. Update Windows tests to verify sandbox enforcement through writes.
GitOrigin-RevId: a03844bd1f0ea583bb54326683cddbfdd050119f
## Why
Removing the selected working directory can prevent filesystem sandbox helpers from launching, even when the requested absolute paths remain accessible. Permission rules must stay anchored to the selected directory while those operations continue.
## What changed
- Require a policy `cwd` in `FileSystemSandboxContext` and launch filesystem helpers from the filesystem root while preserving the policy directory and workspace roots.
- Carry explicit `policyContext` in filesystem RPCs, preserving legacy wire fields and resolving omitted directories from older clients at executor ingress.
- Keep permission paths as executor file URIs and validate host compatibility where they are enforced.
- Bind Windows relative denial globs to the policy directory before changing the helper's launch directory, preserving home-relative patterns.
## Testing
Add regression coverage for `apply_patch` after working-directory removal, legacy RPC directory fallbacks, cross-platform permission URI transport, and Windows relative read denials. The patch regression verifies that an allowed file is updated while an explicitly denied file remains unreadable and unchanged.
GitOrigin-RevId: b0f4db722b27cb72ec129fc297c85732afac11f7
## Why
MXC is a sandbox implementation, not a restricted-token sandbox level. Executor requests need to represent that choice separately from `WindowsSandboxLevel`.
## What changed
- Introduce `WindowsSandboxSelection` for executor sandbox contexts and remove `Mxc` from `WindowsSandboxLevel`.
- Preserve the `windowsSandboxLevel` wire field and its serialized values for compatibility.
- Share sandbox selection between executor process launches and filesystem helpers, and use the new selection in capability discovery and skill reads.
- Disable Windows sandbox selection for executor paths that do not use Windows path conventions.
## Testing
Extend coverage for MXC wire serialization, Windows skill-read sandbox checks, and capability discovery with distinct permissions. Exercise remote filesystem write restrictions with both restricted-token and MXC sandboxes, including rejection when native MXC is unavailable.
GitOrigin-RevId: 266211377bcb138a0dc75861e9ff2225fa37a53d
## What changed
- Report `windows_mxc` from native MXC availability on Windows.
- Allow MXC TTY launches and managed networking, using dedicated proxy listeners without requiring a shared-ingress restricting SID.
- Reject MXC custom `argv0` and private-desktop launches, and continue failing closed when native MXC is unavailable.
## Testing
Extend the Windows remote sandbox process-write test to cover MXC with both pipes and ConPTY. Retain coverage for rejecting MXC requests when native support is unavailable.
GitOrigin-RevId: 80c5f319b9066d06b26f0a7eb7119a109e6ebef7
## What changed
- Add explicit MXC backend selection and carry its identity through exec-server process reporting and sandbox violation classification.
- Launch MXC through the Codex executable with the effective permission profile and command environment.
- Reject exec-server MXC requests when native MXC is unavailable or when they request a TTY, an `arg0` override, or managed networking. Reject private desktop isolation during MXC preparation.
- Allow an explicitly empty child environment and avoid exposing request payload values in launcher decode errors.
## Testing
Add coverage for sandbox selection and unsupported-request rejection, plus Windows RPC tests for stdin writes and temporary-directory permissions derived from the command environment. Native MXC tests skip when MXC is unavailable.
GitOrigin-RevId: 3626ff0f9ad7f9b812ce09b68c31ea9a5a9c72b1
## Why
Private desktops owned by short-lived sandbox wrappers disappear when those wrappers exit, preventing reuse across filesystem helper requests.
## What changed
- Select and cache private desktops in the calling process, keeping desktops separate for different sandbox permissions.
- Pass the desktop name through the wrapper to the restricted-token and elevated backends so helpers reuse the selected desktop.
- Separate sandbox account preparation from filesystem ACL refresh so desktop selection does not perform the wrapper's refresh.
- Propagate desktop preparation errors and require a desktop name when the wrapper's private desktop flag is set.
## Testing
Add a Windows filesystem regression test covering desktop survival and reuse across reads, writes, metadata queries, and streaming reads, plus separate read-only permissions and rejected writes. Extend wrapper argument tests to cover named desktops and rejection of a missing desktop name.
GitOrigin-RevId: 05a1cb829a902732248bfa7f4ad7470d911fa9f6
## Why
Line-based export parsing can truncate multiline values or mistake their contents for declarations. Snapshot replay also needs to restore Bash options before parsing functions that use extended glob syntax.
## What changed
- Capture shell state, aliases, and complete export records with NUL-delimited boundaries, separating capture, credential preparation, and rendering.
- Apply credential and environment policy to whole exports, preserving multiline values and making credential aliases follow allowed overrides.
- Restore Bash `shopt` options before functions, including for Bash running as `sh`.
- Support non-evaluating POSIX `ENV` path expansion and preserve native environment metadata and unset exports.
- Move core and exec-server snapshot consumers to the shared capture parser. Allow capture overhead while enforcing the exec-server's 512 KiB state-and-environment limit before filtering.
## Testing
Add regression coverage for complete capture records, multiline export filtering and replay, credential alias overrides, `ENV` expansion, and `PATH` export state. Extend exec-server tests to cover Bash-backed `sh`, `extglob`, `nocasematch`, `set -u`, and large environments.
GitOrigin-RevId: 7589ab4d137529a395dcee10b5162718de24a621
## Why
Executor compatibility checks need a build identity that distinguishes commits
and compiler targets independently of the package release version.
## What changed
- Add optional `providerId` to exec-server environment metadata, cached at startup
and returned by initialization and `environment/info`.
- Derive the ID as SHA-256 of `git:<lowercase commit>:<target>`. It identifies a
standard build configuration, not exact executable bytes, and is omitted when
the commit stamp or target is unavailable or invalid.
- Embed the compiler target in `BuildInfo`, preserve compatibility with historical
metadata without a target, and stamp Cargo release builds with `STABLE_GIT_COMMIT`.
- Group Bazel build-script argument files under one `--arg-file` flag to reduce
Windows command-line length while preserving file order.
## Testing
Add deterministic build-ID vectors across targets, commit normalization and invalid
input coverage, and historical metadata compatibility tests. Extend exec-server
coverage for metadata caching and ensure runtime environment overrides cannot
replace the executor's build identity.
GitOrigin-RevId: 125a18c23de7ad006571940ba305836376c983f4
## Why
Allow remote exec servers to connect directly to AWS-hosted registries that
authenticate registry requests and WebSocket handshakes with AWS SigV4.
## What changed
- Add `--remote-transport direct` with SigV4 profile, region, and service
options while keeping Noise as the default transport.
- Register the `direct_jsonrpc_v1` transport and carry plain exec-server
JSON-RPC messages over the authenticated WebSocket.
- Reuse direct registrations across transient disconnects, refresh them after
a `409 Conflict`, and require TLS for non-loopback endpoints.
## Testing
- Cover CLI validation and SigV4 request signing.
- Exercise direct registration, handshake retry behavior, JSON-RPC
interoperability, and process recovery after reconnecting.
GitOrigin-RevId: 0755df330ba3abe5db0a516fdaa49338d9bbe2d2
## What changed
- Add the macOS-only `allow_symlinked_codex_home` user setting. When enabled in the execution host's `$CODEX_HOME/config.toml`, writable roots at or beneath that home may traverse symlinks.
- Keep the exception disabled by default and prevent project config, command-line overrides, and ignored user config from enabling it. Other writable roots remain subject to symlink checks.
- Propagate the resolved setting through local, interactive, and exec-server sandbox paths, including `CODEX_HOME` aliases.
- Explain the opt-out in symlink rejection errors, including that it trusts targets outside `CODEX_HOME` and targets that change between commands.
## Testing
- Add macOS coverage for shell commands, patches, filesystem helpers, process execution, and interactive startup with enabled, disabled, aliased, and out-of-scope homes.
GitOrigin-RevId: 99fcdf611200c9e1b7713cf06f7fdea5bfa7f089
## What changed
- Add `Environment::last_ready_info()` to return a snapshot of the most recently accepted `EnvironmentReadyInfo`.
- Preserve the distinction between no accepted report and an accepted report with no capability roots.
## Testing
- Cover pending, ordinary, failed, recovered, replaced, empty, and invalid readiness reports.
- Verify that previously returned snapshots remain unchanged after later reports.
GitOrigin-RevId: cd051a56e7ad54a673c851eb58238c5837335c03
## What changed
- Allow a valid Ready report to replace a deferred environment's provisioning failure while preserving the same environment instance.
- Treat provisioning failures as retryable and reconnect when a completed or concurrently publishing startup attempt contains a stale failure.
- Report provisioning failures from `status()` without starting a connection, and retain Ready state when a late failure arrives.
## Testing
- Cover recovery after failed and invalid provisioning reports, capability-root resolution after recovery, and the race between Ready and publication of an earlier startup failure.
GitOrigin-RevId: cce419403248168da81bc5a6ab20f919aed81142
## Why
Exec-server process and network-policy events need stable attribution to the
launching tool call and executor without recording process payloads.
## What changed
- Add optional `ExecMetadata` to `ExecParams` and propagate the thread and tool
call IDs from unified exec.
- Emit bounded OpenTelemetry events for process start, spawn failure, sandbox
denial, and exit. Correlate them with the launch trace and registry-issued
executor identity while excluding arguments, paths, environment values,
output, and error text.
- Preserve launch attribution across long-running processes and reconnects, and
attach the same metadata to network-policy audit events.
- Keep the protocol backward compatible when metadata is omitted, and prevent
invalid trace headers from inheriting an unrelated active span.
## Testing
Add coverage for metadata serialization and propagation, lifecycle event
fields, trace relationships, reconnect behavior, spawn failures, sandbox
denials, and network-policy attribution.
GitOrigin-RevId: 7aa480a7289c73cb95e2c124c35500bb6f0d5084
## Why
Closing the client WebSocket does not guarantee that the server has finished
detaching its session, so an immediate resume attempt can race with cleanup.
## What changed
- Keep the test process alive through piped stdin instead of a fixed sleep.
- Retry session initialization when the server reports that the session is still
attached, with a five-second timeout.
- Surface unexpected JSON-RPC errors with their response details.
GitOrigin-RevId: 1f5c2bf21719365262e6fa9f4c21e7c3f81a5729