mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
cff337e4e3bd2b84347ddcc26a69775bfc0638fc
283 Commits
-
[rollout_trace] Record core session rollout traces (#18877)
## Summary Wires rollout trace recording into `codex-core` session and turn execution. This records the core model request/response, compaction, and session lifecycle boundaries needed for replay without yet tracing every nested runtime/tool boundary. ## Stack This is PR 2/5 in the rollout trace stack. - [#18876](https://github.com/openai/codex/pull/18876): Add rollout trace crate - [#18877](https://github.com/openai/codex/pull/18877): Record core session rollout traces - [#18878](https://github.com/openai/codex/pull/18878): Trace tool and code-mode boundaries - [#18879](https://github.com/openai/codex/pull/18879): Trace sessions and multi-agent edges - [#18880](https://github.com/openai/codex/pull/18880): Add debug trace reduction command ## Review Notes This layer is the first live integration point. The important review question is whether trace recording is isolated from normal session behavior: trace failures should not become user-visible execution failures, and recording should preserve the existing turn/session lifecycle semantics. The PR depends on the reducer/data model from the first stack entry and only introduces the core recorder surface that later PRs use for richer runtime and relationship events.
cassirer-openai ·
2026-04-22 17:00:48 +00:00 -
feat: add explicit AgentIdentity auth mode (#18785)
## Summary This PR adds `CodexAuth::AgentIdentity` as an explicit auth mode. An AgentIdentity auth record is a standalone `auth.json` mode. When `AuthManager::auth().await` loads that mode, it registers one process-scoped task and stores it in runtime-only state on the auth value. Header creation stays synchronous after that because the task is initialized before callers receive the auth object. This PR also removes the old feature flag path. AgentIdentity is selected by explicit auth mode, not by a hidden flag or lazy mutation of ChatGPT auth records. Reference old stack: https://github.com/openai/codex/pull/17387/changes ## Design Decisions - AgentIdentity is a real auth enum variant because it can be the only credential in `auth.json`. - The process task is ephemeral runtime state. It is not serialized and is not stored in rollout/session data. - Account/user metadata needed by existing Codex backend checks lives on the AgentIdentity record for now. - `is_chatgpt_auth()` remains token-specific. - `uses_codex_backend()` is the broader predicate for ChatGPT-token auth and AgentIdentity auth. ## Stack 1. https://github.com/openai/codex/pull/18757: full revert 2. https://github.com/openai/codex/pull/18871: isolated Agent Identity crate 3. This PR: explicit AgentIdentity auth mode and startup task allocation 4. https://github.com/openai/codex/pull/18811: migrate Codex backend auth callsites through AuthProvider 5. https://github.com/openai/codex/pull/18904: accept AgentIdentity JWTs and load `CODEX_AGENT_IDENTITY` ## Testing Tests: targeted Rust checks, cargo-shear, Bazel lock check, and CI.
efrazer-oai ·
2026-04-21 22:33:24 -07:00 -
refactor: add agent identity crate (#18871)
## Summary This PR adds `codex-agent-identity` as an isolated crate for Agent Identity business logic. The crate owns: - AgentAssertion construction. - Agent task registration. - private-key assertion signing. - bounded blocking HTTP for task registration. It does not wire AgentIdentity into `auth.json`, `AuthManager`, rollout state, or request callsites. That integration happens in later PRs. Reference old stack: https://github.com/openai/codex/pull/17387/changes ## Stack 1. https://github.com/openai/codex/pull/18757: full revert 2. This PR: isolated Agent Identity crate 3. https://github.com/openai/codex/pull/18785: explicit AgentIdentity auth mode and startup task allocation 4. https://github.com/openai/codex/pull/18811: migrate Codex backend auth callsites through AuthProvider 5. https://github.com/openai/codex/pull/18904: accept AgentIdentity JWTs and load `CODEX_AGENT_IDENTITY` ## Testing Tests: targeted Rust checks, cargo-shear, Bazel lock check, and CI.
efrazer-oai ·
2026-04-21 19:57:49 -07:00 -
feat: add AWS SigV4 auth for OpenAI-compatible model providers (#17820)
## Summary Add first-class Amazon Bedrock Mantle provider support so Codex can keep using its existing Responses API transport with OpenAI-compatible AWS-hosted endpoints such as AOA/Mantle. This is needed for the AWS launch path, where provider traffic should authenticate with AWS credentials instead of OpenAI bearer credentials. Requests are authenticated immediately before transport send, so SigV4 signs the final method, URL, headers, and body bytes that `reqwest` will send. ## What Changed - Added a new `codex-aws-auth` crate for loading AWS SDK config, resolving credentials, and signing finalized HTTP requests with AWS SigV4. - Added a built-in `amazon-bedrock` provider that targets Bedrock Mantle Responses endpoints, defaults to `us-east-1`, supports region/profile overrides, disables WebSockets, and does not require OpenAI auth. - Added Amazon Bedrock auth resolution in `codex-model-provider`: prefer `AWS_BEARER_TOKEN_BEDROCK` when set, otherwise use AWS SDK credentials and SigV4 signing. - Added `AuthProvider::apply_auth` and `Request::prepare_body_for_send` so request-signing providers can sign the exact outbound request after JSON serialization/compression. - Determine the region by taking the `aws.region` config first (required for bearer token codepath), and fallback to SDK default region. ## Testing Amazon Bedrock Mantle Responses paths: - Built the local Codex binary with `cargo build`. - Verified the custom proxy-backed `aws` provider using `env_key = "AWS_BEARER_TOKEN_BEDROCK"` streamed raw `responses` output with `response.output_text.delta`, `response.completed`, and `mantle-env-ok`. - Verified a full `codex exec --profile aws` turn returned `mantle-env-ok`. - Confirmed the custom provider used the bearer env var, not AWS profile auth: bogus `AWS_PROFILE` still passed, empty env var failed locally, and malformed env var reached Mantle and failed with `401 invalid_api_key`. - Verified built-in `amazon-bedrock` with `AWS_BEARER_TOKEN_BEDROCK` set passed despite bogus AWS profiles, returning `amazon-bedrock-env-ok`. - Verified built-in `amazon-bedrock` SDK/SigV4 auth passed with `AWS_BEARER_TOKEN_BEDROCK` unset and temporary AWS session env credentials, returning `amazon-bedrock-sdk-env-ok`.
Celia Chen ·
2026-04-22 01:11:17 +00:00 -
[rollout_trace] Add rollout trace crate (#18876)
## Summary Adds the standalone `codex-rollout-trace` crate, which defines the raw trace event format, replay/reduction model, writer, and reducer logic for reconstructing model-visible conversation/runtime state from recorded rollout data. The crate-level design is documented in [`codex-rs/rollout-trace/README.md`](https://github.com/openai/codex/blob/codex/rollout-trace-crate/codex-rs/rollout-trace/README.md). ## Stack This is PR 1/5 in the rollout trace stack. - [#18876](https://github.com/openai/codex/pull/18876): Add rollout trace crate - [#18877](https://github.com/openai/codex/pull/18877): Record core session rollout traces - [#18878](https://github.com/openai/codex/pull/18878): Trace tool and code-mode boundaries - [#18879](https://github.com/openai/codex/pull/18879): Trace sessions and multi-agent edges - [#18880](https://github.com/openai/codex/pull/18880): Add debug trace reduction command ## Review Notes This PR intentionally does not wire tracing into live Codex execution. It establishes the data model and reducer contract first, with crate-local tests covering conversation reconstruction, compaction boundaries, tool/session edges, and code-cell lifecycle reduction. Later PRs emit into this model. The README is the best entry point for reviewing the intended trace format and reduction semantics before diving into the reducer modules.
cassirer-openai ·
2026-04-21 21:54:05 +00:00 -
Preserve Cloudfare HTTP cookies in codex (#17783)
## Summary - Adds a process-local, in-memory cookie store for ChatGPT HTTP clients. - Limits cookie storage and replay to a shared ChatGPT host allowlist. - Wires the shared store into the default Codex reqwest client and backend client. - Shares the ChatGPT host allowlist with remote-control URL validation to avoid drift. - Enables reqwest cookie support and updates lockfiles.
Shijie Rao ·
2026-04-21 14:40:15 -07:00 -
fix: fully revert agent identity runtime wiring (#18757)
## Summary This PR fully reverts the previously merged Agent Identity runtime integration from the old stack: https://github.com/openai/codex/pull/17387/changes It removes the Codex-side task lifecycle wiring, rollout/session persistence, feature flag plumbing, lazy `auth.json` mutation, background task auth paths, and request callsite changes introduced by that stack. This leaves the repo in a clean pre-AgentIdentity integration state so the follow-up PRs can reintroduce the pieces in smaller reviewable layers. ## Stack 1. This PR: full revert 2. https://github.com/openai/codex/pull/18871: move Agent Identity business logic into a crate 3. https://github.com/openai/codex/pull/18785: add explicit AgentIdentity auth mode and startup task allocation 4. https://github.com/openai/codex/pull/18811: migrate auth callsites through AuthProvider ## Testing Tests: targeted Rust checks, cargo-shear, Bazel lock check, and CI.
efrazer-oai ·
2026-04-21 14:30:55 -07:00 -
app-server: implement device key v2 methods (#18430)
## Why The device-key protocol needs an app-server implementation that keeps local key operations behind the same request-processing boundary as other v2 APIs. app-server owns request dispatch, transport policy, documentation, and JSON-RPC error shaping. `codex-device-key` owns key binding, validation, platform provider selection, and signing mechanics. Keeping the adapter thin makes the boundary easier to review and avoids moving local key-management details into thread orchestration code. ## What changed - Added `DeviceKeyApi` as the app-server adapter around `DeviceKeyStore`. - Converted protocol protection policies, payload variants, algorithms, and protection classes to and from the device-key crate types. - Encoded SPKI public keys and DER signatures as base64 protocol fields. - Routed `device/key/create`, `device/key/public`, and `device/key/sign` through `MessageProcessor`. - Rejected remote transports before provider access while allowing local `stdio` and in-process callers to reach the device-key API. - Added stdio, in-process, and websocket tests for device-key validation and transport policy. - Documented the device-key methods in the app-server v2 method list. ## Test coverage - `device_key_create_rejects_empty_account_user_id` - `in_process_allows_device_key_requests_to_reach_device_key_api` - `device_key_methods_are_rejected_over_websocket` ## Stack This is PR 3 of 4 in the device-key app-server stack. It is stacked on #18429. ## Validation - `cargo test -p codex-app-server device_key` - `just fix -p codex-app-server`
Ruslan Nigmatullin ·
2026-04-21 14:07:08 -07:00 -
app-server: add codex-device-key crate (#18429)
## Why Device-key storage and signing are local security-sensitive operations with platform-specific behavior. Keeping the core API in `codex-device-key` keeps app-server focused on routing and business logic instead of owning key-management details. The crate keeps the signing surface intentionally narrow: callers can create a bound key, fetch its public key, or sign one of the structured payloads accepted by the crate. It does not expose a generic arbitrary-byte signing API. Key IDs cross into platform-specific labels, tags, and metadata paths, so externally supplied IDs are constrained to the same auditable namespace created by the crate: `dk_` followed by unpadded base64url for 32 bytes. Remote-control target paths are also tied to each signed payload shape so connection proofs cannot be reused for enrollment endpoints, or vice versa. ## What changed - Added the `codex-device-key` workspace crate. - Added account/client-bound key creation with stable `dk_` key IDs. - Added strict `key_id` validation before public-key lookup or signing reaches a provider. - Added public-key lookup and structured signing APIs. - Split remote-control client endpoint allowlists by connection vs enrollment payload shape. - Added validation for key bindings, accepted payload fields, token expiration, and payload/key binding mismatches. - Added flow-oriented docs on the validation helpers that gate provider signing. - Added protection policy and protection-class types without wiring a platform provider yet. - Added an unsupported default provider so platforms without an implementation fail explicitly instead of silently falling back to software-backed keys. - Updated Cargo and Bazel lock metadata for the new crate and non-platform-specific dependencies. ## Stack This is stacked on #18428. ## Validation - `cargo test -p codex-device-key` - Added unit coverage for strict `key_id` validation before provider use. - Added unit coverage that rejects remote-control paths from the wrong signed payload shape. - `just bazel-lock-update` - `just bazel-lock-check`
Ruslan Nigmatullin ·
2026-04-21 17:57:00 +00:00 -
feat: baseline lib (#18848)
This add with 2 entry point: * `reset_git_repository` that takes a directory and set it as a new git root * `diff_since_latest_init` this returns the diff for a given directory since the last `reset_git_repository`
jif-oai ·
2026-04-21 17:24:30 +01:00 -
build: reduce Rust dev debuginfo (#18844)
## What changed This PR makes the default Cargo dev profile use line-tables-only debug info: ```toml [profile.dev] debug = 1 ``` That keeps useful backtraces while avoiding the cost of full variable debug info in normal local dev builds. This also makes the Bazel CI setting explicit with `-Cdebuginfo=0` for target and exec-configuration Rust actions. Bazel/rules_rust does not read Cargo profiles for this setting, and the current fastbuild action already emitted `--codegen=debuginfo=0`; the Bazel part of this PR makes that choice direct in our build configuration. ## Why The slow codex-core rebuilds are dominated by debug-info codegen, not parsing or type checking. On a warm-dependency package rebuild, the baseline codex-core compile was about 39.5s wall / 38.9s rustc total, with codegen_crate around 14.0s and LLVM_passes around 13.4s. Setting codex-core to line-tables-only debug info brought that to about 27.2s wall / 26.7s rustc total, with codegen_crate around 3.1s and LLVM_passes around 2.8s. `debug = 0` was only about another 0.7s faster than `debug = 1` in the codex-core measurement, so `debug = 1` is the better default dev tradeoff: it captures nearly all of the compile-time win while preserving basic debuggability. I also sampled other first-party crates instead of keeping a codex-core-only package override. codex-app-server showed the same pattern: rustc total dropped from 15.85s to 10.48s, while codegen_crate plus LLVM_passes dropped from about 13.47s to 3.23s. codex-app-server-protocol had a smaller but still real improvement, 16.05s to 14.58s total, and smaller crates showed modest wins. That points to a workspace dev-profile policy rather than a hand-maintained list of large crates. ## Relationship to #18612 [#18612](https://github.com/openai/codex/pull/18612) added the `dev-small` profile. That remains useful when someone wants a working local build quickly and is willing to opt in with `cargo build --profile dev-small`. This PR is deliberately less aggressive: it changes the common default dev profile while preserving line tables/backtraces. `dev-small` remains the explicit "build quickly, no debuggability concern" path. ## Other investigation I looked for another structural win comparable to [#16631](https://github.com/openai/codex/pull/16631) and [#16630](https://github.com/openai/codex/pull/16630), but did not find one. The attempted TOML monomorphization changes were noisy or worse in measurement, and the async task changes reduced some instantiations but only translated to roughly a one-second improvement while being much more disruptive. The debug-info setting was the one repeatable, material win that survived measurement. ## Verification - `just bazel-lock-update` - `just bazel-lock-check` - `cargo check -p codex-core --lib` - `cargo test -p codex-core --lib` - Bazel `aquery --config=ci-linux` confirmed `--codegen=debuginfo=0` and `-Cdebuginfo=0` for `//codex-rs/core:core` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/18844). * #18846 * __->__ #18844
Michael Bolin ·
2026-04-21 09:00:40 -07:00 -
chore: enable await-holding clippy lints (#18698)
Follow-up to https://github.com/openai/codex/pull/18178, where we said the await-holding clippy rule would be enabled separately. Enable `await_holding_lock` and `await_holding_invalid_type` after the preceding commits fixed or explicitly documented the current offenders.
Michael Bolin ·
2026-04-21 06:06:05 +00:00 -
Organize context fragments (#18794)
Organize context fragments under `core/context`. Implement same trait on all of them.
pakrym-oai ·
2026-04-20 22:39:17 -07:00 -
Add remote_sandbox_config to our config requirements (#18763)
## Why Customers need finer-grained control over allowed sandbox modes based on the host Codex is running on. For example, they may want stricter sandbox limits on devboxes while keeping a different default elsewhere. Our current cloud requirements can target user/account groups, but they cannot vary sandbox requirements by host. That makes remote development environments awkward because the same top-level `allowed_sandbox_modes` has to apply everywhere. ## What Adds a new `remote_sandbox_config` section to `requirements.toml`: ```toml allowed_sandbox_modes = ["read-only"] [[remote_sandbox_config]] hostname_patterns = ["*.org"] allowed_sandbox_modes = ["read-only", "workspace-write"] [[remote_sandbox_config]] hostname_patterns = ["*.sh", "runner-*.ci"] allowed_sandbox_modes = ["read-only", "danger-full-access"] ``` During requirements resolution, Codex resolves the local host name once, preferring the machine FQDN when available and falling back to the cleaned kernel hostname. This host classification is best effort rather than authenticated device proof. Each requirements source applies its first matching `remote_sandbox_config` entry before it is merged with other sources. The shared merge helper keeps that `apply_remote_sandbox_config` step paired with requirements merging so new requirements sources do not have to remember the extra call. That preserves source precedence: a lower-precedence requirements file with a matching `remote_sandbox_config` cannot override a higher-precedence source that already set `allowed_sandbox_modes`. This also wires the hostname-aware resolution through app-server, CLI/TUI config loading, config API reads, and config layer metadata so they all evaluate remote sandbox requirements consistently. ## Verification - `cargo test -p codex-config remote_sandbox_config` - `cargo test -p codex-config host_name` - `cargo test -p codex-core load_config_layers_applies_matching_remote_sandbox_config` - `cargo test -p codex-core system_remote_sandbox_config_keeps_cloud_sandbox_modes` - `cargo test -p codex-config` - `cargo test -p codex-core` unit tests passed; `tests/all.rs` integration matrix was intentionally stopped after the relevant focused tests passed - `just fix -p codex-config` - `just fix -p codex-core` - `cargo check -p codex-app-server`
Abhinav ·
2026-04-21 05:05:02 +00:00 -
uds: add async Unix socket crate (#18254)
## Summary - add a codex-uds crate with async UnixListener and UnixStream wrappers - expose helpers for private socket directory setup and stale socket path checks - migrate codex-stdio-to-uds onto codex-uds and Tokio-based stdio/socket relaying - update the CLI stdio-to-uds command path for the async runner ## Tests - cargo test -p codex-uds -p codex-stdio-to-uds - cargo test -p codex-cli - just fmt - just fix -p codex-uds - just fix -p codex-stdio-to-uds - just fix -p codex-cli - just bazel-lock-check - git diff --check
Ruslan Nigmatullin ·
2026-04-20 15:59:05 -07:00 -
Andrey Mishchenko ·
2026-04-19 22:05:17 -07:00 -
Filter Windows sandbox roots from SSH config dependencies (#18493)
## Stack 1. Base PR: #18443 stops granting ACLs on `USERPROFILE`. 2. This PR: filters additional SSH-owned profile roots discovered from SSH config. ## Bug The base PR removes the broadest bad grant: `USERPROFILE` itself. That still leaves one important case. A user profile child can be SSH-owned even when its name is not one of our fixed exclusions. For example: ```sshconfig Host devbox IdentityFile ~/.keys/devbox CertificateFile ~/.certs/devbox-cert.pub UserKnownHostsFile ~/.known_hosts_custom Include ~/.ssh/conf.d/*.conf ``` After profile expansion, the sandbox might see these as normal profile children: ```text C:\Users\me\.keys C:\Users\me\.certs C:\Users\me\.known_hosts_custom C:\Users\me\.ssh ``` Those paths have another owner: OpenSSH and the tools that manage SSH identity and host-key state. Codex should not add sandbox ACLs to them. OpenSSH describes this dependency tree in [`ssh_config(5)`](https://man.openbsd.org/ssh_config.5), and the client parser follows the same shape in `readconf.c`: - `Include` recursively reads more config files and expands globs - `IdentityFile` and `CertificateFile` name authentication files - `UserKnownHostsFile`, `GlobalKnownHostsFile`, and `RevokedHostKeys` name host-key files - `ControlPath` and `IdentityAgent` can name profile-owned sockets or control files - these path directives can use forms such as `~`, `%d`, and `${HOME}` ## Change This PR adds a small SSH config dependency scanner. It starts at: ```text ~/.ssh/config ``` Then it returns concrete paths named by `Include` and by path-valued SSH config directives: ```text IdentityFile CertificateFile UserKnownHostsFile GlobalKnownHostsFile RevokedHostKeys ControlPath IdentityAgent ``` For example: ```sshconfig IdentityFile ~/.keys/devbox CertificateFile ~/.certs/devbox-cert.pub Include ~/.ssh/conf.d/*.conf ``` returns paths like: ```text C:\Users\me\.keys\devbox C:\Users\me\.certs\devbox-cert.pub C:\Users\me\.ssh\conf.d\devbox.conf ``` The setup code then maps those paths back to their top-level `USERPROFILE` child and filters matching sandbox roots out of both the writable and readable root lists. ## Why this shape The parser reports what SSH config references. The sandbox setup code decides which `USERPROFILE` roots are unsafe to grant. That keeps the policy simple: 1. expand broad profile grants 2. remove the profile root 3. remove fixed sensitive profile folders 4. remove profile folders referenced by SSH config dependencies If a path has two possible owners, the sandbox steps back. SSH keeps control of SSH config, keys, certificates, known-hosts files, sockets, and included config files. ## Tests - `cargo test -p codex-windows-sandbox --lib` - `just bazel-lock-check` - `just fix -p codex-windows-sandbox` - `git diff --check`
efrazer-oai ·
2026-04-19 14:58:33 -07:00 -
feat: add opt-in provider runtime abstraction (#17713)
## Summary - Add `codex-model-provider` as the runtime home for model-provider behavior that does not belong in `codex-core`, `codex-login`, or `codex-api`. - The new crate wraps configured `ModelProviderInfo` in a `ModelProvider` trait object that can resolve the API provider config, provider-scoped auth manager, and request auth provider for each call. - This centralizes provider auth behavior in one place today, and gives us an extension point for future provider-specific auth, model listing, request setup, and related runtime behavior. ## Tests Ran tests manually to make sure that provider auth under different configs still work as expected. --------- Co-authored-by: pakrym-oai <pakrym@openai.com>
Celia Chen ·
2026-04-17 02:27:45 +00:00 -
Register agent tasks behind use_agent_identity (#17387)
## Summary Stack PR3 for feature-gated agent identity support. This PR adds per-thread agent task registration behind `features.use_agent_identity`. Tasks are minted on the first real user turn and cached in thread runtime state for later turns. ## Stack - PR1: https://github.com/openai/codex/pull/17385 - add `features.use_agent_identity` - PR2: https://github.com/openai/codex/pull/17386 - register agent identities when enabled - PR3: https://github.com/openai/codex/pull/17387 - this PR, original task registration slice - PR3.1: https://github.com/openai/codex/pull/17978 - persist and prewarm registered tasks per thread - PR4: https://github.com/openai/codex/pull/17980 - use `AgentAssertion` downstream when enabled ## Validation Covered as part of the local stack validation pass: - `just fmt` - `cargo test -p codex-core --lib agent_identity` - `cargo test -p codex-core --lib agent_assertion` - `cargo test -p codex-core --lib websocket_agent_task` - `cargo test -p codex-api api_bridge` - `cargo build -p codex-cli --bin codex` ## Notes The full local app-server E2E path is still being debugged after PR creation. The current branch stack is directionally ready for review while that follow-up continues.
Adrian ·
2026-04-16 14:30:02 -07:00 -
[codex] Add remote thread store implementation (#17826)
- Add a "remote" thread store implementation - Implement the remote thread store as a thin wrapper that makes grpc calls to a configurable service endpoint - Implement only the thread/list method to start - Encode the grpc method/param shape as protobufs in the remote implementation A wart: the proto generation script is an "example" binary target. This is an example target only because Cargo lets examples use dev-dependencies, which keeps tonic-prost-build out of the normal codex-thread-store dependency surface. A regular bin would either need to add proto generation deps as normal runtime deps, or use a feature-gated optional dep, which this repo’s manifest checks explicitly reject.
Tom ·
2026-04-16 10:15:31 -07:00 -
Extract plugin loading and marketplace logic into codex-core-plugins (#18070)
Split plugin loading, marketplace, and related infrastructure out of core into codex-core-plugins, while keeping the core-facing configuration and orchestration flow in codex-core. --------- Co-authored-by: Codex <noreply@openai.com>
xl-openai ·
2026-04-15 23:13:17 -07:00 -
Significantly improve standalone installer (#17022)
## Summary This PR significantly improves the standalone installer experience. The main changes are: 1. We now install the codex binary and other dependencies in a subdirectory under CODEX_HOME. (`CODEX_HOME/packages/standalone/releases/...`) 2. We replace the `codex.js` launcher that npm/bun rely on with logic in the Rust binary that automatically resolves its dependencies (like ripgrep) ## Motivation A few design constraints pushed this work. 1. Currently, the entrypoint to codex is through `codex.js`, which forces a node dependency to kick off our rust app. We want to move away from this so that the entrypoint to codex does not rely on node or external package managers. 2. Right now, the native script adds codex and its dependencies directly to user PATH. Given that codex is likely to add more binary dependencies than ripgrep, we want a solution which does not add arbitrary binaries to user PATH -- the only one we want to add is the `codex` command itself. 3. We want upgrades to be atomic. We do not want scenarios where interrupting an upgrade command can move codex into undefined state (for example, having a new codex binary but an old ripgrep binary). This was ~possible with the old script. 4. Currently, the Rust binary uses heuristics to determine which installer created it. These heuristics are flaky and are tied to the `codex.js` launcher. We need a more stable/deterministic way to determine how the binary was installed for standalone. 5. We do not want conflicting codex installations on PATH. For example, the user installing via npm, then installing via brew, then installing via standalone would make it unclear which version of codex is being launched and make it tough for us to determine the right upgrade command. ## Design ### Standalone package layout Standalone installs now live under `CODEX_HOME/packages/standalone`: ```text $CODEX_HOME/ packages/ standalone/ current -> releases/0.111.0-x86_64-unknown-linux-musl releases/ 0.111.0-x86_64-unknown-linux-musl/ codex codex-resources/ rg ``` where `standalone/current` is a symlink to a release directory. On Windows, the release directory has the same shape, with `.exe` names and Windows helpers in `codex-resources`: ```text %CODEX_HOME%\ packages\ standalone\ current -> releases\0.111.0-x86_64-pc-windows-msvc releases\ 0.111.0-x86_64-pc-windows-msvc\ codex.exe codex-resources\ rg.exe codex-command-runner.exe codex-windows-sandbox-setup.exe ``` This gives us: - atomic upgrades because we can fully stage a release before switching `standalone/current` - a stable way for the binary to recognize a standalone install from its canonical `current_exe()` path under CODEX_HOME - a clean place for binary dependencies like `rg`, Windows sandbox helpers, and, in the future, our custom `zsh` etc ### Command location On Unix, we add a symlink at `~/.local/bin/codex` which points directly to the `$CODEX_HOME/packages/standalone/current/codex` binary. This becomes the main entrypoint for the CLI. On Windows, we store the link at `%LOCALAPPDATA%\Programs\OpenAI\Codex\bin`. ### PATH persistence This is a tricky part of the PR, as there's no ~super reliable way to ensure that we end up on PATH without significant tradeoffs. Most Unix variants will have `~/.local/bin` on PATH already, which means we *should* be fine simply registering the command there in most cases. However, there are cases where this is not the case. In these cases, we directly edit the profile depending on the shell we're in. - macOS zsh: `~/.zprofile` - macOS bash: `~/.bash_profile` - Linux zsh: `~/.zshrc` - Linux bash: `~/.bashrc` - fallback: `~/.profile` On Windows, we update the User `Path` environment variable directly and we don't need to worry about shell profiles. ### Standalone runtime detection This PR adds a new shared crate, `codex-install-context`, which computes install ownership once per process and caches it in a `OnceLock`. That context includes: - install manager (`Standalone`, `Npm`, `Bun`, `Brew`, `Other`) - the managed standalone release directory, when applicable - the managed standalone `codex-resources` directory, when present - the resolved `rg_command` The standalone path is detected by canonicalizing `current_exe()`, canonicalizing CODEX_HOME via `find_codex_home()`, and checking whether the binary is running from under `$CODEX_HOME/packages/standalone/releases`. We intentionally do not use a release metadata file. The binary path is the source of truth. ### Dependency resolution For standalone installs, `grep_files` now resolves bundled `rg` from `codex-resources` next to the Codex binary. For npm/bun/brew/other installs, `grep_files` falls back to resolving `rg` from PATH. For Windows standalone installs, Windows sandbox helpers are still found as direct siblings when present. If they are not direct siblings, the lookup also checks the sibling `codex-resources` directory. ### TUI update path The TUI now has `UpdateAction::StandaloneUnix` and `UpdateAction::StandaloneWindows`, which rerun the standalone install commands. Unix update command: ```sh sh -c "curl -fsSL https://chatgpt.com/codex/install.sh | sh" ``` Windows update command: ```powershell powershell -c "irm https://chatgpt.com/codex/install.ps1|iex" ``` The Windows updater runs PowerShell directly. We do this because `cmd /C` would parse the `|iex` as a cmd pipeline instead of passing it to PowerShell. ## Additional installer behavior - standalone installs now warn about conflicting npm/bun/brew-managed `codex` installs and offer to uninstall them - same-version reruns do not redownload the release if it is already staged locally ## Testing Installer smoke tests run: - macOS: fresh install into isolated `HOME` and `CODEX_HOME` with `scripts/install/install.sh --release latest` - macOS: reran the installer against the same isolated install to verify the same-version/update path and PATH block idempotence - macOS: verified the installed `codex --version` and bundled `codex-resources/rg --version` - Windows: parsed `scripts/install/install.ps1` with PowerShell via `[scriptblock]::Create(...)` - Windows: verified the standalone update action builds a direct PowerShell command and does not route the `irm ...|iex` command through `cmd /C` --------- Co-authored-by: Codex <noreply@openai.com>efrazer-oai ·
2026-04-15 14:44:01 -07:00 -
[codex] Add local thread store listing (#17824)
Builds on top of #17659 Move the filesystem + sqlite thread listing-related operations inside of a local ThreadStore implementation and call ThreadStore from the places that used to perform these filesystem/sqlite operations. This is the first of a series of PRs that will implement the rest of the local ThreadStore. Testing: - added unit tests for the thread store implementation - adjusted some unit tests in the realtime + personality packages whose callsites changed. Specifically I'm trying to hide ThreadMetadata inside of the local implementation and make ThreadMetadata a sqlite implementation detail concern rather than a public interface, preferring the more generate StoredThread interface instead - added a corner case test for the personality migration package that wasn't covered by the existing test suite - adjust the behavior of searched thread listing to run the existing local rollout repair/backfill pass _before_ querying SQLite results, so callers using ThreadStore::list_threads do not miss matches after a partial metadata warm-up
Tom ·
2026-04-15 11:34:27 -07:00 -
Register agent identities behind use_agent_identity (#17386)
## Summary Stack PR 2 of 4 for feature-gated agent identity support. This PR adds agent identity registration behind `features.use_agent_identity`. It keeps the app-server protocol unchanged and starts registration after ChatGPT auth exists rather than requiring a client restart. ## Stack - PR1: https://github.com/openai/codex/pull/17385 - add `features.use_agent_identity` - PR2: https://github.com/openai/codex/pull/17386 - this PR - PR3: https://github.com/openai/codex/pull/17387 - register agent tasks when enabled - PR4: https://github.com/openai/codex/pull/17388 - use `AgentAssertion` downstream when enabled ## Validation Covered as part of the local stack validation pass: - `just fmt` - `cargo test -p codex-core --lib agent_identity` - `cargo test -p codex-core --lib agent_assertion` - `cargo test -p codex-core --lib websocket_agent_task` - `cargo test -p codex-api api_bridge` - `cargo build -p codex-cli --bin codex` ## Notes The full local app-server E2E path is still being debugged after PR creation. The current branch stack is directionally ready for review while that follow-up continues.
Adrian ·
2026-04-15 10:08:27 -07:00 -
ThreadStore interface (#17659)
Introduce a ThreadStore interface for mediating access to the filesystem (rollout jsonl files + sqlite db) based thread storage. In later PRs we'll move the existing fs code behind a "local" implementation of this ThreadStore interface. This PR should be a no-op behaviorally, it only introduces the interface.
Tom ·
2026-04-14 13:51:00 -07:00 -
[codex] Initialize ICU data for code mode V8 (#17709)
Link ICU data into code mode, otherwise locale-dependent methods cause a panic and a crash.
pakrym-oai ·
2026-04-13 22:01:58 -07:00 -
fix: pin inputs (#17471)
## Summary - Pin Rust git patch dependencies to immutable revisions and make cargo-deny reject unknown git and registry sources unless explicitly allowlisted. - Add checked-in SHA-256 coverage for the current rusty_v8 release assets, wire those hashes into Bazel, and verify CI override downloads before use. - Add rusty_v8 MODULE.bazel update/check tooling plus a Bazel CI guard so future V8 bumps cannot drift from the checked-in checksum manifest. - Pin release/lint cargo installs and all external GitHub Actions refs to immutable inputs. ## Future V8 bump flow Run these after updating the resolved `v8` crate version and checksum manifest: ```bash python3 .github/scripts/rusty_v8_bazel.py update-module-bazel python3 .github/scripts/rusty_v8_bazel.py check-module-bazel ``` The update command rewrites the matching `rusty_v8_<crate_version>` `http_file` SHA-256 values in `MODULE.bazel` from `third_party/v8/rusty_v8_<crate_version>.sha256`. The check command is also wired into Bazel CI to block drift. ## Notes - This intentionally excludes RustSec dependency upgrades and bubblewrap-related changes per request. - The branch was rebased onto the latest origin/main before opening the PR. ## Validation - cargo fetch --locked - cargo deny check advisories - cargo deny check - cargo deny check sources - python3 .github/scripts/rusty_v8_bazel.py check-module-bazel - python3 .github/scripts/rusty_v8_bazel.py update-module-bazel - python3 -m unittest discover -s .github/scripts -p 'test_rusty_v8_bazel.py' - python3 -m py_compile .github/scripts/rusty_v8_bazel.py .github/scripts/rusty_v8_module_bazel.py .github/scripts/test_rusty_v8_bazel.py - repo-wide GitHub Actions `uses:` audit: all external action refs are pinned to 40-character SHAs - yq eval on touched workflows and local actions - git diff --check - just bazel-lock-check ## Hash verification - Confirmed `MODULE.bazel` hashes match `third_party/v8/rusty_v8_146_4_0.sha256`. - Confirmed GitHub release asset digests for denoland/rusty_v8 `v146.4.0` and openai/codex `rusty-v8-v146.4.0` match the checked-in hashes. - Streamed and SHA-256 hashed all 10 `MODULE.bazel` rusty_v8 asset URLs locally; every downloaded byte stream matched both `MODULE.bazel` and the checked-in manifest. ## Pin verification - Confirmed signing-action pins match the peeled commits for their tag comments: `sigstore/cosign-installer@v3.7.0`, `azure/login@v2`, and `azure/trusted-signing-action@v0`. - Pinned the remaining tag-based action refs in Bazel CI/setup: `actions/setup-node@v6`, `facebook/install-dotslash@v2`, `bazelbuild/setup-bazelisk@v3`, and `actions/cache/restore@v5`. - Normalized all `bazelbuild/setup-bazelisk@v3` refs to the peeled commit behind the annotated tag. - Audited Cargo git dependencies: every manifest git dependency uses `rev` only, every `Cargo.lock` git source has `?rev=<sha>#<same-sha>`, and `cargo deny check sources` passes with `required-git-spec = "rev"`. - Shallow-fetched each distinct git dependency repo at its pinned SHA and verified Git reports each object as a commit.
viyatb-oai ·
2026-04-14 01:45:41 +00:00 -
Stabilize exec-server filesystem tests in CI (#17671)
## Summary\n- add an exec-server package-local test helper binary that can run exec-server and fs-helper flows\n- route exec-server filesystem tests through that helper instead of cross-crate codex helper binaries\n- stop relying on Bazel-only extra binary wiring for these tests\n\n## Testing\n- not run (per repo guidance for codex changes) --------- Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-04-13 16:53:42 -07:00 -
Revert "Option to Notify Workspace Owner When Usage Limit is Reached" (#17391)
Reverts openai/codex#16969 #sev3-2026-04-10-accountscheckversion-500s-for-openai-workspace-7300
Shijie Rao ·
2026-04-10 23:33:13 +00:00 -
Option to Notify Workspace Owner When Usage Limit is Reached (#16969)
## Summary - Replace the manual `/notify-owner` flow with an inline confirmation prompt when a usage-based workspace member hits a credits-depleted limit. - Fetch the current workspace role from the live ChatGPT `accounts/check/v4-2023-04-27` endpoint so owner/member behavior matches the desktop and web clients. - Keep owner, member, and spend-cap messaging distinct so we only offer the owner nudge when the workspace is actually out of credits. ## What Changed - `backend-client` - Added a typed fetch for the current account role from `accounts/check`. - Mapped backend role values into a Rust workspace-role enum. - `app-server` and protocol - Added `workspaceRole` to `account/read` and `account/updated`. - Derived `isWorkspaceOwner` from the live role, with a fallback to the cached token claim when the role fetch is unavailable. - `tui` - Removed the explicit `/notify-owner` slash command. - When a member is blocked because the workspace is out of credits, the error now prompts: - `Your workspace is out of credits. Request more from your workspace owner? [y/N]` - Choosing `y` sends the existing owner-notification request. - Choosing `n`, pressing `Esc`, or accepting the default selection dismisses the prompt without sending anything. - Selection popups now honor explicit item shortcuts, which is how the `y` / `n` interaction is wired. ## Reviewer Notes - The main behavior change is scoped to usage-based workspace members whose workspace credits are depleted. - Spend-cap reached should not show the owner-notification prompt. - Owners and admins should continue to see `/usage` guidance instead of the member prompt. - The live role fetch is best-effort; if it fails, we fall back to the existing token-derived ownership signal. ## Testing - Manual verification - Workspace owner does not see the member prompt. - Workspace member with depleted credits sees the confirmation prompt and can send the nudge with `y`. - Workspace member with spend cap reached does not see the owner-notification prompt. ### Workspace member out of usage https://github.com/user-attachments/assets/341ac396-eff4-4a7f-bf0c-60660becbea1 ### Workspace owner <img width="1728" height="1086" alt="Screenshot 2026-04-09 at 11 48 22 AM" src="https://github.com/user-attachments/assets/06262a45-e3fc-4cc4-8326-1cbedad46ed6" />
richardopenai ·
2026-04-09 21:15:17 -07:00 -
Move default realtime prompt into core (#17165)
- Adds a core-owned realtime backend prompt template and preparation path. - Makes omitted realtime start prompts use the core default, while null or empty prompts intentionally send empty instructions. - Covers the core realtime path and app-server v2 path with integration coverage. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-08 19:34:40 -07:00 -
Add WebRTC media transport to realtime TUI (#17058)
Adds the `[realtime].transport = "webrtc"` TUI media path using a new `codex-realtime-webrtc` crate, while leaving app-server as the signaling/event source.\n\nLocal checks: fmt, diff-check, dependency tree only; test signal should come from CI. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-08 10:26:55 -07:00 -
extract models manager and related ownership from core (#16508)
## Summary - split `models-manager` out of `core` and add `ModelsManagerConfig` plus `Config::to_models_manager_config()` so model metadata paths stop depending on `core::Config` - move login-owned/auth-owned code out of `core` into `codex-login`, move model provider config into `codex-model-provider-info`, move API bridge mapping into `codex-api`, move protocol-owned types/impls into `codex-protocol`, and move response debug helpers into a dedicated `response-debug-context` crate - move feedback tag emission into `codex-feedback`, relocate tests to the crates that now own the code, and keep broad temporary re-exports so this PR avoids a giant import-only rewrite ## Major moves and decisions - created `codex-models-manager` as the owner for model cache/catalog/config/model info logic, including the new `ModelsManagerConfig` struct - created `codex-model-provider-info` as the owner for provider config parsing/defaults and kept temporary `codex-login`/`codex-core` re-exports for old import paths - moved `api_bridge` error mapping + `CoreAuthProvider` into `codex-api`, while `codex-login::api_bridge` temporarily re-exports those symbols and keeps the `auth_provider_from_auth` wrapper - moved `auth_env_telemetry` and `provider_auth` ownership to `codex-login` - moved `CodexErr` ownership to `codex-protocol::error`, plus `StreamOutput`, `bytes_to_string_smart`, and network policy helpers to protocol-owned modules - created `codex-response-debug-context` for `extract_response_debug_context`, `telemetry_transport_error_message`, and related response-debug plumbing instead of leaving that behavior in `core` - moved `FeedbackRequestTags`, `emit_feedback_request_tags`, and `emit_feedback_request_tags_with_auth_env` to `codex-feedback` - deferred removal of temporary re-exports and the mechanical import rewrites to a stacked follow-up PR so this PR stays reviewable ## Test moves - moved auth refresh coverage from `core/tests/suite/auth_refresh.rs` to `login/tests/suite/auth_refresh.rs` - moved text encoding coverage from `core/tests/suite/text_encoding_fix.rs` to `protocol/src/exec_output_tests.rs` - moved model info override coverage from `core/tests/suite/model_info_overrides.rs` to `models-manager/src/model_info_overrides_tests.rs` --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-02 23:00:02 -07:00 -
Extract MCP into codex-mcp crate (#15919)
- Split MCP runtime/server code out of `codex-core` into the new `codex-mcp` crate. New/moved public structs/types include `McpConfig`, `McpConnectionManager`, `ToolInfo`, `ToolPluginProvenance`, `CodexAppsToolsCacheKey`, and the `McpManager` API (`codex_mcp::mcp::McpManager` plus the `codex_core::mcp::McpManager` wrapper/shim). New/moved functions include `with_codex_apps_mcp`, `configured_mcp_servers`, `effective_mcp_servers`, `collect_mcp_snapshot`, `collect_mcp_snapshot_from_manager`, `qualified_mcp_tool_name_prefix`, and the MCP auth/skill-dependency helpers. Why: this creates a focused MCP crate boundary and shrinks `codex-core` without forcing every consumer to migrate in the same PR. - Move MCP server config schema and persistence into `codex-config`. New/moved structs/enums include `AppToolApproval`, `McpServerToolConfig`, `McpServerConfig`, `RawMcpServerConfig`, `McpServerTransportConfig`, `McpServerDisabledReason`, and `codex_config::ConfigEditsBuilder`. New/moved functions include `load_global_mcp_servers` and `ConfigEditsBuilder::replace_mcp_servers`/`apply`. Why: MCP TOML parsing/editing is config ownership, and this keeps config validation/round-tripping (including per-tool approval overrides and inline bearer-token rejection) in the config crate instead of `codex-core`. - Rewire `codex-core`, app-server, and plugin call sites onto the new crates. Updated `Config::to_mcp_config(&self, plugins_manager)`, `codex-rs/core/src/mcp.rs`, `codex-rs/core/src/connectors.rs`, `codex-rs/core/src/codex.rs`, `CodexMessageProcessor::list_mcp_server_status_task`, and `utils/plugins/src/mcp_connector.rs` to build/pass the new MCP config/runtime types. Why: plugin-provided MCP servers still merge with user-configured servers, and runtime auth (`CodexAuth`) is threaded into `with_codex_apps_mcp` / `collect_mcp_snapshot` explicitly so `McpConfig` stays config-only.
Ahmed Ibrahim ·
2026-04-01 19:03:26 -07:00 -
cloud-tasks: split the mock client out of cloud-tasks-client (#16456)
## Why `codex-cloud-tasks-client` was mixing two different roles: the real HTTP client and the mock implementation used by tests and local mock mode. Keeping both in the same crate forced Cargo feature toggles and Bazel `crate_features` just to pick an implementation. This change keeps `codex-cloud-tasks-client` focused on the shared API surface and real backend client, and moves the mock implementation into its own crate so we can remove those feature permutations cleanly. ## What changed - add a new `codex-cloud-tasks-mock-client` crate that owns `MockClient` - remove the `mock` and `online` features from `codex-cloud-tasks-client` - make `codex-cloud-tasks-client` unconditionally depend on `codex-backend-client` and export `HttpClient` directly - gate the mock-mode path in `codex-cloud-tasks` behind `#[cfg(debug_assertions)]`, so release builds always initialize the real HTTP client - update `codex-cloud-tasks` and its tests to use `codex-cloud-tasks-mock-client::MockClient` wherever mock behavior is needed - remove the matching Bazel `crate_features` override and shrink the manifest verifier allowlist accordingly ## How tested - `cargo test -p codex-cloud-tasks-client` - `cargo test -p codex-cloud-tasks-mock-client` - `cargo test -p codex-cloud-tasks` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/16456). * #16457 * __->__ #16456
Michael Bolin ·
2026-04-01 12:09:14 -07:00 -
Rename tui_app_server to tui (#16104)
This is a follow-up to https://github.com/openai/codex/pull/15922. That previous PR deleted the old `tui` directory and left the new `tui_app_server` directory in place. This PR renames `tui_app_server` to `tui` and fixes up all references.
Eric Traut ·
2026-03-28 11:23:07 -06:00 -
Remove the legacy TUI split (#15922)
This is the part 1 of 2 PRs that will delete the `tui` / `tui_app_server` split. This part simply deletes the existing `tui` directory and marks the `tui_app_server` feature flag as removed. I left the `tui_app_server` feature flag in place for now so its presence doesn't result in an error. It is simply ignored. Part 2 will rename the `tui_app_server` directory `tui`. I did this as two parts to reduce visible code churn.
Eric Traut ·
2026-03-27 22:56:44 +00:00 -
jif-oai ·
2026-03-27 09:41:47 +01:00 -
codex-tools: extract shared tool schema parsing (#15923)
## Why `parse_tool_input_schema` and the supporting `JsonSchema` model were living in `core/src/tools/spec.rs`, but they already serve callers outside `codex-core`. Keeping that shared schema parsing logic inside `codex-core` makes the crate boundary harder to reason about and works against the guidance in `AGENTS.md` to avoid growing `codex-core` when reusable code can live elsewhere. This change takes the first extraction step by moving the schema parsing primitive into its own crate while keeping the rest of the tool-spec assembly in `codex-core`. ## What changed - added a new `codex-tools` crate under `codex-rs/tools` - moved the shared tool input schema model and sanitizer/parser into `tools/src/json_schema.rs` - kept `tools/src/lib.rs` exports-only, with the module-level unit tests split into `json_schema_tests.rs` - updated `codex-core` to use `codex-tools::JsonSchema` and re-export `parse_tool_input_schema` - updated `codex-app-server` dynamic tool validation to depend on `codex-tools` directly instead of reaching through `codex-core` - wired the new crate into the Cargo workspace and Bazel build graph
Michael Bolin ·
2026-03-27 00:03:35 +00:00 -
fix: box apply_patch test harness futures (#15835)
## Why `#[large_stack_test]` made the `apply_patch_cli` tests pass by giving them more stack, but it did not address why those tests needed the extra stack in the first place. The real problem is the async state built by the `apply_patch_cli` harness path. Those tests await three helper boundaries directly: harness construction, turn submission, and apply-patch output collection. If those helpers inline their full child futures, the test future grows to include the whole harness startup and request/response path. This change replaces the workaround from #12768 with the same basic approach used in #13429, but keeps the fix narrower: only the helper boundaries awaited directly by `apply_patch_cli` stay boxed. ## What Changed - removed `#[large_stack_test]` from `core/tests/suite/apply_patch_cli.rs` - restored ordinary `#[tokio::test(flavor = "multi_thread", worker_threads = 2)]` annotations in that suite - deleted the now-unused `codex-test-macros` crate and removed its workspace wiring - boxed only the three helper boundaries that the suite awaits directly: - `apply_patch_harness_with(...)` - `TestCodexHarness::submit(...)` - `TestCodexHarness::apply_patch_output(...)` - added comments at those boxed boundaries explaining why they remain boxed ## Testing - `cargo test -p codex-core --test all suite::apply_patch_cli -- --nocapture` ## References - #12768 - #13429
Michael Bolin ·
2026-03-26 17:32:04 +00:00 -
jif-oai ·
2026-03-26 15:28:59 +01:00 -
feat: exec-server prep for unified exec (#15691)
This PR partially rebase `unified_exec` on the `exec-server` and adapt the `exec-server` accordingly. ## What changed in `exec-server` 1. Replaced the old "broadcast-driven; process-global" event model with process-scoped session events. The goal is to be able to have dedicated handler for each process. 2. Add to protocol contract to support explicit lifecycle status and stream ordering: - `WriteResponse` now returns `WriteStatus` (Accepted, UnknownProcess, StdinClosed, Starting) instead of a bool. - Added seq fields to output/exited notifications. - Added terminal process/closed notification. 3. Demultiplexed remote notifications into per-process channels. Same as for the event sys 4. Local and remote backends now both implement ExecBackend. 5. Local backend wraps internal process ID/operations into per-process ExecProcess objects. 6. Remote backend registers a session channel before launch and unregisters on failed launch. ## What changed in `unified_exec` 1. Added unified process-state model and backend-neutral process wrapper. This will probably disappear in the future, but it makes it easier to keep the work flowing on both side. - `UnifiedExecProcess` now handles both local PTY sessions and remote exec-server processes through a shared `ProcessHandle`. - Added `ProcessState` to track has_exited, exit_code, and terminal failure message consistently across backends. 2. Routed write and lifecycle handling through process-level methods. ## Some rationals 1. The change centralizes execution transport in exec-server while preserving policy and orchestration ownership in core, avoiding duplicated launch approval logic. This comes from internal discussion. 2. Session-scoped events remove coupling/cross-talk between processes and make stream ordering and terminal state explicit (seq, closed, failed). 3. The failure-path surfacing (remote launch failures, write failures, transport disconnects) makes command tool output and cleanup behavior deterministic ## Follow-ups: * Unify the concept of thread ID behind an obfuscated struct * FD handling * Full zsh-fork compatibility * Full network sandboxing compatibility * Handle ws disconnection
jif-oai ·
2026-03-26 15:22:34 +01:00 -
jif-oai ·
2026-03-26 13:21:24 +01:00 -
feat: replace askama by custom lib (#15784)
Finalise the drop of `askama` to use our internal lib instead
jif-oai ·
2026-03-26 10:33:25 +01:00 -
Extract codex-core-skills crate (#15749)
## Summary - move skill loading and management into codex-core-skills - leave codex-core with the thin integration layer and shared wiring ## Testing - CI --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-25 12:57:42 -07:00 -
feat: add websocket auth for app-server (#14847)
## Summary This change adds websocket authentication at the app-server transport boundary and enforces it before JSON-RPC `initialize`, so authenticated deployments reject unauthenticated clients during the websocket handshake rather than after a connection has already been admitted. During rollout, websocket auth is opt-in for non-loopback listeners so we do not break existing remote clients. If `--ws-auth ...` is configured, the server enforces auth during websocket upgrade. If auth is not configured, non-loopback listeners still start, but app-server logs a warning and the startup banner calls out that auth should be configured before real remote use. The server supports two auth modes: a file-backed capability token, and a standard HMAC-signed JWT/JWS bearer token verified with the `jsonwebtoken` crate, with optional issuer, audience, and clock-skew validation. Capability tokens are normalized, hashed, and compared in constant time. Short shared secrets for signed bearer tokens are rejected at startup. Requests carrying an `Origin` header are rejected with `403` by transport middleware, and authenticated clients present credentials as `Authorization: Bearer <token>` during websocket upgrade. ## Validation - `cargo test -p codex-app-server transport::auth` - `cargo test -p codex-cli app_server_` - `cargo clippy -p codex-app-server --all-targets -- -D warnings` - `just bazel-lock-check` Note: in the broad `cargo test -p codex-app-server connection_handling_websocket` run, the touched websocket auth cases passed, but unrelated Unix shutdown tests failed with a timeout in this environment. --------- Co-authored-by: Eric Traut <etraut@openai.com>
viyatb-oai ·
2026-03-25 12:35:57 -07:00 -
Extract codex-analytics crate (#15748)
## Summary - move the analytics events client into codex-analytics - update codex-core and app-server callsites to use the new crate ## Testing - CI --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-25 11:08:05 -07:00 -
Extract codex-plugin crate (#15747)
## Summary - extract plugin identifiers and load-outcome types into codex-plugin - update codex-core to consume the new plugin crate ## Testing - CI --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-25 11:07:31 -07:00 -
Extract codex-utils-plugins crate (#15746)
## Summary - extract shared plugin path and manifest helpers into codex-utils-plugins - update codex-core to consume the utility crate ## Testing - CI --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-25 11:05:35 -07:00 -
Extract codex-instructions crate (#15744)
## Summary - extract instruction fragment and user-instruction types into codex-instructions - update codex-core to consume the new crate ## Testing - CI --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-25 10:43:49 -07:00