Commit Graph
12321 Commits
Author SHA1 Message Date
Michael Bolin 547c8c43a4 merge commit for archive created by Sapling 2026-04-21 19:57:42 -07:00
Michael Bolin 39310e7088 exec-server: carry filesystem sandbox profiles 2026-04-21 19:57:27 -07:00
Michael Bolin 8fea372c77 Fix remote app-server shutdown race (#18936)
## Why

A Mac Bazel CI run saw `remote_notifications_arrive_over_websocket` fail
during shutdown with `remote app-server shutdown channel is closed`
(https://app.buildbuddy.io/invocation/9dac05d6-ae20-40f9-b627-fca6e91cf127).
The remote websocket worker can legitimately finish while `shutdown()`
is waiting for the shutdown acknowledgement: after the test server sends
a notification and exits, the worker may deliver the required disconnect
event, observe that the caller has dropped the event receiver, and exit
before it sends the shutdown one-shot.

That state is already terminal cleanup, not a failed shutdown, so
callers should not see a `BrokenPipe` from the acknowledgement channel.

## What Changed

- Treat a closed remote shutdown acknowledgement as an already-exited
worker while still propagating websocket close errors when the worker
returns them.
- Added a deterministic regression test for the interleaving where the
shutdown command is received and the worker exits before replying.

## Verification

- `cargo test -p codex-app-server-client`
- New test:
`remote::tests::shutdown_tolerates_worker_exit_after_command_is_queued`
2026-04-22 02:41:19 +00:00
Michael Bolin c76ca34261 merge commit for archive created by Sapling 2026-04-21 19:35:55 -07:00
Michael Bolin 9d11c77a95 exec-server: carry filesystem sandbox profiles 2026-04-21 19:34:59 -07:00
Michael Bolin 5508824649 Merge 5a7a2a89c3 into sapling-pr-archive-bolinfest 2026-04-21 19:27:32 -07:00
Michael Bolin 5a7a2a89c3 app-server-client: tolerate remote shutdown race 2026-04-21 19:27:17 -07:00
Michael Bolin 592481ae53 Merge 9187181d15 into sapling-pr-archive-bolinfest 2026-04-21 18:40:59 -07:00
Michael Bolin 9187181d15 ci: keep argument comment lint checks materialized 2026-04-21 18:40:37 -07:00
xl-openaiandCodex a978e411f6 feat: Support remote plugin list/read. (#18452)
Add a temporary internal remote_plugin feature flag that merges remote
marketplaces into plugin/list and routes plugin/read through the remote
APIs when needed, while keeping pure local marketplaces working as
before.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-21 18:39:07 -07:00
Michael Bolin 536952eeee bazel: run wrapped Rust unit test shards (#18913)
## Why

The `codex-tui` Cargo test suite was catching stale snapshot
expectations, but the matching Bazel unit-test target was still green.
The TUI unit target is wrapped by `workspace_root_test` so tests run
from the repository root and Insta can resolve Cargo-like snapshot
paths. After native Bazel sharding was enabled for that wrapped target,
rules_rust also inserted its own sharding wrapper around the Rust test
binary.

Those two wrappers did not compose: rules_rust's sharding wrapper
expects to run from its own runfiles cwd, while `workspace_root_test`
deliberately changes cwd to the repo root before invoking the test. In
that configuration, the inner wrapper could fail to enumerate the Rust
tests and exit successfully with empty shards, so snapshot regressions
were not being exercised by Bazel.

## What Changed

- Stop enabling rules_rust's inner `experimental_enable_sharding` for
unit-test binaries created by `codex_rust_crate`.
- Keep the configured `shard_count` on the outer `workspace_root_test`
target.
- Add libtest sharding directly to `workspace_root_test_launcher.sh.tpl`
and `workspace_root_test_launcher.bat.tpl` after the launcher has
resolved the actual test binary and established the intended
repository-root cwd.
- Partition tests by a stable FNV-1a hash of each libtest test name,
matching the stable-shard behavior we wanted without depending on the
inner rules_rust wrapper.
- Preserve ad-hoc local test filters by running the resolved test binary
directly when explicit test args are supplied.
- On Windows, run selected libtest names from the shard list in bounded
PowerShell batches instead of concatenating every selected test into one
`cmd.exe` command line.

This PR is stacked on top of #18912, which contains only the snapshot
expectation updates exposed once the Bazel target actually runs the TUI
unit tests. It is also the reason #18916 becomes visible: once this
wrapper fix makes Bazel execute the affected `codex-core` test, that
test needs its own executable-path setup fixed.

## Verification

- `cargo test -p codex-tui`
- `bazel test //codex-rs/tui:tui-unit-tests --test_output=errors`
- `bazel test //codex-rs/tui:all --test_output=errors`
- `bash -n workspace_root_test_launcher.sh.tpl`
- Exercised the Windows PowerShell batching fragment locally with a fake
test binary and shard-list file.
2026-04-21 18:35:47 -07:00
Michael Bolin 5c94032350 Merge a7f7c21942 into sapling-pr-archive-bolinfest 2026-04-21 18:31:56 -07:00
Michael Bolin a7f7c21942 tests: isolate approval fixtures from host rules 2026-04-21 18:31:35 -07:00
Michael Bolin 1ffa050cdf shell-escalation: carry resolved permission profiles 2026-04-21 18:31:35 -07:00
Michael Bolin ed38a7a2b2 mcp: include permission profiles in sandbox state 2026-04-21 18:31:35 -07:00
Michael Bolin 9b4b198cf3 tui: carry permission profiles on user turns 2026-04-21 18:31:35 -07:00
Michael Bolin 9c60c2e054 tui: sync session permission profiles 2026-04-21 18:31:35 -07:00
Michael Bolin 8cba245f3f app-server: accept command permission profiles 2026-04-21 18:31:35 -07:00
Michael Bolin 788ee2637a protocol: report session permission profiles 2026-04-21 18:31:35 -07:00
Michael Bolin 84bd51c8b3 rollout: persist turn permission profiles 2026-04-21 18:31:35 -07:00
Michael Bolin 090adf5274 clients: send permission profiles to app-server 2026-04-21 18:31:35 -07:00
Michael Bolin 2b145dd4be app-server: accept permission profile overrides 2026-04-21 18:31:35 -07:00
Michael Bolin 68e82a9a54 app-server: expose thread permission profiles 2026-04-21 18:31:35 -07:00
Michael Bolin 78bd9ab488 core: derive active permission profiles 2026-04-21 18:31:35 -07:00
Michael Bolin 5d75e01b73 exec-server: carry filesystem sandbox profiles 2026-04-21 18:31:35 -07:00
Celia Chen 1cd3ad1f49 feat: add AWS SigV4 auth for OpenAI-compatible model providers (#17820)
## Summary

Add first-class Amazon Bedrock Mantle provider support so Codex can keep
using its existing Responses API transport with OpenAI-compatible
AWS-hosted endpoints such as AOA/Mantle.

This is needed for the AWS launch path, where provider traffic should
authenticate with AWS credentials instead of OpenAI bearer credentials.
Requests are authenticated immediately before transport send, so SigV4
signs the final method, URL, headers, and body bytes that `reqwest` will
send.

## What Changed

- Added a new `codex-aws-auth` crate for loading AWS SDK config,
resolving credentials, and signing finalized HTTP requests with AWS
SigV4.
- Added a built-in `amazon-bedrock` provider that targets Bedrock Mantle
Responses endpoints, defaults to `us-east-1`, supports region/profile
overrides, disables WebSockets, and does not require OpenAI auth.
- Added Amazon Bedrock auth resolution in `codex-model-provider`: prefer
`AWS_BEARER_TOKEN_BEDROCK` when set, otherwise use AWS SDK credentials
and SigV4 signing.
- Added `AuthProvider::apply_auth` and `Request::prepare_body_for_send`
so request-signing providers can sign the exact outbound request after
JSON serialization/compression.
- Determine the region by taking the `aws.region` config first (required
for bearer token codepath), and fallback to SDK default region.

## Testing
Amazon Bedrock Mantle Responses paths:

- Built the local Codex binary with `cargo build`.
- Verified the custom proxy-backed `aws` provider using `env_key =
"AWS_BEARER_TOKEN_BEDROCK"` streamed raw `responses` output with
`response.output_text.delta`, `response.completed`, and `mantle-env-ok`.
- Verified a full `codex exec --profile aws` turn returned
`mantle-env-ok`.
- Confirmed the custom provider used the bearer env var, not AWS profile
auth: bogus `AWS_PROFILE` still passed, empty env var failed locally,
and malformed env var reached Mantle and failed with `401
invalid_api_key`.
- Verified built-in `amazon-bedrock` with `AWS_BEARER_TOKEN_BEDROCK` set
passed despite bogus AWS profiles, returning `amazon-bedrock-env-ok`.
- Verified built-in `amazon-bedrock` SDK/SigV4 auth passed with
`AWS_BEARER_TOKEN_BEDROCK` unset and temporary AWS session env
credentials, returning `amazon-bedrock-sdk-env-ok`.
2026-04-22 01:11:17 +00:00
Michael Bolin fd9ed09ee8 Merge b4ed5c301d into sapling-pr-archive-bolinfest 2026-04-21 18:09:25 -07:00
Michael Bolin b4ed5c301d bazel: run wrapped Rust unit test shards 2026-04-21 18:09:02 -07:00
Michael Bolin e18fe7a07f test(core): move prompt debug coverage to integration suite (#18916)
## Why

`build_prompt_input` now initializes `ExecServerRuntimePaths`, which
requires a configured Codex executable path. The previous inline unit
test in `core/src/prompt_debug.rs` built a bare `test_config()` and then
failed before it could assert anything useful:

```text
Codex executable path is not configured
```

This coverage is also integration-shaped: it drives the public
`build_prompt_input` entry point through config, thread, and session
setup rather than testing a small internal helper in isolation.

Bazel CI did not catch this earlier because the affected test was behind
the same wrapped Rust unit-test path fixed by #18913. Before that
launcher/sharding fix, the outer `workspace_root_test` changed the
working directory for Insta compatibility while the inner `rules_rust`
sharding wrapper still expected its runfiles working directory. In
practice, Bazel could report success without executing the Rust test
cases in that shard. Once #18913 makes the wrapper run the Rust test
binary directly and shard with libtest arguments, this stale unit test
actually runs and exposes the missing `codex_self_exe` setup.

## What Changed

- Moved `build_prompt_input_includes_context_and_user_message` out of
`core/src/prompt_debug.rs`.
- Added `core/tests/suite/prompt_debug_tests.rs` and registered it from
`core/tests/suite/mod.rs`.
- Builds the test config with `ConfigBuilder` and provides
`codex_self_exe` using the current test executable, matching the
runtime-path invariant required by prompt debug setup.
- Preserves the existing assertions that the generated prompt input
includes both the debug user message and project-specific user
instructions.

## Verification

- `cargo test -p codex-core --test all
prompt_debug_tests::build_prompt_input_includes_context_and_user_message`
- `bazel test //codex-rs/core:core-all-test
--test_arg=prompt_debug_tests::build_prompt_input_includes_context_and_user_message
--test_output=errors`

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/18916).
* #18913
* __->__ #18916
2026-04-22 01:08:25 +00:00
Felipe Coury 09ebc34f17 fix(core): emit hooks for apply_patch edits (#18391)
Fixes https://github.com/openai/codex/issues/16732.

## Why

`apply_patch` is Codex's primary file edit path, but it was not emitting
`PreToolUse` or `PostToolUse` hook events. That meant hook-based policy,
auditing, and write coordination could observe shell commands while
missing the actual file mutation performed by `apply_patch`.

The issue also exposed that the hook runtime serialized command hook
payloads with `tool_name: "Bash"` unconditionally. Even if `apply_patch`
supplied hook payloads, hooks would either fail to match it directly or
receive misleading stdin that identified the edit as a Bash tool call.

## What Changed

- Added `PreToolUse` and `PostToolUse` payload support to
`ApplyPatchHandler`.
- Exposed the raw patch body as `tool_input.command` for both
JSON/function and freeform `apply_patch` calls.
- Taught tool hook payloads to carry a handler-supplied hook-facing
`tool_name`.
- Preserved existing shell compatibility by continuing to emit `Bash`
for shell-like tools.
- Serialized the selected hook `tool_name` into hook stdin instead of
hardcoding `Bash`.
- Relaxed the generated hook command input schema so `tool_name` can
represent tools other than `Bash`.

## Verification

Added focused handler coverage for:

- JSON/function `apply_patch` calls producing a `PreToolUse` payload.
- Freeform `apply_patch` calls producing a `PreToolUse` payload.
- Successful `apply_patch` output producing a `PostToolUse` payload.
- Shell and `exec_command` handlers continuing to expose `Bash`.

Added end-to-end hook coverage for:

- A `PreToolUse` hook matching `^apply_patch$` blocking the patch before
the target file is created.
- A `PostToolUse` hook matching `^apply_patch$` receiving the patch
input and tool response, then adding context to the follow-up model
request.
- Non-participating tools such as the plan tool continuing not to emit
`PreToolUse`/`PostToolUse` hook events.

Also validated manually with a live `codex exec` smoke test using an
isolated temp workspace and temp `CODEX_HOME`. The smoke test confirmed
that a real `apply_patch` edit emits `PreToolUse`/`PostToolUse` with
`tool_name: "apply_patch"`, a shell command still emits `tool_name:
"Bash"`, and a denying `PreToolUse` hook prevents the blocked patch file
from being created.
2026-04-21 22:00:40 -03:00
Michael Bolin 3e2bb1e5e6 merge commit for archive created by Sapling 2026-04-21 17:58:33 -07:00
Michael Bolin 10ff9e5509 bazel: run wrapped Rust unit test shards 2026-04-21 17:58:18 -07:00
starr-openaiandCodex 1d4cc494c9 Add turn-scoped environment selections (#18416)
## Summary
- add experimental turn/start.environments params for per-turn
environment id + cwd selections
- pass selections through core protocol ops and resolve them with
EnvironmentManager before TurnContext creation
- treat omitted selections as default behavior, empty selections as no
environment, and non-empty selections as first environment/cwd as the
turn primary

## Testing
- ran `just fmt`
- ran `just write-app-server-schema`
- not run: unit tests for this stacked PR

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-21 17:48:33 -07:00
Michael Bolin 2df8ad9045 Merge 69103a7180 into sapling-pr-archive-bolinfest 2026-04-21 17:43:17 -07:00
Michael Bolin 72baf32fd3 fix build_prompt_input_includes_context_and_user_message 2026-04-21 17:43:06 -07:00
Michael Bolin 69103a7180 bazel: run wrapped Rust unit test shards 2026-04-21 17:43:06 -07:00
Michael Bolin 6368f506b7 fix: windows snapshot for external_agent_config_migration::tests::prompt_snapshot did not match windows output (#18915)
Fix a snapshot test that is failing on Windows, but is currently missed
by Bazel due to https://github.com/openai/codex/pull/18913. We see this
failing on Cargo builds on Windows, though.

This Bazel vs. Cargo inconsistency explains why
https://github.com/openai/codex/pull/18768 did not fix the Cargo Windows
build.
2026-04-22 00:32:46 +00:00
Michael Bolin 799e50412e sandboxing: materialize cwd-relative permission globs (#18867)
## Why

#18275 anchors session-scoped `:cwd` and `:project_roots` grants to the
request cwd before recording them for reuse. Relative deny glob entries
need the same treatment. Without anchoring, a stored session permission
can keep a pattern such as `**/*.env` relative, then reinterpret that
deny against a later turn cwd. That makes the persisted profile depend
on the cwd at reuse time instead of the cwd that was reviewed and
approved.

## What changed

`intersect_permission_profiles` now materializes retained
`FileSystemPath::GlobPattern` entries against the request cwd, matching
the existing materialization for cwd-sensitive special paths.

Materialized accepted grants are now deduplicated before deny retention
runs. This keeps the sticky-grant preapproval shape stable when a
repeated request is merged with the stored grant and both `:cwd = write`
and the materialized absolute cwd write are present.

The preapproval check compares against the same materialized form, so a
later request for the same cwd-relative deny glob still matches the
stored anchored grant instead of re-prompting or rejecting.

Tests cover both the storage path and the preapproval path: a
session-scoped `:cwd = write` grant with `**/*.env = none` is stored
with both the cwd write and deny glob anchored to the original request
cwd, cannot be reused from a later cwd, and remains preapproved when
re-requested from the original cwd after merging with the stored grant.

## Verification

- `cargo test -p codex-sandboxing policy_transforms`
- `cargo test -p codex-core --lib
relative_deny_glob_grants_remain_preapproved_after_materialization`
- `cargo clippy -p codex-sandboxing --tests -- -D
clippy::redundant_clone`
- `cargo clippy -p codex-core --lib -- -D clippy::redundant_clone`

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/18867).
* #18288
* #18287
* #18286
* #18285
* #18284
* #18283
* #18282
* #18281
* #18280
* #18279
* #18278
* #18277
* #18276
* __->__ #18867
2026-04-21 17:28:58 -07:00
Michael Bolin e7455af63b Merge 4fa281f2a7 into sapling-pr-archive-bolinfest 2026-04-21 17:20:36 -07:00
Michael Bolin 4fa281f2a7 fix: windows snapshot for external_agent_config_migration::tests::prompt_snapshot did not match windows output 2026-04-21 17:20:30 -07:00
Michael Bolin b06604587c Merge 960d5145fa into sapling-pr-archive-bolinfest 2026-04-21 17:17:42 -07:00
Michael Bolin 960d5145fa bazel: run wrapped Rust unit test shards 2026-04-21 17:17:17 -07:00
Michael Bolin 3420b06c7d test(tui): update status surface snapshots 2026-04-21 17:17:08 -07:00
canvrno-oai 37701d4654 Update /statusline and /title snapshots (#18909)
Update `/statusline` and `/title` snapshots
2026-04-21 17:16:50 -07:00
Michael Bolin 0fc7c4d6d4 Merge e31ba8fc14 into sapling-pr-archive-bolinfest 2026-04-21 17:09:52 -07:00
Michael Bolin e31ba8fc14 tests: isolate approval fixtures from host rules 2026-04-21 17:09:36 -07:00
Michael Bolin de29218118 shell-escalation: carry resolved permission profiles 2026-04-21 17:09:36 -07:00
Michael Bolin a21bda6eca mcp: include permission profiles in sandbox state 2026-04-21 17:09:36 -07:00
Michael Bolin 905ca8c780 tui: carry permission profiles on user turns 2026-04-21 17:09:36 -07:00
Michael Bolin fac6fd1165 tui: sync session permission profiles 2026-04-21 17:09:36 -07:00