Commit Graph

16957 Commits

Author SHA1 Message Date
Michael Bolin
b79c775202 merge commit for archive created by Sapling 2026-06-03 09:26:24 -07:00
Michael Bolin
baefa8f311 cli: add package path from install context 2026-06-03 09:26:04 -07:00
Michael Bolin
08e1dd0770 Merge 5d531b0a3e into sapling-pr-archive-bolinfest 2026-06-03 09:19:38 -07:00
Michael Bolin
5d531b0a3e cli: add package path from install context 2026-06-03 09:19:24 -07:00
jif
4417e4c193 fix: main (#26176) 2026-06-03 16:47:34 +02:00
jif
96d2d2f68c Implement v1 skills extension prompt injection (#26167)
## Why

The skills extension needs a real turn-time path before host, executor,
or remote skills can be routed through it. The previous code was mostly
a placeholder catalog/provider sketch, so there was no bounded
available-skills fragment, no source-owned `SKILL.md` read, and no place
for warnings or per-turn selection state to live.

This PR makes `ext/skills` the authority-preserving flow for listing
candidate skills and injecting only explicitly selected main prompts,
without adding more of that logic to `codex-core`.

## What changed

- Expands catalog entries with `main_prompt`, display path, short
description, dependency metadata, enabled/prompt visibility flags, and
authority/package-aware read requests.
- Replaces the placeholder `providers/*` modules with
`SkillProviderSource` and `SkillProviders`, routing list/read/search
calls by source kind and surfacing provider failures as warnings.
- Adds bounded available-skills rendering and `SKILL.md` main-prompt
truncation before the fragments enter model context.
- Resolves explicit skill selections from structured `UserInput::Skill`,
skill-file mentions, `skill://...` paths, and plain `$skill` text
mentions, then reads selected prompts through their owning provider.
- Stores mutable per-thread skills config and per-turn
catalog/selection/warning state.
- Adds `install_with_providers` so tests and future host wiring can
supply concrete providers.

## Testing

- Not run locally.
- Added `codex-rs/ext/skills/tests/skills_extension.rs` coverage for
available-catalog injection, selected prompt injection through the
owning provider, and prompt-hidden skills that remain invokable.
2026-06-03 16:24:16 +02:00
jif
c9ae0f48a1 chore: mechanical rename (#26156)
Rename `Session::conversation_id` to `Session::thread_id` with an auto
refactor in RustRover
2026-06-03 15:38:30 +02:00
jif
7db18c8241 fix: serialize goal progress accounting (#26155)
## Why

Goal progress accounting can be reached from multiple completion paths
for the same thread. Each path takes a progress snapshot, writes the
usage delta, and then marks that snapshot as accounted. When two
tool-completion hooks run at the same time, they can both observe the
same unaccounted delta and charge it twice.

## What changed

- Added a per-thread progress-accounting permit to
`GoalAccountingState`.
- Held that permit across the snapshot/write/mark-accounted critical
section for active-turn, idle, and tool-finish accounting.
- Added regression coverage for parallel tool-finish hooks so a shared
token delta is charged once and only one progress event is emitted.

## Testing

- Not run locally.
- Added `parallel_tool_finish_accounts_active_goal_progress_once`.
2026-06-03 15:10:16 +02:00
jif
3389fa554e skills: resolve per-turn catalogs from turn input context (#26106)
## Why

The skills extension needs the resolved turn environments to build a
real per-turn `SkillListQuery`. The previous `TurnLifecycleContributor`
hook only had a turn id, so it could only seed a placeholder query and
never carry the executor authorities that executor-scoped skill routing
will need.

Moving catalog resolution onto `TurnInputContributor` puts the skills
extension on the same turn-preparation path that already has the
environment ids and working directories for the submitted turn, while
keeping the actual prompt injection work for follow-up changes.

## What changed

- switch `ext/skills` from `TurnLifecycleContributor` to
`TurnInputContributor`
- build `executor_authorities` from `TurnInputContext.environments` and
pass them through `SkillListQuery`
- keep storing the resolved catalog in `SkillsTurnState`, but drop the
placeholder query helper that no longer matches the real data flow
- update the extension TODOs to reflect that per-turn catalog resolution
now happens in the turn-input contributor, and that prompt/context
injection still needs to move later

## Testing

- Not run locally.
2026-06-03 13:32:55 +02:00
jif
51493157cd Reject MAv2 close_agent self-targets (#26144)
## Why

`close_agent` is a parent-owned coordination tool: a worker should
return its result, then let its parent decide when to close it. Before
this change, if an MAv2 worker targeted itself, the resolved target
could flow through the normal close path and ask the agent control layer
to close the current conversation.

## What changed

- Reject `close_agent` when the resolved target is the current session's
`conversation_id`, returning a model-visible error that tells the worker
to return its result instead.
- Keep the guard after target resolution so it covers both thread-id
targets and task-path targets.
- Add coverage for self-targeting by thread id and by task name in
`multi_agents_tests.rs`.

Relevant code:

-
[`handle_close_agent`](7c24e6641b/codex-rs/core/src/tools/handlers/multi_agents_v2/close_agent.rs (L39-L57))
- [`multi_agent_v2_close_agent_rejects_self_target_by_id` /
`multi_agent_v2_close_agent_rejects_self_target_by_task_name`](7c24e6641b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs (L3936-L4070))

## Testing

Not run locally.
2026-06-03 13:30:04 +02:00
jif
ac67905fc4 chore: extract context fragments into dedicated crate (#26122)
## Why

`codex-core` currently owns the generic contextual-fragment trait and
several reusable fragment implementations. That makes it harder for
other crates to share the same host-owned model-input abstraction
without depending on all of `codex-core`.

This change extracts the reusable fragment machinery into a small
`codex-context-fragments` crate so future extension and skills work can
depend on the fragment abstraction directly.

## What Changed

- Added the `codex-context-fragments` crate with:
  - `ContextualUserFragment`
  - `FragmentRegistration` / `FragmentRegistrationProxy`
  - additional-context fragment types
- Moved `SkillInstructions` into `codex-core-skills`, since
skill-specific rendering belongs with skills rather than generic core
context machinery.
- Kept `codex-core` re-exporting the fragment types it still uses
internally, so existing call sites keep the same shape.
- Updated Cargo and Bazel workspace metadata for the new crate.

## Verification

- `cargo metadata --locked --format-version 1 --no-deps`
- `just bazel-lock-update`
- `just bazel-lock-check`
2026-06-03 12:25:21 +02:00
jif
668703c23f feat: default hide_spawn_agent_metadata to true (#26114)
For MAv2 CBv9
2026-06-03 12:22:23 +02:00
Shijie Rao
d36a3ead3c revert: publish release symbol artifacts (#25988)
revert https://github.com/openai/codex/pull/25916 and
https://github.com/openai/codex/pull/25649.
2026-06-02 17:34:04 -07:00
Anton Panasenko
98a62a62ce feat(app-server): add remote control client management RPCs (#25785)
## Why

Remote-control clients need to list and revoke controller-device grants
without enabling or enrolling the local relay. These are signed-in
account-management operations, so coupling them to websocket, pairing,
enrollment, or persisted relay state would prevent clients from managing
stale grants from the picker.

Related enhancement request: N/A. This adds the Codex app-server surface
for the planned upstream environment-scoped revoke endpoint.

## What Changed

- Added experimental app-server v2 RPCs:
  - `remoteControl/client/list`
  - `remoteControl/client/revoke`
- Added picker-oriented protocol types and standard generated schema
fixtures. The list response intentionally omits backend account id,
enrollment status, and location fields.
- Added `app-server-transport/src/transport/remote_control/clients.rs`
for environment-scoped GET and DELETE requests. It builds escaped URL
path segments, forwards optional pagination query fields, sends ChatGPT
auth plus `chatgpt-account-id`, converts RFC3339 `last_seen_at` values
to Unix seconds, accepts `204 No Content` revoke responses, and retries
once after a `401`.
- Extracted shared ChatGPT auth loading and recovery into
`app-server-transport/src/transport/remote_control/auth.rs` so
websocket, pairing, and client management use the same account-auth
boundary.
- Retained the configured remote-control base URL on
`RemoteControlHandle` and resolve management URLs lazily, preserving
deferred validation while relay startup is disabled.
- Registered list as `global_shared_read("remote-control-clients")` and
revoke as `global("remote-control-clients")`.

## Verification

- Added transport coverage proving list and revoke work while relay
state is disabled, IDs are escaped, picker-only fields are returned,
timestamps are converted, revoke accepts `204`, auth headers are
forwarded, `401` retries exactly once, `403` is not retried, and
malformed list payloads retain decode context.
- Added an app-server integration test proving both JSON-RPC methods
work before relay enablement and successful revoke returns `{}`.
- Regenerated and validated experimental and standard app-server schema
fixtures.
2026-06-02 17:01:02 -07:00
joeflorencio-openai
1fd2a6d328 Allow EDU accounts to fetch cloud config bundles (#25963)
## Summary

Allow EDU ChatGPT workspaces to fetch cloud config bundles. The existing
cloud config eligibility gate only allowed business-like and enterprise
plans, which meant EDU admins could configure managed policies in the UI
but the Codex client would skip fetching them.

This keeps individual/pro and team-like usage-based plans excluded, and
adds service-level coverage for both `edu` and `education` plan aliases.

## Validation

- `just fmt`
- `just test -p codex-cloud-config`
- Built the Codex app locally, created a new EDU ChatGPT workspace, and
verified config bundles can be fetched and are properly applied.
2026-06-02 16:41:48 -07:00
jif
271d5cecf2 feat: add extension turn-input contributors (#25959)
## Disclaimer
Do not use for now

## Why

Extensions can already contribute prompt fragments and request same-turn
item injection, but there was no host-owned hook for contributing
structured `ResponseItem`s while Codex is assembling a new turn's
initial model input. This change adds that seam so extensions can attach
turn-local input that depends on the submitted user input and resolved
turn environments without routing through prompt text or late injection.

## What changed

- add `TurnInputContributor` to `codex_extension_api` and export the new
`TurnInputContext` / `TurnInputEnvironment` types it receives
- teach `ExtensionRegistry` to register and expose turn-input
contributors alongside the existing extension hooks
- call registered turn-input contributors from
`core/src/session/turn.rs` while building the initial injected input for
a turn, then append their returned `ResponseItem`s after the skill and
plugin injections
2026-06-03 01:33:31 +02:00
Michael Bolin
a28b32a835 config: express implicit sandbox defaults as permission profiles (#25926)
## Why

`PermissionProfile` is becoming the default way to represent Codex
permissions, but the implicit default behavior should stay the same for
now:

- trusted projects use `:workspace`
- untrusted projects also use `:workspace`
- roots without a trust decision use `:read-only`
- unsandboxed Windows falls back to `:read-only`

This keeps the existing sandbox semantics while making silent config
defaults observable as built-in permission profiles instead of treating
the legacy `SandboxPolicy` projection as the primary shape.

## What Changed

- Refactored legacy sandbox derivation to resolve the configured sandbox
mode once, then apply the implicit project fallback only when no sandbox
mode was configured.
- Preserved the existing trust-decision fallback: trusted and untrusted
projects default to workspace-write where supported.
- Added empty-config coverage asserting that an untrusted project
resolves to the built-in active permission profile (`:workspace` outside
unsandboxed Windows).

## Verification

- `just fmt`
- `just test -p codex-core 'config::'`
- `just test -p codex-config`

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/25926).
* __->__ #25926
2026-06-02 16:26:36 -07:00
Adam Perry @ OpenAI
6471f8b31a [codex] Fix Windows BuildBuddy Bazel wrapper execution (#25915)
## Why

#25156 moved Bazel CI launches into a shared Python wrapper. On Windows,
launching Bazel with `os.execvp` can split the spaced
`--test_env=PATH=...` argument and fail to propagate the eventual Bazel
exit status, allowing jobs to pass without running tests. This reapplies
the wrapper after #25909 with a Windows-safe launch path.

## What changed

Use a waited `subprocess.run` launch on Windows while preserving
`os.execvp` on Unix. Add a process-level regression test for spaced
arguments and child exit status, and run it on Windows Bazel shard 1.

## Experiment

To confirm Bazel was actually invoking tests, patch `87b61d0be6`
temporarily added an intentionally failing `codex-core` unit test. Bazel
failed on that sentinel on all three major platforms:

- [Linux Bazel
test](https://github.com/openai/codex/actions/runs/26841132773/job/79151062486)
- [macOS Bazel
test](https://github.com/openai/codex/actions/runs/26841132773/job/79151062362)
- [Windows Bazel test shard
1/4](https://github.com/openai/codex/actions/runs/26841132773/job/79151062155)

The sentinel was removed after collecting this evidence. Windows Bazel
[clippy](https://github.com/openai/codex/actions/runs/26841132773/job/79151062914)
and [release
verification](https://github.com/openai/codex/actions/runs/26841132773/job/79151062739)
also passed.

## Validation

After removing the sentinel, `just test -p codex-core` no longer
reported it. The local run retained two unrelated environment-specific
failures.
2026-06-02 16:22:32 -07:00
jif
2d385e166c feat: add skills extension scaffold (#25953)
## Disclaimer
This is only here for iteration purpose! Do not make any code rely on
this

## Why

Skills still live behind `codex-core` discovery and injection paths, but
the extension system needs an authority-aware home before that logic can
move. This adds that boundary without changing current skills behavior,
and keeps host, executor, and remote skills distinct so future
list/read/search flows do not collapse back to ambient local paths.

## What changed

- Add the `codex-skills-extension` workspace/Bazel crate under
`ext/skills`.
- Define the initial catalog, authority, provider, and turn-state types
for authority-bound skill packages and resources.
- Register placeholder thread/config/prompt/turn lifecycle contributors
plus host, executor, and remote provider aggregation points.
- Capture the remaining extraction work as TODOs, including the missing
extension API hooks needed for per-turn catalog construction and typed
skill injection.
- Keep plugins outside the runtime skills model: plugin-installed skills
are treated as materialized host-owned skill sources once available.

## Verification

- Not run locally.
2026-06-03 01:10:26 +02:00
Michael Bolin
a1b69df79b Merge e90bc96a2a into sapling-pr-archive-bolinfest 2026-06-02 15:48:29 -07:00
Michael Bolin
e90bc96a2a core: stop threading SandboxPolicy through exec
Replace the exec-side legacy SandboxPolicy plumbing with PermissionProfile-based Windows sandbox override resolution.

The runtime still needs a legacy SandboxPolicy projection for a few compatibility surfaces and for Windows override baseline comparisons, but that projection is now derived from a single PermissionProfile instead of accepting separately materialized FileSystemSandboxPolicy and NetworkSandboxPolicy inputs. This avoids mismatched permission arguments while keeping the migration scoped to the existing compatibility boundary.

Keep the Windows exec tests aligned with that shape by constructing PermissionProfile values through the highest-level available helpers instead of routing test setup through SandboxPolicy compatibility conversions.

Validation:
- just test -p codex-sandboxing
- just test -p codex-core windows_restricted_token
- CI for the follow-up exec_tests cleanup
2026-06-02 15:48:19 -07:00
Michael Bolin
93a66a5288 Merge 1ca7b278e0 into sapling-pr-archive-bolinfest 2026-06-02 15:48:09 -07:00
Michael Bolin
1ca7b278e0 core: enforce guardian review file permissions 2026-06-02 15:47:53 -07:00
Michael Bolin
1b15d91e31 Merge cb1978b913 into sapling-pr-archive-bolinfest 2026-06-02 15:47:35 -07:00
Michael Bolin
cb1978b913 core: enforce guardian review file permissions 2026-06-02 15:46:56 -07:00
Michael Bolin
210082227b merge commit for archive created by Sapling 2026-06-02 15:46:09 -07:00
Michael Bolin
6ea2525d52 config: express implicit sandbox defaults as permission profiles 2026-06-02 15:45:39 -07:00
Ahmed Ibrahim
34dc08c214 [codex] Publish Python runtime wheels with Python SDK releases (#25906)
## Summary
- stop publishing Python runtime wheels as a side effect of Rust
releases
- publish runtime wheels from the Python SDK release workflow, either
explicitly before updating the SDK pin or immediately before a
`python-v*` SDK release
- resolve the runtime release from the requested version or the SDK
package's exact `openai-codex-cli-bin` pin
- build two musllinux-tagged wheels from the Rust-release Linux package
archives alongside the six existing runtime wheels
- validate SDK beta tags before any PyPI write

## Release configuration
- update the `openai-codex-cli-bin` PyPI trusted publisher to trust
`.github/workflows/python-sdk-release.yml` and the
`publish-python-runtime` job

## Pin update flow
- run the `python-sdk-release` workflow manually with the new runtime
version before opening or updating the SDK pin PR
- after the pin lands, a `python-v*` SDK tag republishes with
`skip-existing: true` before publishing the SDK package

## Validation
- ran `just fmt`
- validated the edited workflow YAML
- validated the embedded `publish-python-runtime` Bash with `bash -n`
- validated manual `0.136.0 -> rust-v0.136.0` mapping
- validated tag-driven `python-v0.1.0b3 -> 0.132.0 -> rust-v0.132.0`
mapping
- validated rejection of an invalid SDK tag before publication
- confirmed `rust-v0.136.0` contains the two required Linux package
archives
- CI will provide the full test signal
2026-06-02 15:41:53 -07:00
Michael Bolin
ec2d6b4b4d Merge 9ab5f3ca1b into sapling-pr-archive-bolinfest 2026-06-02 15:39:46 -07:00
Michael Bolin
9ab5f3ca1b config: default untrusted projects to read-only permissions 2026-06-02 15:39:34 -07:00
Won Park
bec21c7114 Expose standalone image generation in code mode (#25923)
## Why

Standalone image generation remained top-level-only in code-mode
sessions.

## What changed

- Change imagegen exposure from `DirectModelOnly` to `Direct`.
- Keep direct-mode access while enabling nested code-mode access.
- Add a focused regression test for the exposure contract.

## Validation

- `just test -p codex-image-generation-extension`
2026-06-02 22:27:52 +00:00
Shijie Rao
f752b25fc4 Revert "Use environment secrets for Azure signing" (#25948)
Reverts openai/codex#24859
2026-06-02 15:12:07 -07:00
Michael Bolin
198080ea83 Merge 9f2643d5cb into sapling-pr-archive-bolinfest 2026-06-02 15:06:29 -07:00
Michael Bolin
9f2643d5cb config: default untrusted projects to read-only permissions 2026-06-02 15:06:22 -07:00
Michael Bolin
c6d76750e8 config: remove dead profile sandbox fallback (#25943)
## Why

`profile_sandbox_mode` was left over from the old selected legacy
profile path. Production now always derives permissions without that
value, and legacy profile contents are ignored, so keeping a parameter
that is always `None` makes `derive_permission_profile` look like it
still supports a fallback that no longer exists.

## What Changed

- Removed the `profile_sandbox_mode` argument from
`ConfigToml::derive_permission_profile`.
- Updated the production caller and legacy sandbox-policy test helper to
match.
- Dropped the stale unselected legacy-profile sandbox test that only
protected the removed fallback shape.

## Verification

- `just test -p codex-config`
- `just test -p codex-core 'config::'`


---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/25943).
* #25926
* __->__ #25943
2026-06-02 22:05:04 +00:00
jif
d55e5a9bde Add remote request permissions integration coverage (#25867)
## Stack

1. #25850 - Key request-permission grants by environment: stores and
applies sticky permission grants per environment id.
2. #25858 - Add `environmentId` to `request_permissions`: lets the model
target a selected environment and resolves relative permission paths
against it.
3. #25862 - Propagate permission approval environment id: carries the
selected environment id through approval events, app-server requests,
TUI prompts, and delegate forwarding.
4. This PR (#25867) - Add remote request permissions integration
coverage: verifies the selected remote environment across request,
approval, grant reuse, and exec.

This PR is stacked on #25862 and should be reviewed after #25850,
#25858, and #25862.

## Why

The environment-scoped permission stack needs one end-to-end check that
exercises the CCA-shaped path, not only unit-level parsing. This
verifies that a model-sent `environmentId` on `request_permissions`
reaches the approval event, stores the grant under the selected
environment, and is reused by a later tool call in that same
environment.

## What Changed

- Adds a remote executor integration test for `request_permissions` with
`environmentId: remote` and a relative write root.
- Asserts the permission event reports the remote environment and cwd,
and that the normalized grant resolves under the remote cwd.
- Approves the grant, then runs a remote `exec_command` without explicit
per-call permissions and verifies it completes without another exec
approval and writes only in the remote filesystem.

## Verification

- Not run locally per instruction.
- `git diff --check`
2026-06-02 23:55:08 +02:00
Ahmed Ibrahim
68e2c8ed69 [codex] Keep hosted tools visible in code-only mode (#25890)
## Why

`code_mode_only` moved ordinary runtime tools behind `exec`, but it also
hid hosted Responses tools. Hosted `web_search` and `image_generation`
do not have a nested `exec` runtime path, so code-only sessions lost
those capabilities entirely even when their existing provider, auth,
model, and configuration gates passed.

## What changed

- Keep hosted Responses tools top-level in `code_mode_only` sessions
after their existing gates pass.
- Preserve the existing nested-tool behavior for ordinary runtimes and
the direct-only behavior for multi-agent v2 tools.
- Add planner coverage for `code_mode_only` with default multi-agent v2
settings, hosted live web search, and hosted image generation.

## Verification

- Added focused regression coverage in
`codex-rs/core/src/tools/spec_plan_tests.rs`.
- Left execution to CI per repository workflow.
2026-06-02 14:50:16 -07:00
Michael Bolin
a7c31fc2c8 merge commit for archive created by Sapling 2026-06-02 14:44:19 -07:00
Michael Bolin
c1485dd764 config: default untrusted projects to read-only permissions 2026-06-02 14:44:08 -07:00
Michael Bolin
62870c4b01 merge commit for archive created by Sapling 2026-06-02 14:41:34 -07:00
Michael Bolin
8c38bcf1b1 config: remove dead profile sandbox fallback 2026-06-02 14:39:49 -07:00
Michael Bolin
87a13de70b config: default untrusted projects to read-only permissions 2026-06-02 14:39:49 -07:00
Michael Bolin
d770594532 Merge 97b7ec7534 into sapling-pr-archive-bolinfest 2026-06-02 14:37:18 -07:00
Michael Bolin
97b7ec7534 config: default untrusted projects to read-only permissions 2026-06-02 14:37:07 -07:00
Michael Bolin
bcaf711e72 config: remove dead profile sandbox fallback 2026-06-02 14:37:07 -07:00
Michael Bolin
9958092678 Merge 5750eb9fe4 into sapling-pr-archive-bolinfest 2026-06-02 14:35:59 -07:00
Michael Bolin
5750eb9fe4 config: default untrusted projects to read-only permissions 2026-06-02 14:31:41 -07:00
Michael Bolin
1cb5f32051 config: remove dead profile sandbox fallback 2026-06-02 14:31:35 -07:00
joeflorencio-openai
e7039f9844 Split cloud config bundle service modules (#25668)
## Summary

- Splits the monolithic `codex-cloud-config` implementation into focused
modules.
- Keeps behavior unchanged from the preceding config bundle runtime
switch.

## Details

This is the reviewability follow-up after the lineage-preserving
migration PRs. The split separates backend transport, loader
construction, cache handling, metrics, validation, service
orchestration, and focused tests into named files.

Verification: `just fmt`; `just test -p codex-cloud-config`.
2026-06-02 14:30:12 -07:00
Michael Bolin
8928941469 Merge 964eb85a88 into sapling-pr-archive-bolinfest 2026-06-02 14:18:01 -07:00