mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
bca18cba40a601bc462b7079a06ae486e41a3afa
7038 Commits
-
Wire managed MITM CA trust into child env (#22668)
## Stack 1. Parent PR: #18240 uses named MITM permissions config. 2. This PR wires managed MITM CA trust into spawned child processes. ## Why When Codex terminates HTTPS for limited mode or MITM hooks, child HTTPS clients need to trust Codex's managed MITM CA. Exporting proxy URLs alone is not enough, but blindly replacing user CA settings would be wrong: it can break custom enterprise/test roots, leak unreadable CA files into generated bundles, or make the child env disagree with its sandbox policy. ## Summary 1. Build immutable managed CA bundles under `$CODEX_HOME/proxy` that include native roots, the managed MITM CA, and only inherited or command-scoped CA bundles the child is allowed to read. 2. Export curated CA env vars alongside managed proxy env vars while preserving user CA override semantics, including nested Codex `SSL_CERT_FILE` precedence. 3. Thread generated CA bundle paths into child sandbox readable roots, including debug sandbox execution, so the exported env vars work inside sandboxed commands. 4. Remove only Codex-generated MITM CA bundle env when a child intentionally drops managed proxying for escalation or no-proxy retry. 5. Document the managed CA bundle behavior and cover env injection, per-child bundle generation, sandbox readable roots, and no-proxy cleanup in tests. ## Validation 1. Ran `just test -p codex-network-proxy`. 2. Ran `just test -p codex-protocol`. 3. Ran `just fix -p codex-network-proxy -p codex-protocol`. 4. Tried focused `codex-core` validation, but the crate currently fails to compile in `core/tests/suite/guardian_review.rs` because an existing `Op::UserInput` initializer is missing `additional_context`. --------- Co-authored-by: Eva Wong <evawong@openai.com>
Winston Howes ·
2026-06-01 23:23:59 +00:00 -
Reject directory rollout paths for pathless side chats (#25661)
## Why Fixes openai/codex#20944. Desktop side chats are intentionally ephemeral and pathless. They can still accept live turns while loaded, but after a reload there is no persisted rollout to resume. In the reported failure mode, Desktop could send `$CODEX_HOME` as the resume/fork path for one of these pathless side chats. `thread/resume` and `thread/fork` prefer an explicit `path` over `threadId`, and rollout path lookup only checked that a candidate existed. That let `$CODEX_HOME` pass as a rollout path, so the later rollout reader tried to open a directory and surfaced the low-level `Is a directory` error. ## What Changed - Reject explicit rollout paths that resolve to a directory or other non-file before attempting to read rollout history. - Make `codex_rollout::existing_rollout_path` return only plain or compressed rollout candidates that are actual files. - Add an app-server regression test that creates an ephemeral fork, runs a turn while the side thread is loaded, simulates reload, then verifies both `thread/resume` and `thread/fork` reject `$CODEX_HOME` with `path is a directory` instead of the OS-level directory-read error. - Rebase over the `TestAppServer` rename and update the remaining stale test harness call sites to use `TestAppServer` with `app_server` local variables. Relevant code: - `thread-store/src/local/read_thread.rs` validates explicit rollout paths before rollout reading: https://github.com/openai/codex/blob/25b47c8f425d351aaba4baa955a8092064a1707b/codex-rs/thread-store/src/local/read_thread.rs#L146-L165 - `rollout/src/compression.rs` now requires file metadata for plain and compressed rollout candidates: https://github.com/openai/codex/blob/25b47c8f425d351aaba4baa955a8092064a1707b/codex-rs/rollout/src/compression.rs#L940-L950 - The repro test covers the pathless ephemeral side-chat reload case: https://github.com/openai/codex/blob/25b47c8f425d351aaba4baa955a8092064a1707b/codex-rs/app-server/tests/suite/v2/thread_fork.rs#L774-L886 ## Verification - `just test -p codex-app-server pathless_ephemeral_thread_rejects_codex_home_path_after_reload`
Michael Bolin ·
2026-06-01 16:02:06 -07:00 -
[codex] Publish release symbol artifacts (#25649)
## Why Production Codex binaries are stripped for distribution, which leaves crashes and samples from released builds without the symbols needed for useful stack traces. Publish symbols as separate release assets so production artifacts stay small while released builds remain symbolicateable. ## What changed - Add `.github/scripts/archive-release-symbols-and-strip-binaries.sh` to package platform-native symbols into `codex-symbols-<artifact>.tar.gz` assets while stripping the corresponding Unix binaries before signing. - Build release binaries with full debug information before producing distribution artifacts. - Publish macOS `.dSYM` bundles, Linux `.debug` files with `.gnu_debuglink`, and Windows `.pdb` files. - Strip Linux `bwrap` before computing its packaged-resource digest, but intentionally omit `bwrap` from symbol archives. - Preserve symbols artifacts in the unsigned macOS promotion flow. ## Verification - Ran `shellcheck` and `bash -n` on `.github/scripts/archive-release-symbols-and-strip-binaries.sh`. - Parsed the modified workflow YAML files and ran `git diff --check`. - Built a macOS release smoke binary and verified that the archived `.dSYM` contains DWARF application source information and has the same UUID as the stripped production binary. - Built Linux smoke binaries and verified that the symbol archive contains `codex.debug`, excludes `bwrap.debug`, leaves the expected `.gnu_debuglink` in `codex`, and does not mutate the separately stripped `bwrap` digest. - Staged a Windows smoke archive and verified that it contains the expected `.pdb` file.
Jeremy Rose ·
2026-06-01 15:49:54 -07:00 -
fix(tui): clarify footer shortcut overlay hints (#25625)
## Why The TUI shortcut overlay used static labels for `Tab` and `Ctrl+C`, even though both keys change behavior while a task is running. That made the visible help misleading: idle `Tab` submits rather than queues, and active-turn `Ctrl+C` interrupts rather than exits. Closes #25531. Closes #25564. ## What Changed - Pass task-running state into the shortcut overlay renderer. - Render `Tab` as `submit message` while idle and `queue message` while work is running. - Render `Ctrl+C` as `exit` while idle and `interrupt` while work is running. - Add snapshot coverage for the active-work shortcut overlay and update idle overlay snapshots. ## How to Test 1. Start Codex and open the shortcut overlay with `?` while no task is running. 2. Confirm the overlay shows `tab to submit message` and `ctrl + c to exit`. 3. Start a task, then open or keep the shortcut overlay visible while work is running. 4. Confirm the overlay shows `tab to queue message` and `ctrl + c to interrupt`. 5. Type a follow-up prompt during active work and press `Tab`; confirm it queues rather than submitting immediately. Targeted tests: - `just test -p codex-tui footer_snapshots` - `just test -p codex-tui footer_mode_snapshots` ## Validation Notes `just test -p codex-tui` currently has two unrelated guardian feature-flag test failures on this base: - `app::tests::update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history` - `app::tests::update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default` `just argument-comment-lint codex-rs/tui/src/bottom_pane/footer.rs` could not run locally because the prebuilt wrapper requires `dotslash`; the touched Rust diff was manually inspected for opaque positional literals.
Felipe Coury ·
2026-06-01 19:41:22 -03:00 -
Move tool search metadata onto ToolExecutor (#25684)
Deferred tools need to be searchable even when they are not implemented inside `codex-core`. Extension-provided tools can be registered for later discovery, but the search metadata path was still owned by core-specific runtime hooks, which meant the shared `ToolExecutor` abstraction could not describe how a deferred extension tool should appear in `tool_search`. ## Changes - Move `ToolSearchEntry` and `ToolSearchInfo` into `codex-tools` and re-export them from the shared tools crate. - Add a default `ToolExecutor::search_info` implementation that derives loadable tool-search metadata from function and namespace specs. - Forward search metadata through extension adapters and exposure overrides while keeping custom search text/source metadata for dynamic, MCP, and multi-agent tools. - Remove the old core-local `tool_search_entry` module now that search metadata lives with the shared executor APIs. ## Testing - Added `deferred_extension_tools_are_discoverable_with_tool_search` coverage in `core/src/tools/spec_plan_tests.rs`.
jif-oai ·
2026-06-02 00:24:41 +02:00 -
Fix stale TestAppServer rename in plugin_list test (#25705)
## Why #25701 renamed the app-server test harness to `TestAppServer`, but it raced with #25681, which added a new `plugin_list` test call site still using the old `McpProcess` name. Once both changes met on `main`, app-server test builds failed before running the suite because `McpProcess` no longer exists in that scope. This PR fixes that CI break by updating the remaining stale call site to the renamed helper. ## What Changed - Replaced the `McpProcess::new(...)` use in `codex-rs/app-server/tests/suite/v2/plugin_list.rs` with `TestAppServer::new(...)`. - Renamed the local variable from `mcp` to `app_server` at the same call site to match the helper rename. Relevant code: https://github.com/openai/codex/blob/aadd9c999b4e0789f7afb2b9b8cc43000bb47e86/codex-rs/app-server/tests/suite/v2/plugin_list.rs#L234-L246 ## Verification Not run locally; this is a compile fix for the app-server test harness rename.
Michael Bolin ·
2026-06-01 15:14:03 -07:00 -
[codex] enable parallel standalone web search calls (#25702)
## Summary - opt the extension-backed standalone `web.run` tool into parallel tool execution - update the existing extension registration test to assert that the tool advertises parallel-call support ## Why The standalone web-search API endpoint now supports parallel requests. The extension executor still inherited the shared serial default, causing multiple `web.run` calls to acquire the exclusive runtime lock. ## Impact Models that emit multiple standalone web-search calls can now execute them concurrently when model-level parallel tool calls are enabled. ## Validation - `just fmt` - `just test -p codex-web-search-extension` - `git diff --check origin/main...HEAD`
sayan-oai ·
2026-06-01 15:04:11 -07:00 -
fix: rename McpServer to TestAppServer (#25701)
This PR brought to you via VS Code rather than Codex... - opened `codex-rs/app-server/tests/common/mcp_process.rs` - put the cursor on `McpServer` - hit `F2` and renamed the symbol to `TestAppServer` - went to the file tree - hit enter and renamed `mcp_process.rs` to `test_app_server.rs` - ran **Save All Files** from the Command Palette - ran `just fmt` The End (Admittedly, most of the local variables for `TestAppServer` are still named `mcp`, though.)
Michael Bolin ·
2026-06-01 21:49:38 +00:00 -
fix: Deduplicate installed local and remote curated plugins (#25681)
## Summary - Deduplicate installed `openai-curated` and `openai-curated-remote` plugin conflicts by feature flag. - Prefer remote when remote plugins are enabled; otherwise prefer local, while preserving one-sided installs. ## Testing - `just fmt` - `git diff --check` - Targeted `just test` was blocked locally because `cargo-nextest` is not installed.
xl-openai ·
2026-06-01 14:27:18 -07:00 -
Add Python version compatibility guidance (#25690)
## Why Python contributions in this repository should target the declared Python 3 runtime instead of carrying Python 2 compatibility patterns forward. When compatibility across Python 3 point releases matters, contributors need a consistent source of truth for the minimum supported version. ## What changed - Added Python development guidance to `AGENTS.md` stating that the repository uses Python 3+ and should not use the `__future__` module. - Documented that contributors should check the nearest `pyproject.toml` `requires-python` field when evaluating Python 3 point-release compatibility. ## Testing Not run (guidance-only change).
Adam Perry @ OpenAI ·
2026-06-01 14:05:54 -07:00 -
[codex] Generalize deferred nested tool guidance (#25689)
## Summary - describe omitted code-mode tools as deferred nested tools instead of MCP/app tools - update the prompt-description assertion to match ## Why Deferred dynamic tools are also callable through `tools` and discoverable in `ALL_TOOLS`, so the previous MCP/app-specific wording was too narrow. ## Validation - `just fmt` - `just test -p codex-code-mode` - `git diff --check`
sayan-oai ·
2026-06-01 21:01:30 +00:00 -
Add rollout compression histograms (#25680)
## Summary Stacked on #25679. Add histogram telemetry for rollout compression runtime, per-file compression time, byte sizes, and compression ratio. ## Changes - Emit `codex.rollout_compression.run.duration_ms` tagged by final run status. - Emit `codex.rollout_compression.file.duration_ms` tagged by file outcome. - Emit source and compressed byte histograms for compression candidates/results. - Emit `codex.rollout_compression.file.compression_ratio` for successful compressions, recorded as integer basis points. ## Validation - `just fmt` - `just test -p codex-rollout` - `just fix -p codex-rollout`
jif-oai ·
2026-06-01 22:54:25 +02:00 -
[codex] document out-of-line test module convention (#25682)
## Why New unit test modules should follow one consistent layout so implementation files stay focused and test suites remain easy to locate, without creating cleanup churn in existing inline test modules. ## What changed - Added `AGENTS.md` guidance requiring new test modules to use separate sibling `*_tests.rs` files with an explicit `#[path = "..._tests.rs"]` attribute. - Clarified that existing inline `#[cfg(test)] mod tests { ... }` modules should not be moved solely to follow the new convention. ## Validation - Ran `git diff --check`.Adam Perry @ OpenAI ·
2026-06-01 13:36:16 -07:00 -
Add rollout compression counters (#25679)
## Summary Add counter telemetry for the local rollout compression worker so we can see when it runs, why it skips, and how individual file/materialization paths resolve. ## Changes - Emit `codex.rollout_compression.run` with statuses for start, completion, failure, duplicate-run skip, and missing runtime skip. - Emit `codex.rollout_compression.file` outcomes for scanned, compressed, skipped, and failed compression candidates. - Emit `codex.rollout_compression.temp_cleanup` and `codex.rollout_compression.materialize` counters for cleanup and decompression paths. ## Validation - `just fmt` - `just test -p codex-rollout` - `just fix -p codex-rollout`
jif-oai ·
2026-06-01 22:26:32 +02:00 -
refactor: hide shell override for zsh fork unified exec (#24980)
## Why When unified exec is configured to launch through the zsh fork, local commands should not let the model override the shell binary with the `shell` parameter. The configured zsh fork is the mechanism that makes `execv(2)` interception reliable, so exposing `shell` for local zsh-fork execution would create a confusing API surface and undermine the composition. Remote environments are different: zsh-fork interception is local-only, so remote unified-exec calls must keep direct unified-exec behavior and still expose `shell` when a remote environment can be selected. ## What Changed - Taught the `exec_command` schema builder to omit the `shell` parameter when requested. - Hid `shell` from the unified-exec tool schema only when zsh-fork unified exec applies to all selectable environments. - Kept `shell` visible when any remote environment can be targeted, because those calls run through direct unified exec. - Made unified exec choose the effective shell mode per selected environment: local environments keep zsh-fork mode, remote environments use direct mode. - Left direct unified-exec behavior unchanged, including support for model-specified shells there. ## Verification - Added schema coverage showing `exec_command` can hide `shell`. - Added planner coverage showing zsh-fork unified exec hides `shell` for local-only execution while direct unified exec still exposes it. - Added planner coverage showing `shell` remains visible when a remote environment is available. - Added handler coverage showing remote environments use direct unified-exec shell mode instead of zsh-fork mode. - Ran the focused `codex-core` shell-parameter and zsh-fork tests. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/24980). * #24982 * #24981 * __->__ #24980
Michael Bolin ·
2026-06-01 20:22:28 +00:00 -
feat: gate unified exec zsh fork composition (#24979)
## Why `shell_zsh_fork` and unified exec need to remain independently controllable for enterprise rollouts, but we also need a third mode that composes them. That composed mode is intended to preserve unified exec command lifecycle support while letting the zsh fork provide more accurate `execv(2)` interception. Enabling `unified_exec_zsh_fork` by itself is intentionally not sufficient. It is a composition gate, not a dependency-enabling shortcut: - `unified_exec` selects the PTY-backed unified exec tool. - `shell_zsh_fork` opts into the zsh fork backend. - `unified_exec_zsh_fork` only allows those two already-enabled modes to be composed so local zsh unified exec commands can launch through the zsh fork. This separation is deliberate. Enterprises and staged rollouts must be able to enable or disable unified exec and zsh-fork independently. If `unified_exec_zsh_fork` implied either dependency, then enabling one under-development composition flag would silently activate a shell backend that the configured feature set left disabled. This PR introduces only the configuration and planning gate for that composition. Existing `shell_zsh_fork` behavior continues to use the standalone shell tool unless the new composition feature is explicitly enabled alongside both dependencies. ## What Changed - Added the under-development feature flag `unified_exec_zsh_fork`. - Added `UnifiedExecFeatureMode` so the three input feature flags collapse into `Disabled`, `Direct`, or `ZshFork` mode before tool planning. - Updated tool selection so zsh-fork composition requires `unified_exec`, `shell_zsh_fork`, and `unified_exec_zsh_fork`. - Kept the existing standalone zsh-fork shell tool behavior when only `shell_zsh_fork` is enabled. - Updated config schema output for the new feature flag. ## Verification - Added feature and tool-config coverage for the new gate. - Added planner coverage proving `shell_zsh_fork` remains standalone until composition is explicitly enabled. - Ran focused tests for `codex-features`, `codex-tools`, and the affected `codex-core` planner case. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/24979). * #24982 * #24981 * #24980 * __->__ #24979
Michael Bolin ·
2026-06-01 13:01:36 -07:00 -
fix: deflake zsh-fork approval test (#25669)
Fixes this flake: https://github.com/openai/codex/actions/runs/26773809591/job/78919970410?pr=25659 This test is about zsh-fork subcommand approval behavior, not workspace sandboxing, so it now runs with `DangerFullAccess` to avoid macOS sandbox setup failures before the second subcommand approval.
jif-oai ·
2026-06-01 21:55:44 +02:00 -
exec-server: canonicalize bound filesystem paths (#25149)
## Summary - add executor filesystem canonicalization as a bound-path operation - route remote canonicalization through the exec-server filesystem RPC surface - keep path normalization attached to the filesystem that owns the path ## Stack - 2/5 in the skills path authority stack extracted from https://github.com/openai/codex/pull/25098 - follows merged https://github.com/openai/codex/pull/25121 ## Validation - `cd /Users/starr/code/codex-worktrees/pr-25098-restack-review-pr1b/codex-rs && just fmt` - Not run: tests/checks (not requested) - GitHub CI pending on rewritten head
starr-openai ·
2026-06-01 11:53:31 -07:00 -
[codex-rs] auto-review model override (#23767)
## Why Guardian auto-review normally uses the provider-preferred review model when one is available. Some parent models need model-catalog metadata to select a different review model while keeping older `/models` payloads compatible when that metadata is absent. ## What changed - Added optional `ModelInfo::auto_review_model_override` metadata to the public model payload as a review-model slug. - Updated Guardian review model selection to prefer the catalog override when present, while preserving the existing provider preferred-model path and parent-model fallback when it is omitted. - Added focused Guardian coverage for override and no-override model selection. - Added an `auto_review` core integration suite test that loads override metadata from a remote model catalog path and asserts the strict auto-review `/responses` request uses the catalog-selected review model. - Updated existing `ModelInfo` fixtures and local catalog constructors for the new optional field. ## Validation - `cargo test -p codex-protocol model_info_defaults_availability_nux_to_none_when_omitted` - `cargo test -p codex-core guardian_review_uses_` - `cargo test -p codex-core remote_model_override_uses_catalog_model_for_strict_auto_review --test all` - `just fix -p codex-protocol` - `just fix -p codex-core` - `just fmt` - `git diff --check`
Won Park ·
2026-06-01 11:51:15 -07:00 -
Check root Python script formatting in CI (#25165)
## Why Python files under `scripts/` were not covered by the repository formatting recipe or the CI formatting job, so formatting drift could merge unnoticed. ## What - Add a dedicated `scripts/pyproject.toml` and `scripts/uv.lock` so root-script formatting uses a locked Ruff version. - Extend `just fmt` to format root Python scripts and add `fmt-scripts-check` for CI. - Run `just fmt-scripts-check` from `.github/workflows/ci.yml`, installing `uv` through SHA-pinned `astral-sh/setup-uv` while retaining the `uv` `0.11.3` pin. - Apply Ruff formatting to the root Python scripts, including `scripts/just-shell.py`, and extend `sdk/python/tests/test_artifact_workflow_and_binaries.py` to cover the root formatting recipe. - Update `AGENTS.md` so agents run `just fmt` after code changes anywhere in the repository. ## Validation - Extended the existing Python SDK workflow test to assert that `just fmt` includes root Python scripts.
Adam Perry @ OpenAI ·
2026-06-01 18:50:23 +00:00 -
Throttle repeated rollout compression runs (#25659)
## Why [#25089](https://github.com/openai/codex/pull/25089) introduced the background worker that compresses cold archived rollouts, and [#25654](https://github.com/openai/codex/pull/25654) made that pass faster once it starts. But the worker still deleted `rollout-compression.lock` on successful exit, so the existing six-hour staleness window only helped with overlapping or crashed workers. Each new local thread-store initialization could immediately rescan archived rollouts even if a full pass had just finished. This change keeps the existing marker around long enough to throttle redundant reruns. The worker is still best-effort, but it no longer does repeated startup scans when nothing new is eligible for compression. ## What Changed - Replace the drop-scoped `CompressionLock` with a `CompressionRunMarker` that claims the existing `.tmp/rollout-compression.lock` path and leaves it in place after success. - Reuse the existing six-hour staleness window to block both overlapping starts and immediate reruns, while still letting a stale marker be reclaimed. - Update the worker docs and debug logging to describe the new "already running or recently ran" behavior. - Extend the rollout compression tests to assert that a successful run leaves the marker behind and that a fresh marker suppresses a new run. ## Validation - `just test -p codex-rollout`
jif-oai ·
2026-06-01 20:46:54 +02:00 -
[codex] Consolidate shared prompts in codex-prompts (#25151)
## Why `codex_core` is consistently a bottleneck for incremental builds during iteration. The simplest fix is to make the crate smaller. ## Summary `codex-core` owns several reusable prompt renderers and static prompt assets, which makes the crate harder to split apart. Rename `codex-review-prompts` to `codex-prompts` and move shared review, goal, permissions, compaction, realtime, hierarchical AGENTS.md, and `apply_patch` prompts into it. Move prompt-only tests and update consumers and `CODEOWNERS`. ## Validation - `just test -p codex-prompts -p codex-apply-patch` - `just test -p codex-core prompt_caching` - Bazel builds for the affected crates
Adam Perry @ OpenAI ·
2026-06-01 18:45:07 +00:00 -
[codex] Make justfile recipes Windows-aware (#24983)
## Summary Make the root `justfile` usable from Windows without maintaining a separate Windows copy of most recipes. The repo recipes previously assumed POSIX shell behavior for things like variadic argument forwarding (`"$@"`) and stderr redirection (`2>/dev/null`). That made common workflows such as `just fmt`, `just test`, and `just log` unreliable from Windows. This PR introduces a small cross-platform shell adapter so recipes can stay mostly unified while still expanding the few shell-specific constructs correctly on macOS/Linux and Windows. ## What Changed - Add `scripts/just-shell.py` as the configured `just` shell adapter. - On Unix it invokes `sh -cu`. - On Windows it invokes `pwsh -CommandWithArgs` so arguments containing spaces are preserved. - Add portable recipe placeholders: - `{args}` expands to `"$@"` on Unix and the equivalent PowerShell forwarded-args expression on Windows. - `{stderr-null}` expands to the platform-specific stderr suppression used by `fmt`. - Convert most variadic one-line recipes to the unified `{args}` form, including `codex`, `exec`, `file-search`, `app-server-test-client`, `fix`, `clippy`, `bench`, `mcp-server-run`, `write-app-server-schema`, and `argument-comment-lint-from-source`. - Keep genuinely shell-specific recipes split or Unix-only for now, including recipes backed by `.sh` scripts or recipes whose bodies are more than simple command forwarding. - Add a Windows `just install` path that installs PowerShell via `winget` when `pwsh` is not available, then runs the same basic Rust setup steps. - Update the SDK test that validates the root `fmt` recipe so it recognizes the new portable stderr placeholder. ## Validation - `just --summary` - `just --dry-run fmt` - `just --dry-run bench-smoke` - `just --dry-run codex foo "bar binky" baz` - `just --dry-run write-hooks-schema` - `just --dry-run bazel-lock-update` - `just --dry-run argument-comment-lint-from-source -- "foo bar"` - `git diff --check -- justfile scripts/just-shell.py sdk/python/tests/test_artifact_workflow_and_binaries.py` - Verified Windows argv preservation through `scripts/just-shell.py` with arguments containing spaces. - `uv run --frozen --project sdk/python --extra dev pytest sdk/python/tests/test_artifact_workflow_and_binaries.py::test_root_fmt_recipe_formats_rust_and_python_sdk`iceweasel-oai ·
2026-06-01 11:26:36 -07:00 -
Preserve plugin app manifest order (#25491)
## Summary - Preserve app declaration order when loading plugin .app.json files. - Keep plugin connector summaries in plugin app order after connector metadata is merged and filtered. - Add regression coverage for .app.json order and connector summary order. ## Validation - just fmt - just test -p codex-chatgpt connectors_for_plugin_apps_returns_only_requested_plugin_apps - just test -p codex-core-plugins effective_apps_preserves_app_config_order - just fix -p codex-core-plugins (passes with existing clippy large_enum_variant warning in core-plugins/src/manifest.rs) - just fix -p codex-chatgpt - just bazel-lock-update - just bazel-lock-check
charlesgong-openai ·
2026-06-01 11:04:21 -07:00 -
[codex] Rename multi-agent v2 assign_task to followup_task (#25636)
## Summary Renames the MultiAgentV2 turn-triggering tool from `assign_task` to `followup_task` so the exposed tool name better describes sending an additional task to an existing agent. This updates the tool spec, handler/module names, registry wiring, default multi-agent v2 usage hints, and tests. Rollout trace classification keeps accepting legacy `assign_task` events so older traces still reduce correctly, while docs show the new tool name. ## Test plan - `just test -p codex-core followup_task` - `just test -p codex-core -E 'test(multi_agent_feature_selects_one_agent_tool_family) | test(multi_agent_v2_can_use_configured_tool_namespace) | test(code_mode_only_can_expose_namespaced_multi_agent_v2_as_normal_tools)'` - `just test -p codex-rollout-trace` - `just fix -p codex-core` - `just fix -p codex-rollout-trace` Notes: `just fmt` ran `cargo fmt` but failed in the Python ruff phase because the local environment could not resolve `hatchling>=1.27.0` from the configured internal registry. A full `just test -p codex-core` also hit unrelated environment-sensitive integration failures involving missing spawned test binaries/sandbox behavior; the changed multi-agent spec/handler tests passed in the filtered runs above.
jif-oai ·
2026-06-01 19:57:11 +02:00 -
exec-server: add environment path refs (#25121)
## Summary - add public `codex_exec_server::EnvironmentPathRef` - bind an absolute path to its owning executor filesystem - keep path operations in the next review slice ## Stack - 1/5 in the skills path authority stack extracted from https://github.com/openai/codex/pull/25098 ## Validation - `cd /Users/starr/code/codex-worktrees/pr-25098-restack4/codex-rs && just fmt` - GitHub CI pending on rewritten head
starr-openai ·
2026-06-01 10:55:52 -07:00 -
Parallelize cold rollout compression (#25654)
## Why [#25089](https://github.com/openai/codex/pull/25089) added the background worker for compressing cold archived rollouts, but the worker still processed files effectively one at a time: each compression job was sent to `spawn_blocking` and then awaited before the next file started. On machines with a backlog of archived rollouts, that makes catch-up slower than it needs to be even though the actual compression work already runs off the async runtime. ## What Changed - Queue rollout compression work in a `JoinSet` while directory traversal continues. - Cap the worker at two in-flight compression jobs so it can overlap compression without turning the background task into unbounded blocking work. - Drain pending jobs before returning, including the `read_dir.next_entry()` error path, so every launched job still contributes to the final `compressed`, `skipped`, and `failed` stats. - Treat task join failures the same way as compression failures in the worker's warning and failure accounting.
jif-oai ·
2026-06-01 19:54:52 +02:00 -
jif-oai ·
2026-06-01 19:48:29 +02:00 -
[codex] Use git CLI for release Cargo fetches (#25644)
## Summary - Configure the rust-release build job with `CARGO_NET_GIT_FETCH_WITH_CLI=true` - Document the macOS SecureTransport/libgit2 failure mode that hit the `libwebrtc`/`libyuv` git submodule fetch ## Root cause The release run at https://github.com/openai/codex/actions/runs/26717498860/job/78745156683 repeatedly failed before compilation because Cargo's libgit2 fetch path could not clone the nested `yuv-sys/libyuv` submodule from `chromium.googlesource.com`, ending with `SecureTransport error: connection closed via error`. ## Validation - `git diff --check` This is a workflow-only change, so I did not run Rust package tests.
Shijie Rao ·
2026-06-01 10:34:12 -07:00 -
Vivian Fang ·
2026-06-01 10:13:56 -07:00 -
Disable SQLite intrinsics for Windows x64 releases (#25490)
## Why Codex 0.135.0 started shipping bundled SQLite 3.51.x via SQLx 0.9.0 to avoid the older WAL corruption bug fixed by #24728. On Windows x64, #25367 reports an immediate `STATUS_ILLEGAL_INSTRUCTION` crash on a Haswell CPU when starting normal Codex paths. Rather than downgrading SQLite, this keeps the newer bundled SQLite source and removes SQLite compiler-intrinsic code paths from the Windows x64 release build. ## What changed For `x86_64-pc-windows-msvc` release builds, export `LIBSQLITE3_FLAGS=SQLITE_DISABLE_INTRINSIC` before `cargo build` in: - `.github/workflows/rust-release.yml` - `.github/workflows/rust-release-windows.yml` Other targets keep their current SQLite build flags. ## Verification - `git diff --check`
Eric Traut ·
2026-06-01 09:49:55 -07:00 -
Compress cold local rollouts (#25089)
## Rollout compression stack This stack splits #24941 into reviewable steps for local rollout compression. The design is intentionally staged: 1. Teach readers, listing, search, and lookup to understand compressed rollouts. 2. Make append and resume paths materialize compressed rollouts back to plain JSONL before writing. 3. Add a disabled-by-default worker that can compress cold archived rollouts behind `local_thread_store_compression`. The key invariant is that writers append to plain `.jsonl`. A `.jsonl.zst` file is a cold/read representation; if a write is needed, the compressed file is materialized back to plain JSONL first. Readers prefer plain `.jsonl` when both forms exist and can fall back to the compressed sibling during transitions. The worker is deliberately the last PR and remains behind an under-development feature flag. It currently scans only `archived_sessions`, not active `sessions`, because active sessions have the highest resume/append race risk. That means this stack does not yet compress most unarchived local history. ## Known race / follow-up The remaining unresolved design question is writer/compressor coordination. Even for archived rollouts, a resume or metadata update can append while the worker is replacing the plain file with `.jsonl.zst`; the current double-stat checks narrow but do not fully eliminate the window where a writer has opened the plain file before unlink. Do not treat the worker PR as production-ready until we either: - prevent append/resume paths from racing archived compression, or - introduce a shared representation/append lock or equivalent coordination. The first two PRs are useful independently: they make compressed rollouts readable and make append paths safely recover back to plain JSONL. The third PR isolates the worker behavior so that coordination issue is reviewable separately. ## Validation Focused local validation for the stack includes: - `just test -p codex-rollout` - `just test -p codex-thread-store` where thread-store paths were touched - `just test -p codex-features` for the feature flag slice - `just bazel-lock-check` after dependency graph changes - scoped `just fix -p ...` passes for changed crates CI is still the source of truth for the full platform matrix. ## This PR in the stack This is PR 3/3, based on #25088. It adds the under-development feature flag and starts the best-effort background worker when enabled. The worker currently compresses only cold archived rollouts, skips active sessions, verifies compressed output, preserves mtime and permissions, keeps a store-level lock heartbeat, and cleans stale temp files. Stack order: 1. #25087: read compressed local rollouts. 2. #25088: materialize compressed rollouts before append. 3. This PR: add the disabled local compression worker.
jif-oai ·
2026-06-01 18:35:58 +02:00 -
Preserve renamed thread titles during reconciliation (#25624)
## Summary - preserve existing explicit SQLite thread titles during rollout reconciliation/backfill when the incoming rollout title is only first-message-derived - keep stale inferred-title repair behavior while avoiding session-index scans during startup backfill - add a regression test for renamed titles surviving reconcile ## Testing - just fmt - just test -p codex-rollout - just test -p codex-state
jif-oai ·
2026-06-01 18:33:05 +02:00 -
Add reasoning-only status surface item (#25504)
Closes #24886. ## Why Users can configure the TUI status line and terminal title with `model-with-reasoning`, but issue #24886 asks for a compact reasoning-only item. That lets a setup show just `default`, `low`, `medium`, `high`, or `xhigh` without repeating the model name. ## What changed - Added a `reasoning` item for `/statusline` and `/title` setup flows. - Rendered the item from the effective reasoning effort, including collaboration-mode overrides. - Registered `reasoning` with `codex doctor` so Codex-generated terminal-title config is not reported as invalid. - Updated TUI setup snapshots so the picker previews include the new item.
Eric Traut ·
2026-06-01 09:30:20 -07:00 -
Reset slash popup selection when filter changes (#25492)
## Summary Fixes #25295. The slash-command popup reused its previous `ScrollState` when the composer filter token changed. After scrolling the full `/` command list, typing a narrower filter such as `/st` could clamp the stale selection into the filtered results and highlight the wrong command. This resets the popup selection and viewport only when the parsed filter token changes, so normal arrow navigation is preserved while new filters start at the first match.
Eric Traut ·
2026-06-01 09:17:19 -07:00 -
Use deep links for macOS codex app paths (#25485)
## Why `codex app [PATH]` is the documented CLI entry point for opening Codex Desktop on a workspace. Recent desktop builds can focus the app while failing to honor paths passed as macOS document-open arguments via `open -a Codex.app <workspace>`, which broke `codex app .` for users. See #25333; related report: #25166. The desktop app still supports the explicit `codex://threads/new?path=...` route, so the CLI should use that app-owned launch surface instead of depending on folder-open event delivery. ## What Changed - Build a `codex://threads/new?path=<workspace>` URL in the macOS app launcher. - Pass that URL to `open -a <Codex.app>` instead of passing the workspace path as a document argument. - Add coverage that workspace paths needing escaping round-trip through URL query encoding. ## Verification - `just test -p codex-cli codex_new_thread_url_encodes_workspace_path`
Eric Traut ·
2026-06-01 09:17:08 -07:00 -
Allow paste in searchable selection menus (#25400)
## Summary I frequently want to be able to paste into the searchable menu -- the most common use-case here is when specifying an upstream for a `/review`, where I copy the upstream from an open terminal.
Charlie Marsh ·
2026-06-01 18:01:52 +02:00 -
Preserve auto-review approval policy in codex exec (#23763)
## Why `codex exec` was forcing headless runs to `approval_policy = "never"` even when the resolved reviewer was `auto_review`. That prevented unattended exec workflows from reaching the reviewed MCP write path they were configured to use. ## What changed - Keep the existing headless `never` default for ordinary exec runs. - Re-resolve exec config without that synthetic override when the final reviewer resolves to `AutoReview`, so configured or requirements-driven approval policy is preserved. - Add regression coverage for: - `auto_review` plus `on-request` from user config - requirements-driven `AutoReview`, asserting exec’s final approval policy matches the no-override control config exactly ## Validation - `just fmt` - `cargo test -p codex-exec`
Won Park ·
2026-06-01 08:53:25 -07:00 -
feat(tui): restore output-free cancelled prompts (#25316)
## TL;DR When you press Esc or Ctrl+C after sending a prompt but before any output was rendering, it restores the last composer and the message. ## Summary Cancelling a prompt immediately after submission should behave like returning to edit that prompt, not like discarding the user's draft. Today, pressing `Esc` or `Ctrl+C` before Codex responds leaves the submitted prompt in the transcript and returns an empty composer, forcing the user to recall or retype it. When an interrupted turn has not produced substantive visible output, restore its submitted prompt directly into the composer and roll back that latest turn. This also covers the first prompt in a fresh thread, before the TUI has retained a local user-history cell. The restored draft keeps its text, image attachments, and active collaboration mode so it can be edited and resubmitted in place. Restoration is intentionally suppressed once the turn has produced user-visible activity such as assistant output, tool work, hooks, or patches. A transient thinking status does not make the prompt ineligible. Rollback also rebuilds terminal scrollback from the retained transcript cells so repeated cancellations and terminal resizes do not duplicate history. ## How to Test 1. Start the TUI with `cargo run -p codex-cli --bin codex`. 2. In a fresh thread, submit the first prompt and press `Esc` before Codex emits substantive output. Confirm that the prompt returns to the composer for editing and its submitted transcript row is removed. 3. Repeat with `Ctrl+C`, then repeat after at least one completed turn. Confirm the same behavior. 4. Submit a prompt, wait for assistant output or tool activity, then cancel. Confirm that the transcript remains intact and the prompt is not restored into the composer. 5. Cancel several output-free prompts and resize the terminal between attempts. Confirm that the startup banner, tip, and transcript history do not duplicate in scrollback. Targeted tests: - `just test -p codex-tui cancelled_turn_edit_restores_prompt` - `just test -p codex-tui output_free_interrupted_turn_requests_prompt_restore` - `just test -p codex-tui visible_output_prevents_cancelled_turn_prompt_restore` - `just test -p codex-tui thinking_status_keeps_cancelled_turn_prompt_restore_eligible` - `just test -p codex-tui patch_activity_prevents_cancelled_turn_prompt_restore` The full `just test -p codex-tui` run completed with `2746` passing tests and two unrelated existing guardian feature-flag failures. `just argument-comment-lint` remains blocked locally by the existing Bazel LLVM `compiler-rt` sanitizer-header glob failure; the touched Rust diff was manually audited for positional literal comments.
Felipe Coury ·
2026-06-01 11:49:14 -03:00 -
[codex] fix compressed rollout fixture SessionMeta initialization (#25628)
## Summary - initialize `parent_thread_id` in the compressed rollout test fixture's `SessionMeta` - restore rollout test compilation across Bazel test, clippy, release-build, and argument-comment-lint jobs ## Root cause PR #25087 (`Read compressed rollouts and materialize before append`) added `codex-rs/rollout/src/compression_tests.rs` in merge commit `a8a6071279b6f3112fcc5fc3fee69c48473d7149`. Its `write_rollout` fixture constructs `SessionMeta` without the required `parent_thread_id` field, causing `error[E0063]` when Bazel compiles `rollout-unit-tests-bin` on `main` and downstream PRs. ## Validation - `UV_CACHE_DIR=/private/tmp/codex-uv-cache just fmt` - `just test -p codex-rollout` (`59` tests passed; bench smoke passed) - `git diff --check` - manually audited the touched Rust diff for positional literal argument comments; the change adds no positional callsite ## Local lint blocker - `just argument-comment-lint` could not reach source inspection locally because Bazel's LLVM dependency fails analysis: `compiler-rt/BUILD.bazel` glob `include/sanitizer/*.h` matched no files.
Felipe Coury ·
2026-06-01 16:43:21 +02:00 -
Read compressed rollouts and materialize before append (#25087)
## Why Local rollout compression needs a cold `.jsonl.zst` representation without letting compressed physical paths leak into append-mode writers. The unsafe case is resume or metadata update code successfully reading a compressed rollout and then appending raw JSONL bytes to the zstd file. This PR folds the former #25088 materialization slice into the read-support PR so the reader changes and append-safety invariant land together. ## What Changed - Teach rollout readers, discovery, listing, search, and ID lookup to understand compressed `.jsonl.zst` rollouts. - Keep `.jsonl` as the logical/stored rollout path while allowing read paths to open either plain or compressed storage. - Materialize compressed rollouts back to plain `.jsonl` before append-mode writes, including resume and direct metadata append paths. - Preserve compressed-file permissions when materializing back to plain JSONL. - Refresh thread-store resolved rollout paths after compatibility metadata writes so reconciliation follows the materialized file. - Avoid treating transient compression temp files as real rollout lookup results. ## Remaining Stack #25089 remains the separate worker PR. It is based directly on this PR and stays behind the disabled `local_thread_store_compression` feature flag. The worker still has a broader coordination question: a resume or metadata update can race with background compression while a plain file is being replaced by `.jsonl.zst`. This PR handles the read and materialize-before-append primitives; it does not make the worker production-ready. ## Validation - `just test -p codex-rollout` - `just test -p codex-thread-store` - `just fix -p codex-rollout` - `just fix -p codex-thread-store` - `just bazel-lock-check`
jif-oai ·
2026-06-01 15:14:19 +02:00 -
Add goal extension GoalApi (#25096)
## Summary - add an extension-owned `GoalApi` for thread goal get/set/clear operations - register live goal runtimes with the API from the goal extension backend - cover the API and runtime-effect paths in goal extension tests ## Stack Follow-up app-server wiring PR: #25108 ## Validation - `just fmt` - `just fix -p codex-goal-extension` - `just test -p codex-goal-extension`
jif-oai ·
2026-06-01 11:32:13 +02:00 -
Remove Plan-mode gate from idle turn injection (#25577)
## Why `try_start_turn_if_idle` is the core helper for starting injected input only when the session is actually idle. It should stay focused on generic turn-lifecycle safety. The previous `ModeKind::Plan` guard mixed caller policy into that helper: Plan mode may choose not to auto-start some extension work, but that decision belongs at the extension or caller boundary rather than in the session injection primitive. ## What changed - Removed the `ModeKind::Plan` early return from `Session::try_start_turn_if_idle`. - Removed the now-unused `ModeKind` import from `core/src/session/inject.rs`. ## Testing Not run locally.
jif-oai ·
2026-06-01 11:06:38 +02:00 -
Use templates for goal steering prompts (#25576)
## Why Goal steering prompts have grown into long inline Rust strings, which makes the authored prompt text hard to review and easy to damage while changing the surrounding plumbing. Moving those prompts into embedded Markdown templates keeps the policy text in the shape reviewers actually read, while preserving the existing runtime substitution and objective escaping behavior. ## What changed - Added `ext/goal/templates/goals/continuation.md`, `budget_limit.md`, and `objective_updated.md` for the three goal steering prompts. - Updated `ext/goal/src/steering.rs` to parse those embedded templates once with `codex-utils-template` and render the existing goal values into them. - Kept user objectives XML-escaped before rendering and converted budget counters into template variables. - Added the template directory to `ext/goal/BUILD.bazel` `compile_data` so Bazel has the same embedded prompt inputs as Cargo. ## Testing - Not run locally.
jif-oai ·
2026-06-01 10:55:14 +02:00 -
Add goal extension idle continuation (#25060)
## Why The goal extension needs a way to resume an active goal after the thread becomes idle, but the old core goal runtime should not be refactored as part of this step. The missing piece is a small core-owned turn-start primitive: let an extension ask for a normal model turn only when the thread is idle, and otherwise fail without injecting into whatever is currently active. ## What Changed - Adds `CodexThread::try_start_turn_if_idle(...)` as the narrow extension-facing primitive for synthetic idle work. - Implements the session side so it refuses to start when: - the provided input is empty, - the session is in plan mode, - a turn is already active, or - trigger-turn mailbox work is pending. - Gives trigger-turn mailbox work priority if it appears while the idle turn is being prepared. - Wires `GoalExtension::on_thread_idle` to read the active persisted goal and submit the continuation prompt through this idle-only primitive. - Keeps the legacy core goal continuation implementation in place instead of folding it into this PR. ## Behavior This is intentionally best-effort. If `try_start_turn_if_idle` observes that the thread is not idle, or that higher-priority mailbox work should run first, it returns the input to the caller. The goal extension drops that continuation prompt and waits for a future idle opportunity instead of injecting stale synthetic goal text into an active turn. ## Validation - `just test -p codex-core try_start_turn_if_idle_rejects_active_turn_without_injecting` - `just test -p codex-goal-extension`
jif-oai ·
2026-06-01 10:42:01 +02:00 -
Set multi-agent v2 dogfood defaults (#25266)
## Summary - default multi-agent v2 to direct-model-only tools so code mode does not wrap subagent tools - add default root/subagent team prompts aligned with dogfood training assumptions - tighten spawn-agent model override wording to prefer the inherited model by default ## Tests - just fmt - just test -p codex-core spawn_agent_description_lists_visible_models_and_reasoning_efforts - just test -p codex-core multi_agent_v2_default_session_thread_cap_counts_root - just test -p codex-rollout-trace - just fix -p codex-core - just fix -p codex-rollout-trace Note: a broad just test -p codex-core run was attempted locally, but this sandbox produced unrelated environment failures around sandbox-exec, missing test_stdio_server, and realtime timeouts.
jif-oai ·
2026-06-01 10:24:46 +02:00 -
store and expose parent_thread_id on Threads (#25113)
## Why This PR https://github.com/openai/codex/pull/24161#discussion_r3325692763 revealed a subagent data modeling issue, where we overloaded `forked_from_id` to also mean `parent_thread_id`. That's incorrect since guardian and review subagents can be a subagent and NOT fork the main thread's history. The solution here is to explicitly store a new `parent_thread_id` on `SessionMeta`, alongside `forked_from_id` which already exists. While we're at it, also expose it in the app-server protocol on the `Thread` object. A thread->subagent relationship and a fork of thread history are orthogonal concepts. ## What Changed - Added top-level `parent_thread_id` persistence on `SessionMeta` and runtime/session plumbing through `SessionConfiguredEvent`, `CodexSpawnArgs`, `SessionConfiguration`, `ThreadConfigSnapshot`, `TurnContext`, and `ModelClient`. - Made turn metadata, request headers, analytics, and subagent-start events read the separate runtime/top-level parent field instead of deriving general parent lineage from `SessionSource` or `forked_from_thread_id`. - Passed parent lineage separately at delegated subagent, review, guardian, agent-job, and multi-agent spawn construction sites; copied-history fork lineage remains derived only from `InitialHistory`. - Persisted and exposed parent lineage through rollout/thread-store projections and app-server v2 `Thread.parentThreadId`. - Updated app-server README text and regenerated app-server schema fixtures for the additive `parentThreadId` response field.
Owen Lin ·
2026-06-01 04:33:20 +00:00 -
Shijie Rao ·
2026-05-31 16:05:33 -07:00 -
Add cloud-managed config layer support (#24620)
## Summary PR 3 of 5 in the cloud-managed config client stack. Adds enterprise-managed cloud config as a first-class config layer source. The layer metadata is preserved through config loading, diagnostics, debug output, hook attribution, and app-server protocol surfaces. ## Details - Enterprise-managed config becomes a normal config layer source with backend-supplied `id` and display `name` attached for provenance. - These layers are designed to behave like non-file managed config: they can surface syntax/type diagnostics by layer name even though there is no physical config file. - Relative path settings are resolved from a stored config base so cloud-delivered config remains consistent with existing MDM-delivered config semantics. - Hook attribution distinguishes config-delivered hooks from requirements-delivered hooks via `HookSource::CloudManagedConfig`. - This remains pull-based and snapshot-oriented; the PR adds layer identity/diagnostics, not dynamic reload behavior. ## Validation Validated through the targeted stack checks after rebasing onto current `main`: - Rust crate tests for config/hooks/cloud-config/backend-client/app-server-protocol - Filtered `codex-core` and `codex-app-server` `cloud_config_bundle` tests - Python generated-file contract test - `cargo shear --deny-warnings` - Targeted `argument-comment-lint` for config/hooks
joeflorencio-openai ·
2026-05-31 15:54:31 -07:00 -
Compose requirements layers (#24619)
## Summary PR 2 of 5 in the cloud-managed config client stack. Adds a shared requirements-layer composition engine. The composer defines how ordered requirements layers combine, with focused tests for the merge semantics and provenance behavior. The final PR in the stack wires runtime requirements sources into this path. ## Details - Mental model: requirements layers are ordered lowest priority first, matching `ConfigLayerStack`; lower-priority layers provide defaults while higher-priority layers win scalar/list conflicts. - Regular fields use config-style TOML merging, including recursive table merging, so requirements layering follows the same broad model as `config.toml` layering. - Domain-specific fields keep explicit semantics: `rules.prefix_rules` and hooks preserve high-priority-first output, hooks fail closed on active managed-dir conflicts, and `permissions.filesystem.deny_read` dedupes as a stable high-priority-first union. - `remote_sandbox_config` is evaluated within each layer before the regular TOML merge, so host-specific sandbox constraints do not leak across layers. - Provenance points at the exact source when one layer owns a value and uses composite provenance when a table field is assembled from multiple layers. ## Validation Local validation: - `just fmt` - `cargo check -p codex-config` - `just test -p codex-config requirements_composition` - `git diff --check` CI will run the broader test matrix.
joeflorencio-openai ·
2026-05-31 15:14:06 -07:00