Commit Graph
281 Commits
Author SHA1 Message Date
jif 18344a972d Centralize executable fixture creation to avoid Linux ETXTBSY races (#48727)
## 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
2026-09-27 15:25:13 +00:00
Felipe Coury 1a89aec960 Prevent console windows for piped Windows child processes (#48483)
## Why

Piped child processes launched from a detached Windows process should not allocate a console window.

## What changed

Set `CREATE_NO_WINDOW` by default for `codex-rs/utils/pty` child commands. Preserve it alongside `CREATE_SUSPENDED` when preparing a child for Job Object containment, since Tokio's `creation_flags` replaces existing flags.

## Testing

Add a Windows regression test that runs from a detached process and verifies that children have no console window and retain working piped stdin and stdout, both with and without Job Object containment.

GitOrigin-RevId: 990386032d74fa783a66bb20faff769539ea41c1
2026-09-26 16:46:08 +00:00
malsamiri-oai 4b9e0cc77f Suppress console windows for local Windows MCP servers (#48238)
## What changed

Expose Windows process creation flags on the shared command wrapper and use
`CREATE_NO_WINDOW` when launching local stdio MCP servers, including fallback
launches without Job Object containment. Preserve `CREATE_SUSPENDED` when
assigning the server to a Job Object before execution.

## Testing

Add a Windows regression test covering direct launches and launches through
`cmd.exe`. Verify that the server has no console, initializes successfully,
returns tools, and exits after shutdown.

GitOrigin-RevId: 84475e82999d91a431e09327d4f5639b59c01427
2026-09-25 22:56:00 +00:00
felixxia-oai 6f51c65958 Fix macOS system-alias matching in patch permission checks (#47879)
## 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
2026-09-24 16:36:57 +00:00
jif df06bb054c Initialize media estimates outside the global cache lock (#47856)
## Why

Image and audio estimate cache misses computed values while holding the cache mutex, blocking access to unrelated keys during initialization.

## What changed

Add `BlockingLruCache::get_or_init` using `Arc<OnceLock<V>>` and migrate the image and audio estimate caches to it. Initialization and same-key waits run in a Tokio blocking region after releasing the cache mutex. Callers share initialization while an entry remains cached; eviction can allow another initialization, so factories must be deterministic.

## Testing

Add a concurrency test covering access to other keys during initialization, eviction of an in-flight entry, and successful completion of both the evicted initializer and its replacement.

GitOrigin-RevId: 079226a58828b854eddc2b501079527bcbe5e603
2026-09-24 14:58:04 +00:00
jif 51d4562070 Support close-on-exec attachments without changing PTY semantics (#47797)
## Why

Passing extra descriptors to a PTY previously selected behavior intended for inherited escalation sockets: no EOF on stdin close, different signal exit statuses, and no default `SHELL`. Launch attachments need ordinary PTY behavior and must survive execution even when marked `FD_CLOEXEC`.

## What changed

- Add `ChildFds::Attached` alongside `ChildFds::Inherited` to distinguish launch attachments from legacy inherited descriptors.
- Preserve ordinary EOF, default `SHELL`, and signal exit status behavior for PTY attachments.
- Allow explicitly supplied close-on-exec descriptors through pipe and PTY launches without changing the parent's descriptor flags, using child-side flag updates and macOS spawn inheritance actions.
- Update existing callers to use `ChildFds::Inherited`.

## Testing

Add Unix coverage for attachment accessibility, unchanged parent descriptor flags, default `SHELL`, and signal exit statuses. Extend the PTY stdin-draining test to cover attachments and EOF delivery.

GitOrigin-RevId: 864aedc6c5717d8b43c9d71057c9f54409834509
2026-09-24 09:25:19 +00:00
Ahmed Ibrahim f5960fcc22 Reduce dependency coupling in shared configuration crates (#47713)
## What changed

- Move `Provider` and `RetryConfig` into `codex-client`, retaining re-exports from `codex-api`, and switch `codex-model-provider-info` to depend on `codex-client`.
- Move feature-state metric emission into `codex-core`, preserving its behavior while removing the `codex-features` dependency on `codex-otel`.
- Explicitly enable TLS features for `tonic` in `codex-config` and `reqwest` in `codex-http-client`.
- Enable `png`'s `zlib-rs` feature directly in `codex-utils-image` to keep encoded PNG bytes stable when WebSocket dependencies are absent.

GitOrigin-RevId: 91fd63ab01b55d516b3e80e3644d06af8d5a01f6
2026-09-24 01:50:36 +00:00
Sean Huang 6989c6548b Fix spawn flag typing and isolate project configuration tests (#47704)
## What changed

- Cast `POSIX_SPAWN_SETSID` to the inferred flag type in the `ProcessMode::NewSession` branch.
- Use `LoaderOverrides::without_managed_config_for_tests()` for both cases in `project_layers_disabled_when_untrusted_or_unknown` so host-managed configuration does not affect the test.

GitOrigin-RevId: 1b27ac3ea139507d3f9402f4c2e3e63933c4d05c
2026-09-24 00:57:27 +00:00
Yuzhu Shen b086ad5493 Make Linux descriptor cleanup fork-safe (#47654)
## Why

Linux descriptor cleanup used allocating directory enumeration after `fork`. The child needs allocation-free cleanup while preserving Rust's spawn-error channel until `exec` succeeds.

## What changed

- Mark unrelated descriptors close-on-exec with `close_range(CLOSE_RANGE_CLOEXEC)`, leaving stdio and explicitly preserved descriptors' flags untouched.
- Fall back to stack-backed `getdents64` enumeration of the child's descriptor table when `close_range` fails.
- Document best-effort cleanup: failures allow launch to proceed and may leave unrelated descriptors inherited.

## Testing

Add Linux tests for descriptor inheritance, unsorted and duplicate allowlists, unchanged parent descriptors, fallback cleanup above a lowered descriptor limit, preserved exec-error reporting, and successful launch when both cleanup paths fail. Retain MCP coverage for descriptor exclusion in servers and descendants.

GitOrigin-RevId: 13abb95f82557324c7b40feb36bd6f806d60674e
2026-09-23 20:20:06 +00:00
Charlie Marsh 88b498ded4 Route Linux PTY launches through the process setup helper (#47617)
## Why

PTY launches need to establish a controlling terminal and reset signal state. Extend the Linux process setup helper to perform this work in a fresh, single-threaded process image without forking the application when the native helper is available.

## What changed

- Add a PTY setup mode and support caller-owned stdout and stderr descriptors so all three standard streams use the PTY slave.
- Use the helper for eligible Linux PTY launches, including launches with explicitly preserved descriptors, and wait for child exit asynchronously.
- Preserve portable PTY behavior for `PATH` lookup, custom `argv[0]`, missing working directories, default `SHELL`, stdin EOF, and signal exit status.
- Retain compatibility fallbacks and release the initial PTY descriptors before allocating a portable replacement.

## Testing

Add regression tests for controlling-terminal setup without forking, portable signal exit status, and successful fallback under file-descriptor pressure. Resolve the Python test executable to an absolute path to exercise the helper path.

GitOrigin-RevId: 4b07ce68aa33c5b79548581e221caf5953b0eda1
2026-09-23 18:36:48 +00:00
Charlie Marsh 15922a50aa Expand Linux spawn-helper lifecycle test coverage (#47613)
## What changed

Add real-child tests for parent-death signaling, large environment transfers, explicit file descriptor inheritance, and fallback when the helper exits before acknowledgement.

Introduce test-only pause points during environment transfer, reporting, and exec to verify that cancelling startup kills and reaps the helper. Cover cancellation after runtime shutdown and verify that the fallback reaper can reap an exited child while an earlier child remains alive.

Probe an actual helper launch before asserting native-helper behavior, and skip fixtures when their required procfs or pidfd support is unavailable.

GitOrigin-RevId: 5136dc242a91efd0596171266965f29903c6c970
2026-09-23 18:25:32 +00:00
Free Wortley df3ecee6f0 Launch Linux pipe processes through a fresh setup helper (#47612)
## Why

Linux pipe launches need session, parent-death signal, and descriptor setup. Move this work into a fresh, single-threaded executable image to avoid forking the app-server for child setup.

## What changed

- Register an early setup helper and launch it through `posix_spawn` for Linux pipe processes.
- Start the helper with an empty environment, then transfer the target environment over a control socket so loader settings cannot interfere with helper startup.
- Await target execution asynchronously, propagate setup and execution errors, and kill incomplete launches on cancellation.
- Preserve direct spawning as a fallback when the helper is unavailable or fails before target execution.

## Testing

Add coverage for launch semantics, avoiding fork, loader environment isolation, early argument dispatch, closed standard descriptors, and fallback under bootstrap failure or descriptor pressure. Add an app-server regression test that reuses a process handle after an execution failure.

GitOrigin-RevId: 079c673f0f22ebd531f8c57e5338095cc98acfdc
2026-09-23 18:25:07 +00:00
Charlie Marsh 7aa6519909 Use native POSIX spawning for command hooks (#47610)
## Why

Unix command hooks use a `pre_exec` callback to detach from the controlling terminal, forcing the launcher to fork. Native spawn attributes can create the detached session without that callback.

## What changed

- Route Unix hooks through `codex_utils_pty::Command` with `ProcessMode::NewSession`.
- Extend the native `posix_spawn` launcher to detached Linux sessions, retaining compatibility fallbacks for unsupported libc features and executable handling.
- Preserve the session environment snapshot, hook overrides, and restricted-variable filtering.

## Testing

Add regression coverage for launches without parent forks, terminal detachment, environment and argument handling, Linux `PATH` lookup, and executable compatibility. Cover process-group cleanup on cancellation and timeout, including descendants holding output pipes open, and preservation of background descendants after completed hooks.

GitOrigin-RevId: dbe2cf12d84aa79868cfb55ace40c7d5b5282703
2026-09-23 18:24:05 +00:00
Charlie Marsh 50fc133d05 Route pipe processes through the shared child launcher (#47605)
## Why

Pipe spawning installs Unix `pre_exec` hooks, forcing a fork on macOS even though the shared child launcher supports native spawning.

## What changed

- Use the shared `Command` for pipe processes, enabling native macOS spawning while preserving session isolation, explicit descriptor inheritance, and Linux parent-death handling.
- Select `ReapOnly` so the pipe adapter retains ownership of process-tree termination.
- Track embedded NUL bytes in original Unix command inputs and reject them before spawning, including when invalid `current_dir` or `arg0` values are later replaced.

## Testing

Add macOS integration coverage verifying fork avoidance, executable path lookup, pipe I/O, session isolation, and descriptor inheritance. Add Unix regression tests for pipe and PTY fallback under descriptor pressure and for rejecting NUL inputs without running the child.

GitOrigin-RevId: f4fa2c1d3c1aee2c4ffa1dc2ff946f9f0b08eb20
2026-09-23 18:00:11 +00:00
Charlie Marsh b8d365b18e Extend child commands with session and descriptor controls (#47604)
## What changed

- Add `ProcessMode::NewSession`, null stdin, and opt-in Linux parent-death termination to the shared child command API.
- Replace `DescriptorPolicy::StdioOnly` with `Explicit` and add `preserve_fds` to allow selected inheritable Unix descriptors alongside stdio. Preserve descriptor numbers without duplicating or closing the parent's descriptors, keeping POSIX record locks intact.
- Support session creation and preserved descriptors in the native macOS backend, with a compatible fallback for high descriptor numbers rejected by native file actions.

## Testing

Add regression coverage for process groups and sessions, descriptor preservation across native and executable-text launches, the last descriptor slot below the file limit, and retention of parent record locks.

GitOrigin-RevId: 29ecd859d3b673da6ae6412cc06a32fa10d11346
2026-09-23 17:59:47 +00:00
Charlie Marsh 897b7ae285 Add a reap-only drop policy for child processes (#47603)
## What changed

Add a crate-private `ChildDropPolicy` to choose whether dropping a child kills it or only reaps it after exit. Keep `KillAndReap` as the default.

For `ReapOnly` on Unix, transfer dropped children to a shared reaper thread that operates independently of the Tokio runtime. Support both Tokio children and native macOS children, without blocking drop or letting a live child delay reaping others.

## Testing

Add an isolated regression test verifying that reap-only children survive handle drop after runtime shutdown, are reaped after exit, and do not prevent other exited children from being reaped.

GitOrigin-RevId: 5ec639597dba7f3b61694d6d465991e054ae3397
2026-09-23 17:59:23 +00:00
peilin-openai ac98537678 Track cumulative MCP attribution across requests and thread history (#47081)
## What changed

- Record each MCP source and its first turn, including connector and plugin identifiers when available. Cover direct and Code Mode calls, including returned errors and results that are not printed.
- Persist cumulative attribution checkpoints and restore them across compaction, resume, and forks, including forks limited to recent turns.
- Attach fresh attribution to Responses API `client_metadata` under `mcp_attribution`, outside model-visible content. Restrict transmission to allowed OpenAI HTTPS destinations for both HTTP and WebSocket requests.
- Report `attribution_error` for legacy history without checkpoints, malformed or conflicting attribution, and serialized attribution exceeding 16 KiB.

## Testing

Add coverage for source deduplication, checkpoint persistence and restoration, recent-turn forks, direct and Code Mode calls, destination filtering, and the serialized size limit.

GitOrigin-RevId: fd285e152ca9e24bfa000debb20013709d67a86e
2026-09-21 18:19:07 +00:00
Charlie Marsh 595cc91e8c Avoid fork when spawning macOS filesystem helpers (#46661)
## 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
2026-09-19 15:15:25 +00:00
Charlie Marsh 3801fc8dea Make local child process launch settings explicit (#46660)
## Why

The native macOS backend cannot inspect every setting or callback on a Tokio command. A shared, constrained launch API makes the supported settings explicit for both backends.

## What changed

- Replace `spawn_child` with `codex_utils_pty::Command`, enforcing an explicitly supplied environment, piped stdio, and kill-on-drop behavior.
- Add `ProcessMode::Inherit` and `ProcessMode::NewGroup`, honoring the selected mode in native macOS and Tokio spawning.
- Share the `Child` wrapper across platforms and migrate local MCP server launching to the new API, retaining its new process group and Windows suspended-spawn support.

## Testing

Adapt the existing macOS spawn compatibility and child lifecycle tests to the new API. Add a regression test that checks inherited and new process groups with both backends.

GitOrigin-RevId: 3e7a401659e3a8a94a13c4ff58d67bdcd2eea33d
2026-09-19 15:14:22 +00:00
Charlie Marsh d086e2752d Move local child-process spawning into codex-utils-pty (#46659)
## What changed

Expose the shared `Child` type and `spawn_child` function from `codex-utils-pty`, and update the MCP stdio transport to use them. Move the existing macOS spawning implementation and its tests into the utility crate, preserving platform-specific spawning, piped stdio, and kill-on-drop behavior.

GitOrigin-RevId: 26c2fb2f22cdba907aa9d18cab7dc8c4ac1c909e
2026-09-19 15:13:59 +00:00
jif d6fb836f31 Use macOS member fallback in shared process-group termination helpers (#46521)
## Why

On macOS, process-group signals can be denied even when individual members can be signalled. Core execution cleanup used helpers that did not retry those signals against group members.

## What changed

- Make `terminate_process_group` and `kill_process_group` use the existing member fallback on macOS, and simplify MCP and pipe callers to use the shared helpers.
- Use the saved process-group ID when escalating cancellation after the termination grace period, so this path also uses the fallback.
- Update the unsafe process-group ID test to exercise `terminate_process_group`.

GitOrigin-RevId: 1bab28d3d53cd401b51ffe71d41fbece12aed66d
2026-09-18 23:59:18 +00:00
Sean Huang 3724dc8361 Share platform identity across path, network, and sandbox configuration (#46334)
## What changed

- Add `Platform` to `codex-utils-path-uri` with metadata parsing, native platform detection, and path convention mapping. Preserve missing or unrecognized metadata as `Unknown`.
- Replace `NetworkProxyExecutorOs` with the shared type and keep executor-specific socket path validation in the network proxy.
- Extract `effective_sandbox_mode` with explicit platform and Windows sandbox level inputs, preserving the native Windows fallback from `workspace-write` to `read-only` when the sandbox is disabled.

## Testing

Add unit tests for platform metadata, path conventions, native platform detection, and sandbox mode selection across platforms and Windows sandbox levels.

GitOrigin-RevId: 4fe0972e3a91040e35f2a6dfa5bcdf6c9a29be88
2026-09-18 00:51:34 +00:00
Adam Perry @ OpenAI 47fc8d661e Route skill discovery and loading through EnvironmentAccess (#46293)
## What changed

Use `EnvironmentAccess` for skill discovery, environment skill loading, and plugin namespace resolution, replacing direct `ExecutorFileSystem` calls with explicit `None` sandbox arguments.

Wrap existing host and executor filesystems with `FileSystemEnvironmentAccessor::unrestricted` to preserve their current access behavior. Update discovery, loading, and namespace tests to use the same adapter.

GitOrigin-RevId: d68168cc0ee19dc303ef4ee726cf1de1a8db81e0
2026-09-17 19:52:03 +00:00
Sean Huang 7322c5e790 Preserve executor path conventions in permission summaries (#45852)
## Why

Permission summaries must preserve executor paths without interpreting them in the host's filesystem namespace.

## What changed

Accept `PathUri` values and summarize permission profiles directly instead of converting them to a legacy sandbox policy. Render additional workspace roots using their inferred native path convention, and update the exec and TUI callers.

Keep workspace subpath writes and writes outside the working directory classified as `custom permissions` when the working directory itself is not writable.

## Testing

Add coverage for POSIX, Windows drive, and UNC workspace paths, including encoded spaces and case-distinct roots, plus opaque workspace subpath writes.

GitOrigin-RevId: ff2c456e2a720e7216f13e0241b3a935cc925d00
2026-09-16 03:40:53 +00:00
Krish Chainani 7b8b17b97a Support image references by file ID in inputs and tool outputs (#45794)
## What changed

- Accept `fileId` alongside the existing `url` form for app-server image inputs, and forward file references to the Responses API as `file_id`. Update generated schemas and client types.
- Preserve file references, image detail hints, and mixed inline/file image ordering through user-message events, thread history, and rollout migration. Retain file images when truncating tool output.
- Pass file references through image preparation without resolving them, while keeping resize-notice numbering correct. Omit them from unsupported TUI display and Guardian image context.
- Reject image-edit requests whose recent-image window includes a file reference, preventing selection of an older inline image instead.

## Testing

Add coverage for serialization, request and rollout preservation, mixed-image history ordering, incomplete ordering metadata, tool-output truncation, and rejection of unsupported image-edit selections.

GitOrigin-RevId: 6ca20a8577155cc934b720803c3b7b3bffdf972a
2026-09-15 21:19:08 +00:00
Krish Chainani 5a66d460d3 Refactor image content to use a shared ImageReference type (#45543)
## What changed

Represent images in `ContentItem` and `FunctionCallOutputContentItem` with `ImageReference::Inline`, flattened to preserve the existing `image_url` wire format. Update image producers and consumers and regenerate app-server schemas and SDK artifacts.

Preserve the Python SDK's `InputImageContentItem` and `InputImageFunctionCallOutputContentItem` class names during generation.

## Testing

Add a regression test for stable Python image class names and adapt existing image tests to the shared representation.

GitOrigin-RevId: c38a780ac3314c2ac2deb3afc1b93b94b6f93fec
2026-09-14 23:25:09 +00:00
iceweasel-oai 6ce16aadce Allow ConPTY output to close after the last console client exits (#45504)
## Why

Retaining the pseudoconsole's creation pipe handles prevents output readers from seeing EOF while the session remains alive.

## What changed

Drop the creation handles after a successful process spawn and call `ReleasePseudoConsole` when available on Windows 11 24H2 or newer. This lets output close after the last attached client exits while preserving I/O for surviving console descendants. Older Windows versions retain the `ClosePseudoConsole` cleanup path on drop.

## Testing

Add Windows lifecycle tests for output closure after normal exit and termination while retaining the session, plus continued input and output for a surviving console child. These tests skip when `ReleasePseudoConsole` is unavailable.

GitOrigin-RevId: fb1094fb2a570e6fec0cc80d6356f5d7eb1edcbf
2026-09-14 19:38:45 +00:00
Eric Traut 5fb3b7e401 Fix fuzzy match scoring within Unicode lowercase expansions (#45475)
## Why

Matches starting inside a lowercase expansion such as `İ` → `i̇` could receive an incorrect prefix bonus or gap penalty, causing strings that lowercase identically to rank differently.

## What changed

Track the first matched position in the lowercased text directly when calculating scores. Preserve original character indices for highlighting.

## Testing

Add a skill popup regression test and snapshot covering ranking and highlighting for matches beginning at the combining dot in expanded and already-lowercase names.

GitOrigin-RevId: 78a8b79f1defca9f76fde5df945b0b1ff4af25da
2026-09-14 17:36:11 +00:00
Felipe Coury b876f88981 Fix clipboard routing for tmux and SSH sessions (#45457)
## Why

A persistent tmux session can gain remote clients after Codex starts, so successful native copying must not skip terminal forwarding. Terminal sends also lack delivery acknowledgement and cannot replace native copying reliably.

## What changed

- Attempt native copying first, then independently forward through tmux or OSC 52 in tmux and SSH sessions. Preserve existing native clipboard leases when a later copy returns no new lease.
- Target the most recently active client in the current pane's tmux session, checking that client's clipboard capability before sending. Retain OSC 52 fallback when tmux forwarding fails.
- Reject empty selections without touching clipboards and apply the 100,000-byte terminal payload limit to tmux copies.
- Resolve tmux and PowerShell through trusted system locations, adding Nix system profiles and the WSL PowerShell directory to helper discovery.

## Testing

Add regression coverage for native-before-terminal ordering, fallback routing, clipboard lease retention, empty and oversized payloads, tmux client selection, capability checks, and combined backend errors.

GitOrigin-RevId: df4b66fa4368a3cf19b4d07fde6c76ea96a8fef5
2026-09-14 16:15:34 +00:00
Felipe Coury 8d3c6cc13d Preserve conversation context and separate next actions in recaps (#45090)
## Why

The 900-byte recap prompt limit leaves little room for completed progress, unresolved caveats, and recent corrections. Recaps need this context to distinguish completed work from pending requests.

## What changed

- Introduce a shared `RecapPrompt` with a 32 KiB ceiling for instructions and history, using an 8,192-token estimate. Instruct summaries to retain the broader goal, completed outcomes, and unresolved availability or validation caveats.
- Select up to eight answered exchanges plus a pending request, preserving adjacent steering and progress messages. Drop older whole exchanges before excerpting both ends of oversized messages, while retaining the newest answer and pending correction.
- Require a `summary` and nullable `next_action`, bounded to 700 and 200 characters respectively. Reject malformed or oversized responses and display an optional, separately styled `Next:` line.

## Testing

Add coverage for UTF-8 prompt bounds, exchange selection, pending corrections, excerpt boundaries, strict response parsing, and next-action rendering. Extend the recap generation integration test to verify bounded history and the structured response schema.

GitOrigin-RevId: 6c6a84bc602a168418c1952feb1d286ec0cb9e28
2026-09-12 18:16:17 +00:00
Sean Huang 9e22e74e8d Resolve permission profiles with explicit execution-host path context (#44676)
## Why

Permission paths need to follow the execution host's path conventions and home directory. Literal directory names containing glob syntax must not change the meaning of deny patterns, and profile availability checks need to account for configured workspace roots.

## What changed

- Use `ConfigPathContext` to compile built-in and custom profiles, returning the resolved profile and deduplicated `PathUri` workspace roots. Materialize configured roots while retaining runtime workspace symbols.
- Use the same compiler for configuration loading, persisted profile validation, and profile catalogs. Resolve roots against the requested `cwd` when listing profiles.
- Resolve home-relative scoped rules using the supplied home directory and reject unsafe directory prefixes when constructing globs.
- Share workspace-root materialization across native paths and URIs. Deny the affected root when a workspace glob cannot be safely resolved, and clear grants for legacy home-relative workspace denials whose target is unknown.

## Testing

Add coverage for POSIX, Windows, and UNC path resolution, inherited workspace roots, scoped home denials, missing home context, and conservative denial behavior for unsafe globs. Add an app-server test verifying that profile availability reflects the requested `cwd`.

GitOrigin-RevId: ca259434742365c16d0b72629cabfbab41513a80
2026-09-11 00:03:40 +00:00
Sean Huang cc05ecfe17 Resolve filesystem denials with explicit path context (#44669)
## Why

Filesystem denial paths need to use the owning environment's path syntax, base directory, and home directory. Host-native resolution cannot supply those facts for another platform, and invalid denials must not be silently skipped when building the sandbox policy.

## What changed

- Add `ConfigPathContext` to requirements layers so `permissions.filesystem.deny_read` can resolve using explicit POSIX or Windows path facts, with native defaults when no context is supplied.
- Share URI-based resolution and validation for literal paths and glob prefixes. Reject ambiguous or lossy paths, including NUL bytes, Windows stream syntax, and unsupported UNC spellings.
- Move denial conversion into `FilesystemConstraints::apply_to_policy`, preserving glob patterns and deduplicating entries. Validate all denials before modifying the policy and propagate failures through configuration loading.

## Testing

Add tests for per-layer base and home resolution, Windows drives and globs, nested context restoration, missing home directories, and policy conversion without partial mutation. Add a configuration-loading regression test for a required denial glob containing a NUL byte.

GitOrigin-RevId: fa0da0d149407958e39897a39fe7b87edd6f1644
2026-09-10 23:08:23 +00:00
Abhinav aa88a0333c Preserve tool output truncation budgets across resume and fork (#44248)
## Why

Replaying tool outputs under a different model can expand or shrink the history shown to the model if truncation uses the new model's budget.

## What changed

Save the originating history truncation budget on function and custom tool outputs and reuse it during replay, preserving existing tool-specific overrides. Include the existing 20% serialization allowance once, before converting byte budgets to tokens.

Rename the metadata field to `history_truncation_token_limit` while retaining `fallback_token_limit_override` as its serialized name for compatibility.

## Testing

Add regression coverage for resume and fork with different model budgets, including custom tool outputs. Extend unit coverage for existing overrides and byte-budget conversion.

GitOrigin-RevId: a62c8fd3e43198e2252b150fba72f022939c1070
2026-09-09 17:55:00 +00:00
Jennifer Zhao 129fd21687 Reject empty audio payloads in data URLs (#44070)
Return `AudioPreparationError::InvalidDataUrl` with the reason
`audio payload is empty` when the decoded base64 payload is empty.

GitOrigin-RevId: e886dab5f49ebb1a363dbc1c292813b2b52698d4
2026-09-09 05:56:45 +00:00
rhan-oai 6515a72db7 Preserve runtime workspace roots across thread resume (#43848)
## Why

Resuming a thread should retain its selected workspace folders, including additional roots and explicit empty selections. Resume overrides also need to survive a subsequent resume when no turn has run.

## What changed

- Persist `runtime_workspace_roots` in startup metadata and thread settings snapshots, separately from explicit environment selections and permission-profile roots.
- Restore roots from the latest snapshot owned by the resumed thread, falling back to owned startup metadata only when no snapshot exists. Honor explicit `runtimeWorkspaceRoots` overrides, retarget the old `cwd` root when `cwd` changes, deduplicate roots, and validate restored paths for the current host.
- Checkpoint effective settings on resume and restored settings after revert. Reload resume configuration if saved workspace roots change during loading.
- Normalize Windows rollout path spellings when matching thread search results, preserving selection of the correct rollout after revert, including compressed rollouts.

## Testing

Add regression coverage for workspace restoration, empty and explicit overrides, foreign paths, compaction and revert, resume checkpoints without recency changes, concurrent settings persistence, and rollout search path matching.

GitOrigin-RevId: d98d9d34dd63934d441120916c61c12b69e7f062
2026-09-08 16:24:38 +00:00
Benjamin Carlsson eb5a00b068 Add managed worktrees to codex exec (#42652)
## What changed

- Add the experimental `worktrees` feature and a shared `--worktree` flag for new and forked `codex exec` sessions.
- Create each enabled session in a managed Git worktree, use that checkout as the session working directory, and bind the checkout to the new thread.
- Share the configured worktree pool with Desktop while leaving automatic cleanup disabled for CLI allocations.
- Reject unsupported commands, remote execution, ignored user configuration, ephemeral sessions, and use without the feature enabled before allocating a worktree.

## Testing

- Cover flag placement and inheritance, supported and rejected command combinations, worktree allocation and thread ownership, configuration gating, and compatibility with existing worktree-backed sessions.

GitOrigin-RevId: 011ff4639b09e8992c50d7b823df23e71798670e
2026-09-04 01:56:38 +00:00
Krish Chainani 280ae8b9fc Centralize prompt image detail modes (#42624)
## What changed

- Add `PromptImageMode::HIGH_DETAIL` and `PromptImageMode::ORIGINAL_DETAIL`
  constants with the standard resize limits.
- Use the shared modes during core image preparation instead of defining the
  limits locally.
- Cover the dimension and patch budgets for both detail modes in the image
  utility tests.

GitOrigin-RevId: 27fdc77719f23d2e8f1060886576b3be843a8491
2026-09-03 22:22:48 +00:00
felixxia-oai 0d502a4230 Support durable reasoning configuration updates (#42328)
## Why

Reasoning configuration changes need to retain their position and trusted provenance when model history is persisted and replayed. Client-injected history must not be able to forge these controls.

## What changed

- Add a typed `configuration_update` response item carrying reasoning effort, including custom model-defined values.
- Persist harness-authored updates with provenance and preserve them across history reconstruction, thread resume, raw response notifications, and agent forks.
- Exclude untrusted configuration updates from model history, strip client-supplied provenance metadata, and reject configuration updates supplied as turn input.
- Export the new item through the JSON and TypeScript app-server schemas and classify it in telemetry and persistence metrics.

## Testing

- Cover serialization, provenance persistence, history filtering and rollback, resume reconstruction, and injection attempts before and after restart.

GitOrigin-RevId: eb5559d2b52b7a931621e7c9812f009ff9fb8939
2026-09-02 18:52:44 +00:00
Felipe Coury 637c3227b3 Avoid executing PATH helpers before workspace trust (#42324)
## Why

Automatic startup work and `codex doctor` can run before a workspace is
trusted. A repository-controlled `PATH` must not be able to make those flows
execute workspace-provided helpers.

## What changed

- Resolve helpers used by automatic startup from trusted system installation
  directories, and give plugin-sync Git subprocesses a sanitized environment.
- Make terminal detection environment-only and have doctor inspect executable
  locations without running them. Fetch update metadata with the HTTP client
  instead of `curl`.
- Fall back conservatively when trusted terminal helpers are unavailable,
  including for tmux keyboard enhancement flags.

## Testing

Add black-box coverage with hostile workspace `PATH` entries for startup,
interactive tmux startup, support log collection, doctor, and curated plugin
sync. Add unit coverage for trusted executable resolution and bounded update
HTTP responses.

GitOrigin-RevId: 3b8995eb422b60ed53b0386951de59e8f9bfc542
2026-09-02 18:34:27 +00:00
iceweasel-oai cd8bd62c6e Resolve permission requests in the executor context (#42146)
## Why

`request_permissions` paths and grants need to be evaluated against the selected executor environment, including its path convention, home directory, workspace roots, and temporary directories.

## What changed

- Resolve relative and home-relative permission paths using the executor context, reject mismatched path conventions and lossy paths, and support legacy `read` and `write` path lists.
- Move grant intersection into core so requested and granted permissions use the originating environment's sandbox context. Preserve deny entries conservatively when a special path cannot be resolved.
- Keep the full originating environment with pending permission requests so delayed responses are normalized against the same context.

## Testing

- Cover POSIX, Windows, UNC, relative, and home-relative path resolution and invalid path contexts.
- Verify end-to-end app-server grants are limited to the requested workspace scope and unresolved temporary-directory denies are preserved.

GitOrigin-RevId: 730a2aacd391262e92a6314f3a5b6c262e3dca10
2026-09-01 22:08:08 +00:00
Charlie Marsh 8436b749a4 Bound Git root discovery for metadata enrichment (#42132)
## Why

Git root discovery is optional metadata work, but filesystem probes can block. They should not exhaust Tokio's blocking pool, delay runtime shutdown, or prevent later turns from observing repository changes.

## What changed

- Add a shared `GitRootDiscovery` service that coalesces concurrent lookups for the same working directory and limits probes across directories.
- Run probes on detached threads, retain in-flight work across caller cancellation, and discard completed results instead of caching them.
- Use the service for turn and memory metadata enrichment, abort unused turn enrichment when its state is dropped, and limit memory metadata waits to one second.

## Testing

Add coverage for probe sharing, capacity limits, cancellation, fresh discovery, runtime shutdown, memory timeouts, and repositories restored after startup prewarming.

GitOrigin-RevId: bca46fc263e7a12a2f69146d8a0b3e7c7e0846cb
2026-09-01 20:41:32 +00:00
Benjamin Carlsson 13bc770eaf Add installed voice host lifecycle support (#41902)
## What changed

- Add `VoiceHost` to resolve the packaged voice helper, launch it with an
  allowlisted environment, perform the protocol handshake, and enforce bounded
  shutdown and process cleanup.
- Preserve native executable path encoding in the pipe process APIs.
- Add `third_party/voice/assemble_package.py` to create a fresh package copy
  containing a target-compatible helper and a provenance manifest with file
  hashes.

## Testing

- Cover installed helper lifecycle, build matching, missing and symlinked
  helpers, non-UTF-8 package paths, environment filtering, package validation,
  target pairing, and failure cleanup.

GitOrigin-RevId: f893074b36ae6bb9bcedc00fbe7af6bb72745f4c
2026-08-31 19:44:44 +00:00
pakrym-oai f742dabc6f Support per-tool MCP output limits (#41421)
## What changed

- Add a positive `output_token_limit` setting to each entry under an MCP server's `tools` configuration.
- Apply the most restrictive limit when plugin and user policies overlap, while keeping approval policy independent.
- Carry the effective MCP output budget in conversation history so tool output, post-tool hook responses, and resumed sessions use the same truncation limit.

## Testing

- Cover configuration parsing, serialization, schema validation, and plugin policy merging.
- Cover MCP output below and above the configured limit, post-tool hook responses, and session resume.

GitOrigin-RevId: d0beb4fca9ba6055d9e1d31c137373b465d50d61
2026-08-28 21:40:23 +00:00
iceweasel-oai 34e74fda0e Align deny-read matching with executor path semantics (#41209)
## Why

Read-deny policies must use the target executor's path convention so URI-based
policy checks and native filesystem enumeration enforce the same rules.

## What changed

- Prepare deny roots and glob matchers from `PathUri` policy context, including
  executor-relative working directories and home-relative patterns.
- Match Windows globs case-insensitively with normalized separators, while
  preserving byte-oriented POSIX matching for non-UTF-8 paths.
- Fail closed for malformed paths, incompatible path conventions, unresolved
  home-relative patterns, and invalid globs.
- Make Windows deny-read discovery use case-insensitive ripgrep glob matching.

## Testing

Added coverage for Windows URI conventions, executor home expansion,
case-insensitive `.env` discovery, malformed paths, non-UTF-8 names, and
canonical directory-link targets.

GitOrigin-RevId: 36001219a2e9b36acfce8972dc1d3bbc304271c5
2026-08-27 21:15:37 +00:00
iceweasel-oai 2926014075 Make filesystem policy matching URI-native (#41001)
## Why

Filesystem policies can describe paths using a convention that differs from the
host running Codex. Native path comparisons can therefore mis-handle cases such
as case-variant Windows paths or ambiguous encoded components.

## What changed

- Resolve policy entries and special roots as `PathUri` values using the
  executor's path convention.
- Use validated URI components for containment, overlap, and precedence, and
  fail closed when component boundaries are ambiguous.
- Restrict relative joins to descendants and apply the same matching rules to
  protected metadata paths and permission-profile intersections.

## Testing

Added coverage for Windows case variants, encoded and opaque paths, repeated
separators, descendant joins, special roots, metadata protection, and preserved
deny entries.

GitOrigin-RevId: fb09d44d11df25faaac806fe00457e6f6b0d8596
2026-08-26 23:49:05 +00:00
pakrym-oai 75cb7c903d Preserve MCP tool output as content items (#40737)
## What changed

- Convert unstructured MCP results into typed function-call output items instead of serializing the entire content array as a text string.
- Keep structured MCP results as serialized text and preserve media, encrypted content, and unknown content through their existing item conversions.
- Drop empty text items during output truncation so they do not consume API array slots.

## Testing

- Cover text-only, mixed unstructured, structured, and image-sanitized MCP results.
- Verify empty text items are discarded under byte- and token-based truncation policies.

GitOrigin-RevId: fa1c5b7dee6f003a094265379dcabdd060386a48
2026-08-25 23:42:50 +00:00
viyatb-oai bf3eb2ec91 Prevent Unix PTY I/O from blocking runtime shutdown (#40460)
## Why

Blocking PTY reads and output-channel sends can keep Tokio runtime shutdown
waiting when a detached child retains the terminal or output backpressure fills
the channel.

## What changed

- Drive Unix PTY reads and writes through nonblocking `AsyncFd` readiness so
  their tasks can be cancelled during shutdown.
- Keep draining child output after its receiver closes, and preserve queued
  input plus EOF delivery when portable PTY stdin closes.
- Return a descriptive error when PTY spawning uses a Tokio runtime without an
  I/O driver.

## Testing

Add Unix coverage for detached children, full and dropped output channels,
large input with EOF, inherited file descriptors, and runtimes without I/O.

GitOrigin-RevId: f7f1f58abebf8bf1d39285cd61b8d69946d54155
2026-08-24 19:25:32 +00:00
zm-oai 0d9bb6c34c Harden Windows file URI conversion (#40423)
## What changed

- Recognize percent-encoded drive colons when inferring Windows paths, rendering
  native path strings, and resolving same-drive relative joins.
- Reject Windows file URIs with percent-encoded `/` or `\` separators before
  converting them to native absolute paths, so decoding cannot reinterpret URI
  segment boundaries.

## Testing

- Cover uppercase and lowercase encodings for drive colons and path separators,
  including local-drive and UNC file URIs.

GitOrigin-RevId: ecb6c92f4ef1af73f85e57a135abf6bc5bb968dc
2026-08-24 15:54:16 +00:00
andrewgu-oai 79b7606803 Keep credentials out of app-server logs (#39993)
## Why

App-server logs can be persisted or included in submitted diagnostics, so credentials used by model providers, authentication refreshes, and attestation requests must not appear in diagnostic output.

## What changed

- Add `RedactedString`, which preserves serialization and string access while replacing debug output with `<redacted>`.
- Use it for model-provider bearer tokens, header and query values, authentication command arguments, and attestation tokens.
- Avoid logging JSON-RPC error payloads and parser or authentication errors that may echo credentials; retain safe context such as error codes and categories.

## Testing

- Add an app-server regression test that exercises provider credentials, refreshed authentication tokens, and attestation tokens, then verifies none appear in persisted SQLite or submitted diagnostic logs.

GitOrigin-RevId: 8c50408adf94d93847658b1320682cf3b637d2cc
2026-08-21 19:04:32 +00:00
rka-oai 763787d061 Support standalone named function call outputs (#39782)
## Why

External tool events may need to enter thread history without a preceding function call and therefore do not have a `call_id`.

## What changed

- Allow `function_call_output` items to omit `call_id` and carry optional `name` and `namespace` fields.
- Preserve named standalone outputs during history normalization and agent forks while retaining existing pairing behavior for outputs with a `call_id`.
- Accept, persist, and forward these outputs through `thread/inject_items`, and update the app-server schemas and documentation.

## Testing

- Cover paired and standalone JSON round trips, history normalization, agent forks, and injected thread history.

GitOrigin-RevId: a3258163a7dc93777c7c3023116fe204819bdbb0
2026-08-20 19:19:41 +00:00