Commit Graph
13730 Commits
Author SHA1 Message Date
Michael Bolin ccf7320227 Merge b7dc64bf3d into sapling-pr-archive-bolinfest 2026-04-27 20:41:26 -07:00
Michael Bolin b7dc64bf3d permissions: add built-in default profiles 2026-04-27 20:41:10 -07:00
Michael Bolin 737f95d313 app-server-protocol: mark permission profiles experimental 2026-04-27 20:41:10 -07:00
Michael Bolin 7edd6bde2e permissions: store thread sessions as profiles 2026-04-27 20:41:10 -07:00
Michael Bolin 7497c0207a permissions: derive snapshot sandbox projections 2026-04-27 20:41:10 -07:00
Michael Bolin 86b7c3fef2 permissions: make SessionConfigured profile-only 2026-04-27 20:41:10 -07:00
Michael Bolin af95662a70 permissions: require profiles in TUI thread state (#19773)
## Why

`ThreadSessionState` is the TUI's cached view of an app-server session.
To make `PermissionProfile` the canonical runtime permissions model,
cached thread sessions need to always have a profile instead of treating
the profile as an optional supplement to a legacy `sandbox` response
field.

The main compatibility concern is older app-server v2 lifecycle
responses that only include `sandbox` and omit `permissionProfile`:

- `thread/start` -> `ThreadStartResponse.sandbox`
- `thread/resume` -> `ThreadResumeResponse.sandbox`
- `thread/fork` -> `ThreadForkResponse.sandbox`

Those responses must still hydrate correctly when the TUI is pointed at
an older app-server. This PR converts the legacy `sandbox` value into a
`PermissionProfile` immediately at response ingestion time, using the
response `cwd`, so cached sessions do not carry an optional profile that
can later reinterpret cwd-bound grants against a different thread cwd.

This fallback is intentionally boundary compatibility. The follow-up PRs
in this stack continue the cleanup by making `SessionConfiguredEvent`
profile-only, deriving sandbox projections from snapshots only when an
API still needs them, and then removing `sandbox_policy` from
`ThreadSessionState`.

## What Changed

- Makes `ThreadSessionState.permission_profile` required.
- Converts legacy app-server response `sandbox` values into a
`PermissionProfile` at ingestion time using the response cwd.
- Ensures `thread/read` hydration does not reuse a primary session
profile that may be anchored to a different cwd; it uses the active
widget permission settings for the read thread fallback instead of
reusing cached primary-session permissions.
- Keeps the app-server request path unchanged: embedded sessions send
profiles, while remote sessions continue using legacy sandbox overrides
for compatibility.

## Verification

- `cargo test -p codex-tui thread_read --lib`
- `cargo test -p codex-tui
permission_settings_sync_preserves_active_profile_only_rules --lib`
- `cargo test -p codex-tui
resume_response_restores_turns_from_thread_items --lib`
- `cargo test -p codex-tui thread_session_state::tests --lib`




























---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19773).
* #19900
* #19899
* #19776
* #19775
* #19774
* __->__ #19773
2026-04-27 20:39:06 -07:00
Michael Bolin 3f8be22845 Merge 7ca20b4669 into sapling-pr-archive-bolinfest 2026-04-27 20:18:03 -07:00
Michael Bolin 7ca20b4669 permissions: add built-in default profiles 2026-04-27 20:17:21 -07:00
Michael Bolin d1871b88e9 app-server-protocol: mark permission profiles experimental 2026-04-27 20:17:21 -07:00
Michael Bolin 08e200fd06 permissions: store thread sessions as profiles 2026-04-27 20:17:21 -07:00
Michael Bolin 2f9c725c72 permissions: derive snapshot sandbox projections 2026-04-27 20:17:21 -07:00
Michael Bolin 2d01c68aff permissions: make SessionConfigured profile-only 2026-04-27 20:17:21 -07:00
Michael Bolin bf530bf056 permissions: require profiles in TUI thread state 2026-04-27 20:17:21 -07:00
pakrym-oai 4e05f3053c Remove ghost snapshots (#19481)
## Summary
- Remove `ghost_snapshot` / `GhostCommit` from the Responses API surface
and generated SDK/schema artifacts.
- Keep legacy config loading compatible, but make undo a no-op that
reports the feature is unavailable.
- Clean up core history, compaction, telemetry, rollout, and tests to
stop carrying ghost snapshot items.

## Testing
- Unit tests passed for `codex-protocol`, `codex-core` targeted undo and
compaction flows, `codex-rollout`, and `codex-app-server-protocol`.
- Regenerated config and app-server schemas plus Python SDK artifacts
and verified they match the checked-in outputs.
2026-04-27 18:48:57 -07:00
Dylan Hurd 7e8594fc19 Stabilize plugin MCP fixture tests (#19452)
## Why

Recent `main` CI had repeated flakes in the plugin fixture tests:

- `codex-core::all
suite::plugins::explicit_plugin_mentions_inject_plugin_guidance` failed
in runs
[24909500958](https://github.com/openai/codex/actions/runs/24909500958),
[24908076251](https://github.com/openai/codex/actions/runs/24908076251),
[24906197645](https://github.com/openai/codex/actions/runs/24906197645),
and
[24898949647](https://github.com/openai/codex/actions/runs/24898949647).
- `codex-core::all suite::plugins::plugin_mcp_tools_are_listed` failed
in runs
[24909500958](https://github.com/openai/codex/actions/runs/24909500958),
[24908076251](https://github.com/openai/codex/actions/runs/24908076251),
and
[24898949647](https://github.com/openai/codex/actions/runs/24898949647).

The failures were in the same plugin/MCP fixture family: assertions
expected sample plugin guidance or tool inventory, but the test could
observe the session before the sample MCP server had finished startup.

## Root Cause

`explicit_plugin_mentions_inject_plugin_guidance` submitted the user
turn immediately after constructing the session. MCP startup is
asynchronous, so on a slower or busier CI runner the prompt could be
built before the sample plugin MCP server had reported its tools. That
made the test depend on scheduler timing rather than the fixture being
ready.

`plugin_mcp_tools_are_listed` already needed the same readiness
condition, but its wait logic was local to that test.

## What Changed

- Added a shared `wait_for_sample_mcp_ready` helper for the plugin
fixture tests.
- Wait for `McpStartupComplete` before submitting the explicit plugin
mention turn.
- Reuse the same readiness helper in the MCP tool-listing test.

## Why This Should Be Reliable

The tests now wait for the explicit readiness signal from the sample MCP
server before asserting guidance or tools derived from that server. This
removes the startup race while still exercising the real fixture path,
so the assertions should only run after the plugin inventory is
deterministic.

## Verification

- `cargo test -p codex-core --test all plugins::`
- GitHub CI for this PR is passing.
2026-04-28 01:14:44 +00:00
Michael Bolin ee327e0069 Merge 393a21dcd6 into sapling-pr-archive-bolinfest 2026-04-27 17:46:25 -07:00
Michael Bolin 393a21dcd6 permissions: add built-in default profiles 2026-04-27 17:44:45 -07:00
Michael Bolin 5fca8f2fa1 app-server-protocol: mark permission profiles experimental 2026-04-27 17:44:45 -07:00
Michael Zeng a3350de855 Refactor exec-server filesystem API into codex-file-system (#19892)
## Summary
- Extracted the shared filesystem types and `ExecutorFileSystem` trait
into a new `codex-file-system` crate
- Switched `codex-config` and `codex-git-utils` to depend on that crate
instead of `codex-exec-server`
- Kept `codex-exec-server` re-exporting the same API for existing
callers

## Testing
- Ran `cargo test -p codex-file-system`
- Ran `cargo test -p codex-git-utils`
- Ran `cargo test -p codex-config`
- Ran `cargo test -p codex-exec-server`
- Ran `just fix -p codex-file-system`, `just fix -p codex-git-utils`,
`just fix -p codex-config`, `just fix -p codex-exec-server`
- Ran `just fmt`
- Updated and verified the Bazel module lockfile
2026-04-27 17:43:15 -07:00
colby-oai 2f3b5ed81a disallow fileparams metadata for custom mcps (#19836)
## Summary
Disallow fileParams metadata for custom MCPs 

Restricts Codex openai/fileParams handling to the first-party codex_apps
MCP server. Custom MCP servers may still advertise the metadata, but
Codex now ignores it for upload rewriting, preventing non-Apps tools
from receiving signed OpenAI file refs for local paths. Added a
regression test for the allowed and denied cases.
2026-04-27 20:42:10 -04:00
Michael Bolin 12824baa72 Merge 88df7ef0b8 into sapling-pr-archive-bolinfest 2026-04-27 17:12:19 -07:00
Michael Bolin 88df7ef0b8 permissions: store thread sessions as profiles 2026-04-27 17:11:10 -07:00
Michael Bolin dd9545ccdf permissions: derive snapshot sandbox projections 2026-04-27 17:11:10 -07:00
Michael Bolin 1588963deb permissions: make SessionConfigured profile-only 2026-04-27 17:10:37 -07:00
Michael Bolin d17063d193 merge commit for archive created by Sapling 2026-04-27 17:06:01 -07:00
Michael Bolin 6cc84ca923 permissions: require profiles in TUI thread state 2026-04-27 17:05:37 -07:00
Michael Bolin 7481ea3952 permissions: store thread sessions as profiles 2026-04-27 17:05:37 -07:00
Michael Bolin 7a2d35660c permissions: derive snapshot sandbox projections 2026-04-27 17:05:37 -07:00
Michael Bolin 25a8e1d617 permissions: make SessionConfigured profile-only 2026-04-27 17:05:37 -07:00
Michael Bolin dfe7507253 merge commit for archive created by Sapling 2026-04-27 17:04:36 -07:00
Michael Bolin 457d0a6dfd permissions: store thread sessions as profiles 2026-04-27 17:04:20 -07:00
Michael Bolin 5772009240 permissions: derive snapshot sandbox projections 2026-04-27 17:04:20 -07:00
Michael Bolin 0676603e5e permissions: make SessionConfigured profile-only 2026-04-27 16:59:45 -07:00
Michael Bolin 5ffd2158da permissions: require profiles in TUI thread state 2026-04-27 16:59:08 -07:00
Michael Bolin 7a49eabf0b merge commit for archive created by Sapling 2026-04-27 16:58:48 -07:00
Michael Bolin 2558ae6bc4 permissions: store thread sessions as profiles 2026-04-27 16:55:02 -07:00
Michael Bolin 3fe6c38abf permissions: derive snapshot sandbox projections 2026-04-27 16:54:21 -07:00
Michael Bolin 1e8a11fda0 permissions: make SessionConfigured profile-only 2026-04-27 16:54:21 -07:00
Michael Bolin fcfcacf9a6 permissions: require profiles in TUI thread state 2026-04-27 16:54:21 -07:00
Michael Bolin 755880ef9c permissions: derive config defaults as profiles (#19772)
## Why

This continues the permissions migration by making legacy config default
resolution produce the canonical `PermissionProfile` first. The legacy
`SandboxPolicy` projection should stay available at compatibility
boundaries, but config loading should not create a legacy policy just to
immediately convert it back into a profile.

Specifically, when `default_permissions` is not specified in
`config.toml`, instead of creating a `SandboxPolicy` in
`codex-rs/core/src/config/mod.rs` and then trying to derive a
`PermissionProfile` from it, we use `derive_permission_profile()` to
create a more faithful `PermissionProfile` using the values of
`ConfigToml` directly.

This also keeps the existing behavior of `sandbox_workspace_write` and
extra writable roots after #19841 replaced `:cwd` with `:project_roots`.
Legacy workspace-write defaults are represented as symbolic
`:project_roots` write access plus symbolic project-root metadata
carveouts. Extra absolute writable roots are still added directly and
continue to get concrete metadata protections for paths that exist under
those roots.

The platform sandboxes differ when a symbolic project-root subpath does
not exist yet.

* **Seatbelt** can encode literal/subpath exclusions directly, so macOS
emits project-root metadata subpath policies even if `.git`, `.agents`,
or `.codex` do not exist.
* **bwrap** has to materialize bind-mount targets. Binding `/dev/null`
to a missing `.git` can create a host-visible placeholder that changes
Git repo discovery. Binding missing `.agents` would not affect Git
discovery, but it would still create a host-visible project metadata
placeholder from an automatic compatibility carveout. Linux therefore
skips only missing automatic `.git` and `.agents` read-only metadata
masks; missing `.codex` remains protected so first-time project config
creation goes through the protected-path approval flow. User-authored
`read` and `none` subpath rules keep normal bwrap behavior, and `none`
can still mask the first missing component to prevent creation under
writable roots.

## What Changed

- Adds profile-native helpers for legacy workspace-write semantics,
including `PermissionProfile::workspace_write_with()`,
`FileSystemSandboxPolicy::workspace_write()`, and
`FileSystemSandboxPolicy::with_additional_legacy_workspace_writable_roots()`.
- Makes `FileSystemSandboxPolicy::workspace_write()` the single legacy
workspace-write constructor so both `from_legacy_sandbox_policy()` and
`From<&SandboxPolicy>` include the project-root metadata carveouts.
- Removes the no-carveout `legacy_workspace_write_base_policy()` path
and the `prune_read_entries_under_writable_roots()` cleanup that was
only needed by that split construction.
- Adds `ConfigToml::derive_permission_profile()` for legacy sandbox-mode
fallback resolution; named `default_permissions` profiles continue
through the permissions profile pipeline instead of being reconstructed
from `sandbox_mode`.
- Updates `Config::load()` to start from the derived profile, validate
that it still has a legacy compatibility projection, and apply
additional writable roots directly to managed workspace-write filesystem
policies.
- Updates Linux bwrap argument construction so missing automatic
`.git`/`.agents` symbolic project-root read-only carveouts are skipped
before emitting bind args; missing `.codex`, user-authored `read`/`none`
subpath rules, and existing missing writable-root behavior are
preserved.
- Adds coverage that legacy workspace-write config produces symbolic
project-root metadata carveouts, extra legacy workspace writable roots
still protect existing metadata paths such as `.git`, and bwrap skips
missing `.git`/`.agents` project-root carveouts while preserving missing
`.codex` and user-authored missing subpath rules.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19772).
* #19776
* #19775
* #19774
* #19773
* __->__ #19772
2026-04-27 16:50:10 -07:00
pakrym-oai c5a495c2cd Streamline review and feedback handlers (#19498)
## Why

The remaining review, interrupt, fuzzy search, feedback, and git-diff
handlers still had local send-error branches that obscured otherwise
simple request handling. This final slice flattens those handlers
without changing the public protocol behavior.

## What Changed

- Streamlined review start, turn interrupt, fuzzy search session,
feedback upload, and git diff handlers in
`codex-rs/app-server/src/codex_message_processor.rs`.
- Converted validation and upload failures into returned JSON-RPC errors
where that avoids nested `send_error`/`return` blocks.
- Left unrelated sandbox setup and notification code untouched.

## Verification

- `cargo check -p codex-app-server`
- `cargo test -p codex-app-server --test all v2::review --
--test-threads=1`
2026-04-27 16:36:04 -07:00
Matthew Zeng dcd139b7c4 Add MCP app feature flag (#19884)
## Summary
- Add the `enable_mcp_apps` feature flag to the `codex-features`
registry
- Keep it under development and disabled by default

## Testing
- Unit tests for `codex-features` passed
- Formatting passed
2026-04-27 16:28:49 -07:00
Michael Bolin 8100a5aa89 merge commit for archive created by Sapling 2026-04-27 16:12:26 -07:00
Michael Bolin d7ebb4cd37 permissions: derive config defaults as profiles 2026-04-27 16:12:15 -07:00
Michael Bolin 7e8dd67d07 permissions: store thread sessions as profiles 2026-04-27 16:12:15 -07:00
Michael Bolin 41d0199a7a permissions: derive snapshot sandbox projections 2026-04-27 16:12:15 -07:00
Michael Bolin 1ec30342a1 permissions: make SessionConfigured profile-only 2026-04-27 16:12:15 -07:00
Michael Bolin 80686c3dfe permissions: require profiles in TUI thread state 2026-04-27 16:12:15 -07:00
Michael Bolin aa43c1b782 merge commit for archive created by Sapling 2026-04-27 16:02:44 -07:00