mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
b128da272e640371c75913033bdcc96bcea85ec4
3164 Commits
-
[codex] Exclude external tool output from memories (#26821)
## Summary - add contains_external_context() to tool output so other tools can be opted out of influencing memory when disable_on_external_context=true - Classify standalone web-search output as external context (to match behavior as hosted web search) - Verify with integration test
rka-oai ·
2026-06-08 16:53:04 +00:00 -
Avoid reopening v2 descendants on resume (#26997)
## Why Multi-agent v2 residency is intended to keep only the threads that need to be live. The existing rollout resume path still walked persisted open descendants and reopened the entire descendant tree when resuming a v2 root, which turns resume into an eager reload of work that should stay unloaded until it is explicitly needed. The interrupted-agent path has a related residency issue. Interrupted agents remain open by design, so an idle interrupted resident should be eligible for eviction just like an idle completed or errored resident. Otherwise a resident set full of interrupted agents can consume every v2 slot and block later spawns or reloads with `AgentLimitReached`. ## What Changed - Return early from `resume_agent_from_rollout` after resuming a v2 thread so persisted v2 descendants are not reopened eagerly. - Treat idle `Interrupted` v2 residents as unloadable in the LRU residency path. - Add focused coverage for v2 root resume leaving descendants unloaded and for eviction of an idle interrupted v2 resident when a new slot is needed. ## Verification Added targeted `codex-core` tests covering: - v2 root resume with persisted descendants, verifying only the root is loaded after resume. - residency eviction of an idle interrupted v2 agent when the resident set is full.
jif ·
2026-06-08 16:44:50 +02:00 -
Rename multi-agent v2 close_agent to interrupt_agent (#26994)
## Why `close_agent` is the wrong model-facing name for the v2 operation after the residency changes. V2 agents remain reusable by task name, and residency/unloading owns capacity management; the exposed tool should describe the action it actually performs: interrupt the target agent's current turn without making the agent unavailable for future messages or follow-up tasks. ## What changed - Rename the multi-agent v2 tool from `close_agent` to `interrupt_agent`. - Keep the v1 `close_agent` surface unchanged. - Update the v2 handler to send `Op::Interrupt`, keep interrupted agents registered, and reject root/self targets with interrupt-specific errors. - Route interrupt delivery through the existing dead-thread cleanup path so stale resident entries do not keep consuming capacity. - Update tool planning and handler tests for the new v2 surface and semantics. ## Verification Added focused coverage in: - `core/src/tools/spec_plan_tests.rs` - `core/src/tools/handlers/multi_agents_tests.rs`
jif ·
2026-06-08 14:46:35 +02:00 -
feat: count V2 concurrency by active execution (#26969)
## Why Multi-Agent V2 concurrency should count active non-root turns, not resident or durable agent threads. The limit is intentionally best effort: admission checks are synchronous, but concurrent successful checks may overshoot slightly. ## What changed - Keep one root-derived execution limit on the shared `AgentControl`. - Count active V2 subagent turns with an RAII guard owned by `RunningTask`. - Check capacity before spawning or starting an idle agent, including direct app-server `turn/start` submissions. - Preserve queued delivery for agents that are already running. - Exempt automatic idle continuations so `/goal` work is not dropped when capacity is temporarily full. - Keep root and V1 turns outside this limiter. ## Test coverage - `execution_guards_count_active_v2_subagent_turns` - `execution_guards_ignore_root_and_v1_turns` - `v2_nested_spawn_checks_shared_active_execution_capacity`
jif ·
2026-06-08 14:21:28 +02:00 -
feat: add v2 agent residency lru (#26632)
## Why Multi-agent v2 treats agents as durable logical agents, not just live entries in `ThreadManager`. After the reload-on-delivery change, a v2 agent can be addressed even if its thread is not currently loaded. This PR adds the next layer: loaded v2 subagents can be paged out of `ThreadManager` when the session has too many resident agents. That keeps residency separate from logical identity and prepares the stack for making v2 concurrency count active execution instead of existing agents. ## What Changed - Add an `AgentControl`-scoped LRU for resident v2 subagents. - Reserve residency before spawning or reloading a v2 subagent. - If resident capacity is full, unload the least-recently-used idle v2 subagent from `ThreadManager`. - Keep `ThreadManager` as a primitive loaded-thread store; it does not own the LRU policy. - Keep unloaded agents registered and durable so they can be reloaded by the delivery path. - Preserve the existing v2 cap semantics by using the derived non-root v2 cap for residency. Eviction is intentionally conservative. A thread is unloadable only when it is a v2 subagent, has completed or errored, has no active turn, and has no pending mailbox work. Before removal, the rollout is materialized and flushed. ## Assumptions And Non-Goals - PR #26623 provides the reload-on-delivery path for unloaded v2 agents. - `ThreadManager` membership means loaded/resident, not logical agent existence. - `AgentRegistry` remains the logical identity/metadata source for v2 agents that may be unloaded. - `list_agents` remains a recent/resident view for now. - This does not change active execution concurrency; that is the next PR. - This does not change `close_agent` semantics. - This does not change or remove `resume_agent`. - This does not add a new residency config knob. ## Stack 1. V2 durable lookup and reload on delivery (#26623) - reload unloaded v2 agents before delivering follow-up/input. 2. V2 residency LRU (this PR) - unload idle resident v2 agents from `ThreadManager` when resident capacity is full. 3. V2 active-execution concurrency - count running non-root v2 turns instead of logical agents. 4. V2 close/interrupt semantics - make v2 close interrupt the current turn without deleting durable identity. 5. V2 resume cleanup - remove the manual resume surface for v2 while keeping internal reload support. ## Validation - Added focused coverage for the residency LRU eviction path. - Local clippy/check/tests were not run; CI will cover them.
jif ·
2026-06-08 10:24:48 +02:00 -
fix: preserve approval sandbox decisions in unified exec (#24981)
## Why This PR fixes approval sandbox semantics in the unified-exec path. The zsh-fork runtime exposed the bug because the shell can do meaningful work before any intercepted child `execv(2)` exists: redirections, builtins, globbing, and pipeline setup all happen in the launch process. If the model requested `sandbox_permissions=require_escalated`, or an exec-policy `allow` rule explicitly bypassed the sandbox, that approved sandbox decision needs to be preserved for the launch path and for intercepted execs that use the same approval machinery. The behavior is not only about zsh fork. The production changes are in shared approval/escalation code, so they also affect non-zsh-fork intercepted exec paths that go through the same sandbox decision logic. The narrow intent is to preserve the approval decision while still keeping denied-read profiles and bounded additional-permission requests sandboxed. ## Production Changes - `codex-rs/core/src/tools/runtimes/unified_exec.rs`: derives a `launch_sandbox_permissions` value from the requested sandbox permissions and the runtime filesystem policy, then uses that value for managed-network/env setup and launch sandbox selection. This keeps full approval or policy-bypass decisions visible to the first unified-exec attempt, while still preventing a full sandbox override from discarding denied-read restrictions. Direct unified exec keeps the same decision surface; the important difference is that zsh-fork launch setup no longer accidentally loses the approved parent sandbox decision. - `codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs`: makes intercepted-exec escalation selection explicit for the three sandbox permission modes. `UseDefault` only escalates when an exec-policy decision allows sandbox bypass, `RequireEscalated` escalates when unsandboxed execution is allowed, and `WithAdditionalPermissions` escalates through the bounded additional-permissions path instead of being treated as a full unsandboxed override. Unsandboxed intercepted execs now also rebuild the environment as `RequireEscalated`, which strips managed-network proxy variables consistently with other unsandboxed execution. ## Test Coverage Most of the PR is tests. The new coverage verifies: - unified exec preserves parent approval and exec-policy sandbox decisions for zsh-fork launch selection; - bounded `with_additional_permissions` remains sandboxed and permission-profile based; - denied-read profiles are not weakened by parent approval; - explicit prompt rules still prompt for intercepted execs after the parent command is approved; - unsandboxed intercepted execs strip managed-network env vars. No documentation update is needed; this is an internal approval/sandbox correctness fix. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/24981). * #24982 * __->__ #24981
Michael Bolin ·
2026-06-07 11:33:16 -07:00 -
permissions: enforce managed permission profile allowlists (#24852)
## Why Permission profile allowlists are an enterprise security boundary, but they also need to compose across the managed requirements layers added in #24620. A map representation lets each requirements layer add, allow, or revoke individual profiles without replacing an entire array. ## Managed Contract Administrators configure the mergeable allow map with `allowed_permission_profiles`. A recommended enterprise configuration explicitly lists every built-in and custom profile users should be able to select: ```toml default_permissions = "review_only" [allowed_permission_profiles] ":read-only" = true ":workspace" = true review_only = true # ":danger-full-access" is intentionally omitted, so it is denied. [permissions.review_only] extends = ":read-only" ``` - Profiles whose effective merged value is `true` are allowed. - Missing profiles and profiles set to `false` are denied. - This is a closed allowlist: built-in profiles and profiles introduced in future versions are denied unless explicitly allowed. - Explicitly list each built-in profile the enterprise wants to make available. Omit built-ins such as `:danger-full-access` when they should remain unavailable. - Set `default_permissions` explicitly to the allowed profile users should receive when they have no local selection. - Higher-precedence layers override only the profile keys they define. - `false` is only needed when a higher-precedence layer must revoke a `true` inherited from a lower layer. - Explicit keys must refer to known built-in or managed profiles. A custom or narrowed allowlist requires an allowed `default_permissions`. For compatibility, if both `:workspace` and `:read-only` are explicitly allowed, an omitted default resolves to `:workspace`; customer configurations should still set the intended default explicitly. When `allowed_permission_profiles` is absent, existing implicit permission and legacy `sandbox_mode` behavior is unchanged. ## What Changed - Add `allowed_permission_profiles` as a `BTreeMap<String, bool>` that merges per profile across requirements layers. - Enforce managed defaults, strict denial of omitted profiles, and the explicitly allowed standard-pair fallback. - Expose `allowedPermissionProfiles` through `configRequirements/read` and regenerate its schemas. - Add regression coverage for map composition and revocation, managed defaults, strict denial of omitted built-ins, and API output. ## Verification - Focused `codex-config` coverage for layered map composition and revocation - Focused `codex-core` coverage for managed defaults, invalid defaults, strict denial of omitted built-ins, and the standard built-in pair - Focused `codex-app-server` coverage for requirements API output - Scoped Clippy for `codex-config`, `codex-core`, `codex-app-server-protocol`, and `codex-app-server` ## Documentation The managed `requirements.toml` documentation should introduce `allowed_permission_profiles` as a closed permission-profile allowlist before this setting is published on developers.openai.com. --------- Co-authored-by: Codex <noreply@openai.com>
viyatb-oai ·
2026-06-05 18:06:29 -07:00 -
[codex] Send Responses Lite transport header (#26542)
## Summary - send `X-OpenAI-Internal-Codex-Responses-Lite: true` on HTTP Responses requests and WebSocket upgrade requests when model metadata enables Responses Lite - use client metadata when sending it over the websocket This PR is stacked on #26490. ## Why The Responses Lite marker is request-scoped for HTTP but connection-scoped for Responses-over-WebSocket because it is carried on the upgrade request. Reusing a cached socket opened for the opposite mode would therefore send the wrong transport contract. ## Validation - `just test -p codex-core responses_lite` - `just test -p codex-core responses_websocket_reconnects_when_responses_lite_mode_changes` - `just fix -p codex-core` - `just fmt`
rka-oai ·
2026-06-06 01:01:20 +00:00 -
[codex-rs] support v2 personal access tokens (#25731)
## Summary - add v2 personal access token support for `codex login --with-access-token` and `CODEX_ACCESS_TOKEN` - classify opaque `at-` tokens separately from legacy Agent Identity JWTs - hydrate required ChatGPT account metadata through AuthAPI `/v1/user-auth-credential/whoami` - use PATs directly as bearer tokens while preserving existing ChatGPT account surfaces - expose PAT-backed auth as the explicit `personalAccessToken` app-server auth mode ## Implementation PAT auth is intentionally small and stateless. Loading a PAT performs one AuthAPI metadata request, stores the hydrated metadata in the in-memory auth object, and redacts the secret from debug output. Legacy Agent Identity JWT handling remains unchanged. The shared access-token classifier lives in a private neutral module because it dispatches between both credential types. PAT hydration fails closed when AuthAPI omits any required metadata, including email. Hydrated metadata is intentionally not persisted: startup performs a live `whoami` preflight so revoked tokens or changed account metadata are not accepted from a stale cache. ## Workspace restriction scope This change intentionally does **not** apply `forced_chatgpt_workspace_id` to PAT authentication. The setting is a client-side config guardrail, not an authorization boundary, and PAT does not currently require workspace-ID parity. The PAT login and `CODEX_ACCESS_TOKEN` paths therefore validate through AuthAPI without threading workspace-restriction state through access-token loading. Existing workspace checks for non-PAT auth remain on their established paths. ## App-server compatibility The public app-server `AuthMode` is shared across v1 and v2, and PAT-backed auth reports `personalAccessToken` through both APIs. Following human review, this intentionally removes the temporary v1 compatibility mapping that reported PATs as `chatgpt`; the deprecated v1 API is kept in parity with v2 rather than maintaining a separate closed enum. Clients with exhaustive auth-mode handling in either API version must add the new case and should generally treat it as ChatGPT-backed unless they need PAT-specific behavior. The v1 auth-status response still omits the raw PAT when `includeToken` is requested because that response cannot carry the account metadata needed to reuse the credential safely. Persisted PAT auth also omits the new enum value so older Codex builds can deserialize `auth.json` and infer PAT auth from the credential field after a rollback. ## Validation Latest review-fix validation: - `CARGO_INCREMENTAL=0 just test -p codex-login` (126 passed) - `CARGO_INCREMENTAL=0 just test -p codex-cli` (263 passed) - `CARGO_INCREMENTAL=0 just test -p codex-cli stored_auth_validation_handles_personal_access_token` - `CARGO_INCREMENTAL=0 just test -p codex-app-server-protocol` (226 passed) - `CARGO_INCREMENTAL=0 just test -p codex-models-manager refresh_available_models_uses_remote_only_catalog_for_chatgpt_auth` - `CARGO_INCREMENTAL=0 just test -p codex-tui existing_non_oauth_chatgpt_login_counts_as_signed_in` - `CARGO_INCREMENTAL=0 just fix -p codex-login -p codex-app-server-protocol -p codex-models-manager -p codex-tui -p codex-cli` - `just fmt` - `git diff --check` The broader `codex-tui` suite previously compiled and ran 2,834 tests. Three unrelated environment-sensitive guardian/IDE-socket tests failed after retries; the PAT-relevant TUI coverage passed.
cooper-oai ·
2026-06-05 17:36:18 -07:00 -
[codex] Use standalone tools for Responses Lite (#26490)
## Summary Responses Lite does not execute hosted Responses tools, so models using it must route web search and image generation through Codex-owned executors & standalone Response's API endpoints. This PR is stacked on #26487. ## Validation - `cargo test -p codex-core responses_lite_ --lib` - `cargo test -p codex-core standalone_executors_remain_hidden_without_flags_or_responses_lite --lib` - `cargo test -p codex-core hosted_tools_follow_provider_auth_model_and_config_gates --lib` - `cargo test -p codex-web-search-extension -p codex-image-generation-extension` - `cargo test -p codex-app-server --test all standalone_` - `cargo fmt --all -- --check`
rka-oai ·
2026-06-06 00:23:40 +00:00 -
[2 of 2] Finish moving goal runtime to extension (#26548)
## Stack 1. [#26547](https://github.com/openai/codex/pull/26547) - [1 of 2] Align goal extension with core behavior 2. [#26548](https://github.com/openai/codex/pull/26548) - [2 of 2] Move goal runtime to extension ## Why This PR completes the switch of the goal behavior to the extension-backed runtime and removes the old core goal implementation. ## What Changed - Installs the goal extension for app-server `ThreadManager` sessions. - Routes app-server thread goal `get`, `set`, and `clear` through `GoalService`. - Uses thread-idle lifecycle emission after goal resume and snapshot ordering so the extension can decide whether to continue the goal. - Forwards extension goal updates through a FIFO async app-server notification path so backpressure does not drop them or reorder updates. - Keeps review turns from enabling goal runtime behavior. - Plans extension tools before dynamic tools so built-in goal tool names keep their old precedence when goals are enabled. - Removes the old core goal runtime, core goal tool handlers, and core goal tool specs. - Updates tests that were coupled to the core-owned goal runtime while leaving the legacy `<goal_context>` compatibility path in core for old threads. - Removes the stale cargo-shear ignore now that `codex-goal-extension` is used by the workspace. - Keeps realtime event matching exhaustive after removing the old goal-specific realtime text path. ## Validation - Ran manual `/goal` runs in TUI. Validated time accounting matched wall-clock time and goal lifecycle state transitions.
Eric Traut ·
2026-06-05 14:17:30 -07:00 -
Make runtime workspace roots absolute in app-server API (#26552)
Stacked on #26532. ## Why #26532 moves cwd normalization to the app-server/core boundary. `runtimeWorkspaceRoots` still accepted raw paths in v2 requests and in `ConfigOverrides`, which left core responsible for interpreting those roots later. This makes runtime workspace roots follow the same absolute-path boundary as cwd. ## What - Change v2 `runtimeWorkspaceRoots` request fields for `thread/start`, `thread/resume`, `thread/fork`, and `turn/start` to `AbsolutePathBuf`. - Deduplicate already-absolute runtime roots in app-server handlers and pass them through `ConfigOverrides.workspace_roots` as `AbsolutePathBuf`. - Update TUI and exec client request builders to pass absolute runtime roots directly. - Update app-server docs, schema fixtures, and focused tests for absolute runtime roots. ## Testing - `just test -p codex-app-server-protocol` - `just test -p codex-app-server runtime_workspace_roots` - `just test -p codex-core session_permission_profile_rebinds_runtime_workspace_roots` - `just test -p codex-tui app_server_session` - `just test -p codex-exec`
pakrym-oai ·
2026-06-05 11:36:53 -07:00 -
[codex] Add turn profiling analytics (#26484)
## Summary Add flat profiling fields to `codex_turn_event` so analytics can explain where turn wall-clock time is spent without changing tool execution behavior. The profile reports: - time before the first sampling request - sampling time across all attempts and follow-ups - overhead between sampling requests - time blocked in the post-sampling tool drain - time after the final sampling request - sampling request and retry counts ## Implementation - Extend the existing turn timing state with constant-memory phase accounting and one RAII phase guard. - Observe sampling and the existing post-sampling drain only at turn orchestration boundaries. - Keep tool runtime, tool futures, response item handling, and turn lifecycle values unchanged. - Add the profiling fields directly to the existing analytics turn event without changing app-server protocol or rollout persistence. - Use the existing turn `status` to distinguish completed, failed, and interrupted profiles. Exact sampling/tool overlap is intentionally omitted because measuring tool completion accurately would require hooks in the tool execution path. ## Validation - Add app-server end-to-end coverage for a single-sampling turn with no blocking tool work. - Add app-server end-to-end coverage for `request_user_input` blocking followed by a second sampling request. - CI is running on the PR; tests were not executed locally per repository guidance.
Ahmed Ibrahim ·
2026-06-05 11:27:10 -07:00 -
[codex] Respect Windows sandbox backend in exec policy (#26307)
## Why Windows managed filesystem permissions can now be backed by a real Windows sandbox. `exec-policy` was still treating the managed read-only policy shape as if there were never a sandbox backend, so benign unmatched commands such as PowerShell directory listings could be rejected with `blocked by policy` even when `windows.sandbox` was enabled. The inverse case still needs to stay conservative: when the Windows sandbox backend is disabled, managed filesystem restrictions are only configuration intent, not an enforced filesystem boundary. That applies to writable-root restricted profiles too, not just read-only profiles. ## What Changed - Thread the effective `WindowsSandboxLevel` into exec-policy approval decisions for shell, unified exec, and intercepted shell exec paths. - Treat managed restricted filesystem profiles as lacking sandbox protection only on Windows when `WindowsSandboxLevel::Disabled`. - Exclude full-disk-write profiles from that no-backend path because they do not rely on filesystem sandbox enforcement. - Remove the cwd-sensitive read-only heuristic and the now-stale cwd plumbing from exec-policy approval contexts. - Add Windows coverage for both enabled-sandbox and disabled-backend behavior, including a writable-root managed profile. ## Validation - Added/updated `exec_policy` coverage for managed filesystem restrictions, full-disk-write exclusion, enabled Windows sandbox behavior, and disabled-backend read-only/writable-root behavior. - `just test -p codex-core exec_policy` — 100 passed, 10 leaky - Empirical local `codex exec` probe with `--sandbox read-only -c 'windows.sandbox="unelevated"'`: PowerShell directory listing completed successfully. - Disabled-backend control with Windows sandbox cleared: the same command was rejected with `blocked by policy`.
iceweasel-oai ·
2026-06-05 11:20:52 -07:00 -
Make turn diff tracker multi-env aware (#26433)
## Why Turn diffs were tracked as one flat set of absolute paths. In multi-environment turns, local and remote environments can report the same path while representing different filesystems, so a single path key can collapse distinct changes or attribute them to the wrong environment. The environment name is **NOT** included in the generated unified diff. This can come later.
pakrym-oai ·
2026-06-05 17:31:22 +00:00 -
Require absolute cwd in thread settings (#26532)
## Why Thread settings cwd overrides are expected to be resolved before they enter core. Keeping this boundary as a plain `PathBuf` made it easy for core/session code to keep fallback normalization and relative-path resolution logic in places that should only receive an already-resolved cwd. This is intentionally the absolute-cwd-only slice: it does not change environment selection stickiness or cwd-to-default-environment fallback behavior. ## What changed - Changes `ThreadSettingsOverrides.cwd`, `CodexThreadSettingsOverrides.cwd`, and `SessionSettingsUpdate.cwd` to use `AbsolutePathBuf`. - Removes core-side cwd normalization/resolution from session settings updates. - Updates affected core/app-server test helpers and callsites to pass existing absolute cwd values or use `abs()` helpers. ## Validation Opening as draft so CI can start while local validation continues.
pakrym-oai ·
2026-06-05 09:29:15 -07:00 -
feat: reload v2 agents on delivery (#26623)
## Summary This is the first small step toward making multi-agent v2 agents durable logical agents whose `ThreadManager` residency is only an implementation detail. This PR adds a narrow v2 reload-on-delivery hook: - If a known v2 agent target is already loaded, delivery is unchanged. - If the target is still registered but missing from `ThreadManager`, delivery reloads that exact v2 thread from durable rollout history before submitting the message. - If the target is unknown, closed, missing from storage, or not a v2 thread, delivery still fails as not found. The reload is wired only into existing-agent delivery paths: v2 `send_message` / `followup_task`, and legacy `send_input` when its target is a known v2 agent. ## Stack 1. **Reload on delivery**: load known unloaded v2 agents before `followup_task`, `send_message`, or `send_input` delivery. This PR. 2. **Residency LRU**: unload idle resident v2 agents from `ThreadManager` without making them closed or unreachable. 3. **Execution concurrency**: count active non-root turns, not logical agents or resident idle threads. 4. **Close semantics**: make v2 close interrupt-only and leave durable agent identity intact. 5. **Resume cleanup**: remove user-facing v2 resume semantics; addressing an unloaded durable agent reloads it implicitly. ## Validation - Ran `just fmt`. - Left broader tests and clippy to CI.
jif ·
2026-06-05 18:18:29 +02:00 -
refactor: split agent control modules (#26610)
## Summary Mechanically splits `AgentControl` into focused modules so later agent runtime changes are easier to review. The shared lookup, messaging, and completion logic remains in `control.rs`, while spawn-specific code and V1 legacy close/resume behavior move into dedicated files. ## Changes - Extract spawn-agent code into `agent/control/spawn.rs`. - Extract V1-only legacy close/resume behavior into `agent/control/legacy.rs`. - Keep shared control-plane behavior in `agent/control.rs`. - Preserve existing behavior; this PR is intended to be mechanical. ## Stack 1. This PR - Mechanical `AgentControl` split: extracts spawn and V1 legacy code without behavior changes. 2. #26614 - Execution slot accounting: separates logical agents from active execution slots. 3. #26611 - Residency and reload runtime: adds resident-agent LRU, eviction/reload, durable lookup, and V2 delivery through reload. 4. #26612 - V2 tool semantics: narrows `close_agent` to interrupt-only and updates V2 tool coverage.
jif ·
2026-06-05 16:24:22 +02:00 -
[codex] Keep v1 spawn metadata visible (#26599)
## Summary - keep the legacy v1 `spawn_agent` role and model selectors visible - add regression coverage for the default v1 tool plan ## Why `hide_spawn_agent_metadata` is a multi-agent v2 setting, but the v1 planning branch also consumed it. After the default changed to `true`, v1 stopped advertising `agent_type`, `model`, `reasoning_effort`, and `service_tier`, preventing configured agents from being selected. This keeps the hidden-metadata default for v2 while opting v1 out of that behavior. Fixes #26363. ## Validation Not run locally, per request; CI will validate the change.
jif ·
2026-06-05 14:52:51 +02:00 -
[codex] Forward turn moderation metadata through app-server (#25710)
## Why First-party backends can supply turn-scoped moderation metadata that app-server clients need for client-side presentation. Exposing this as an experimental typed notification lets opted-in clients consume it without interpreting raw Responses API events. ## What changed - forward `response.metadata.openai_chatgpt_moderation_metadata` from Responses API SSE and WebSocket streams as turn-scoped moderation metadata - emit the experimental app-server v2 `turn/moderationMetadata` notification with `{ threadId, turnId, metadata }` - add app-server integration coverage for the typed moderation metadata notification ## Testing - `just test -p codex-core build_ws_client_metadata_includes_window_lineage_and_turn_metadata` - `just test -p codex-core` (fails locally: 46 failures and 1 timeout, primarily missing `test_stdio_server` and shell snapshot timeouts) - `just test -p codex-app-server-protocol` - `just test -p codex-app-server turn_moderation_metadata_emits_typed_notification_v2` - `just test -p codex-app-server` (fails locally: 792 passed, 10 failed, and 5 timed out; failures are in existing environment-sensitive tests, primarily because nested macOS `sandbox-exec` is not permitted) - `just write-app-server-schema --experimental --schema-root /tmp/codex-app-server-schema-experimental`carlc-oai ·
2026-06-05 02:41:06 -07:00 -
nit: doc (#26566)
Matching CBv9
jif ·
2026-06-05 11:10:32 +02:00 -
Encrypt multi-agent v2 message payloads (#26210)
## Why Multi-agent v2 currently routes agent instructions through normal tool arguments and inter-agent context. That means the parent model can emit plaintext task text, Codex can persist it in history/rollouts, and the recipient can receive it as ordinary assistant-message JSON. This changes the v2 path so agent instructions stay encrypted between model calls: Responses encrypts the `message` argument returned by the model, Codex forwards only that ciphertext, and Responses decrypts it internally for the recipient model. ## What changed - Mark the v2 `message` parameter as encrypted for `spawn_agent`, `send_message`, and `followup_task`. - Treat multi-agent v2 tool `message` values as ciphertext unconditionally. - Store v2 inter-agent task text in `InterAgentCommunication.encrypted_content` with empty plaintext `content`. - Convert encrypted inter-agent communications into the Responses `agent_message` input item before sending the child request. - Preserve `agent_message` items across history, rollout, compaction, telemetry, and app-server schema paths. - Leave multi-agent v1 unchanged. ## Message shape The model still calls the v2 tools with a `message` argument, but that value is now ciphertext: ```json { "name": "spawn_agent", "arguments": { "task_name": "worker", "message": "<ciphertext>" } } ``` Codex stores the task as encrypted inter-agent communication: ```json { "author": "/root", "recipient": "/root/worker", "content": "", "encrypted_content": "<ciphertext>", "trigger_turn": true } ``` When Codex builds the recipient request, it forwards the ciphertext using the new Responses input item: ```json { "type": "agent_message", "author": "/root", "recipient": "/root/worker", "content": [ { "type": "encrypted_content", "encrypted_content": "<ciphertext>" } ] } ``` Responses decrypts that item internally for the recipient model. ## Context impact - Parent context no longer carries plaintext v2 agent task instructions from these tool arguments. - Codex rollout/history stores ciphertext for v2 agent instructions. - Recipient requests receive an `agent_message` item instead of assistant commentary JSON for encrypted task delivery. - Plaintext completion/status notifications are still plaintext because they are Codex-generated status messages, not encrypted model tool arguments. ## Validation - `just test -p codex-tools` - `just test -p codex-protocol` - `just test -p codex-rollout` - `just test -p codex-rollout-trace` - `just test -p codex-otel` - `just write-app-server-schema`jif ·
2026-06-05 10:25:57 +02:00 -
[codex] Add environment shell info (#26480)
## Why Shell detection needs to be available through the `Environment` abstraction so callers can ask the selected local or remote environment for shell metadata without adding a separate HTTP endpoint or parallel info-source path. This keeps shell metadata shaped like the existing environment-owned filesystem capability and lets remote environments answer through exec-server JSON-RPC. ## What changed - Added `environment/info` to the exec-server protocol/client/server and exposed `Environment::info()`. - Added local and remote environment info providers on `Environment`, following the existing capability-provider pattern used for filesystem access. - Moved the shared shell detection logic into `codex-shell-command` and kept core shell APIs as wrappers around that implementation. - Returned shell metadata as `EnvironmentInfo { shell: ShellInfo }` using the existing shell detection path. - Added a remote environment test that calls `Environment::info()` through an exec-server-backed environment. ## Validation - `git diff --check` - `just test -p codex-shell-command` - `just test -p codex-core -E 'test(/shell::tests::/)'`\n- `just test -p codex-exec-server environment`pakrym-oai ·
2026-06-04 22:36:25 -07:00 -
core: derive exec policy filesystem policy from profile (#26499)
## Why `PermissionProfile` already owns the runtime filesystem sandbox policy through `file_system_sandbox_policy()`. Keeping a separate `FileSystemSandboxPolicy` on exec-policy fallback contexts made it possible for callers and tests to construct split states that the production permission model should not rely on. ## What changed - Removed `file_system_sandbox_policy` from `UnmatchedCommandContext`, `ExecApprovalRequest`, and the intercepted Unix exec-policy context. - Derived filesystem sandbox policy inside unmatched-command decision logic from `PermissionProfile::file_system_sandbox_policy()`. - Simplified shell/unified-exec callers and tests that were only plumbing the duplicate policy through. ## Testing Local tests not run per request; relying on remote CI.
Michael Bolin ·
2026-06-04 21:48:45 -07:00 -
[codex] Add use_responses_lite 'override' logic (#26487)
## Summary - add a defaulted `ModelInfo.use_responses_lite` catalog field - support serializing `reasoning.context` while preserving the existing effort and summary path - has not been turned on for any models yet I've added an override to parallel tools if responses_lite is on. I've also forced persistent reasoning when using responses_lite. It would be ideal if we could centralize all the responses_lite plumbing, but I think this is best for now to keep the plumbing & diffs small. ## Testing - `cargo test -p codex-protocol model_info_defaults_availability_nux_to_none_when_omitted` - `RUST_MIN_STACK=8388608 cargo test -p codex-core responses_lite_sets_all_turns_context_and_disables_parallel_tool_calls` - `RUST_MIN_STACK=8388608 cargo test -p codex-core configured_reasoning_summary_is_sent` - `cargo check -p codex-core --tests` - `RUST_MIN_STACK=8388608 cargo clippy -p codex-core --tests` (passes with pre-existing warnings in `codex-code-mode` and `codex-core-plugins`)
rka-oai ·
2026-06-04 18:49:51 -07:00 -
[codex] Emit sandbox outcome telemetry event (#25955)
## Summary Adds a dedicated `codex.sandbox_outcome` telemetry event so we can query sandbox edge outcomes without threading sandbox metadata through tool-result output types. This is meant to make sandbox failures and approved escalation retries visible in OTEL while keeping the existing `codex.tool_result` event shape focused on tool completion data. ## What changed - Adds `SessionTelemetry::sandbox_outcome(...)`, which emits `codex.sandbox_outcome` as both a log and trace event. - Records the tool name, call id, sandbox outcome, initial attempt duration, and escalated attempt duration when a retry runs. - Emits `denied` when the sandbox blocks execution and no retry is run. - Emits `timed_out` and `signal` when those sandbox errors surface from tool execution. - Emits `escalated` when the initial sandboxed attempt fails and the approved unsandboxed retry succeeds. - Adds OTEL coverage for the new event payload, including timing fields. ## Validation - `RUST_MIN_STACK=8388608 just test -p codex-core sandbox_outcome_event_records_outcome handle_sandbox_error_user_approves_retry_records_tool_decision` - `just test -p codex-otel otel_export_routing_policy_routes_tool_result_log_and_trace_events runtime_metrics_summary_collects_tool_api_and_streaming_metrics` - `just fix -p codex-core` - `just fix -p codex-otel`
rreichel3-oai ·
2026-06-04 20:58:14 -04:00 -
[codex] Preserve logical paths during AGENTS.md discovery (#26465)
## Intent Follow up on #26205 by avoiding unnecessary filesystem canonicalization during `AGENTS.md` discovery. The configured working directory is already absolute, and canonicalization incorrectly switches symlinked workspaces from their logical parent hierarchy to the target's hierarchy. ## User-facing behavior For a symlinked working directory such as: ```text test-root/ |-- logical-repo/ | |-- AGENTS.md ("logical parent doc") | `-- workspace ------------> physical-repo/workspace/ `-- physical-repo/ |-- AGENTS.md ("physical parent doc") `-- workspace/ `-- AGENTS.md ("workspace doc") ``` Before this change, Codex canonicalized `logical-repo/workspace` to `physical-repo/workspace` before discovery. It therefore loaded `physical-repo/AGENTS.md` and `physical-repo/workspace/AGENTS.md`, ignoring the instructions from the repository through which the user entered the workspace. After this change, ancestor discovery walks the configured logical path, so Codex loads `logical-repo/AGENTS.md`. Opening `logical-repo/workspace/AGENTS.md` still follows the symlink through the host filesystem, so the workspace document is also loaded. `physical-repo/AGENTS.md` is not loaded. ## Implementation Use the logical absolute working directory when discovering project instructions and reporting instruction sources. Filesystem reads still follow the working-directory symlink, so an `AGENTS.md` in the target workspace continues to load while ancestor discovery uses the symlink's parents. ## Validation Added integration coverage proving that discovery loads the logical parent's instructions and the target workspace's instructions, but not the target parent's instructions.
Adam Perry @ OpenAI ·
2026-06-04 15:08:52 -07:00 -
[codex] Support model-defined reasoning efforts (#26444)
## Summary - accept non-empty model-defined reasoning effort values while preserving built-in effort behavior - propagate the non-Copy effort type through core, app-server, TUI, telemetry, and persistence call sites - preserve string wire encoding and expose an open-string schema for clients - update model selection and shortcut behavior for model-advertised effort values ## Root cause `ReasoningEffort` gained a string-backed custom variant, so it could no longer implement `Copy` or rely on derived closed-enum serialization. Existing consumers still moved effort values from shared references and assumed a fixed built-in value set. ## Validation - `just fmt` - Local tests and compilation were not run per request; relying on CI.
Ahmed Ibrahim ·
2026-06-04 13:36:24 -07:00 -
Remove response.processed websocket request (#26447)
## Why The Responses websocket client no longer needs to send a follow-up `response.processed` request after a turn response has already been recorded. Keeping that extra acknowledgement path adds feature-gated control flow and a second websocket request shape that no longer carries useful behavior. ## What Changed - Removed the `response.processed` websocket request type and sender. - Removed the `responses_websocket_response_processed` feature flag and schema entry. - Removed turn and remote-compaction plumbing that only tracked response IDs to send the acknowledgement. - Removed tests that existed solely to cover the deleted feature path. ## Validation - `just fix -p codex-core -p codex-api -p codex-features`
pakrym-oai ·
2026-06-04 13:15:50 -07:00 -
Route AGENTS.md loading through environment filesystems (#26205)
## Why Workspace-specific `AGENTS.md` loading needs to use the selected environment filesystem so remote workspaces and child agents read instructions from their actual environment instead of the host filesystem. The app-server should report the same instruction sources the initialized thread actually loaded, rather than independently rescanning configuration and filesystem state. ## What changed - Introduce `LoadedAgentsMd` to retain ordered user, project, and internal instructions with their provenance. - Load and canonicalize workspace `AGENTS.md` paths through the primary `EnvironmentManager` environment, then render the loaded instructions when constructing turn context. - Expose cached loaded instruction sources from initialized threads and use them for app-server start, resume, and fork responses. - Preserve global `CODEX_HOME` loading and separator behavior while excluding empty project files that did not supply model-visible instructions. - Add integration coverage for CLI injection, selected-environment provenance and rendering, empty environment selection, and cached sources on loaded-thread resume. ## Validation - `just test -p codex-core agents_md` - `just test -p codex-core selected_environment_sources_match_model_visible_instructions` - `just test -p codex-exec agents_md` - `just test -p codex-app-server instruction_sources` - `just test -p codex-app-server --status-level fail`
Adam Perry @ OpenAI ·
2026-06-04 12:43:07 -07:00 -
core: allow excluding tool namespaces from code mode (#26320)
## Why Research and training setups need to control which tool namespaces appear inside code mode's nested `tools` surface without disabling those tools entirely. This makes it possible to train against a deliberately reduced nested-tool setup while preserving the normal direct and deferred tool paths. ## What - Extend `features.code_mode` to accept structured configuration while preserving the existing boolean syntax. - Add an exact `excluded_tool_namespaces` list under `[features.code_mode]`: ```toml [features.code_mode] enabled = true excluded_tool_namespaces = ["mcp__codex_apps", "multi_agent_v1"] ``` - Filter matching canonical `ToolName` namespaces when constructing code mode's nested router and code-mode-specific direct tool descriptions. - Keep excluded tools registered, directly exposed in mixed code mode, and discoverable through top-level `tool_search` when otherwise eligible. - Derive deferred nested-tool guidance after namespace filtering so the `exec` description does not advertise excluded-only deferred tools. - Preserve the boolean/table representation when materializing config locks and update the generated config schema. ## Testing - `just test -p codex-features` - `just test -p codex-config` - `just test -p codex-core load_config_resolves_code_mode_config` - `just test -p codex-core lock_contains_prompts_and_materializes_features` - `just test -p codex-core excluded_deferred_namespaces_do_not_enable_nested_tool_guidance` - `just test -p codex-core code_mode_excludes_configured_nested_tool_namespaces` - `cargo check -p codex-thread-manager-sample`
sayan-oai ·
2026-06-04 18:40:18 +00:00 -
[codex-analytics] emit forked thread id on initialization (#26248)
## Why - Thread initialization analytics do not identify the source thread for forked threads. - The session viewer needs this lineage to construct thread trees. - Depends on openai/openai#987854. Do not release this change before that backend schema change is deployed. ## What Changed - Adds optional `forked_from_thread_id` to `codex_thread_initialized`. - Populates it from the existing thread fork lineage for app-server and in-process subagent initialization paths. - Keeps it null for non-forked threads. ## Verification - `just fmt` - `just test -p codex-analytics` - `just test -p codex-app-server thread_fork_tracks_thread_initialized_analytics`
kbazzi ·
2026-06-04 11:24:12 -07:00 -
Add saved image path hint to standalone image generation (#25947)
## Why Standalone image generation returns image bytes to the model, but the model also needs the host artifact path to reference the generated file in follow-up work. ## What changed - Append the default saved-image path hint alongside the generated image tool output. - Reuse the existing core image-generation hint text. - Pass the thread ID and Codex home directory needed to compute the artifact path. - Add app-server and extension coverage for the model-visible hint. ## Validation - `just fmt` - `just bazel-lock-check` - `just test -p codex-app-server standalone_image_generation_returns_saved_path_hint_to_model`
Won Park ·
2026-06-04 09:39:20 -07:00 -
Bridge host-loaded skills into the skills extension (#26172)
## Why The skills extension needs to become the path that exposes local host skills without losing the behavior already owned by core skill loading. Host skill discovery is not just `$CODEX_HOME/skills`: it also includes config layers, bundled-skill settings, plugin roots, runtime extra roots, and the filesystem for the selected primary environment. Rather than making the extension reload host skills and risk drifting from that authoritative load, this PR bridges the already-loaded per-turn skills outcome into the extension. That lets the extension advertise host skills and inject explicit `$skill` prompts while preserving the same roots, disabled/hidden state, rendered paths, and environment-backed file reads that the legacy path uses. ## What Changed - Adds `HostLoadedSkills` in `core-skills` to wrap the turn's `SkillLoadOutcome` and read `SKILL.md` through the filesystem that loaded that skill. - Stores `HostLoadedSkills` in turn extension data for normal turns and review turns, so the skills extension can consume the loaded host catalog without reloading it. - Adds `HostSkillProvider` under `ext/skills/src/provider/host.rs`, mapping host-loaded skill metadata into the skills-extension catalog/read contract. - Registers the host provider by default from `codex_skills_extension::install()`. - Preserves host skill metadata such as dependencies, disabled state, hidden-from-prompt policy, and slash-normalized display paths. - Passes host-loaded skills through `SkillListQuery` and `SkillReadRequest` so explicit skill invocation reads only resources from the loaded host catalog. - Adds integration coverage for a real legacy `$CODEX_HOME/skills/.../SKILL.md` skill being listed and injected through the installed extension. ## Testing - Added `installed_extension_loads_host_skills_from_legacy_roots` in `ext/skills/tests/skills_extension.rs`. - `just test -p codex-skills-extension`
jif ·
2026-06-04 15:28:06 +02:00 -
Gate automatic idle turns in Plan mode (#26147)
## Why Goal idle continuation is extension-triggered model-visible work, so it should follow one core-owned rule for when automatic work may start. In particular, it should not jump ahead of queued user/client work, start while another task is active, or inject a continuation turn while the thread is in Plan mode. Keeping this policy in `try_start_turn_if_idle` avoids passing `collaboration_mode` or review-specific state through `ThreadLifecycleContributor::on_thread_idle`. Active `/review` is covered by the same active-task gate because Review turns are not steerable. ## What Changed - Teach `Session::try_start_turn_if_idle` to reject automatic idle turns in Plan mode, both before reserving an idle turn and after building the turn context. - Document `CodexThread::try_start_turn_if_idle` as the extension-facing gate for automatic idle work, including Plan-mode and active Review-task behavior. - Add focused coverage for Plan-mode rejection and active Review-task rejection without queuing synthetic input. ## Testing - `just test -p codex-core try_start_turn_if_idle`
jif ·
2026-06-04 14:44:45 +02:00 -
chore: calm down (#26367)
Prompt update to address feedback
jif ·
2026-06-04 12:46:02 +02:00 -
[codex-analytics] report compaction request token counts (#25946)
## Why Compaction analytics need token counts that better represent the request being compacted. The existing session snapshot can diverge from the actual remote compaction request after output rewriting, and remote v2 can use server-side Responses usage when available. ## What changed - Add an optional `active_context_tokens_before` override to `CompactionAnalyticsAttempt::track(...)` for remote compaction when it has a better before-token value than the begin-time session snapshot. The local `/compact` path passes no override. - For remote v1 `responses_compact`, subtract the estimated token delta from pre-compaction output rewriting from the session snapshot, capped by locally-added tokens since the last successful API response. - For remote v2 `responses_compaction_v2`, use the same bounded output-rewrite fallback as remote v1, then overwrite `active_context_tokens_before` with server `token_usage.input_tokens` from the `response.completed` event when present. - Keep the existing v2 compaction-output validation while carrying the completed response token usage through `collect_compaction_output`. ## Verification - `just fmt` - `just test -p codex-core collect_compaction_output_accepts_additional_output_items` - `git diff --check`
rhan-oai ·
2026-06-04 03:00:44 +00:00 -
cli: add package path from install context (#26189)
## Why Codex package installs include helper binaries in `codex-path`, such as the bundled `rg`. Package-layout launches should add that directory before user commands run, but standalone launches were missing it while npm launches only worked because `codex.js` had its own legacy `PATH` rewrite. That made npm and standalone package behavior diverge. Shell snapshot restoration can also reset `PATH` after runtime setup. Any package-owned `PATH` prepend has to be recorded as an explicit runtime override so shells, unified exec, and user-shell commands keep access to `codex-path` after a snapshot is sourced. ## Repro Before this change, a curl-installed package could contain `rg` under `codex-path` but still fail to put it on `PATH`: ```shell mkdir /tmp/test-codex-curl curl -fsSL https://chatgpt.com/codex/install.sh \ | CODEX_HOME=/tmp/test-codex-curl CODEX_NON_INTERACTIVE=1 sh /tmp/test-codex-curl/packages/standalone/current/bin/codex exec \ --skip-git-repo-check 'print `which -a rg`' find /tmp/test-codex-curl -name rg ``` The `which -a rg` output omitted the packaged helper even though `find` showed it under `/tmp/test-codex-curl/packages/standalone/releases/.../codex-path/rg`. The npm install path behaved differently only because `codex-cli/bin/codex.js` had legacy `PATH` rewriting: ```shell mkdir /tmp/test-codex-npm cd /tmp/test-codex-npm npm install @openai/codex ./node_modules/.bin/codex exec --skip-git-repo-check 'print `which -a rg`' ``` That printed the npm package's `vendor/<target>/codex-path/rg` first. This PR moves that behavior into Rust-side package launch setup so curl/standalone and npm/bun launches agree without JS rewriting `PATH`. ## What Changed - `codex-rs/arg0` now uses `InstallContext::current().package_layout.path_dir` to prepend the package helper directory before any threads are created. - Package helper `PATH` setup is independent from the temporary arg0 alias setup, so `codex-path` is still added even if CODEX_HOME tempdir, lock, or symlink setup fails. - `codex-rs/install-context` detects the canonical package layout we ship: `bin/`, `codex-resources/`, and `codex-path/` next to `codex-package.json`. - Shell, local unified exec, and user-shell runtimes now record package `codex-path` prepends in `explicit_env_overrides`, matching the existing zsh-fork behavior so shell snapshots cannot restore over the package helper path. - Remote unified exec requests do not receive the local app-server package path overlay. - `codex-cli/bin/codex.js` no longer computes or overrides `PATH`; it only locates the native binary in the canonical package layout and passes npm/bun management metadata. - Added regression tests for `PATH` ordering, package layout detection, and shell snapshot preservation of package path prepends. ## Verification - `node --check codex-cli/bin/codex.js` - `just test -p codex-install-context -p codex-arg0` - `just test -p codex-core user_shell_snapshot_preserves_package_path_prepend` - `just test -p codex-core tools::runtimes::tests` - `just bazel-lock-update` - `just bazel-lock-check` - `just fix -p codex-install-context -p codex-arg0 -p codex-core`
Michael Bolin ·
2026-06-03 19:08:19 -07:00 -
Rewrite oversized tool outputs during remote compaction (#26251)
## Why When trying to fit history under compaction limit rewrite output items instead of removing them entirely. Otherwise we're breaking incrementality in relation to the previous response.
pakrym-oai ·
2026-06-03 15:25:50 -07:00 -
feat: catalog multi-agent v2 config (#26254)
## Why Model metadata can now select multi-agent v2 even when a user has not enabled `features.multi_agent_v2` in their config. Some existing configs still set the legacy `agents.max_threads` knob for v1 multi-agent behavior, so treating every v2 runtime as incompatible with `agents.max_threads` would break users whose only v2 signal came from the model catalog. The incompatible configuration is specifically enabling `features.multi_agent_v2` while also setting `agents.max_threads`. Catalog-forced v2 should use the v2 concurrency setting and ignore the legacy v1 cap instead of rejecting the config. ## What changed - Split config validation from runtime concurrency calculation: `effective_agent_max_threads` now just returns the effective cap for the resolved multi-agent runtime. - Added explicit validation for `features.multi_agent_v2` + `agents.max_threads` at session startup. - Preserved catalog-selected v2 behavior when `features.multi_agent_v2` is disabled, so existing configs with `agents.max_threads` keep starting. - Updated model-runtime selector coverage so a catalog v2 model still exposes v2 tools even when `agents.max_threads` is set and the config flag is disabled. ## Validation - `cargo check -p codex-core --lib` - `just test -p codex-core --lib -E "test(multi_agent_v2_feature_rejects_agents_max_threads) | test(catalog_v2_allows_agents_max_threads_when_feature_disabled)"`
jif ·
2026-06-04 00:24:40 +02:00 -
Expose local image paths to models (#25944)
## Why Local image attachments include image bytes, but the adjacent model-visible label omits the source path. Exposing the path lets model-selected workflows refer back to the intended local image explicitly. ## What changed - Include an escaped `path` attribute in model-visible local image opening tags. - Reuse the path-aware marker generator in rollout coverage. - Update protocol, replay, and rollout coverage for the new request shape. ## Validation - `just fmt` - `just test -p codex-protocol` - `just test -p codex-core skips_local_image_label_text` - `just test -p codex-core copy_paste_local_image_persists_rollout_request_shape` - `git diff --check`
Won Park ·
2026-06-03 19:49:58 +00:00 -
core: stop threading SandboxPolicy through exec (#25700)
## Why #25450 attempts a broad `SandboxPolicy` removal across several unrelated surfaces, which makes it hard to review and still leaves new helper code moving legacy policies around. This PR is a narrower alternative: migrate only the exec-side Windows sandbox plumbing so the review can focus on one production path and one compatibility boundary. The goal is to stop threading `SandboxPolicy` through exec code without expanding the migration into app-server, protocol, telemetry, config, or session behavior. ## What changed - Removed `ExecRequest::compatibility_sandbox_policy()`. - Changed the Windows restricted-token and elevated filesystem override helpers to accept `PermissionProfile` plus the split filesystem/network policies instead of a `SandboxPolicy`. - Kept the remaining legacy projection local to the writable-root comparison that still needs to compare split policy behavior against the legacy Windows backend model. - Rejected restricted split filesystem policies that still grant full-disk writes before using the Windows restricted-token backend, preserving the previous clear-failure behavior for profiles that project to `ExternalSandbox`. - Updated the Windows sandbox override tests to exercise the new call shape and cover the full-write split-profile regression. ## Verification - `just test -p codex-core windows_restricted_token` - `just test -p codex-core windows_elevated`
Michael Bolin ·
2026-06-03 10:41:41 -07:00 -
feat: guard git enrichment (#26175)
Skip turn git metadata enrichment when a turn has remote or multiple executors, so we do not report the orchestrator checkout as executor workspace metadata. Test: `just test -p codex-core` (blocked by existing `Session::conversation_id` compile error in `close_agent.rs`).
jif ·
2026-06-03 18:36:10 +02:00 -
nit: small prompt update for MAv2 (#26179)
Simple prompt change for MAv2 because of OOD compared to CBv9
jif ·
2026-06-03 18:34:32 +02:00 -
jif ·
2026-06-03 16:47:34 +02:00 -
chore: mechanical rename (#26156)
Rename `Session::conversation_id` to `Session::thread_id` with an auto refactor in RustRover
jif ·
2026-06-03 15:38:30 +02:00 -
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.
jif ·
2026-06-03 13:32:55 +02:00 -
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`](https://github.com/openai/codex/blob/7c24e6641b693a3eed933dd376ce8f424ab6ea5f/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`](https://github.com/openai/codex/blob/7c24e6641b693a3eed933dd376ce8f424ab6ea5f/codex-rs/core/src/tools/handlers/multi_agents_tests.rs#L3936-L4070) ## Testing Not run locally.
jif ·
2026-06-03 13:30:04 +02:00 -
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`
jif ·
2026-06-03 12:25:21 +02:00 -
feat: default hide_spawn_agent_metadata to true (#26114)
For MAv2 CBv9
jif ·
2026-06-03 12:22:23 +02:00