Commit Graph

2443 Commits

Author SHA1 Message Date
Roy Han
f0bc8dec3e consolidate thread context 2026-03-25 15:28:52 -07:00
Roy Han
4a163ee2a9 remove turn context 2026-03-25 14:36:12 -07:00
Roy Han
7daa98793d remove flaky test 2026-03-25 14:02:09 -07:00
Roy Han
2dc789b211 rebase cleanup after migration 2026-03-25 13:49:47 -07:00
Roy Han
e25d698cb3 test cleanup 2026-03-25 13:43:17 -07:00
rhan-oai
c6cc9de6e9 Merge branch 'main' into rhan/oob-thread-metadata 2026-03-25 13:39:37 -07:00
Ahmed Ibrahim
9dbe098349 Extract codex-core-skills crate (#15749)
## Summary
- move skill loading and management into codex-core-skills
- leave codex-core with the thin integration layer and shared wiring

## Testing
- CI

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-25 12:57:42 -07:00
Matthew Zeng
91337399fe [apps][tool_suggest] Remove tool_suggest's dependency on tool search. (#14856)
- [x] Remove tool_suggest's dependency on tool search.
2026-03-25 12:26:02 -07:00
Roy Han
94da6b2289 rebase 2026-03-25 11:43:43 -07:00
evawong-oai
6566ab7e02 Clarify codex_home base for MDM path resolution (#15707)
## Summary

Add the follow up code comment Michael asked for at the MDM
`managed_config_from_mdm` - a follow up from
https://github.com/openai/codex/pull/15351.

## Validation

1. `cargo fmt --all --check`
2. `cargo test -p codex-core
managed_preferences_expand_home_directory_in_workspace_write_roots --
--nocapture`
3. `cargo test -p codex-core
write_value_succeeds_when_managed_preferences_expand_home_directory_paths
-- --nocapture`
4. `./tools/argument-comment-lint/run-prebuilt-linter.sh -p codex-core`
2026-03-25 18:40:43 +00:00
Roy Han
3ddd859344 Merge origin/main into rhan/oob-thread-metadata 2026-03-25 11:19:18 -07:00
Ahmed Ibrahim
d273efc0f3 Extract codex-analytics crate (#15748)
## Summary
- move the analytics events client into codex-analytics
- update codex-core and app-server callsites to use the new crate

## Testing
- CI

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-25 11:08:05 -07:00
Ahmed Ibrahim
2bb1027e37 Extract codex-plugin crate (#15747)
## Summary
- extract plugin identifiers and load-outcome types into codex-plugin
- update codex-core to consume the new plugin crate

## Testing
- CI

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-25 11:07:31 -07:00
Ahmed Ibrahim
ad74543a6f Extract codex-utils-plugins crate (#15746)
## Summary
- extract shared plugin path and manifest helpers into
codex-utils-plugins
- update codex-core to consume the utility crate

## Testing
- CI

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-25 11:05:35 -07:00
Roy Han
0f770257e5 test fix 2026-03-25 10:52:34 -07:00
Ahmed Ibrahim
fba3c79885 Extract codex-instructions crate (#15744)
## Summary
- extract instruction fragment and user-instruction types into
codex-instructions
- update codex-core to consume the new crate

## Testing
- CI

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-25 10:43:49 -07:00
Roy Han
5362886490 event rename and resume support 2026-03-25 10:27:05 -07:00
Roy Han
74b8b800c7 session source update 2026-03-25 09:59:56 -07:00
jif-oai
14c35a16a8 chore: remove read_file handler (#15773)
Co-authored-by: Codex <noreply@openai.com>
2026-03-25 16:27:32 +00:00
pakrym-oai
504aeb0e09 Use AbsolutePathBuf for cwd state (#15710)
Migrate `cwd` and related session/config state to `AbsolutePathBuf` so
downstream consumers consistently see absolute working directories.

Add test-only `.abs()` helpers for `Path`, `PathBuf`, and `TempDir`, and
update branch-local tests to use them instead of
`AbsolutePathBuf::try_from(...)`.

For the remaining TUI/app-server snapshot coverage that renders absolute
cwd values, keep the snapshots unchanged and skip the Windows-only cases
where the platform-specific absolute path layout differs.
2026-03-25 16:02:22 +00:00
jif-oai
178c3b15b4 chore: remove grep_files handler (#15775)
# External (non-OpenAI) Pull Request Requirements

Before opening this Pull Request, please read the dedicated
"Contributing" markdown file or your PR may be closed:
https://github.com/openai/codex/blob/main/docs/contributing.md

If your PR conforms to our contribution guidelines, replace this text
with a detailed and high quality description of your changes.

Include a link to a bug report or enhancement request.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-25 16:01:45 +00:00
Fouad Matin
32c4993c8a fix(core): default approval behavior for mcp missing annotations (#15519)
- Changed `requires_mcp_tool_approval` to apply MCP spec defaults when
annotations are missing.
- Unannotated tools now default to:
  - `readOnlyHint = false`
  - `destructiveHint = true`
  - `openWorldHint = true`
- This means unannotated MCP tools now go through approval/ARC
monitoring instead of silently bypassing it.
- Explicitly read-only tools still skip approval unless they are also
explicitly marked destructive.

**Previous behavior**
Failed open for missing annotations, which was unsafe for custom MCP
tools that omitted or forgot annotations.

---------

Co-authored-by: colby-oai <228809017+colby-oai@users.noreply.github.com>
2026-03-25 07:55:41 -07:00
jif-oai
047ea642d2 chore: tty metric (#15766) 2026-03-25 13:34:43 +00:00
Matthew Zeng
e590fad50b [plugins] Add a flag for tool search. (#15722)
- [x] Add a flag for tool search.
2026-03-25 07:00:25 +00:00
viyatb-oai
95ba762620 fix: support split carveouts in windows restricted-token sandbox (#14172)
## Summary
- keep legacy Windows restricted-token sandboxing as the supported
baseline
- support the split-policy subset that restricted-token can enforce
directly today
- support full-disk read, the same writable root set as legacy
`WorkspaceWrite`, and extra read-only carveouts under those writable
roots via additional deny-write ACLs
- continue to fail closed for unsupported split-only shapes, including
explicit unreadable (`none`) carveouts, reopened writable descendants
under read-only carveouts, and writable root sets that do not match the
legacy workspace roots

## Example
Given a filesystem policy like:

```toml
":root" = "read"
":cwd" = "write"
"./docs" = "read"
```

the restricted-token backend can keep the workspace writable while
denying writes under `docs` by layering an extra deny-write carveout on
top of the legacy workspace-write roots.

A policy like:

```toml
"/workspace" = "write"
"/workspace/docs" = "read"
"/workspace/docs/tmp" = "write"
```

still fails closed, because the unelevated backend cannot reopen the
nested writable descendant safely.

## Stack
-> fix: support split carveouts in windows restricted-token sandbox
#14172
fix: support split carveouts in windows elevated sandbox #14568
2026-03-24 22:54:18 -07:00
Matthew Zeng
8c62829a2b [plugins] Flip on additional flags. (#15719)
- [x] Flip on additional flags.
2026-03-24 21:52:11 -07:00
Matthew Zeng
0bff38c54a [plugins] Flip the flags. (#15713)
- [x] Flip the `plugins` and `apps` flags.
2026-03-25 03:31:21 +00:00
Charley Cunningham
d72fa2a209 [codex] Defer fork context injection until first turn (#15699)
## Summary
- remove the fork-startup `build_initial_context` injection
- keep the reconstructed `reference_context_item` as the fork baseline
until the first real turn
- update fork-history tests and the request snapshot, and add a
`TODO(ccunningham)` for remaining nondiffable initial-context inputs

## Why
Fork startup was appending current-session initial context immediately
after reconstructing the parent rollout, then the first real turn could
emit context updates again. That duplicated model-visible context in the
child rollout.

## Impact
Forked sessions now behave like resume for context seeding: startup
reconstructs history and preserves the prior baseline, and the first
real turn handles any current-session context emission.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-24 18:34:44 -07:00
Roy Han
9e5874df07 test bug 2026-03-24 18:23:35 -07:00
Ahmed Ibrahim
2e03d8b4d2 Extract rollout into its own crate (#15548) 2026-03-24 18:10:53 -07:00
evawong-oai
ea3f3467e2 Expand ~ in MDM workspace write roots (#15351)
## Summary
- Reuse the existing config path resolver for the macOS MDM managed
preferences layer so `writable_roots = ["~/code"]` expands the same way
as file-backed config
- keep the change scoped to the MDM branch in `config_loader`; the
current net diff is only `config_loader/mod.rs` plus focused regression
tests in `config_loader/tests.rs` and `config/service_tests.rs`
- research note: `resolve_relative_paths_in_config_toml(...)` is already
used in several existing configuration paths, including [CLI
overrides](74fda242d3/codex-rs/core/src/config_loader/mod.rs (L152-L163)),
[file-backed managed
config](74fda242d3/codex-rs/core/src/config_loader/mod.rs (L274-L285)),
[normal config-file
loading](74fda242d3/codex-rs/core/src/config_loader/mod.rs (L311-L331)),
[project `.codex/config.toml`
loading](74fda242d3/codex-rs/core/src/config_loader/mod.rs (L863-L865)),
and [role config
loading](74fda242d3/codex-rs/core/src/agent/role.rs (L105-L109))

## Validation
- `cargo fmt --all --check`
- `cargo test -p codex-core
managed_preferences_expand_home_directory_in_workspace_write_roots --
--nocapture`
- `cargo test -p codex-core
write_value_succeeds_when_managed_preferences_expand_home_directory_paths
-- --nocapture`

---------

Co-authored-by: Michael Bolin <mbolin@openai.com>
Co-authored-by: Michael Bolin <bolinfest@gmail.com>
2026-03-24 17:55:06 -07:00
Michael Bolin
4a210faf33 fix: keep rmcp-client env vars as OsString (#15363)
## Why

This is a follow-up to #15360. That change fixed the `arg0` helper
setup, but `rmcp-client` still coerced stdio transport environment
values into UTF-8 `String`s before program resolution and process spawn.
If `PATH` or another inherited environment value contains non-UTF-8
bytes, that loses fidelity before it reaches `which` and `Command`.

## What changed

- change `create_env_for_mcp_server()` to return `HashMap<OsString,
OsString>` and read inherited values with `std::env::var_os()`
- change `TransportRecipe::Stdio.env`, `RmcpClient::new_stdio_client()`,
and `program_resolver::resolve()` to keep stdio transport env values in
`OsString` form within `rmcp-client`
- keep the `codex-core` config boundary stringly, but convert configured
stdio env values to `OsString` once when constructing the transport
- update the rmcp-client stdio test fixtures and callers to use
`OsString` env maps
- add a Unix regression test that verifies `create_env_for_mcp_server()`
preserves a non-UTF-8 `PATH`

## How to verify

- `cargo test -p codex-rmcp-client`
- `cargo test -p codex-core mcp_connection_manager`
- `just argument-comment-lint`

Targeted coverage in this change includes
`utils::tests::create_env_preserves_path_when_it_is_not_utf8`, while the
updated stdio transport path is exercised by the existing rmcp-client
tests that construct `RmcpClient::new_stdio_client()`.
2026-03-24 23:32:31 +00:00
Ahmed Ibrahim
062fa7a2bb Move string truncation helpers into codex-utils-string (#15572)
- move the shared byte-based middle truncation logic from `core` into
`codex-utils-string`
- keep token-specific truncation in `codex-core` so rollout can reuse
the shared helper in the next stacked PR

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-24 15:45:40 -07:00
pakrym-oai
0b619afc87 Drop sandbox_permissions from sandbox exec requests (#15665)
## Summary
- drop `sandbox_permissions` from the sandboxing `ExecOptions` and
`ExecRequest` adapter types
- remove the now-unused plumbing from shell, unified exec, JS REPL, and
apply-patch runtime call sites
- default reconstructed `ExecParams` to `SandboxPermissions::UseDefault`
where the lower-level API still requires the field

## Testing
- `just fmt`
- `just argument-comment-lint`
- `cargo test -p codex-core` (still running locally; first failures
observed in `suite::cli_stream::responses_mode_stream_cli`,
`suite::cli_stream::responses_mode_stream_cli_supports_openai_base_url_config_override`,
and
`suite::cli_stream::responses_mode_stream_cli_supports_openai_base_url_env_fallback`)
2026-03-24 15:42:45 -07:00
Roy Han
ed9e59ceb0 restructure history and source 2026-03-24 15:28:41 -07:00
rhan-oai
66534ad1d4 Merge branch 'main' into rhan/oob-thread-metadata 2026-03-24 15:11:23 -07:00
Roy Han
92e529a8ec thread event start 2026-03-24 15:10:10 -07:00
Matthew Zeng
b32d921cd9 [plugins] Additional gating for tool suggest and apps. (#15573)
- [x] Additional gating for tool suggest and apps.
2026-03-24 15:10:00 -07:00
Ahmed Ibrahim
0f957a93cd Move git utilities into a dedicated crate (#15564)
- create `codex-git-utils` and move the shared git helpers into it with
file moves preserved for diff readability
- move the `GitInfo` helpers out of `core` so stacked rollout work can
depend on the shared crate without carrying its own git info module

---------

Co-authored-by: Ahmed Ibrahim <219906144+aibrahim-oai@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
2026-03-24 13:26:23 -07:00
Michael Bolin
e89e5136bd fix: keep zsh-fork release assets after removing shell-tool-mcp (#15644)
## Why

`shell-tool-mcp` and the Bash fork are no longer needed, but the patched
zsh fork is still relevant for shell escalation and for the
DotSlash-backed zsh-fork integration tests.

Deleting the old `shell-tool-mcp` workflow also deleted the only
pipeline that rebuilt those patched zsh binaries. This keeps the package
removal, while preserving a small release path that can be reused
whenever `codex-rs/shell-escalation/patches/zsh-exec-wrapper.patch`
changes.

## What changed

- removed the `shell-tool-mcp` workspace package, its npm
packaging/release jobs, the Bash test fixture, and the remaining
Bash-specific compatibility wiring
- deleted the old `.github/workflows/shell-tool-mcp.yml` and
`.github/workflows/shell-tool-mcp-ci.yml` workflows now that their
responsibilities have been replaced or removed
- kept the zsh patch under
`codex-rs/shell-escalation/patches/zsh-exec-wrapper.patch` and updated
the `codex-rs/shell-escalation` docs/code to describe the zsh-based flow
directly
- added `.github/workflows/rust-release-zsh.yml` to build only the three
zsh binaries that `codex-rs/app-server/tests/suite/zsh` needs today:
  - `aarch64-apple-darwin` on `macos-15`
  - `x86_64-unknown-linux-musl` on `ubuntu-24.04`
  - `aarch64-unknown-linux-musl` on `ubuntu-24.04`
- extracted the shared zsh build/smoke-test/stage logic into
`.github/scripts/build-zsh-release-artifact.sh`, made that helper
directly executable, and now invoke it directly from the workflow so the
Linux and macOS jobs only keep the OS-specific setup in YAML
- wired those standalone `codex-zsh-*.tar.gz` assets into
`rust-release.yml` and added `.github/dotslash-zsh-config.json` so
releases also publish a `codex-zsh` DotSlash file
- updated the checked-in `codex-rs/app-server/tests/suite/zsh` fixture
comments to explain that new releases come from the standalone zsh
assets, while the checked-in fixture remains pinned to the latest
historical release until a newer zsh artifact is published
- tightened a couple of follow-on cleanups in
`codex-rs/shell-escalation`: the `ExecParams::command` comment now
describes the shell `-c`/`-lc` string more clearly, and the README now
points at the same `git.code.sf.net` zsh source URL that the workflow
uses

## Testing

- `cargo test -p codex-shell-escalation`
- `just argument-comment-lint`
- `bash -n .github/scripts/build-zsh-release-artifact.sh`
- attempted `cargo test -p codex-core`; unrelated existing failures
remain, but the touched `tools::runtimes::shell::unix_escalation::*`
coverage passed during that run
2026-03-24 12:56:26 -07:00
Charley Cunningham
2d61357c76 Trim pre-turn context updates during rollback (#15577)
## Summary
- trim contiguous developer/contextual-user pre-turn updates when
rollback cuts back to a user turn
- add a focused history regression test for the trim behavior
- update the rollback request-boundary snapshots to show the fixed
non-duplicating context shape

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-24 12:43:53 -07:00
Celia Chen
88694e8417 chore: stop app-server auth refresh storms after permanent token failure (#15530)
built from #14256. PR description from @etraut-openai:

This PR addresses a hole in [PR
11802](https://github.com/openai/codex/pull/11802). The previous PR
assumed that app server clients would respond to token refresh failures
by presenting the user with an error ("you must log in again") and then
not making further attempts to call network endpoints using the expired
token. While they do present the user with this error, they don't
prevent further attempts to call network endpoints and can repeatedly
call `getAuthStatus(refreshToken=true)` resulting in many failed calls
to the token refresh endpoint.

There are three solutions I considered here:
1. Change the getAuthStatus app server call to return a null auth if the
caller specified "refreshToken" on input and the refresh attempt fails.
This will cause clients to immediately log out the user and return them
to the log in screen. This is a really bad user experience. It's also a
breaking change in the app server contract that could break third-party
clients.
2. Augment the getAuthStatus app server call to return an additional
field that indicates the state of "token could not be refreshed". This
is a non-breaking change to the app server API, but it requires
non-trivial changes for all clients to properly handle this new field
properly.
3. Change the getAuthStatus implementation to handle the case where a
token refresh fails by marking the AuthManager's in-memory access and
refresh tokens as "poisoned" so it they are no longer used. This is the
simplest fix that requires no client changes.

I chose option 3.

Here's Codex's explanation of this change:

When an app-server client asks `getAuthStatus(refreshToken=true)`, we
may try to refresh a stale ChatGPT access token. If that refresh fails
permanently (for example `refresh_token_reused`, expired, or revoked),
the old behavior was bad in two ways:

1. We kept the in-memory auth snapshot alive as if it were still usable.
2. Later auth checks could retry refresh again and again, creating a
storm of doomed `/oauth/token` requests and repeatedly surfacing the
same failure.

This is especially painful for app-server clients because they poll auth
status and can keep driving the refresh path without any real chance of
recovery.

This change makes permanent refresh failures terminal for the current
managed auth snapshot without changing the app-server API contract.

What changed:
- `AuthManager` now poisons the current managed auth snapshot in memory
after a permanent refresh failure, keyed to the unchanged `AuthDotJson`.
- Once poisoned, later refresh attempts for that same snapshot fail fast
locally without calling the auth service again.
- The poison is cleared automatically when auth materially changes, such
as a new login, logout, or reload of different auth state from storage.
- `getAuthStatus(includeToken=true)` now omits `authToken` after a
permanent refresh failure instead of handing out the stale cached bearer
token.

This keeps the current auth method visible to clients, avoids forcing an
immediate logout flow, and stops repeated refresh attempts for
credentials that cannot recover.

---------

Co-authored-by: Eric Traut <etraut@openai.com>
2026-03-24 12:39:58 -07:00
Celia Chen
7dc2cd2ebe chore: use access token expiration for proactive auth refresh (#15545)
Follow up to #15357 by making proactive ChatGPT auth refresh depend on
the access token's JWT expiration instead of treating `last_refresh` age
as the primary source of truth.
2026-03-24 19:34:48 +00:00
xl-openai
621862a7d1 feat: include marketplace loading error in plugin/list (#15438)
Include error.
2026-03-24 11:47:23 -07:00
jif-oai
773fbf56a4 feat: communication pattern v2 (#15647)
See internal communication
2026-03-24 18:45:49 +00:00
Ruslan Nigmatullin
daf5e584c2 core: Make FileWatcher reusable (#15093)
### Summary
Make `FileWatcher` a reusable core component which can be built upon.
Extract skills-related logic into a separate `SkillWatcher`.
Introduce a composable `ThrottledWatchReceiver` to throttle filesystem
events, coalescing affected paths among them.

### Testing
Updated existing unit tests.
2026-03-24 11:04:47 -07:00
canvrno-oai
66edc347ae Pretty plugin labels, preserve plugin app provenance during MCP tool refresh (#15606)
- Prefer plugin manifest `interface.displayName` for plugin labels.
- Preserve plugin provenance when handling `list_mcp_tools` so connector
`plugin_display_names` are not clobbered.
- Add a TUI test to ensure plugin-owned app mentions are deduped
correctly.
2026-03-24 10:34:19 -07:00
Charley Cunningham
910cf49269 [codex] Stabilize second compaction history test (#15605)
## Summary
- replace the second-compaction test fixtures with a single ordered
`/responses` sequence
- assert against the real recorded request order instead of aggregating
per-mock captures
- realign the second-summary assertion to the first post-compaction user
turn where the summary actually appears

## Root cause
`compact_resume_after_second_compaction_preserves_history` collected
requests from multiple `mount_sse_once_match` recorders. Overlapping
matchers could record the same HTTP request more than once, so the test
indexed into a duplicated synthetic list rather than the true request
stream. That made the summary assertion depend on matcher evaluation
order and platform-specific behavior.

## Impact
- makes the flaky test deterministic by removing duplicate request
capture from the assertion path
- keeps the change scoped to the test only

## Validation
- `just fmt`
- `just argument-comment-lint`
- `env -u CODEX_SANDBOX_NETWORK_DISABLED cargo test -p codex-core
compact_resume_after_second_compaction_preserves_history -- --nocapture`
- repeated the same targeted test 10 times

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-24 10:14:21 -07:00
jif-oai
b51d5f18c7 feat: disable notifier v2 and start turn on agent interaction (#15624)
Make the inter-agent communication start a turn

As part of this, we disable the v2 notifier to prevent some odd
behaviour where the agent restart working while you're talking to it for
example
2026-03-24 17:01:24 +00:00
pakrym-oai
f49eb8e9d7 Extract sandbox manager and transforms into codex-sandboxing (#15603)
Extract sandbox manager
2026-03-24 08:20:57 -07:00