Commit Graph
11783 Commits
Author SHA1 Message Date
Michael Bolin 74bceac44c Merge 07ac71ba8a into sapling-pr-archive-bolinfest 2026-04-17 16:00:03 -07:00
Michael Bolin 07ac71ba8a protocol: canonicalize file system permissions 2026-04-17 15:59:47 -07:00
Michael Bolin f99160a081 merge commit for archive created by Sapling 2026-04-17 15:52:56 -07:00
Michael BolinandCodex f6f700facf bazel: use native rust test sharding
Configure the large Rust test targets with Bazel's native shard_count while keeping rules_rust's stable test-name hash bucket assignment.

With rules_rs 0.0.58 available on main, this change only adds the Codex macro wiring and opts the selected large test targets into sharding.

Co-authored-by: Codex <noreply@openai.com>
2026-04-17 15:52:07 -07:00
zbarsky-openaiandCodex 680c4102ae [codex] Upgrade rules_rs and llvm to latest BCR versions (#18397)
## Why
This branch brings the Bazel module pins for `rules_rs` and `llvm` up to
the latest BCR releases and aligns the root direct dependencies with the
versions the module graph already resolves to.

That gives us a few concrete wins:
- picks up newer upstream fixes in the `rules_rs` / `rules_rust` stack,
including work around repo-rule nondeterminism and default Cargo binary
target generation
- picks up test sharding support from the newer `rules_rust` stack
([hermeticbuild/rules_rust#13](https://github.com/hermeticbuild/rules_rust/pull/13))
- picks up newer built-in knowledge for common system crates like
`gio-sys`, `glib-sys`, `gobject-sys`, `libgit2-sys`, and `libssh2-sys`,
which gives us a future path to reduce custom build-script handling
- reduces local patch maintenance by dropping fixes that are now
upstream and rebasing the remaining Windows patch stack onto a newer
upstream base
- removes the direct-dependency warnings from `bazel-lock-check` by
making the root pins match the resolved graph

## What Changed
- bump `rules_rs` from `0.0.43` to `0.0.58`
- bump `llvm` from `0.6.8` to `0.7.1`
- bump `bazel_skylib` from `1.8.2` to `1.9.0` so the root direct dep
matches the resolved graph
- regenerate `MODULE.bazel.lock` for the updated module graph
- refresh the remaining Windows-specific patch stack against the newer
upstream sources:
  - `patches/rules_rs_windows_gnullvm_exec.patch`
  - `patches/rules_rs_windows_exec_linker.patch`
  - `patches/rules_rust_windows_exec_std.patch`
  - `patches/rules_rust_windows_msvc_direct_link_args.patch`
- remove patches that are no longer needed because the underlying fixes
are upstream now:
  - `patches/rules_rs_delete_git_worktree_pointer.patch`
  - `patches/rules_rust_repository_set_exec_constraints.patch`

## Validation
- `just bazel-lock-update`
- `just bazel-lock-check`

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-17 18:45:32 -04:00
viyatb-oaiandCodex f705f42ba8 fix: fix fs sandbox helper for apply_patch (#18296)
## Summary

- pass split filesystem sandbox policy/cwd through apply_patch contexts,
while omitting legacy-equivalent policies to keep payloads small
- keep the fs helper compatible with legacy Landlock by avoiding helper
read-root permission expansion in that mode and disabling helper network
access

## Root Cause

`d626dc38950fb40a1a5ad0a8ffab2485e3348c53` routed exec-server filesystem
operations through a sandboxed helper. That path forwarded legacy
Landlock into a helper policy shape that could require direct
split-policy enforcement. Sandboxed `apply_patch` hit that edge through
the filesystem abstraction.

The same 0.121 edit-regression path is consistent with #18354: normal
writes route through the `apply_patch` filesystem helper, fail under
sandbox, and then surface the generic retry-without-sandbox prompt.

Fixes #18069
Fixes #18354

## Validation

- `cd codex-rs && just fmt`
- earlier branch validation before merging current `origin/main` and
dropping the now-separate PATH fix:
  - `cd codex-rs && cargo test -p codex-exec-server`
- `cd codex-rs && cargo test -p codex-core file_system_sandbox_context`
  - `cd codex-rs && just fix -p codex-exec-server`
  - `cd codex-rs && just fix -p codex-core`
  - `git diff --check`
  - `cd codex-rs && cargo clean`

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-17 15:39:07 -07:00
Michael Bolin 24638147ee Merge 29dd204720 into sapling-pr-archive-bolinfest 2026-04-17 15:22:38 -07:00
Michael Bolin 29dd204720 refactor: use semaphores for async serialization gates 2026-04-17 15:21:04 -07:00
Michael Bolin c9c4caafd8 refactor: use cloneable async channels for shared receivers (#18398)
This is the first mechanical cleanup in a stack whose higher-level goal
is to enable Clippy coverage for async guards held across `.await`
points.

The follow-up commits enable Clippy's
[`await_holding_lock`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock)
lint and the configurable
[`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type)
lint for Tokio guard types. This PR handles the cases where the
underlying issue is not protected shared mutable state, but a
`tokio::sync::mpsc::UnboundedReceiver` wrapped in `Arc<Mutex<_>>` so
cloned owners can call `recv().await`.

Using a mutex for that shape forces the receiver lock guard to live
across `.await`. Switching these paths to `async-channel` gives us
cloneable `Receiver`s, so each owner can hold a receiver handle directly
and await messages without an async mutex guard.

## What changed

- In `codex-rs/code-mode`, replace the turn-message
`mpsc::UnboundedSender`/`UnboundedReceiver` plus `Arc<Mutex<Receiver>>`
with `async_channel::Sender`/`Receiver`.
- In `codex-rs/codex-api`, replace the realtime websocket event receiver
with an `async_channel::Receiver`, allowing `RealtimeWebsocketEvents`
clones to receive without locking.
- Add `async-channel` as a dependency for `codex-code-mode` and
`codex-api`, and update `Cargo.lock`.

## Verification

- The split stack was verified at the final lint-enabling head with
`just clippy`.
2026-04-17 15:20:30 -07:00
xli-oai 0e111e08d0 [codex] Add cross-repo plugin sources to marketplace manifests (#18017)
## Summary
- add first-class marketplace support for git-backed plugin sources
- keep the newer marketplace parsing behavior from `main`, including
alternate manifest locations and string local sources
- materialize remote plugin sources during install, detail reads, and
non-curated cache refresh
- expose git plugin source metadata through the app-server protocol

## Details
This teaches the marketplace parser to accept all of the following:
- local string sources such as `"source": "./plugins/foo"`
- local object sources such as
`{"source":"local","path":"./plugins/foo"}`
- remote repo-root sources such as
`{"source":"url","url":"https://github.com/org/repo.git"}`
- remote subdir sources such as
`{"source":"git-subdir","url":"owner/repo","path":"plugins/foo","ref":"main","sha":"..."}`

It also preserves the newer tolerant behavior from `main`: invalid or
unsupported plugin entries are skipped instead of breaking the whole
marketplace.

## Validation
- `cargo test -p codex-core plugins::marketplace::tests`
- `just fix -p codex-core`
- `just fmt`

## Notes
- A full `cargo test -p codex-core` run still hit unrelated existing
failures in agent and multi-agent tests during this session; the
marketplace-focused suite passed after the rebase resolution.
2026-04-17 15:11:42 -07:00
Michael Bolin fd47b60f30 merge commit for archive created by Sapling 2026-04-17 14:37:00 -07:00
Michael Bolin f3ff42af7a protocol: canonicalize file system permissions 2026-04-17 14:36:43 -07:00
Michael Bolin baf29474e1 Merge 7e295bf422 into sapling-pr-archive-bolinfest 2026-04-17 14:24:05 -07:00
Michael Bolin 28d6f4a1ee Merge f7496e7238 into sapling-pr-archive-bolinfest 2026-04-17 14:23:03 -07:00
Michael Bolin f7496e7238 protocol: canonicalize file system permissions 2026-04-17 14:22:54 -07:00
Michael Bolin 7e295bf422 refactor: use cloneable async channels for shared receivers 2026-04-17 14:09:07 -07:00
Michael Bolin 015d90a5d9 merge commit for archive created by Sapling 2026-04-17 14:07:02 -07:00
Michael Bolin 1265df0ec2 refactor: narrow async lock guard lifetimes (#18211)
Follow-up to https://github.com/openai/codex/pull/18178, where we called
out enabling the await-holding lint as a follow-up.

The long-term goal is to enable Clippy coverage for async guards held
across awaits. This PR is intentionally only the first, low-risk cleanup
pass: it narrows obvious lock guard lifetimes and leaves
`codex-rs/Cargo.toml` unchanged so the lint is not enabled until the
remaining cases are fixed or explicitly justified. It intentionally
leaves the active-turn/turn-state locking pattern alone because those
checks and mutations need to stay atomic.

## Common fixes used here

These are the main patterns reviewers should expect in this PR, and they
are also the patterns to reach for when fixing future `await_holding_*`
findings:

- **Scope the guard to the synchronous work.** If the code only needs
data from a locked value, move the lock into a small block, clone or
compute the needed values, and do the later `.await` after the block.
- **Use direct one-line mutations when there is no later await.** Cases
like `map.lock().await.remove(&id)` are acceptable when the guard is
only needed for that single mutation and the statement ends before any
async work.
- **Drain or clone work out of the lock before notifying or awaiting.**
For example, the JS REPL drains pending exec senders into a local vector
and the websocket writer clones buffered envelopes before it serializes
or sends them.
- **Use a `Semaphore` only when serialization is intentional across
async work.** The test serialization guards intentionally span awaited
setup or execution, so using a semaphore communicates "one at a time"
without holding a mutex guard.
- **Remove the mutex when there is only one owner.** The PTY stdin
writer task owns `stdin` directly; the old `Arc<Mutex<_>>` did not
protect shared access because nothing else had access to the writer.
- **Do not split locks that protect an atomic invariant.** This PR
deliberately leaves active-turn/turn-state paths alone because those
checks and mutations need to stay atomic. Those cases should be fixed
separately with a design change or documented with `#[expect]`.

## What changed

- Narrow scoped async mutex guards in app-server, JS REPL, network
approval, remote-control websocket, and the RMCP test server.
- Replace test-only async mutex serialization guards with semaphores
where the guard intentionally lives across async work.
- Let the PTY pipe writer task own stdin directly instead of wrapping it
in an async mutex.

## Verification

- `just fix -p codex-core -p codex-app-server -p codex-rmcp-client -p
codex-shell-escalation -p codex-utils-pty -p codex-utils-readiness`
- `just clippy -p codex-core`
- `cargo test -p codex-core -p codex-app-server -p codex-rmcp-client -p
codex-shell-escalation -p codex-utils-pty -p codex-utils-readiness` was
run; the app-server suite passed, and `codex-core` failed in the local
sandbox on six otel approval tests plus
`suite::user_shell_cmd::user_shell_command_does_not_set_network_sandbox_env_var`,
which appear to depend on local command approval/default rules and
`CODEX_SANDBOX_NETWORK_DISABLED=1` in this environment.
2026-04-17 14:06:50 -07:00
Michael Bolin 8e61e7e15f protocol: canonicalize file system permissions 2026-04-17 14:06:46 -07:00
xl-openai ecc8599c56 Remove the tier constraint from connectors directory requests (#18381)
We should allow all apps regardless of tier.
2026-04-17 14:05:09 -07:00
Michael Bolin 63ee9c2508 merge commit for archive created by Sapling 2026-04-17 13:58:24 -07:00
Michael Bolin 29869a9acf protocol: canonicalize file system permissions 2026-04-17 13:58:04 -07:00
starr-openaiandCodex 63e4a900c9 exec-server: preserve fs helper runtime env (#18380)
## Summary
- preserve a small fs-helper runtime env allowlist (`PATH`, temp vars)
instead of launching the sandboxed helper with an empty env
- add unit coverage for the allowlist and transformed sandbox request
env
- add a Linux smoke test that starts the test exec-server with a fake
`bwrap` on `PATH`, runs a sandboxed fs write through the remote fs
helper path, and asserts that bwrap path was exercised

## Validation
- `cd /tmp/codex-worktrees/fs-helper-env-defaults/codex-rs && export
PATH=$HOME/code/openai/project/dotslash-gen/bin:$HOME/.local/bin:$PATH
&& bazel test --bes_backend= --bes_results_url=
//codex-rs/exec-server:exec-server-file_system-test
--test_filter=sandboxed_file_system_helper_finds_bwrap_on_preserved_path`
- `cd /tmp/codex-worktrees/fs-helper-env-defaults/codex-rs && export
PATH=$HOME/code/openai/project/dotslash-gen/bin:$HOME/.local/bin:$PATH
&& bazel test --bes_backend= --bes_results_url=
//codex-rs/exec-server:exec-server-unit-tests
--test_filter="helper_env|sandbox_exec_request_carries_helper_env"`
- earlier on this branch before the smoke-test harness adjustment: `cd
/tmp/codex-worktrees/fs-helper-env-defaults/codex-rs && export
PATH=$HOME/code/openai/project/dotslash-gen/bin:$HOME/.local/bin:$PATH
&& bazel test --bes_backend= --bes_results_url=
//codex-rs/exec-server:all`

Co-authored-by: Codex <noreply@openai.com>
2026-04-17 20:44:01 +00:00
richardopenai 139fa8b8f2 [codex] Propagate rate limit reached type (#18227)
## Summary

First PR in the split from #17956.

- adds the core/app-server `RateLimitReachedType` shape
- maps backend `rate_limit_reached_type` into Codex rate-limit snapshots
- carries the field through app-server notifications/responses and
generated schemas
- updates existing constructors/tests for the new optional field

## Validation

- `cargo test -p codex-backend-client`
- `cargo test -p codex-app-server-protocol`
- `cargo test -p codex-app-server rate_limits`
- `cargo test -p codex-tui workspace_`
- `cargo test -p codex-tui status_`
- `just fmt`
- `just fix -p codex-backend-client`
- `just fix -p codex-app-server-protocol`
- `just fix -p codex-app-server`
- `just fix -p codex-tui`
2026-04-17 13:37:25 -07:00
canvrno-oaiandCodex f017a23835 /plugins: Add v2 tabbed marketplace menu (#18222)
This PR moves `/plugins` onto the shared tabbed selection-list
infrastructure and introduces the new v2 menu. The menu now groups
plugins into All Plugins, Installed, OpenAI Curated, and per-marketplace
tabs.

- Rebuild /plugins on top of the shared tabbed selection list
- Add All Plugins, Installed, OpenAI Curated, and per-marketplace tabs
- Preserve active tab and selected-row behavior across popup refreshes
- Add duplicate marketplace tab-label disambiguation
- Update browse-mode popup tests and snapshots

Co-authored-by: Codex <noreply@openai.com>
2026-04-17 12:59:18 -07:00
Felipe Coury 48f117d0a2 perf(tui): defer startup skills refresh (#18370)
# Summary

This removes startup `skills/list` from the critical path to first
input. In release measurements, median startup-to-input time improved
from `307.5 ms` to `191.0 ms` across 30 measured runs with 5 warmups.

# Background

Startup currently waits for a forced `skills/list` app-server request
before scheduling the first usable TUI frame. That makes skill metadata
freshness part of the process-launch-to-input path, even though the
prompt can safely accept normal input before skill metadata has finished
loading.

I measured startup from process launch until the TUI reports that the
user can type. The measurement harness watched the startup measurement
record, killed Codex after a successful sample, and enforced a timeout
so repeated runs would not leave TUI processes behind. The debug runs
had enough outliers that I used median as the primary signal and ran a
baseline self-compare to understand the noise floor.

# Why skills/list

The `skills/list` cut was the best practical optimization because it
improved startup without changing the important readiness contract: when
the prompt is shown, it is still backed by an active session. Only
enrichment data arrives later.

| Candidate | Result | Decision |
| --- | --- | --- |
| Defer startup `skills/list` | Debug median improved from `524.0 ms` to
`348.0 ms`; release median improved from `307.5 ms` to `191.0 ms`. |
Keep |
| Defer fresh `thread/start` | Debug median improved from `494.0 ms` to
`256.0 ms`, but the prompt could appear before an active thread was
attached. | Reject as too risky for this PR |
| Avoid forced skills config reload | Debug median moved from `509.0 ms`
to `512.0 ms`. | Reject as neutral |
| Skip fresh history metadata | Debug median moved from `496.5 ms` to
`531.5 ms`. | Reject as regression/noise |
| Defer app-server startup | Not implemented because it would only
permit a loading frame unless the TUI gained a deliberate pre-server
state. | Out of scope |

# Implementation

`App::refresh_startup_skills` now clones the app-server request handle,
spawns a background task, and issues the same forced `skills/list`
request after the first frame is scheduled. When the request completes,
the task sends `AppEvent::SkillsListLoaded` back through the normal app
event queue.

The existing skills response handling still converts the app-server
response, updates the chat widget, and emits invalid `SKILL.md`
warnings. Explicit user-initiated skills refreshes still use the
existing synchronous app command path, so callers that intentionally
requested fresh skill state do not race ahead of their own refresh.

# Tradeoffs

The main tradeoff is a narrow theoretical race at startup: skill mention
completion depends on a background `skills/list` response, so it could
briefly show stale or empty metadata if opened before that response
arrives. In manual testing, pressing `$` as soon as possible after
launch still showed populated skill metadata, so this risk appears
minimal in normal use. Plain input remains available immediately, and
the UI updates through the existing skills response path once the
refresh completes.

This PR does not change how skills are discovered, cached,
force-reloaded, displayed, enabled, or warned about. It only changes
when the startup refresh is allowed to complete relative to the first
usable TUI frame.

# Verification

- `cargo test -p codex-tui`
2026-04-17 16:55:00 -03:00
Ahmed IbrahimandCodex 92cf90277d [4/6] Abstract MCP stdio server launching (#18087)
## Summary
- Move local MCP stdio process startup behind a launcher trait.
- Preserve existing local stdio behavior while making transport creation
explicit.

## Stack
```text
o  #18027 [6/6] Fail exec client operations after disconnect
│
o  #18212 [5/6] Wire executor-backed MCP stdio
│
@  #18087 [4/6] Abstract MCP stdio server launching
│
o  #18020 [3/6] Add pushed exec process events
│
o  #18086 [2/6] Support piped stdin in exec process API
│
o  #18085 [1/6] Add MCP server environment config
│
o  main
```

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-17 12:34:48 -07:00
Michael Bolin b8fbb98b88 Merge 9afbb4b7db into sapling-pr-archive-bolinfest 2026-04-17 12:33:38 -07:00
Michael Bolin 9afbb4b7db tests: isolate approval fixtures from host rules 2026-04-17 12:31:56 -07:00
Michael Bolin 21e8320ab7 shell-escalation: carry resolved permission profiles 2026-04-17 12:31:56 -07:00
Michael Bolin f37b753bcd mcp: include permission profiles in sandbox state 2026-04-17 12:31:56 -07:00
Michael Bolin 592ca7bb63 tui: carry permission profiles on user turns 2026-04-17 12:31:56 -07:00
Michael Bolin a49d6eae93 tui: sync session permission profiles 2026-04-17 12:31:56 -07:00
Michael Bolin e5f2e576f6 app-server: accept command permission profiles 2026-04-17 12:31:56 -07:00
Michael Bolin 6e24a28529 protocol: report session permission profiles 2026-04-17 12:31:56 -07:00
Michael Bolin 6d6a8254e7 rollout: persist turn permission profiles 2026-04-17 12:31:56 -07:00
Michael Bolin 6ed6281806 clients: send permission profiles to app-server 2026-04-17 12:31:56 -07:00
Michael Bolin 36b39b05bd app-server: accept permission profile overrides 2026-04-17 12:31:56 -07:00
Michael Bolin 56b3b8a04e app-server: expose thread permission profiles 2026-04-17 12:31:56 -07:00
Michael Bolin 5a57cef23f core: derive active permission profiles 2026-04-17 12:31:56 -07:00
Michael Bolin 2d42d10ccf exec-server: carry filesystem sandbox profiles 2026-04-17 12:31:56 -07:00
Michael Bolin af87f2160e sandboxing: intersect permission profiles semantically 2026-04-17 12:31:56 -07:00
Michael Bolin 346920b89a protocol: canonicalize file system permissions 2026-04-17 12:31:56 -07:00
Michael Bolin 27f7223f48 merge commit for archive created by Sapling 2026-04-17 12:29:29 -07:00
Michael Bolin 174cf76490 refactor: narrow async lock guard lifetimes
Follow-up to https://github.com/openai/codex/pull/18178. This handles the straightforward await-holding cleanup first, without enabling the Clippy lint yet; the long-term goal is to enable the lint in a follow-up once the remaining cases are resolved or explicitly justified.
2026-04-17 12:28:40 -07:00
Eric Traut d8b91f5fa1 Attribute automated PR Babysitter review replies (#18379)
## Summary
PR Babysitter can reply directly to GitHub code review comments when
feedback is non-actionable, already addressed, or not valid. Those
replies should be visibly attributed so reviewers do not mistake an
automated Codex response for a message from the human operator.

This updates the skill instructions to require GitHub code review
replies from the babysitter to start with `[codex]`.

## Changes
- Adds the `[codex]` prefix requirement to the core PR Babysitter
workflow.
- Repeats the requirement in the review comment handling guidance where
agents decide whether to reply to a review thread.
2026-04-17 12:27:48 -07:00
Ahmed Ibrahim 0f0ef094b6 Show default reasoning in /status (#18373)
- Shows the model catalog default reasoning effort when no reasoning
override is configured.
- Adds /status coverage for the empty-config fallback.
2026-04-17 12:21:09 -07:00
a801b999ff Update models.json (#12640)
Automated update of models.json.

Co-authored-by: aibrahim-oai <219906144+aibrahim-oai@users.noreply.github.com>
Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
2026-04-17 12:16:07 -07:00
Michael Bolin 5f2bdf8cd1 Merge 5de0d38e61 into sapling-pr-archive-bolinfest 2026-04-17 12:10:28 -07:00
Ahmed IbrahimandCodex 9d3a5cf05e [3/6] Add pushed exec process events (#18020)
## Summary
- Add a pushed `ExecProcessEvent` stream alongside retained
`process/read` output.
- Publish local and remote output, exit, close, and failure events.
- Cover the event stream with shared local/remote exec process tests.

## Testing
- `cargo check -p codex-exec-server`
- `cargo check -p codex-rmcp-client`
- Not run: `cargo test` per repo instruction; CI will cover.

## Stack
```text
o  #18027 [6/6] Fail exec client operations after disconnect
│
o  #18212 [5/6] Wire executor-backed MCP stdio
│
o  #18087 [4/6] Abstract MCP stdio server launching
│
@  #18020 [3/6] Add pushed exec process events
│
o  #18086 [2/6] Support piped stdin in exec process API
│
o  #18085 [1/6] Add MCP server environment config
│
o  main
```

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-17 19:07:43 +00:00