Commit Graph

4481 Commits

  • Cleanup code_mode tool descriptions (#14480)
    Move to separate files and clarify a bit.
  • fix: preserve split filesystem semantics in linux sandbox (#14173)
    ## Stack
    
       fix: fail closed for unsupported split windows sandboxing #14172
    -> fix: preserve split filesystem semantics in linux sandbox #14173
       fix: align core approvals with split sandbox policies #14171
       refactor: centralize filesystem permissions precedence #14174
    
    ## Summary
    ## Summary
    - Preserve Linux split filesystem carveouts in bubblewrap by applying
    mount masks in the right order, so narrower rules still win under
    broader writable roots.
    - Preserve unreadable ancestors of writable roots by masking them first
    and then rebinding the narrower writable descendants.
    - Stop rejecting legacy-plus-split Linux configs that are
    sandbox-equivalent after `cwd` resolution by comparing semantics instead
    of raw legacy structs.
    - Fail closed when callers provide partial split policies, mismatched
    legacy-plus-split policies, or force `--use-legacy-landlock` for
    split-only shapes that legacy Landlock cannot enforce.
    - Add Linux regressions for overlapping writable, read-only, and denied
    paths, and document the supported split-policy enforcement path.
    
    ## Example
    Given a split filesystem policy like:
    
    ```toml
    [permissions.dev.filesystem]
    ":root" = "read"
    "/code" = "write"
    "/code/.git" = "read"
    "/code/secrets" = "none"
    "/code/secrets/tmp" = "write"
    ```
    
    this PR makes Linux enforce the intended result under bubblewrap:
    
    - `/code` stays writable
    - `/code/.git` stays read-only
    - `/code/secrets` stays denied
    - `/code/secrets/tmp` can still be reopened as writable if explicitly
    allowed
    
    Before this, Linux could lose one of those carveouts depending on mount
    order or legacy-policy fallback. This PR keeps the split-policy
    semantics intact and rejects configurations that legacy Landlock cannot
    represent safely.
  • rename spawn_csv feature flag to enable_fanout (#14475)
    ## Summary
    - rename the public feature flag for `spawn_agents_on_csv()` from
    `spawn_csv` to `enable_fanout`
    - regenerate the config schema so only `enable_fanout` is advertised
    - keep the behavior the same: enabling `enable_fanout` still pulls in
    `multi_agent`
    
    ## Notes
    - this is a hard rename with no `spawn_csv` compatibility alias
    - the internal enum remains `Feature::SpawnCsv` to keep the patch small
    
    ## Testing
    - `cd codex-rs && just fmt`
    - `cd codex-rs && cargo test -p codex-core` (running locally;
    `suite::agent_jobs::*` and rename-specific coverage passed so far)
  • Move code mode tool files under tools/code_mode and split functionality (#14476)
    - **Summary**
    - migrate the code mode handler, service, worker, process, runner, and
    bridge assets into the `tools/code_mode` module tree
    - split Execution, protocol, and handler logic into dedicated files and
    relocate the tool definition into `code_mode/spec.rs`
    - update core references and tests to stitch the new organization
    together
    - **Testing**
      - Not run (not requested)
  • Fix stdio-to-uds peer-close flake (#13882)
    ## What changed
    - `codex-stdio-to-uds` now tolerates `NotConnected` when
    `shutdown(Write)` happens after the peer has already closed.
    - The socket test was rewritten to send stdin from a fixture file and to
    read an exact request payload length instead of waiting on EOF timing.
    
    ## Why this fixes the flake
    - This one exposed a real cross-platform runtime edge case: on macOS,
    the peer can close first after a successful exchange, and
    `shutdown(Write)` can report `NotConnected` even though the interaction
    already succeeded.
    - Treating that specific ordering as a harmless shutdown condition
    removes the production-level false failure.
    - The old test compounded the problem by depending on EOF timing, which
    varies by platform and scheduler. Exact-length IO makes the test
    deterministic and focused on the actual data exchange.
    
    ## Scope
    - Production logic change with matching test rewrite.
  • fix(cli): support legacy use_linux_sandbox_bwrap flag (#14473)
    ## Summary
    - restore `use_linux_sandbox_bwrap` as a removed feature key so older
    `--enable` callers parse again
    - keep it as a no-op by leaving runtime behavior unchanged
    - add regression coverage for the legacy `--enable` path
    
    ## Testing
    - Not run (updated and pushed quickly)
  • Add Python app-server SDK (#14435)
    ## TL;DR
    Bring the Python app-server SDK from `main-with-prs-13953-and-14232`
    onto current `main` as a standalone SDK-only PR.
    
    - adds the new `sdk/python` and `sdk/python-runtime` package trees
    - keeps the scope to the SDK payload only, without the unrelated
    branch-history or workflow changes from the source branch
    - regenerates `sdk/python/src/codex_app_server/generated/v2_all.py`
    against current `main` schema so the extracted SDK matches today's
    protocol definitions
    
    ## Validation
    - `PYTHONPATH=sdk/python/src python3 -m pytest sdk/python/tests`
    
    Co-authored-by: Codex <noreply@openai.com>
  • Dispatch tools when code mode is not awaited directly (#14437)
    ## Summary
    - start a code mode worker once per turn and let it pump nested tool
    calls through a dedicated queue
    - simplify code mode request/response dispatch around request ids and
    generic runner-unavailable errors
    - clean up the code mode process API and runner protocol plumbing
    
    ## Testing
    - not run yet
  • fix: move inline codex-rs/core unit tests into sibling files (#14444)
    ## Why
    PR #13783 moved the `codex.rs` unit tests into `codex_tests.rs`. This
    applies the same extraction pattern across the rest of `codex-rs/core`
    so the production modules stay focused on runtime code instead of large
    inline test blocks.
    
    Keeping the tests in sibling files also makes follow-up edits easier to
    review because product changes no longer have to share a file with
    hundreds or thousands of lines of test scaffolding.
    
    ## What changed
    - replaced each inline `mod tests { ... }` in `codex-rs/core/src/**`
    with a path-based module declaration
    - moved each extracted unit test module into a sibling `*_tests.rs`
    file, using `mod_tests.rs` for `mod.rs` modules
    - preserved the existing `cfg(...)` guards and module-local structure so
    the refactor remains structural rather than behavioral
    
    ## Testing
    - `cargo test -p codex-core --lib` (`1653 passed; 0 failed; 5 ignored`)
    - `just fix -p codex-core`
    - `cargo fmt --check`
    - `cargo shear`
  • [elicitation] User-friendly tool call messages. (#14403)
    - [x] Add a curated set of tool call messages and human-readable tool
    param names.
  • fix: follow up on linux sandbox review nits (#14440)
    ## Summary
    - address the follow-up review nits from #13996 in a separate PR
    - make the approvals test command a raw string and keep the
    managed-network path using env proxy routing
    - inline `--apply-seccomp-then-exec` in the Linux sandbox inner command
    builder
    - remove the bubblewrap-specific sandbox metric tag path and drop the
    `use_legacy_landlock` shim from `sandbox_tag`/`TurnMetadataState::new`
    - restore the `Feature` import that `origin/main` currently still needs
    in `connectors.rs`
    
    ## Testing
    - `cargo test -p codex-linux-sandbox`
    - focused `codex-core` tests were rerun/started, but the final
    verification pass was interrupted when I pushed at request
  • refactor: make bubblewrap the default Linux sandbox (#13996)
    ## Summary
    - make bubblewrap the default Linux sandbox and keep
    `use_legacy_landlock` as the only override
    - remove `use_linux_sandbox_bwrap` from feature, config, schema, and
    docs surfaces
    - update Linux sandbox selection, CLI/config plumbing, and related
    tests/docs to match the new default
    - fold in the follow-up CI fixes for request-permissions responses and
    Linux read-only sandbox error text
  • feat: refactor on openai-curated plugins. (#14427)
    - Curated repo sync now uses GitHub HTTP, not local git.
    - Curated plugin cache/versioning now uses commit SHA instead of local.
    - Startup sync now always repairs or refreshes curated plugin cache from
    tmp (auto update to the lastest)
  • Support waiting for code_mode sessions (#14295)
    ## Summary
    - persist the code mode runner process in the session-scoped code mode
    store
    - switch the runner protocol from `init` to `start` with explicit
    session ids
    - handle runner-side session processing without the init waiter queue
    
    ## Validation
    - just fmt
    - cargo check -p codex-core
    - node --check codex-rs/core/src/tools/code_mode_runner.cjs
  • Clarify spawn agent authorization (#14432)
    - Clarify that spawn_agent requires explicit user permission for
    delegation or parallel agent work.
    - Add a regression test covering the new description text.
  • [apps] Add tool_suggest tool. (#14287)
    - [x] Add tool_suggest tool.
    - [x] Move chatgpt/src/connectors.rs and core/src/connectors.rs into a
    dedicated mod so that we have all the logic and global cache in one
    place.
    - [x] Update TUI app link view to support rendering the installation
    view for mcp elicitation.
    
    ---------
    
    Co-authored-by: Shaqayeq <shaqayeq@openai.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
    Co-authored-by: pakrym-oai <pakrym@openai.com>
    Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
    Co-authored-by: guinness-oai <guinness@openai.com>
    Co-authored-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
    Co-authored-by: Charlie Guo <cguo@openai.com>
    Co-authored-by: Fouad Matin <fouad@openai.com>
    Co-authored-by: Fouad Matin <169186268+fouad-openai@users.noreply.github.com>
    Co-authored-by: xl-openai <xl@openai.com>
    Co-authored-by: alexsong-oai <alexsong@openai.com>
    Co-authored-by: Owen Lin <owenlin0@gmail.com>
    Co-authored-by: sdcoffey <stevendcoffey@gmail.com>
    Co-authored-by: Codex <noreply@openai.com>
    Co-authored-by: Won Park <won@openai.com>
    Co-authored-by: Dylan Hurd <dylan.hurd@openai.com>
    Co-authored-by: celia-oai <celia@openai.com>
    Co-authored-by: gabec-openai <gabec@openai.com>
    Co-authored-by: joeytrasatti-openai <joey.trasatti@openai.com>
    Co-authored-by: Leo Shimonaka <leoshimo@openai.com>
    Co-authored-by: Rasmus Rygaard <rasmus@openai.com>
    Co-authored-by: maja-openai <163171781+maja-openai@users.noreply.github.com>
    Co-authored-by: pash-openai <pash@openai.com>
    Co-authored-by: Josh McKinney <joshka@openai.com>
  • chore: use AVAILABLE and ON_INSTALL as default plugin install and auth policies (#14407)
    make `AVAILABLE` the default plugin installPolicy when unset in
    `marketplace.json`. similarly, make `ON_INSTALL` the default authPolicy.
    
    this means, when unset, plugins are available to be installed (but not
    auto-installed), and the contained connectors will be authed at
    install-time.
    
    updated tests.
  • feat(app-server): propagate traces across tasks and core ops (#14387)
    ## Summary
    
    This PR keeps app-server RPC request trace context alive for the full
    lifetime of the work that request kicks off (e.g. for `thread/start`,
    this is `app-server rpc handler -> tokio background task -> core op
    submissions`). Previously we lose trace lineage once the request handler
    returns or hands work off to background tasks.
    
    This approach is especially relevant for `thread/start` and other RPC
    handlers that run in a non-blocking way. In the near future we'll most
    likely want to make all app-server handlers run in a non-blocking way by
    default, and only queue operations that must operate in order (e.g.
    thread RPCs per thread?), so we want to make sure tracing in app-server
    just generally works.
    
    Depends on https://github.com/openai/codex/pull/14300
    
    **Before**
    <img width="155" height="207" alt="image"
    src="https://github.com/user-attachments/assets/c9487459-36f1-436c-beb7-fafeb40737af"
    />
    
    
    **After**
    <img width="299" height="337" alt="image"
    src="https://github.com/user-attachments/assets/727392b2-d072-4427-9dc4-0502d8652dea"
    />
    
    ## What changed
    
    - Keep request-scoped trace context around until we send the final
    response or error, or the connection closes.
    - Thread that trace context through detached `thread/start` work so
    background startup stays attached to the originating request.
    - Pass request trace context through to downstream core operations,
    including:
      - thread creation
      - resume/fork flows
      - turn submission
      - review
      - interrupt
      - realtime conversation operations
    - Add tracing tests that verify:
      - remote W3C trace context is preserved for `thread/start`
      - remote W3C trace context is preserved for `turn/start`
      - downstream core spans stay under the originating request span
      - request-scoped tracing state is cleaned up correctly
    - Clean up shutdown behavior so detached background tasks and spawned
    threads are drained before process exit.
  • Include spawn agent model metadata in app-server items (#14410)
    - add model and reasoning effort to app-server collab spawn items and
    notifications
    - regenerate app-server protocol schemas for the new fields
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • fix: align core approvals with split sandbox policies (#14171)
    ## Stack
    
       fix: fail closed for unsupported split windows sandboxing #14172
       fix: preserve split filesystem semantics in linux sandbox #14173
    -> fix: align core approvals with split sandbox policies #14171
       refactor: centralize filesystem permissions precedence #14174
    
    ## Why This PR Exists
    
    This PR is intentionally narrower than the title may suggest.
    
    Most of the original split-permissions migration already landed in the
    earlier `#13434 -> #13453` stack. In particular:
    
    - `#13439` already did the broad runtime plumbing for split filesystem
    and network policies.
    - `#13445` already moved `apply_patch` safety onto filesystem-policy
    semantics.
    - `#13448` already switched macOS Seatbelt generation to split policies.
    - `#13449` and `#13453` already handled Linux helper and bubblewrap
    enforcement.
    - `#13440` already introduced the first protocol-side helpers for
    deriving effective filesystem access.
    
    The reason this PR still exists is that after the follow-on
    `[permissions]` work and the new shared precedence helper in `#14174`, a
    few core approval paths were still deciding behavior from the legacy
    `SandboxPolicy` projection instead of the split filesystem policy that
    actually carries the carveouts.
    
    That means this PR is mostly a cleanup and alignment pass over the
    remaining core consumers, not a fresh sandbox backend migration.
    
    ## What Is Actually New Here
    
    - make unmatched-command fallback decisions consult
    `FileSystemSandboxPolicy` instead of only legacy `DangerFullAccess` /
    `ReadOnly` / `WorkspaceWrite` categories
    - thread `file_system_sandbox_policy` into the shell, unified-exec, and
    intercepted-exec approval paths so they all use the same split-policy
    semantics
    - keep `apply_patch` safety on the same effective-access rules as the
    shared protocol helper, rather than letting it drift through
    compatibility projections
    - add loader-level regression coverage proving legacy `sandbox_mode`
    config still builds split policies and round-trips back without semantic
    drift
    
    ## What This PR Does Not Do
    
    This PR does not introduce new platform backend enforcement on its own.
    
    - Linux backend parity remains in `#14173`.
    - Windows fail-closed handling remains in `#14172`.
    - The shared precedence/model changes live in `#14174`.
    
    ## Files To Focus On
    
    - `core/src/exec_policy.rs`: unmatched-command fallback and approval
    rendering now read the split filesystem policy directly
    - `core/src/tools/sandboxing.rs`: default exec-approval requirement keys
    off `FileSystemSandboxPolicy.kind`
    - `core/src/tools/handlers/shell.rs`: shell approval requests now carry
    the split filesystem policy
    - `core/src/unified_exec/process_manager.rs`: unified-exec approval
    requests now carry the split filesystem policy
    - `core/src/tools/runtimes/shell/unix_escalation.rs`: intercepted exec
    fallback now uses the same split-policy approval semantics
    - `core/src/safety.rs`: `apply_patch` safety keeps using effective
    filesystem access rather than legacy sandbox categories
    - `core/src/config/config_tests.rs`: new regression coverage for legacy
    `sandbox_mode` no-drift behavior through the split-policy loader
    
    ## Notes
    
    - `core/src/codex.rs` and `core/src/codex_tests.rs` are just small
    fallout updates for `RequestPermissionsResponse.scope`; they are not the
    point of the PR.
    - If you reviewed the earlier `#13439` / `#13445` stack, the main review
    question here is simply: “are there any remaining approval or
    patch-safety paths that still reconstruct semantics from legacy
    `SandboxPolicy` instead of consuming the split filesystem policy
    directly?”
    
    ## Testing
    - cargo test -p codex-core
    legacy_sandbox_mode_config_builds_split_policies_without_drift
    - cargo test -p codex-core request_permissions
    - cargo test -p codex-core intercepted_exec_policy
    - cargo test -p codex-core
    restricted_sandbox_requires_exec_approval_on_request
    - cargo test -p codex-core
    unmatched_on_request_uses_split_filesystem_policy_for_escalation_prompts
    - cargo test -p codex-core explicit_
    - cargo clippy -p codex-core --tests -- -D warnings
  • chore(app-server): delete unused rpc methods from v1.rs (#14394)
    ## Description
    
    This PR trims `app-server-protocol`'s v1 surface down to the small set
    of legacy types we still actually use.
    
    Unfortunately, we can't delete all of them yet because:
    - a few one-off v1 RPCs are still used by the Codex app
    - a few of these app-server-protocol v1 types are actually imported by
    core crates
    
    This change deletes that unused RPC surface, keeps the remaining
    compatibility types in place, and makes the crate root re-export only
    the v1 structs that downstream crates still depend on.
    
    ## Why
    
    The main goal here is to make the legacy protocol surface match reality.
    Leaving a large pile of dead v1 structs in place makes it harder to tell
    which compatibility paths are still intentional, and it keeps old
    schema/types around even though nothing should be building against them
    anymore.
    
    This also gives us a cleaner boundary for future cleanup. Instead of
    re-exporting all of `protocol::v1::*`, the crate now explicitly exposes
    only the v1 types that are still live, which makes it much easier to see
    what remains and delete more safely later.
    
    ## What changed
    
    - Deleted the unused v1 RPC/request/response structs from
    `app-server-protocol/src/protocol/v1.rs`.
    - Kept the small set of v1 compatibility types that are still live,
    including:
      - `initialize`
      - `getConversationSummary`
      - `getAuthStatus`
      - `gitDiffToRemote`
      - legacy approval payloads
      - config-related structs still used by downstream crates
    - Replaced the blanket `pub use protocol::v1::*` export in
    `app-server-protocol/src/lib.rs` with an explicit list of the remaining
    supported v1 types.
    - Regenerated the schema/type artifacts, which also updated the
    `InitializeCapabilities` opt-out example to use `thread/started` instead
    of the old `codex/event/session_configured` example.
    
    ## Validation
    
    - `just write-app-server-schema`
    - `cargo test -p codex-app-server-protocol`
    
    ## Follow-up
    
    The next cleanup is to keep shrinking the remaining v1 compatibility
    surface as callers migrate off it. Once the remaining consumers stop
    importing these legacy types, we should be able to remove more of the v1
    module and eventually stop exporting it from the crate root entirely.
  • refactor: centralize filesystem permissions precedence (#14174)
    ## Stack
    
       fix: fail closed for unsupported split windows sandboxing #14172
       fix: preserve split filesystem semantics in linux sandbox #14173
       fix: align core approvals with split sandbox policies #14171
    -> refactor: centralize filesystem permissions precedence #14174
    
    ## Summary
    - add a shared per-path split filesystem precedence helper in
    `FileSystemSandboxPolicy`
    - derive readable, writable, and unreadable roots from the same
    most-specific resolution rules
    - add regression coverage for nested `write` / `read` / `none` carveouts
    and legacy bridge enforcement detection
    
    ## Testing
    - cargo test -p codex-protocol
    - cargo clippy -p codex-protocol --tests -- -D warnings
  • feat: search_tool migrate to bring you own tool of Responses API (#14274)
    ## Why
    
    to support a new bring your own search tool in Responses
    API(https://developers.openai.com/api/docs/guides/tools-tool-search#client-executed-tool-search)
    we migrating our bm25 search tool to use official way to execute search
    on client and communicate additional tools to the model.
    
    ## What
    - replace the legacy `search_tool_bm25` flow with client-executed
    `tool_search`
    - add protocol, SSE, history, and normalization support for
    `tool_search_call` and `tool_search_output`
    - return namespaced Codex Apps search results and wire namespaced
    follow-up tool calls back into MCP dispatch
  • chore(app-server): stop emitting codex/event/ notifications (#14392)
    ## Description
    
    This PR stops emitting legacy `codex/event/*` notifications from the
    public app-server transports.
    
    It's been a long time coming! app-server was still producing a raw
    notification stream from core, alongside the typed app-server
    notifications and server requests, for compatibility reasons. Now,
    external clients should no longer be depending on those legacy
    notifications, so this change removes them from the stdio and websocket
    contract and updates the surrounding docs, examples, and tests to match.
    
    ### Caveat
    I left the "in-process" version of app-server alone for now, since
    `codex exec` was recently based on top of app-server via this in-process
    form here: https://github.com/openai/codex/pull/14005
    
    Seems like `codex exec` still consumes some legacy notifications
    internally, so this branch only removes `codex/event/*` from app-server
    over stdio and websockets.
    
    ## Follow-up
    
    Once `codex exec` is fully migrated off `codex/event/*` notifications,
    we'll be able to stop emitting them entirely entirely instead of just
    filtering it at the external transport boundary.
  • check for large binaries in CI (#14382)
    Prevent binaries >500KB from being committed. And maintain an allowlist
    if we need to bypass on a case-by-case basis.
    
    I checked the currently tracked binary-like assets in the repo. There
    are only 5 obvious committed binaries by extension/MIME type:
    - `.github/codex-cli-splash.png`: `838,131` bytes, about `818 KiB`
    - `codex-rs/vendor/bubblewrap/bubblewrap.jpg`: `40,239` bytes, about `39
    KiB`
    -
    `codex-rs/skills/src/assets/samples/skill-creator/assets/skill-creator.png`:
    `1,563` bytes
    - `codex-rs/skills/src/assets/samples/openai-docs/assets/openai.png`:
    `1,429` bytes
    -
    `codex-rs/skills/src/assets/samples/skill-installer/assets/skill-installer.png`:
    `1,086` bytes
    
    So `500 KB` looks like a good default for this repo. It would only trip
    on one existing intentional asset, which keeps the allowlist small and
    the policy easy to understand.
    
    Here's a smoke-test from a throwaway branch that tries to commit a large
    binary:
    https://github.com/openai/codex/actions/runs/22971558828/job/66689330435?pr=14383
  • Let models opt into original image detail (#14175)
    ## Summary
    
    This PR narrows original image detail handling to a single opt-in
    feature:
    
    - `image_detail_original` lets the model request `detail: "original"` on
    supported models
    - Omitting `detail` preserves the default resized behavior
    
    The model only sees `detail: "original"` guidance when the active model
    supports it:
    
    - JS REPL instructions include the guidance and examples only on
    supported models
    - `view_image` only exposes a `detail` parameter when the feature and
    model can use it
    
    The image detail API is intentionally narrow and consistent across both
    paths:
    
    - `view_image.detail` supports only `"original"`; otherwise omit the
    field
    - `codex.emitImage(..., detail)` supports only `"original"`; otherwise
    omit the field
    - Unsupported explicit values fail clearly at the API boundary instead
    of being silently reinterpreted
    - Unsupported explicit `detail: "original"` requests fall back to normal
    behavior when the feature is disabled or the model does not support
    original detail
  • Keep agent-switch word-motion keys out of draft editing (#14376)
    ## Summary
    - only trigger multi-agent fast-switch shortcuts when the composer is
    empty
    - keep the Option+b/f fallback for terminals that encode Option+arrow
    that way
    - document why the empty-composer gate preserves expected word-wise
    editing behavior
    
    ## Testing
    - just fmt
    - cargo test -p codex-tui
    
    Co-authored-by: Codex <noreply@openai.com>
  • Add js_repl cwd and homeDir helpers (#14385)
    ## Summary
    
    This PR adds two read-only path helpers to `js_repl`:
    
    - `codex.cwd`
    - `codex.homeDir`
    
    They are exposed alongside the existing `codex.tmpDir` helper so the
    REPL can reference basic host path context without reopening direct
    `process` access.
    
    ## Implementation
    
    - expose `codex.cwd` and `codex.homeDir` from the js_repl kernel
    - make `codex.homeDir` come from the kernel process environment
    - pass session dependency env through js_repl kernel startup so
    `codex.homeDir` matches the env a shell-launched process would see
    - keep existing shell `HOME` population behavior unchanged
    - update js_repl prompt/docs and add runtime/integration coverage for
    the new helpers
  • fix(network-proxy): serve HTTP proxy listener as HTTP/1 (#14395)
    ## Summary
    - switch the local HTTP proxy listener from Rama's auto server to
    explicit HTTP/1 so CONNECT clients skip the version-sniffing pre-read
    path
    - move rustls crypto-provider bootstrap into the HTTP proxy runner so
    direct callers do not need hidden global init
    - add a regression test that exercises a plain HTTP/1 CONNECT request
    against a live loopback listener
  • Defer initial context insertion until the first turn (#14313)
    ## Summary
    - defer fresh-session `build_initial_context()` until the first real
    turn instead of seeding model-visible context during startup
    - rely on the existing `reference_context_item == None` turn-start path
    to inject full initial context on that first real turn (and again after
    baseline resets such as compaction)
    - add a regression test for `InitialHistory::New` and update affected
    deterministic tests / snapshots around developer-message layout,
    collaboration instructions, personality updates, and compact request
    shapes
    
    ## Notes
    - this PR does not add any special empty-thread `/compact` behavior
    - most of the snapshot churn is the direct result of moving the initial
    model-visible context from startup to the first real turn, so first-turn
    request layouts no longer contain a pre-user startup copy of permissions
    / environment / other developer-visible context
    - remote manual `/compact` with no prior user still skips the remote
    compact request; local first-turn `/compact` still issues a compact
    request, but that request now reflects the lack of startup-seeded
    context
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • Clarify locked role settings in spawn prompt (#14283)
    - tell agents when a role pins model or reasoning effort so they know
    those settings are not changeable
    - add prompt-builder coverage for the locked-setting notes
  • feat(core): emit turn metric for network proxy state (#14250)
    ## Summary
    - add a per-turn `codex.turn.network_proxy` metric constant
    - emit the metric from turn completion using the live managed proxy
    enabled state
    - add focused tests for active and inactive tag emission
  • spawn prompt (#14362)
    # External (non-OpenAI) Pull Request Requirements
    
    Before opening this Pull Request, please read the dedicated
    "Contributing" markdown file or your PR may be closed:
    https://github.com/openai/codex/blob/main/docs/contributing.md
    
    If your PR conforms to our contribution guidelines, replace this text
    with a detailed and high quality description of your changes.
    
    Include a link to a bug report or enhancement request.
  • Add ALL_TOOLS export to code mode (#14294)
    So code mode can search for tools.
  • chore: wire through plugin policies + category from marketplace.json (#14305)
    wire plugin marketplace metadata through app-server endpoints:
    - `plugin/list` has `installPolicy` and `authPolicy`
    - `plugin/install` has plugin-level `authPolicy`
    
    `plugin/install` also now enforces `NOT_AVAILABLE` `installPolicy` when
    installing.
    
    
    added tests.
  • fix(otel): make HTTP trace export survive app-server runtimes (#14300)
    ## Summary
    
    This PR fixes OTLP HTTP trace export in runtimes where the previous
    exporter setup was unreliable, especially around app-server usage. It
    also removes the old `codex_otel::otel_provider` compatibility shim and
    switches remaining call sites over to the crate-root
    `codex_otel::OtelProvider` export.
    
    ## What changed
    
    - Use a runtime-safe OTLP HTTP trace exporter path for Tokio runtimes.
    - Add an async HTTP client path for trace export when we are already
    inside a multi-thread Tokio runtime.
    - Make provider shutdown flush traces before tearing down the tracer
    provider.
    - Add loopback coverage that verifies traces are actually sent to
    `/v1/traces`:
      - outside Tokio
      - inside a multi-thread Tokio runtime
      - inside a current-thread Tokio runtime
    - Remove the `codex_otel::otel_provider` shim and update remaining
    imports.
    
    ## Why
    
    I hit cases where spans were being created correctly but never made it
    to the collector. The issue turned out to be in exporter/runtime
    behavior rather than the span plumbing itself. This PR narrows that gap
    and gives us regression coverage for the actual export path.
  • Allow bool web_search in ToolsToml (#14352)
    Summary
    - add a custom deserializer so `[tools].web_search` can be a bool
    (treated as disabled) or a config object
    - extend core and app-server tests to cover bool handling in TOML config
    
    Testing
    - Not run (not requested)
  • Responses: set x-client-request-id as convesration_id when talking to responses (#14312)
    Right now we're sending the header session_id to responses which is
    ignored/dropped. This sets a useful x-client-request-id to the
    conversation_id.
  • fix(arc_monitor): api path (#14290)
    This PR just fixes the API path for ARC monitor.
  • Add snippets annotated with types to tools when code mode enabled (#14284)
    Main purpose is for code mode to understand the return type.
  • Split spawn_csv from multi_agent (#14282)
    - make `spawn_csv` a standalone feature for CSV agent jobs
    - keep `spawn_csv -> multi_agent` one-way and preserve restricted
    subagent disable paths
  • Add realtime start instructions config override (#14270)
    - add `realtime_start_instructions` config support
    - thread it into realtime context updates, schema, docs, and tests
  • Make unified exec session_id numeric (#14279)
    It's a number on the write_stdin input, make it a number on the output
    and also internally.