Decodex

Signal layer for Codex. GitHub-first, release-aware, and optimized for what is worth trying next.

19 signals worth trying now 39 behavior shifts tracked · Latest Mar 20, 2026
Are we reset today? No

Preview changes

From to

59 commits ahead 58 tracked signals Preview live since Mar 20, 2026 GitHub compare

Tracked changes

19 changes stand out first for this version pair.

  1. Behavior Change
    Resumed threads now restore generated image history

    Merged PR #15223 restores image-generation items in resumed thread history and preserves the saved paths tied to those earlier outputs.

    Try Resume a thread that previously generated images, then inspect the thread history and completed items for restored image entries and saved paths.

    Full signal
  2. Behavior Change
    App server now syncs remote plugins once at startup

    Merged PR #15264 adds a one-time startup remote plugin sync so app-server startup can reconcile curated plugin state automatically.

    Try Start an app-server session in a codex_home with plugins enabled and remote plugin sync configured, then open the plugin list on first startup.

    Full signal
  3. Try Now
    A first /plugins browser lands in the TUI

    Merged PR #15215 adds a first /plugins browser to both tui and tui_app_server, with listing, search, and read-only plugin detail views.

    Try Launch Codex CLI with --enable plugins, run /plugins, search the curated marketplace, and open a plugin detail view. Optionally repeat with --enable tui_app_server.

    Full signal
  4. Behavior Change
    Argument-comment lint now uses the released DotSlash artifact by default

    PR #15199 retools the repository's standard argument-comment lint path to use a checked-in DotSlash package and introduces a separate source-build wrapper path, while fixing rustup/toolchain compatibility in the prebuilt runner.

    Try Check out the PR version, run just argument-comment-lint (or CI argument_comment_lint_prebuilt path in rust-ci.yml), and confirm it executes via tools/argument-comment-lint/run-prebuilt-linter.sh with the DotSlash manifest.

    Full signal
  5. Try Now
    plugin/install now installs bundled MCP servers

    Merged PR #15195 extends plugin/install so marketplace plugins can install their bundled MCP servers during the install flow instead of leaving that as a separate manual step.

    Try Enable plugins, call plugin/install for a plugin that ships an .mcp.json, then issue a follow-up plugin or MCP read in the same session.

    Full signal
  6. Behavior Change
    Generated images now save under codex_home instead of a temp directory

    Merged PR #15222 moves generated-image artifacts out of transient temp paths and into a predictable location under codex_home.

    Try Generate an image from a Codex build that includes PR #15222, then inspect the active codex_home directory for a generated_images/<thread_id>/ subtree.

    Full signal
  7. Try Now
    mcpServer/startupStatus/updated lands in API v2

    Merged PR #15220 promotes MCP startup progress to a first-class API v2 notification instead of leaving it as a legacy internal event.

    Try Connect to the app-server v2 notification stream, trigger an MCP server startup or refresh, and listen for mcpServer/startupStatus/updated events.

    Full signal
  8. Behavior Change
    TUI image history now shows generated files as file URIs

    PR #15154 updates Codex TUI output so image-generation history entries render saved image locations as full file:// URIs (for example file:///tmp/...) instead of plain local paths, across both TUI binaries.

    Try Generate an image in the TUI workflow and inspect the resulting history row; verify the saved location is shown as a file://... path (e.g., file:///tmp/ig-1.png) in place of /tmp/..., then open it in VSCode Terminal.

    Full signal
  9. Behavior Change
    Product-scoped plugins and skills via session source

    PR 15041 makes session source a first-class input with --session-source and uses it to filter plugin installation and skill visibility by product, so different Codex surfaces can expose different plugin catalogs.

    Try Start app-server with --session-source chatgpt or another custom source, then list or install marketplace plugins that declare policy.products restrictions.

    Full signal
  10. Behavior Change
    Codex now distinguishes directory mentions from file mentions

    Merged PR #14970 adds basic directory-mention support by carrying directory vs. file match metadata through fuzzy file search results and related protocol schemas.

    Try On a build that includes PR #14970, trigger fuzzy file search or mention completion for a known folder and a similarly named file, then inspect the returned mention/search result payloads or UI labels for directory-specific handling.

    Full signal
  11. Capability
    Stop and UserPromptSubmit hooks now receive the active turn_id

    Merged PR #15118 adds a Codex-specific turn_id field to the Stop and UserPromptSubmit hook payloads so hook scripts can tie each invocation to a specific conversation turn.

    Try Enable Stop or UserPromptSubmit hooks in a build that includes PR #15118, print the incoming JSON payload in your hook script, and run two prompts in the same session.

    Full signal
  12. Capability
    Python SDK adds thread.run() convenience methods for one-shot turns

    Merged PR #15088 adds thread.run(...) and async thread.run(...) to the Python SDK, giving users a simpler path for common prompt-response flows without manually creating and running a turn handle.

    Try In a Codex build that includes PR #15088, start a Python SDK thread with codex.thread_start(...) and call thread.run("Say hello in one sentence.") or await thread.run("Say hello in one sentence.") in the async API.

    Full signal
  13. Capability
    Codex plugin listings now expose featured plugin IDs

    Merged PR #15042 adds a featuredPluginIds array to plugin/list responses and wires it to the curated remote plugin service.

    Try Call plugin/list from a Codex build that includes PR #15042 while remote plugin sync is available and the session is authenticated, then inspect the response payload.

    Full signal
  14. Behavior Change
    Code-mode update_plan now returns a structured result

    This merged PR updates the plan tool path so code-mode calls to tools.update_plan now yield a parseable result payload, and adds a regression test for the nested call shape.

    Try In code mode, run an update_plan call like const result = await tools.update_plan({ plan: [{ step: 'Run update_plan', status: 'in_progress' }] }); text(JSON.stringify(result)); and check the response parses as JSON.

    Full signal
  15. Behavior Change
    Realtime handoff output now labels the agent's final message

    Merged PR #15077 changes realtime handoff payloads so the emitted assistant text is prefixed with an "Agent Final Message": label instead of sending the raw message body alone.

    Try Run a Codex build that includes PR #15077, trigger a realtime conversation handoff, and inspect the emitted conversation.handoff.append payload in either the v1 or Realtime v2 websocket stream.

    Full signal
  16. Behavior Change
    Codex TUI now warns at startup when legacy custom prompts are present

    Merged PR #15076 adds a startup deprecation notice in the Codex TUI when it finds custom prompts under $CODEX_HOME/prompts, with guidance to migrate them to skills.

    Try Run a Codex build that includes PR #15076, place at least one custom prompt file under $CODEX_HOME/prompts, start the TUI, and confirm a deprecation notice appears at startup telling you to convert prompts into skills with $skill-creator.

    Full signal
  17. Behavior Change
    Code mode can now pass view_image results straight into image()

    Merged PR #15072 makes Codex code mode treat view_image as a structured image producer, so scripts can hand its result directly to image() instead of manually extracting a URL string.

    Try Run a Codex build that includes PR #15072 in code mode, call const img = await tools.view_image({ path: "/absolute/path/to/local-image.png" }); image(img);, and confirm the script can attach the local image without manually pulling out img.image_url.

    Full signal
  18. Behavior Change
    Code mode now surfaces tool failures as exceptions

    Merged PR #15075 changes Codex code mode so nested tool-call failures propagate as errors you can catch, instead of being folded into normal tool output.

    Try Run a Codex build that includes PR #15075, execute a code-mode script that wraps an invalid nested tool call such as await tools.exec_command({}) in try/catch, and confirm the catch block receives the error.

    Full signal
  19. Behavior Change
    App-server TUI now restores composer history

    Merged PR #14945 brings prompt-history recall and persistence to the app-server TUI, so Up/Down navigation and cross-session history now work like the legacy TUI.

    Try Run a Codex build that includes PR #14945 in app-server TUI mode, submit a prompt, then press Up in the composer or restart the session and press Up again to recall earlier entries.

    Full signal

Latest signals

Codex adds a cross-platform V8 integration proof of concept

Merged PR #15203 adds a v8-poc crate plus Bazel and CI wiring that proves Codex can link and run V8 across the main supported non-Windows target platforms.

This does not expose a new end-user feature yet, but it gives Codex a verified integration path for embedding V8 in future runtime or tooling work without treating cross-platform linking as an open risk.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 3 proof points
  • The PR body explicitly says the new dummy v8-poc project demonstrates that Codex can successfully link and use V8 on the platforms it wants to target.
  • codex-rs/Cargo.toml adds a new v8-poc workspace member and pins v8 = =146.4.0, while codex-rs/v8-poc/src/lib.rs adds a proof-of-concept crate with tests that initialize V8 and evaluate an expression.
  • MODULE.bazel, third_party/v8/BUILD.bazel, and the Rust CI and release workflows add target-specific V8 artifact wiring, including musl overrides and Bazel-side source-built archives for shipped platforms.
  1. PR Add v8-poc consumer of our new built v8 #15203
  2. Commit Add v8-poc consumer of our new built v8 733e868
  3. Commit Build v8-poc as part of CI 20ce301
  4. Commit Working on all platforms 9ae2f06
  5. Commit Ignore codex-v8-poc 1fb916a
  6. Commit Prepull our artifacts for musl f8a239e
  7. Commit Path b6b58e1
  8. Commit Fix bazel build for v8-poc 7b80661
  9. Commit Repatch rusty_v8 393b560
  10. Commit Always link v8 6c0deb2
  11. Commit Build v8 for our bazel platforms ffbe942
  12. Commit Remove local=1 e43c0f6
  13. Commit darwin exception 9edd9a3

Curated plugin sync now prefers Git with HTTP fallback

PR #15275 moves curated plugin sync into startup synchronization and changes it so startup sync tries git-based curated-plugin fetching first, with a fallback path for failures.

This improves startup resilience for plugin discovery by broadening transport options during curated plugin refresh, reducing the chance that a temporary Git-only failure blocks plugin sync behavior.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • The primary PR is explicitly about this behavior: title feat: prefer git for curated plugin sync and body start with git clone, fallback to http.
  • codex-rs/core/src/plugins/startup_sync.rs is heavily expanded and includes the curated-sync pipeline, while codex-rs/core/src/plugins/curated_repo.rs is removed, indicating the sync mechanism was relocated and updated.
  • codex-rs/core/src/plugins/mod.rs now re-exports curated_plugins_repo_path, read_curated_plugins_sha, and sync_openai_plugins_repo from startup_sync, showing the canonical call path for curated sync now goes through that module.
  • Commit metadata includes fallback in all errors, matching the PR intent to use HTTP as a fallback path when sync encounters failures.
  • codex-rs/core/src/plugins/manager.rs adds a remote_sync_lock: Mutex<()>, suggesting startup sync is serialized to reduce concurrent sync races at runtime. Each change set is backed by moved and newly added tests in startup_sync_tests.rs, replacing the removed curated_repo_tests.rs.
  1. PR feat: prefer git for curated plugin sync #15275
  2. Commit refactor: move curated plugin sync into startup_sync 7a7d7a3
  3. Commit feat: prefer git for curated plugin sync fa898ba
  4. Commit fallback in all errors 5af4513

Resumed threads now restore generated image history

Merged PR #15223 restores image-generation items in resumed thread history and preserves the saved paths tied to those earlier outputs.

Image work no longer disappears when you come back to an older thread. That makes long-running image sessions easier to resume, audit, and copy from without losing the earlier generation context.

Try now Resume a thread that previously generated images, then inspect the thread history and completed items for restored image entries and saved paths.

Resumed threads should show earlier image-generation items and preserve saved image paths instead of dropping that part of the history.

Sources and evidence 3 proof points
  • The PR body explicitly says image-generation items should be restored in resumed thread history.
  • The protocol schemas add a savedPath field to image-related notifications and thread responses so image history can carry the persisted file location.
  • The commit sequence includes Persist image generation end events for history replay and Add tests for resumed image history preservation, which confirms this is an intended behavior change.
  1. PR Feat/restore image generation history #15223
  2. Commit Restore image generation items in resumed thread history f065885
  3. Commit Persist image generation end events for history replay 005e6fc
  4. Commit Restore saved image paths in resumed history e870aae
  5. Commit Add copy guidance for generated images 85464fb
  6. Commit Fix tui app server image generation adapter f1a6367
  7. Commit Add tests for resumed image history preservation ace552c
  8. Commit Remove temporary image history proof tests b1ed4a7
  9. Commit Avoid duplicating saved image blobs in limited rollouts 050a478
  10. Commit Remove rollout image persistence test 66aa6d1
  11. Commit Revert rollout image blob clearing 6e7d372
  12. Commit Trim restore image history branch scope 0552a98

Guardian follow-up reviews now include a reusable review-context reminder

PR 15262 refines guardian follow-up review behavior by adding a short reminder to follow-up prompts and updating tests/snapshots so reused prior-review context is surfaced more consistently during repeat approvals.

For users hitting repeated guardian follow-up requests, the system now explicitly states how to proceed with previously rejected actions, reducing ambiguity and making the second-pass approval flow clearer and safer without changing core functionality elsewhere.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • PR body says this change adds a guardian follow-up reminder and caches prior-review state on the guardian session, indicating user-visible follow-up behavior is the intent.
  • commits show a two-step PR implementation focused on the same feature (Add guardian follow-up reminder and wording refinement), supporting a cohesive behavior change rather than unrelated refactors.
  • codex-rs/core/src/guardian/review_session.rs introduces GUARDIAN_FOLLOWUP_REVIEW_REMINDER and related session-level plumbing, directly aligning with the stated PR intent to alter follow-up request messaging.
  • codex-rs/core/src/guardian/snapshots/...guardian_followup_review_request_layout.snap and codex-rs/core/src/guardian/tests.rs were updated to expect/verify the new reminder text in follow-up request output.
  1. PR Add guardian follow-up reminder #15262
  2. Commit Add guardian follow-up reminder 0c5c63f
  3. Commit Update guardian followup reminder wording 6956900

App server now syncs remote plugins once at startup

Merged PR #15264 adds a one-time startup remote plugin sync so app-server startup can reconcile curated plugin state automatically.

Plugin-enabled setups become closer to it just shows up. Early users do not have to rely on a later manual sync path before the plugin list reflects remote curated state.

Try now Start an app-server session in a codex_home with plugins enabled and remote plugin sync configured, then open the plugin list on first startup.

When the app server starts with plugin sync configured, remote curated plugin state should be reconciled automatically on first startup instead of waiting for a later explicit sync path.

Sources and evidence 3 proof points
  • The PR body says early users with enabled apps should have plugins enabled as part of initial setup.
  • The core plugin manager now routes startup work through startup_sync.rs and renames the old curated-repo sync path into broader startup plugin tasks.
  • The integration test app_server_startup_remote_plugin_sync_runs_once verifies that the remote plugin sync happens once at startup.
  1. PR feat: Add One-Time Startup Remote Plugin Sync #15264
  2. Commit feat: Add One-Time Startup Remote Plugin Sync 56c33c2

Hooks are disabled on Windows sessions in Codex Rust hook engine

The PR changes hook initialization so Windows sessions skip lifecycle hook discovery and return with no hooks plus a warning, reflecting that codex_hooks is not supported on Windows yet.

This prevents Windows users from hitting unsupported-hook execution paths by failing safely with a clear warning, which is a user-facing behavior change that keeps sessions usable while hook support is incomplete on that platform.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • Primary PR metadata identifies the change as “Disable hooks on windows for now” and includes a temporary-status body (“We'll verify a bit later... and re-enable”).
  • The modified file codex-rs/hooks/src/engine/mod.rs adds a cfg!(windows) early return that initializes handlers as empty and sets a warnings message stating hooks are disabled because lifecycle hooks are not yet supported on Windows.
  • Bundle evidence shows exactly one commit (933ef3ccbdeb1877f2f9ba45d1379826f4c63088) with message “disable hooks on windows for now,” and that commit is tied to the merged PR 15252.
  • The patch shows no deletions and only additions around hook startup logic, indicating a targeted behavioral gate rather than broad refactoring.
  1. PR Disable hooks on windows for now #15252
  2. Commit disable hooks on windows for now 933ef3c

A first /plugins browser lands in the TUI

Merged PR #15215 adds a first /plugins browser to both tui and tui_app_server, with listing, search, and read-only plugin detail views.

Plugin discovery moves into the terminal itself. Early users no longer need to hunt for plugin metadata outside Codex just to browse what is available and inspect what a plugin contains.

Try now Launch Codex CLI with --enable plugins, run /plugins, search the curated marketplace, and open a plugin detail view. Optionally repeat with --enable tui_app_server.

The TUI should expose a searchable /plugins flow with loading states, plugin detail views, and back navigation, and the same flow should work under tui_app_server.

--enable plugins --enable tui_app_server
Sources and evidence 3 proof points
  • The PR body explicitly describes a preliminary /plugins menu in both tui and tui_app_server, including loading, search, and detail-view behavior.
  • The testing section in the PR body documents the exact /plugins flow to verify, including disabled behavior when plugins are not enabled.
  • The patch adds plugin list and plugin read wiring in tui/src/app.rs and tui/src/app_event.rs, which is the concrete UI plumbing for the new menu.
  1. PR Initial plugins TUI menu - list and read only. tui + tui_app_server #15215
  2. Commit Initial plugins TUI - list and read only. tui + tui_app_server ff5efc8
  3. Commit Combine marketplace_path and plugin_name into PluginReadParams a101165

Argument-comment lint now uses the released DotSlash artifact by default

PR #15199 retools the repository's standard argument-comment lint path to use a checked-in DotSlash package and introduces a separate source-build wrapper path, while fixing rustup/toolchain compatibility in the prebuilt runner.

This reduces lint turnaround in normal dev and CI workflows by avoiding repeated source builds and making the lint job more deterministic. It also lowers environment-fragility on CI, especially Windows, by standardizing toolchain context handling for the shipped prebuilt lint package.

Try now Check out the PR version, run just argument-comment-lint (or CI argument_comment_lint_prebuilt path in rust-ci.yml), and confirm it executes via tools/argument-comment-lint/run-prebuilt-linter.sh with the DotSlash manifest.

Linting uses the checked-in prebuilt package path, so normal local/CI runs avoid rebuilding the lint from source and no longer fail due to the Windows RUSTUP_HOME/toolchain naming assumptions the PR fixes.

Sources and evidence 4 proof points
  • PR #15199 body explicitly states the lint path is moving to the released DotSlash artifact for normal CI and just workflows, while preserving source-build for active lint development.
  • The files changes include adding tools/argument-comment-lint/argument-comment-lint and run-prebuilt-linter.sh, plus wrapper behavior updates in tools/argument-comment-lint/run.sh and src/bin/argument-comment-lint.rs to normalize nightly toolchain naming and infer RUSTUP_HOME when needed.
  • CI and task wiring changed to enforce this path: .github/workflows/rust-ci.yml is split into dedicated lint jobs and justfile routes argument-comment-lint to the prebuilt wrapper instead of the source wrapper.
  • A follow-up evidence bundle commit (a1b8effb15edfc337ba58215adc4d70f60c548ac) adds compatibility fixes across Windows sandbox call sites to make the stricter lint clean on current code, supporting the PR’s stated goal of a green prebuilt lint run.
  1. PR Use released DotSlash package for argument-comment lint #15199
  2. Commit Use released DotSlash package for argument-comment lint a1b8eff

Exec process layer now uses a shared local/remote abstraction

PR #15233 refactors the exec-server process stack by extracting a shared process interface, wiring Environment and handlers to it, and adding explicit local and remote implementations plus shared execution tests.

The change reduces the chance of local and remote command-execution behavior diverging by enforcing a single process contract for both backends. That gives users more reliable command execution behavior and makes future runtime backend changes safer and less likely to introduce regressions.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • The PR body states the new structure explicitly: LocalProcess is the real implementation, RemoteProcess is a thin network proxy, and Environment now exposes ExecProcess.
  • local_backend.rs is removed and replaced by new process.rs, local_process.rs, and remote_process.rs, indicating a concrete local/remote split behind a shared ExecProcess trait.
  • environment.rs is changed to hold an Arc<dyn ExecProcess> and initialize an execution strategy (local default with optional remote override), so consumers depend on a common process API.
  • Server wiring adds process_handler.rs and updates server/handler.rs to delegate execution handling through that adapter, centralizing execution semantics.
  • The new exec_process.rs test exercises process behavior for both local and remote modes, directly validating parity across backends.
  1. PR Split exec process into local and remote implementations #15233
  2. Commit Split exec process into local and remote implementations 1cb2425
  3. Commit Initialize default local exec process 23b8169
  4. Commit Avoid expect in default environment setup c23d879
  5. Commit Address exec process review comments 63333b0
  6. Commit Fix environment test after accessor cleanup 25585b9

Refactor: move feature-flag plumbing into a dedicated codex-features crate

This PR reorganizes feature flag definitions and APIs into a new codex-features crate and rewires existing binaries, libraries, and tests to consume that crate instead of feature symbols from codex-core. The change also updates workspace dependencies so features participates as a first-class workspace member and dependency across the Rust workspace.

Decoupling feature gating from codex-core reduces cross-crate coupling and creates a cleaner ownership boundary for feature control, which improves maintainability as feature definitions and warning behavior can evolve without being tied to core runtime changes. It also helps avoid broad feature-related churn inside core, making future CLI/server/TUI edits safer and easier to release.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • The PR body explicitly states the intent: "Split the feature system into a new codex-features crate" and migrate codex-core and workspace consumers to new config and warning APIs.
  • Primary PR metadata includes commit dc4350ff7d118af85cb2eff28447ce9c440f0610 with title Split features into codex-features crate and merged state.
  • New crate wiring was added in codex-rs/features/Cargo.toml plus codex-rs/features/BUILD.bazel, and the workspace now references it from codex-rs/Cargo.toml and multiple component Cargo.toml files.
  • File-level patches repeatedly replace imports like codex_core::features::... with codex_features::... across app server, core, CLI, TUI, and MCP crates, confirming the migration is system-wide rather than localized.
  1. PR Split features into codex-features crate #15253
  2. Commit Split features into codex-features crate dc4350f

Plugin product gating now distinguishes missing from explicitly empty product lists

This PR changes plugin product restrictions from a single empty-list semantics to explicit tri-state behavior: omitted product constraints now mean unrestricted, while an explicit empty list means no products are allowed. That fixes ambiguous plugin marketplace eligibility behavior.

When product restrictions are serialized, missing and empty data previously collapsed in practice, creating unclear plugin eligibility rules. This change makes plugin access decisions explicit and safer by preventing accidental all-products access for entries that should be blocked, and by making restrictive intent expressible.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • The PR title/body (fix: Distinguish missing and empty plugin products), plus merge commit 93e87d1e8182afdac575d679564be6d677d4a42f, explicitly define the semantic change.
  • codex-rs/core/src/plugins/marketplace.rs now matches policy.products as None => true, Some([]) => false, and only allows a match for non-empty product lists, replacing the prior is_empty-based rule.
  • codex-rs/core/src/plugins/manager.rs mirrors this with Option<&[Product]> handling (None => true, Some([]) => false) so manager-level checks follow the same missing-vs-empty contract.
  • Plugin model and tests (codex-rs/core/src/plugins/marketplace.rs, manager.rs, marketplace_tests.rs, manager_tests.rs) were updated to carry Option<Vec<Product>> and use products: None for unrestricted plugin entries, confirming intended usage.
  1. PR fix: Distinguish missing and empty plugin products #15263
  2. Commit fix: Distinguish missing and empty plugin products 93e87d1

Added a full-buffer exec capture mode with safer pipe draining

PR #15254 updates the exec pipeline to make output-capture semantics explicit via an ExecCapturePolicy, adding a FullBuffer mode for trusted internal helpers while preserving existing shell-style capped behavior by default.

This improves reliability and correctness for internal tool invocations by preventing accidental truncation on trusted helpers that need complete output, while keeping the long-standing capped/timeout behavior for normal shell-style tool calls and avoiding hangs when child processes leave inherited stdout/stderr pipes open after exit.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 6 proof points
  • primary_pr.body states the change was introduced to separate shell-style output capping from internal-helper execution needs and to avoid output truncation/hang risks for trusted helpers.
  • codex-rs/core/src/exec.rs adds ExecCapturePolicy with ShellTool (default) and FullBuffer, making capture strategy explicit in ExecParams.
  • codex-rs/app-server/src/codex_message_processor.rs wires disable_output_cap to ExecCapturePolicy::FullBuffer, so callers can opt into uncapped buffering when appropriate.
  • The exec and sandbox paths now accept and propagate capture_policy through structs in codex-rs/core/src/sandboxing/mod.rs, codex-rs/core/src/tools/runtimes/unix_escalation.rs, and related handlers/tests, indicating cross-cutting behavior change rather than a single-site tweak.
  • codex-rs/core/src/exec_tests.rs and related test updates rename coverage to read_output_limits_retained_bytes_for_shell_capture and add full-buffer/inherited-pipe considerations, showing guard-preservation (IO_DRAIN_TIMEOUT_MS) for edge cases.
  • Change set includes updates across many construction sites (shell.rs, user_shell.rs, apply_patch.rs, js_repl/mod.rs, etc.), consistent with PR-first evidence that semantics are applied consistently where exec is invoked.
  1. PR core: add a full-buffer exec capture policy #15254
  2. Commit core: add an exec capture policy for full output 90cb67e

plugin/install now installs bundled MCP servers

Merged PR #15195 extends plugin/install so marketplace plugins can install their bundled MCP servers during the install flow instead of leaving that as a separate manual step.

Plugin setup becomes much closer to one step. Users and client builders get fewer post-install surprises when a plugin depends on MCP servers or requires OAuth to complete setup.

Try now Enable plugins, call plugin/install for a plugin that ships an .mcp.json, then issue a follow-up plugin or MCP read in the same session.

A plugin install that bundles MCP servers should make those servers available immediately after install, with auth surfaced as part of the install flow when needed.

Sources and evidence 3 proof points
  • The app-server README now documents plugin/install as installing bundled MCPs in addition to returning auth policy information.
  • The new plugin_mcp_oauth.rs path wires OAuth login handling for MCP servers discovered during plugin installation.
  • The integration test plugin_install_makes_bundled_mcp_servers_available_to_followup_requests verifies that bundled MCP servers become usable right after install.
  1. PR [plugins] Install MCPs when calling plugin/install #15195
  2. Commit update 1a910fd

Auth stack moved into dedicated codex-login crate

PR #15150 refactors auth ownership in openai/codex by relocating auth implementation details into codex-login and making codex-core re-export a compatibility surface for existing callers.

The split reduces cross-crate coupling around authentication and keeps legacy call sites working, which makes future auth changes and maintenance less risky while preserving current CLI/TUI/app-server behavior.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • PR body explicitly states the intent: move auth implementation and token data into codex-login, while keeping codex-core re-exporting that surface.
  • New auth-focused files were added under codex-rs/login/src/auth (including error.rs and util.rs), and logic previously in core files (for example core/src/error.rs and core/src/util.rs) was moved to those modules.
  • codex-rs/core/src/lib.rs now re-exports codex_login auth/default-client modules so downstream crates can continue using core-facing auth APIs after the move.
  • Consumers were updated across app-server, exec, tui, and cli to import auth structures from codex_login compatibility paths, showing an intentional dependency re-alignment rather than a feature addition.
  1. PR Move auth code into login crate #15150
  2. Commit Move terminal module to its own crate df7a587
  3. Commit Rename terminal crate to terminal-detection 3661c08
  4. Commit codex: fix CI failure on PR #15216 9e6c404
  5. Commit Move auth code into login crate 4b9dde5
  6. Commit codex: clean up auth import style on PR #15150 a717396
  7. Commit codex: fix CI failure on PR #15150 905255d
  8. Commit codex: avoid default_client imports in login on PR #15150 59c056e
  9. Commit codex: restore login auth API surface on PR #15150 499c319
  10. Commit unify 112d231

Add a dedicated Bazel pipeline for building and releasing rusty_v8 artifacts

PR #15021 adds a new Bazel-based workflow for building and packaging rusty_v8, including musl targets for x86_64/aarch64, while removing third_party/v8 from the default CI test path so V8 work is handled by dedicated canary/release flows.

This gives the project a reliable way to produce and publish prebuilt V8 artifacts for additional toolchains (notably musl), improving build reproducibility for dependents and reducing pressure on normal CI by isolating heavy V8 builds into explicit workflows.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • The PR body explicitly says the approach is to use rusty_v8 everywhere possible and to build a musl V8 from source for x86/aarch64, with a release step for consumption.
  • Added .github/scripts/rusty_v8_bazel.py introduces the musl-oriented Bazel build orchestration and packaging metadata used by the new release path.
  • Added .github/workflows/v8-canary.yml and .github/workflows/rusty-v8-release.yml, creating a dedicated canary/release lane (including optional GitHub release publishing) for V8 artifacts instead of coupling them to standard CI.
  • Updated build metadata in MODULE.bazel, MODULE.bazel.lock, and new Bazel patches under patches/ to pin/use V8 14.6.202.9 plus required dependency/workspace overrides.
  • Adjusted .github/workflows/bazel.yml to exclude //third_party/v8:all from ordinary Bazel test runs, matching the PR’s “keep V8 out of ordinary CI” intent and evidence trail in commit history.
  1. PR V8 Bazel Build #15021
  2. Commit Setup a new v8-poc package d317180
  3. Commit Merge the v8 building for musl 6c2e61f
  4. Commit Update v8 version ca8204a
  5. Commit Link in the missing llvm runtime archives cef4b77
  6. Commit Version match f496726
  7. Commit Do not test this package by default d040eda
  8. Commit Add canary workflow for now dc98f8e
  9. Commit I swear no v8 4809cd1
  10. Commit Split v8-poc consumer to follow-up branch 1ab6566
  11. Commit rename to v8-canary 2d05604
  12. Commit Remove v8 from cargo.toml for now 93dbe48
  13. Commit Fix build 3b573d1
  14. Commit Hermetic python + cleanup e358585
  15. Commit skylib b9f2761
  16. Commit Build opt for release abc472b
  17. Commit Release fixes d0289aa
  18. Commit Stronger lean in to opt 14f4bd9
  19. Commit Address PR feedback f92d130
  20. Commit Drop patch to prebuilt v8 cef0a87

Split ExecServer filesystem into local and remote backends

The PR refactors filesystem handling in codex-exec-server behind a shared trait with separate local and remote implementations, and routes execution environment selection through that abstraction.

This reduces coupling between local and remote execution paths, making remote file operations a first-class implementation path rather than ad-hoc logic and improving confidence the same filesystem behavior is available in both modes. It also sets up safer future changes by isolating responsibilities and extending test coverage to both backends.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 7 proof points
  • PR narrative states the change pattern per feature: trait on environment, local implementation, remote implementation via network proxy, and handler integration for PRC requests.
  • codex-rs/exec-server/src/file_system.rs introduces the shared ExecutorFileSystem interface and supporting option/type definitions.
  • codex-rs/exec-server/src/environment.rs switches get_filesystem to return RemoteFileSystem when a remote client exists, otherwise LocalFileSystem.
  • codex-rs/exec-server/src/remote_file_system.rs adds a new remote implementation that fulfills the shared trait with protocol-level filesystem operations.
  • codex-rs/exec-server/tests/file_system.rs adds a large parameterized test module covering filesystem operations for both local and remote file systems.
  • codex-rs/exec-server/src/server/file_system_handler.rs and codex-rs/exec-server/src/server/handler.rs are updated to use the new module split and handler naming.
  • codex-rs/exec-server/src/server/transport.rs adds websocket URL output support used by the test harness (exec_server.rs).
  1. PR Refactor ExecServer filesystem split between local and remote #15232
  2. Commit Extract local and remote fs APIs 4b42ea8
  3. Commit Add parameterized file system tests ec76d77
  4. Commit Merge remote-tracking branch 'origin/main' into pakrym/compare-execserverfilesystem-and 7dc0759
  5. Commit Print exec server websocket URL 4a9479b
  6. Commit exec-server: remove expect usage in filesystem tests 4b303df

Generated images now save under codex_home instead of a temp directory

Merged PR #15222 moves generated-image artifacts out of transient temp paths and into a predictable location under codex_home.

This makes image outputs easier to find, persist, and script against. Users who rely on generated artifacts no longer have to guess where a temp file landed or whether it will disappear between runs.

Try now Generate an image from a Codex build that includes PR #15222, then inspect the active codex_home directory for a generated_images/<thread_id>/ subtree.

New image-generation outputs should land under codex_home/generated_images/<thread_id>/... instead of an OS temp directory.

Sources and evidence 3 proof points
  • The PR body explicitly says the default image-generation save directory now points at codex_home with a per-thread path.
  • The Rust helper in stream_events_utils.rs now builds image artifact paths from codex_home and a dedicated generated_images directory instead of std::env::temp_dir().
  • Tests in codex_tests.rs and stream_events_utils_tests.rs were updated to expect the new codex-home path, which confirms this is a behavior change rather than a comment-only cleanup.
  1. PR changed save directory to codex_home #15222
  2. Commit changed save directory to codex_home 5d11650
  3. Commit Collapse generated image artifact helpers 6cd6f49
  4. Commit Avoid expect in image artifact path handling f8b8920

mcpServer/startupStatus/updated lands in API v2

Merged PR #15220 promotes MCP startup progress to a first-class API v2 notification instead of leaving it as a legacy internal event.

Clients can track MCP readiness without scraping legacy events. That makes plugin UIs, status surfaces, and startup diagnostics easier to build and less brittle.

Try now Connect to the app-server v2 notification stream, trigger an MCP server startup or refresh, and listen for mcpServer/startupStatus/updated events.

API v2 clients should receive starting, ready, failed, or cancelled MCP startup updates, including the server name and optional error details.

Sources and evidence 3 proof points
  • The PR body explicitly says the legacy MCP startup update event is now exposed as an API v2 notification.
  • The protocol schemas add both McpServerStartupState and McpServerStatusUpdatedNotification, which defines the new event contract.
  • The server notification schema now registers mcpServer/startupStatus/updated as a first-class v2 notification method.
  1. PR feat(app-server): add mcpServer/startupStatus/updated notification #15220
  2. Commit feat(app-server): add mcpServer/status/updated notification 9c0fdb4
  3. Commit mcpServer/startupStatus/updated ba1d743
  4. Commit fix random bug c58e46d

Propagate MCP tool-call context through _meta

This PR shifts MCP tools/call metadata handling so MCP tool calls now carry both session and turn context in the request _meta payload, restoring end-to-end traceability across MCP interactions that previously lacked it.

By putting turn/session identifiers into MCP call metadata, the change enables better correlation of tool calls with user turns and sessions in downstream processing and observability systems, which improves debugging and incident triage for multi-step MCP workflows without changing user-facing command behavior.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 6 proof points
  • The PR body explicitly states the goal: group MCP tool calls with Codex sessions/turns and switch from header-based assumptions to _meta for tools/call due to shared rmcp-client concurrency constraints.
  • codex-rs/core/src/mcp_tool_call.rs now builds MCP request metadata via build_mcp_tool_call_request_meta(turn_context, ...), explicitly plumbing turn/session context into request metadata while preserving existing _codex_apps handling.
  • codex-rs/core/src/turn_metadata.rs adds session_id to the metadata bag and wires it through metadata construction, and codex-rs/core/src/codex.rs passes conversation_id into turn-context creation.
  • codex-rs/rmcp-client/src/rmcp_client.rs updates CallToolRequestParams transport to send per-request metadata explicitly through RMCP request options instead of relying on mutable shared client header state.
  • codex-rs/core/src/mcp_tool_call_tests.rs and codex-rs/core/tests/suite/search_tool.rs add assertions confirming _meta includes expected turn/session info (including existing resource_uri/_codex_apps expectations) for custom MCP and codex-apps flows.
  • The file changes are mostly additive metadata/transport plumbing with no removal of prior user-facing tool-call features, matching an incremental internal behavior update for observability and traceability.
  1. PR Plumb MCP turn metadata through _meta #15190
  2. Commit Revert "Forward session and turn headers to MCP HTTP requests (#15011)" bab2a28
  3. Commit Plumb MCP turn metadata through _meta 9124fe9
  4. Commit Merge RMCP tool call _meta entries edc8e17
  5. Commit Include session id in MCP turn metadata e84f542
  6. Commit Skip non-JSON apps requests in search tool test 98f97df
  7. Commit Simplify RMCP tool call _meta plumbing 88653c9
  8. Commit Restore RMCP meta local variable name db3ddea
  9. Commit Restore explicit RMCP tools/call request path cbd0700

Expose needsAuth in plugin app summaries

PR #15217 extends Codex plugin summary payloads with a new required needsAuth boolean so plugin/read/plugin/list style responses can explicitly signal whether an app requires authorization.

Clients can now distinguish auth-gated plugins from directly usable ones before launching a plugin flow, which enables cleaner UI behavior (e.g., showing auth prompts or disabled actions) without guessing from installer metadata alone.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • The PR narrative is explicitly feat: expose needs_auth for plugin/read and the merge record is openai/codex#15217.
  • Schema updates add needsAuth: boolean and require it in codex_app_server_protocol.schemas.json, codex_app_server_protocol.v2.schemas.json, v2/PluginInstallResponse.json, and v2/PluginReadResponse.json, indicating a contract-level API field addition.
  • Protocol type definitions were updated in v2/AppSummary.ts and protocol/v2.rs to carry a needs_auth/needsAuth field in AppSummary, with conversion paths updated to populate it.
  • plugin_app_helpers.rs now queries connector access/auth status before emitting plugin summaries, and returns early with plugin summaries when the auth-status service is unavailable, showing runtime handling for the new metadata.
  • Tests in plugin_install.rs were updated with needs_auth: true expectations for auth-required plugin cases, anchoring the new behavior in executable behavior checks.
  1. PR feat: expose needs_auth for plugin/read. #15217
  2. Commit feat: expose needs_auth for plugin/read. d9f6b7f

TUI image history now shows generated files as file URIs

PR #15154 updates Codex TUI output so image-generation history entries render saved image locations as full file:// URIs (for example file:///tmp/...) instead of plain local paths, across both TUI binaries.

This makes generated images easier to open directly from the terminal history in environments that treat file:// links as clickable resources, improving discoverability right after generation.

Try now Generate an image in the TUI workflow and inspect the resulting history row; verify the saved location is shown as a file://... path (e.g., file:///tmp/ig-1.png) in place of /tmp/..., then open it in VSCode Terminal.

Generated-image entries now present Saved to values as URI links, enabling easier direct opening of files in supported terminals and reducing manual path-copy steps.

Sources and evidence 5 proof points
  • Primary PR title/body says it adds full image paths so generated images are open-able in TUI, currently limited to VSCode Terminal.
  • In codex-rs/tui/src/chatwidget.rs and codex-rs/tui_app_server/src/chatwidget.rs, image generation end handling now maps saved paths through url::Url::from_file_path(...).to_string(), producing URI-formatted paths.
  • In both codex-rs/tui/src/history_cell.rs and codex-rs/tui_app_server/src/history_cell.rs, rendering changed from saved_to to saved_path and directly displays the formatted path string after Saved to:.
  • Snapshot and test updates in TUI history outputs/tests replace /tmp/ig-1.png with file:///tmp/ig-1.png, showing the visible output change.
  • Additional identical updates in both codex-rs/tui and codex-rs/tui_app_server indicate the behavior applies to both terminal UI variants.
  1. PR adding full imagepath to tui #15154
  2. Commit adding full imagepath to tui 51153be
  3. Commit added snapshots 8ca6ef3
  4. Commit flaky code f27a4e9

Windows shell guidance now includes explicit destructive-command safety rules

This PR updates Codex tool descriptions and related tests to give stronger, consistent Windows safety guidance for filesystem-destructive commands, while a small supporting server change fixes construction/default behavior for filesystem access.

It reduces the chance of dangerous cross-shell command patterns on Windows by clearly documenting safer practices in the tool specs users see before execution, which helps prevent accidental deletes or moves from mis-composed shell pipelines.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • The PR’s main narrative is a documentation-focused change: primary_pr.body adds explicit Windows destructive command rules for exec_command, shell, and shell_command (avoid cross-shell composition, prefer native PowerShell cmdlets, validate absolute workspace-local targets before recursive delete/move).
  • In codex-rs/core/src/tools/spec.rs, the bundle shows a new windows_destructive_filesystem_guidance() helper plus windows_shell_safety_description() integration, indicating the safety guidance is part of tool-spec text generation.
  • codex-rs/core/src/tools/spec_tests.rs was updated to include the revised Windows text in expected shell spec output, tying the change to public-facing schema/help behavior and protecting against regression.
  • codex-rs/exec-server/src/server/filesystem.rs includes Environment::default().get_filesystem() and the commit sequence includes compile/test fixes, supporting the same PR as a cohesive maintenance pass around rollout stability.
  1. PR add specific tool guidance for Windows destructive commands #15207
  2. Commit add specific tool guidance for Windows destructive commands 4151776
  3. Commit fix test compile error 5c8adeb
  4. Commit fix environment compile error 58ab27f
  5. Commit fix failing test 503fc56

Move terminal utilities into a dedicated terminal-detection crate

This PR refactors terminal-related code by extracting core/src/terminal.rs and its tests into a new terminal-detection workspace crate, then rewires CLI, core, TUI, TUI app server, and MCP-related code to consume the new crate through existing imports and dependency entries.

The change centralizes terminal detection and user-agent/terminal-type logic behind a single shared crate, which reduces duplicate terminal dependencies across binaries and should make terminal behavior updates easier to maintain consistently across the CLI and UI stacks. User-visible behavior is expected to remain unchanged, so the practical impact is mostly engineering hygiene and modularity.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • Primary PR body states the refactor goal: move core/src/terminal.rs and tests into a standalone terminal-detection crate and update direct consumers to depend on codex-terminal-detection.
  • codex-rs/Cargo.toml, codex-rs/Cargo.lock, and multiple crate manifests (codex-rs/cli/Cargo.toml, codex-rs/core/Cargo.toml, codex-rs/tui/Cargo.toml, codex-rs/tui_app_server/Cargo.toml) now include terminal-detection as a workspace member/dependency.
  • codex-rs/core/src/lib.rs removes the previous pub mod terminal, while cli, core, tui, tui_app_server, and MCP test code replace codex_core::terminal::* imports with codex_terminal_detection::*.
  • codex-rs/terminal-detection/BUILD.bazel and codex-rs/terminal-detection/Cargo.toml are added, and terminal-related source/tests are moved (src/lib.rs, src/terminal_tests.rs) indicating the new crate boundary is active in repository structure.
  1. PR Move terminal module to terminal-detection crate #15216
  2. Commit Move terminal module to its own crate df7a587
  3. Commit Rename terminal crate to terminal-detection 3661c08
  4. Commit codex: fix CI failure on PR #15216 9e6c404

Trace spans now include turn IDs for app-server turn APIs

This PR adds instrumentation to propagate turn.id into app-server request tracing for turn/start, turn/steer, and turn/interrupt, plus tests to verify the attribute is present.

It gives operators and maintainers a reliable way to correlate all spans for a single turn across the app-server lifecycle, making debugging and latency triage more precise without changing API payloads.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • PR #15206 explicitly sets the goal to tag app-server turn spans with turn.id for turn/start, turn/steer, and turn/interrupt.
  • primary_pr.title and the two commits (7f9f93e057d7c73a84ea071aabcc88ddfe743150, 8e042a093cceac78a48d1d8cabd6f6247e51532f) are narrowly scoped to tracing and turn-id propagation.
  • app_server_tracing.rs adds a turn.id field into the server request span template.
  • codex_message_processor.rs records turn IDs into request context for both turn start and turn interrupt request flows.
  • outgoing_message.rs introduces a shared context method that stores turn IDs by request_id, and tracing tests assert turn.id equals the returned turn ID.
  1. PR feat(tracing): tag app-server turn spans with turn_id #15206
  2. Commit feat(tracing): tag app-server turn spans with turn_id 7f9f93e
  3. Commit also record turn id for turn/steer and turn/interrupt 8e042a0

/title adds configurable terminal-title support in the TUI

PR #12334 introduces a new TUI /title command and config path so users can control which compact items appear in the terminal window/tab title, with a default spinner,project layout when unset.

This gives users a practical way to distinguish multiple active Codex sessions at the terminal level, improving session visibility and reducing “which tab is which” confusion without requiring app focus.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • The PR description explicitly frames the change as solving multi-session identification and documents /title as a new, separate terminal-title surface.
  • codex-rs/core/src/config/types.rs and codex-rs/core/src/config/mod.rs add tui.terminal_title mapped into runtime config, with defaults in docs/schema (config.schema.json) to spinner and project when unset.
  • codex-rs/tui/src/slash_command.rs adds the /title command, and codex-rs/tui/src/bottom_pane/title_setup.rs introduces the in-TUI selection/reordering UI, wired through bottom_pane/mod.rs and app_event.rs.
  • codex-rs/tui/src/terminal_title.rs adds dedicated OSC terminal-title output and sanitization logic, while codex-rs/tui/src/chatwidget/status_surfaces.rs and chatwidget.rs integrate title refresh with the existing status pipeline.
  • The bundle includes added/updated tests and snapshots (title_setup snapshot + chatwidget/config tests), indicating behavior verification for the new user-facing flow rather than purely internal cleanup.
  1. PR feat(tui): add /title terminal title configuration #12334
  2. Commit feat(tui): add /title terminal title configuration db4b7fe
  3. Commit codex: fix CI failure on PR #12334 5d24272

Add automated reviewer as separate source for tool approval telemetry

The change introduces a new automated_reviewer approval source in Codex’s tool decision telemetry so guardian-reviewed approvals are emitted distinctly from user and config approvals.

This improves observability and operator workflows by making approval provenance explicit in codex.tool_decision logs, reducing ambiguity when debugging policy decisions and investigating approval behavior in production.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • The pull request description explicitly says it logs guardian-reviewed tool approvals as source=automated_reviewer while keeping user approvals as source=user and config approvals as source=config.
  • codex-rs/core/src/tools/orchestrator.rs adds ToolDecisionSource::AutomatedReviewer and chooses it when routes_approval_to_guardian(turn_ctx) is true before calling otel.tool_decision(...).
  • codex-rs/otel/src/lib.rs extends ToolDecisionSource with an AutomatedReviewer enum variant so the new telemetry source is represented end-to-end.
  • The single commit a3dcc1d69412c7f72ef738a8ef86a84bf7915c69 contains the focused code changes in both the orchestrator and OpenTelemetry enum definitions.
  1. PR Log automated reviewer approval sources distinctly #15201
  2. Commit Log automated approval reviewers distinctly a3dcc1d

exec-server adds process and filesystem JSON-RPC capabilities

PR #15090 expands exec-server from a stub-oriented shape into a real process and filesystem RPC implementation, adding protocol methods, routing, client/server event plumbing, and tests. It also includes a CI cache guard for a specific macOS cross-target build issue.

This is a user-facing capability increase: clients can now drive process lifecycle and file operations through exec-server with structured RPCs and event notifications (output/exited), which is a prerequisite for richer automation and tool integration workflows. The CI tweak reduces environment-specific instability during release/integration builds.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 8 proof points
  • The PR body explicitly states that it carries surviving exec-server process and filesystem RPC implementation on top of existing websocket-based scaffolding and calls out the macOS SCCACHE regression workaround.
  • Primary PR narrative + commits show a feature rollout: initial implementation (Add exec-server process and filesystem RPCs) plus follow-up lifecycle fix (exec-server: report false after retained exit).
  • codex-rs/exec-server/src/protocol.rs adds method constants for process (process/start, process/read, process/write, process/terminate, process/output, process/exited) and filesystem RPCs (fs/readFile, fs/writeFile, fs/createDirectory, etc.).
  • Server-side expansion is added in codex-rs/exec-server/src/server/filesystem.rs and codex-rs/exec-server/src/server/registry.rs, with substantial handler updates, indicating the new RPC surface is actually dispatched and handled.
  • Client-facing layers were updated (client.rs, client_api.rs, lib.rs, local_backend.rs) to expose/read new RPC/notification types, while transport/routing internals in rpc.rs/processor.rs were refactored to support the new request/notification paths.
  • Regression-hardening is included via .github/workflows/rust-ci.yml: SCCACHE is disabled for windows and macos-15-xlarge + x86_64-apple-darwin to avoid mixed-architecture ring/cc-rs cache failures.
  • New/updated tests in codex-rs/exec-server/src/server/handler/tests.rs and codex-rs/exec-server/tests/process.rs show validation of the new behavior path.
  • Build metadata changes (base64 and codex-utils-pty dependencies) and Cargo.lock updates support the newly added process and FS implementation paths.
  1. PR Add exec-server process and filesystem RPCs #15090
  2. Commit Add exec-server process and filesystem RPCs (#15090) dd1416a
  3. Commit exec-server: report false after retained exit ab89fdf

argument-comment lint is now shipped as a runnable DotSlash package

The PR adds cross-platform release packaging for the argument-comment linter so teams can use a runnable artifact instead of building the linting tool from source.

This changes the developer workflow from rebuild-required to consume-ready, which reduces setup time and makes the lint more likely to be run earlier in day-to-day development and review loops.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • Primary PR context states the previous linter flow required building from source and that PRs commonly failed later in CI because violations were not checked until later, motivating a prebuilt artifact distribution.
  • The new .github/dotslash-argument-comment-lint-config.json defines packaged outputs for macos-aarch64, linux-x86_64, linux-aarch64, and windows-x86_64, each pointing to argument-comment-lint executables under a packaged bin/ path.
  • A new .github/workflows/rust-release-argument-comment-lint.yml workflow is added to build host-specific release artifacts (archives/zips), and rust-release.yml is updated to invoke it and publish the new DotSlash manifest on releases.
  • tools/argument-comment-lint/src/bin/argument-comment-lint.rs adds a dedicated runner binary that resolves sibling packaged binaries/libraries and invokes cargo-dylint with the bundled library path, making the release artifact directly runnable.
  • Docs were updated (tools/argument-comment-lint/README.md) to describe the released argument-comment-lint DotSlash package layout and target coverage.
  1. PR Publish runnable DotSlash package for argument-comment lint #15198
  2. Commit Publish runnable DotSlash package for argument-comment lint 5afbcf6

Add experimental exec server URL override for Codex sessions

PR #15196 introduces an experimental experimental_exec_server_url configuration key and wires it into environment/session creation, allowing the remote exec server endpoint to be overridden from defaults.

It gives operators a configurable escape hatch for deployment-specific or proxied exec-server setups without requiring code changes, improving flexibility while keeping existing behavior unchanged by default.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • The PR metadata identifies the change as "Add experimental exec server URL handling" and documents it as merged in openai/codex PR 15196, with commit 1f0ed50a125c758bb8d4d2f71e425e9eef3519f4.
  • codex-rs/core/src/config/mod.rs adds experimental_exec_server_url: Option<String> to both Config and ConfigToml, with doc text explicitly describing it as an override for the remote exec server URL.
  • codex-rs/core/src/config.schema.json adds experimental_exec_server_url as a schema field, exposing it as a configurable runtime input.
  • codex-rs/core/src/codex.rs now constructs environment via Environment::create(config.experimental_exec_server_url.clone()).await?, directly consuming the new config value during session setup.
  • codex-rs/exec-server/src/environment.rs replaces a unit Environment with a stateful struct that stores the optional override URL and a possible remote_exec_server_client, supporting the configurable connection path.
  1. PR Add experimental exec server URL handling #15196
  2. Commit Add experimental exec server config 1f0ed50

Stop-hook continuation prompts are now persisted as user-visible hook prompts

This PR changes stop-hook continuation behavior so hook-provided continuation text is carried as structured user-context messages (HookPrompt) instead of being treated like hidden developer instruction content, improving turn-loop handling when hooks run multiple times.

Users are less likely to hit unstable stop-hook replay behavior: continuation prompts from hooks are now part of normal user-visible context and survive history compaction, which helps avoid inconsistent or looping hook-driven turns while keeping prompt continuity aligned with turn-loop expectations.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • PR 14867 explicitly states the intent: persist stop-hook continuation prompts as user messages rather than hidden developer messages to match turn-loop training behavior.
  • core/src/event_mapping.rs now parses user-role items via parse_visible_hook_prompt_message into TurnItem::HookPrompt, and core/src/compact_remote.rs preserves TurnItem::HookPrompt during compaction filtering.
  • Protocol/model updates add a new hookPrompt/HookPromptFragment surface (HookRunId + text) across Rust and generated TypeScript schema (app-server-protocol and protocol/src/items.rs), making continuation prompts a first-class event payload.
  • Hook execution now stores continuation data as continuation_fragments: Vec<HookPromptFragment> (hooks/src/events/stop.rs) with tests added for hook prompt fragment parsing/escaping and multi stop-hook continuation behavior in core hook and contextual user message tests.
  1. PR [hooks] use a user message > developer message for prompt continuation #14867
  2. Commit use a user message > developer message for prompt continuation 9ad2b00
  3. Commit tui_app_server: handle hook prompt items e837ce9
  4. Commit codex: fix CI failure on PR #14867 94d66dc
  5. Commit tui_app_server: fix hook prompt replay build after rebase 7b8c000
  6. Commit tui_app_server: remove dead replay helpers 7964382
  7. Commit remove unneeded hook_run_ids plural variant ae25f38
  8. Commit use quick-xml instead of hand roll 8824eba
  9. Commit tests: fix flaky CI expectations 8e59ce1
  10. Commit core: fix merge-ref auth telemetry compile f664f40
  11. Commit Merge origin/main into user_message_xml 3c358c7
  12. Commit tui_app_server: ignore hook prompt snapshot items 2518b8f
  13. Commit app-server-protocol: refresh generated typescript schema 4034f28

Reverted MCP session/turn header forwarding

This PR rolls back PR #15011’s change that forwarded session and turn metadata as headers on MCP HTTP requests, restoring prior MCP request behavior.

It is a stabilization rollback: the revert removes a recently introduced request-header path that could alter MCP behavior for downstream MCP servers. Treating this as a behavior change is appropriate because it reverses a protocol-level transmission change that may have affected integrations, even though it does not add new capability.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 6 proof points
  • Primary PR narrative is explicit: title is Revert "Forward session and turn headers to MCP HTTP requests" and body states it reverts openai/codex#15011.
  • The revert commit is bab2a28f26223da6a3a6f61bb9656d2f8d6cc4ee, whose message matches the PR title and confirms intent.
  • codex-rs/core/src/codex.rs removes sync_mcp_request_headers_for_turn, which was responsible for building/stashing turn- and session-derived request headers.
  • codex-rs/core/src/tasks/mod.rs removes both the per-turn header sync call and turn-state header-clear calls, indicating the rollback of that lifecycle behavior.
  • codex-rs/core/src/mcp_connection_manager.rs and codex-rs/core/src/mcp_connection_manager_tests.rs remove request-header storage/carrying state in AsyncManagedClient and related tests.
  • codex-rs/rmcp-client/src/rmcp_client.rs removes request-scoped-header handling for JSON-RPC client messages, including the message_uses_request_scoped_headers logic.
  1. PR Revert "Forward session and turn headers to MCP HTTP requests" #15185
  2. Commit Revert "Forward session and turn headers to MCP HTTP requests (#15011)" bab2a28

Disable memory generation during consolidation runs

The PR updates phase-2 memory consolidation so the internal sub-agent is configured with generate_memories disabled, and test coverage is adjusted to validate the configured consolidation thread path.

This prevents consolidation workers from writing memory entries while they are meant to consolidate context only, reducing the chance of recursive or noisy memory writes and helping keep stored memory cleaner and more stable across runs.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 3 proof points
  • PR #15175 is explicitly framed as "morpheus does not generate memories" and is merged in openai/codex as a PR-first bundle (analysis_mode: pr_first).
  • codex-rs/core/src/memories/phase2.rs adds agent_config.memories.generate_memories = false when creating the consolidation sub-agent config, directly changing runtime behavior for that path.
  • codex-rs/core/src/memories/tests.rs now binds the consolidation thread id before fetching the thread and reads its config_snapshot, indicating test-level verification tied to the consolidation thread behavior.
  1. PR chore: morpheus does not generate memories #15175
  2. Commit chore: morpheus does not generate memories db01ae2
  3. Commit nit fix 9c1838e

Added codex.profile.usage metric for active profile sessions

PR #15180 adds a new OpenTelemetry counter that increments when a session starts with an active profile, enabling explicit tracking of profile usage in telemetry pipelines.

This gives operators and maintainers a direct signal for how often active coding profiles are used in live sessions. It helps with visibility into feature adoption and debugging profile-related behavior without changing runtime user flows.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 3 proof points
  • PR #15180 is titled chore: add metrics for profile and has a committed change set tied to a single merged commit (959dc2a4d88ebe8caad796b05e5a76096ba20f2e)
  • codex-rs/otel/src/metrics/names.rs now defines PROFILE_USAGE_METRIC as codex.profile.usage, establishing a new named metric in the shared telemetry namespace
  • codex-rs/otel/src/events/session_telemetry.rs imports PROFILE_USAGE_METRIC and increments it via self.counter(..., 1, &[]) whenever active_profile.is_some() is true
  1. PR chore: add metrics for profile #15180
  2. Commit chore: add metrics for profile 959dc2a

Move environment abstraction into the exec server crate

PR #15125 migrates Codex’s environment abstraction from the standalone codex-environment crate into codex-exec-server, rewiring core and server crates to import Environment, ExecutorFileSystem, and related helpers from the exec-server boundary instead.

This is mainly an architectural refactor that reduces cross-crate coupling: execution environment concerns are now centralized in the exec-server API surface, which makes it easier to support different execution backends (local vs remote) without changing core/app-server logic.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • The PR body states the goal explicitly: the Environment abstraction now lives behind codex-exec-server, with construction-time differences hidden from core.
  • codex-rs/environment is removed (crate file + Bazel target + source deletion) while codex-exec-server gains exports for Environment and filesystem types.
  • Dependencies in codex-rs/Cargo.toml, app-server/Cargo.toml, and core/Cargo.toml were updated from codex-environment to codex-exec-server, and imports in app-server/core moved accordingly.
  • Filesystem and environment usage sites such as app-server/src/fs_api.rs and core/src/codex.rs now pull Environment/ExecutorFileSystem APIs from codex_exec_server, showing behavior is now mediated through the exec-server crate boundary.
  • Cargo.lock changes replace codex-environment with codex-exec-server dependencies and move execution-related deps into the latter, confirming the migration at the workspace dependency graph level.
  1. PR Move environment abstraction into exec server #15125
  2. Commit Move environment into exec server b3807c5
  3. Commit Move environment module into exec 46eb5f4
  4. Commit Merge origin/main 7dd923d
  5. Commit Align exec server build deps 86b0538
  6. Commit codex: fix CI failure on PR #15125 8902a18

Agent shutdown now handles already-closed sessions safely

This PR fixes the close/shutdown path for agents by making shutdown operations idempotent when an agent thread is already closed, preventing unnecessary follow-up op dispatch in already-finished states.

Users and orchestrators can issue close/shutdown actions without triggering avoidable shutdown failures or noisy errors if an agent is already in the shutdown state, which improves robustness for repeated or race-prone multi-agent workflows.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • PR #15163 is titled "fix: case where agent is already closed", matching the observed behavior correction.
  • In codex-rs/core/src/agent/control.rs, shutdown_live_agent now checks thread.agent_status() and returns Ok(String::new()) when already Shutdown, instead of always sending Op::Shutdown {}.
  • The same function still materializes/flushes rollout state before returning, preserving teardown-side effects while avoiding duplicate shutdown operations.
  • In codex-rs/core/src/tools/handlers/multi_agents/close_agent.rs, the pre-check that skipped close handling when status was already Shutdown was removed, so close requests now consistently delegate to control-layer shutdown logic that now safely handles already-closed threads.
  • The change is a single-commit update touching two core agent lifecycle paths (agent/control.rs and tools/handlers/multi_agents/close_agent.rs) with 9 insertions and 14 deletions, indicating a focused behavioral fix.
  1. PR fix: case where agent is already closed #15163
  2. Commit fix: case where agent is already closed 17fb326

Agent trees now cascade close and resume

Merged PR #15056 adds persisted parent-child agent graph state so close and resume flows can apply to descendant agents instead of treating each agent as an isolated thread.

Users working with nested agents are less likely to leave orphaned child agents behind when closing a parent, and resumed sessions can restore the same subtree structure instead of losing those relationships.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • The PR body says the new agent-graph representation is now used for both cascading agent close and cascading resume.
  • The bundle adds a new thread_spawn_edges table plus DirectionalThreadSpawnEdgeStatus (Open and Closed), which shows parent-child agent relationships are now persisted as first-class state.
  • The close_agent tool path switches to agent_control.close_agent(...), and the tool description was updated to say it closes an agent "and any open descendants," making descendant shutdown part of the user-visible contract.
  • agent/control.rs and control_tests.rs add graph-aware lifecycle and resume coverage, which supports the PR's claim that subtree resume now uses the persisted agent network.
  1. PR feat: add graph representation of agent network #15056
  2. Commit feat: add graph representation of agent network e24a0f8
  3. Commit fix bazel 90c350a
  4. Commit nit c3b9f1b

Product-scoped plugins and skills via session source

PR 15041 makes session source a first-class input with --session-source and uses it to filter plugin installation and skill visibility by product, so different Codex surfaces can expose different plugin catalogs.

Users on one product surface are less likely to see or install incompatible plugins or skills. That reduces confusion and helps keep plugin availability aligned with the product context the session came from.

Try now Start app-server with --session-source chatgpt or another custom source, then list or install marketplace plugins that declare policy.products restrictions.

Plugins and skills whose product policy does not match the active session source should be filtered out or reported as unavailable, while unrestricted or matching items remain visible.

Sources and evidence 5 proof points
  • The PR body explicitly frames the change around three behaviors: adding SessionSource::Custom(String) plus --session-source, enforcing plugin and skill products by session_source, and applying the same filtering to curated background refresh.
  • Protocol and schema changes add a custom session-source shape, which shows this is a supported runtime input rather than an internal one-off.
  • The runtime wiring passes the chosen session source through app-server setup instead of hardcoding a fixed source, making product-aware filtering active at execution time.
  • Plugin and skill loading paths now check product restrictions against the session-derived product, so mismatched items are hidden or treated as unavailable.
  • The test additions cover disallowed product plugins and product-scoped skill visibility, confirming this is a deliberate user-visible behavior change.
  1. PR feat: support product-scoped plugins. #15041
  2. Commit feat: support product-scoped plugins. d3b349c
  3. Commit Address comments. 06e9a1a

App server adds thread/shellCommand support for TUI ! commands

Merged PR #14988 adds a new thread/shellCommand app-server request and wires app-server-backed TUI ! shell commands through that API, with command execution persisted into thread history.

This turns app-server-backed ! shell commands from a blocked path into a supported workflow. Users on the app-server TUI can run shell shortcuts again and have the command activity show up in the same thread history and execution-event flow as other command items.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • The PR title and body frame the change around a new thread/shellCommand API plus TUI support for ! shell commands, making the PR itself a clear user-facing capability addition.
  • Protocol/schema files add a dedicated ThreadShellCommand request shape and ThreadShellCommandParams, while command items gain a CommandExecutionSource field, showing this is a first-class app-server surface rather than an internal workaround.
  • codex_message_processor.rs, app_server_session.rs, and tui_app_server/src/app.rs wire request handling and submission for thread/shellCommand, connecting the new API to the app-server-backed TUI path.
  • tui_app_server/src/chatwidget.rs removes the prior disabled-error behavior for ! commands and instead dispatches run_user_shell_command, while core/src/tasks/user_shell.rs adds rollout materialization for standalone shell-output persistence.
  • The new test suite app-server/tests/suite/v2/thread_shell_command.rs and updated chatwidget tests provide direct evidence that the request path and TUI behavior were intentionally added and verified.
  1. PR Add thread/shellCommand to app server API surface #14988
  2. Commit Add thread shellCommand support to tui app server eb6a697
  3. Commit codex: address PR review feedback (#14988) e14a72a
  4. Commit codex: fix CI failure on PR #14988 aac5786
  5. Commit codex: revert broad rollout persistence change 3aadef3
  6. Commit codex: fix protocol clippy default derivation 6fa40a7
  7. Commit codex: fix CI formatting on PR #14988 03dd655
  8. Commit codex: clarify standalone shell turn docs on PR #14988 37d04c6
  9. Commit codex: revert thread command output delta raw-bytes followup (#14988) f4d42d0

Codex now distinguishes directory mentions from file mentions

Merged PR #14970 adds basic directory-mention support by carrying directory vs. file match metadata through fuzzy file search results and related protocol schemas.

This makes path mentions less ambiguous in the TUI and gives clients enough information to treat folders differently from files. For users, that should reduce mistaken links for extensionless paths and make folder references clearer.

Try now On a build that includes PR #14970, trigger fuzzy file search or mention completion for a known folder and a similarly named file, then inspect the returned mention/search result payloads or UI labels for directory-specific handling.

Directory matches should be marked distinctly from file matches, with folder mentions rendered using a trailing slash and available for client-specific link behavior.

Sources and evidence 3 proof points
  • The PR title and body explicitly frame the change as adding simple directory-mention support in the TUI, with trailing slashes used to distinguish directories from extensionless files.
  • The Rust search model in codex-rs/file-search adds a MatchType on search results, and the app-server mapping forwards that as FuzzyFileSearchMatchType with file and directory variants.
  • Generated JSON/TypeScript protocol schemas now require match_type on FuzzyFileSearchResult, and fuzzy-file-search tests were updated to expect the new field, confirming this is a real behavior-contract change rather than internal cleanup.
  1. PR Simple directory mentions #14970
  2. Commit Simple folder mentions a4277b0
  3. Commit Use trailing slash df3a8b4
  4. Commit Add match type 385be6b
  5. Commit Added match_type to indicate file/directory mentions c0617a5
  6. Commit Merge conflicts f9634cb
  7. Commit Fix test in windows envs 0dbfa40

Stop and UserPromptSubmit hooks now receive the active turn_id

Merged PR #15118 adds a Codex-specific turn_id field to the Stop and UserPromptSubmit hook payloads so hook scripts can tie each invocation to a specific conversation turn.

This makes hook automation more precise. If you log, correlate, or enforce turn-scoped behavior in custom hooks, you can now distinguish one turn from the next instead of inferring that from prompt text or timestamps.

Try now Enable Stop or UserPromptSubmit hooks in a build that includes PR #15118, print the incoming JSON payload in your hook script, and run two prompts in the same session.

Each Stop and UserPromptSubmit invocation should include a turn_id string, and the value should differ between separate turns so your hook can correlate events within the same turn.

Sources and evidence 3 proof points
  • The PR title and body explicitly frame the change as exposing turn_id to hook scripts so runs can be connected to particular turns.
  • The generated hook input schemas for stop.command.input and user-prompt-submit.command.input now require a string turn_id field.
  • The Rust hook event code now serializes request.turn_id into both Stop and UserPromptSubmit payloads, and the test suite was expanded to log hook inputs and verify turn-scoped behavior.
  1. PR [hooks] turn_id extension for Stop & UserPromptSubmit #15118
  2. Commit turn_id extension for stop/userpromptsubmit 9647be0
  3. Commit codex: fix CI failure on PR #15118 524f3aa

MCP HTTP requests now carry turn- and session-scoped headers

PR #15011 updates Codex's MCP HTTP flow to forward request-scoped headers from the current session/turn into MCP tool metadata lookups and tool calls, with turn-bound lifecycle cleanup and fixes for regressions introduced during rollout.

This improves the correctness of MCP interactions that depend on per-turn or per-session context, reducing cross-turn header leakage and making tool calls and recovery behavior more predictable in streamable HTTP MCP clients.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • The PR body explicitly says the change forwards task headers through MCP metadata lookups and tool calls, including streamable HTTP initialize, tools/list, and tools/call requests.
  • The diff evidence in codex.rs and tasks/mod.rs adds turn-lifecycle header sync and cleanup hooks, showing the headers are scoped to the active turn instead of left ambient.
  • The MCP client stack files (mcp_connection_manager.rs, rmcp_client.rs, and related tests) add request-header plumbing and updated test setup, which supports this as a real behavior change rather than a docs-only update.
  • The commit trail includes follow-up fixes for turn scoping and CI regressions before the PR merged on 2026-03-19, indicating an incremental rollout of the new header propagation behavior.
  1. PR Forward session and turn headers to MCP HTTP requests #15011
  2. Commit Forward tool call task headers to MCP HTTP requests bccce0f
  3. Commit codex: fix CI failure on PR #15011 fb27c20
  4. Commit codex: scope MCP request headers to turn lifecycle 732d7ac
  5. Commit codex: fix MCP header CI regressions 1a2536d

Websocket turn requests now propagate per-turn trace context

Merged PR #14632 updates Codex websocket tracing so each response.create request carries W3C trace context in client_metadata, instead of only attaching tracing metadata when the websocket connection starts.

This closes an observability gap in persistent websocket sessions. Teams tracing Codex turn execution can now follow individual turns end to end, which makes latency and failure analysis more reliable when a single socket is reused across many requests.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 3 proof points
  • The PR description says websocket tracing was previously attached only at connection time and that this change propagates the current tracing context on every response.create request.
  • Bundle evidence in codex-rs/codex-api/src/common.rs adds ws_request_header_traceparent and ws_request_header_tracestate metadata keys plus request-building support for websocket create calls.
  • The changed core client and websocket test files add W3cTraceContext/current_span_w3c_trace_context usage and new tracing test support, which indicates the active span context is now wired into runtime websocket traffic and validated in tests.
  1. PR feat(core, tracing): create turn spans over websockets #14632
  2. Commit feat(core, tracing): create turn spans over websockets c17855e
  3. Commit clean up b6671aa

Exec server switches from stdio plumbing to websocket-only transport

Merged PR #15119 removes deprecated stdio transport support from Codex exec-server and standardizes the binary, library surface, docs, and tests around websocket listen URLs.

This is a user-visible contract change for anyone integrating with exec-server. The transport story is simpler and more consistent, but setups that depended on stdio:// or local stdio spawn helpers now need to move to websocket-based usage.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • The PR title and body explicitly frame the change as deleting deprecated stdio transport plumbing and replacing it with websocket-oriented test utilities.
  • codex-rs/exec-server/src/bin/codex-exec-server.rs changes --listen from a transport enum to a raw URL string and documents only ws://IP:PORT as supported.
  • codex-rs/exec-server/src/server/transport.rs replaces the old transport enum with listen-URL parsing centered on DEFAULT_LISTEN_URL = "ws://127.0.0.1:0".
  • The bundle shows stdio-specific public/client paths being removed, including src/local.rs, stdio smoke tests, and stdio connect helpers, while new websocket tests are added for initialize, process, and malformed JSON handling.
  1. PR Remove stdio transport from exec server #15119
  2. Commit Add codex-exec-server crate 144c359
  3. Commit docs(exec-server): add protocol README 949932c
  4. Commit Add Bazel package for exec-server 40cc199
  5. Commit Trim exec-server PR to stub server slice 2958067
  6. Commit Keep first exec-server PR initialize-only 7607197
  7. Commit Add generic RPC server glue to exec-server stub 16ff474
  8. Commit Add generic exec-server RPC foundation 0a846a2
  9. Commit Wire notification sender into exec-server RPC foundation c5dbe42
  10. Commit Remove outer handler mutex from exec-server RPC base 66f49ea
  11. Commit Test generic exec-server RPC response matching 43b112c
  12. Commit exec-server: simplify stub json-rpc transport shape 2661dc5
  13. Commit exec-server: address transport review feedback 3b4a522
  14. Commit exec-server: keep malformed-json connections alive 2ed509d
  15. Commit exec-server: trim unused stub dependencies 866743d
  16. Commit Remove stdio transport add harness a2feb4b

Python SDK adds thread.run() convenience methods for one-shot turns

Merged PR #15088 adds thread.run(...) and async thread.run(...) to the Python SDK, giving users a simpler path for common prompt-response flows without manually creating and running a turn handle.

This lowers the amount of SDK code needed for basic request-response usage. Python users can now send a string or input bundle directly from a thread and get a compact result object back, while the lower-level turn API remains available for streaming and more advanced control.

Try now In a Codex build that includes PR #15088, start a Python SDK thread with codex.thread_start(...) and call thread.run("Say hello in one sentence.") or await thread.run("Say hello in one sentence.") in the async API.

The call should return a RunResult object with the collected thread items, optional token usage, and a final_response string when the turn produces a final-answer or phase-less assistant message.

Sources and evidence 3 proof points
  • The PR title and body explicitly frame this as new Python SDK convenience methods: thread.run(...) and async thread.run(...) for the common case.
  • The code adds new _inputs.py and _run.py helpers, including RunInput and a RunResult dataclass with final_response, collected items, and optional usage.
  • The README, getting-started guide, quickstart examples, and runtime/signature tests were updated to use thread.run(...), which shows the new flow is intended for public use rather than internal refactoring.
  1. PR Add Python SDK thread.run convenience methods #15088
  2. Commit python-sdk: add thread.run convenience methods 3536149
  3. Commit python-sdk: update quickstart examples for thread.run 33289a1
  4. Commit python-sdk: fix thread.run final response semantics 5f141ad
  5. Commit python-sdk: use typed thread items for run results 62ff8ba
  6. Commit Merge remote-tracking branch 'origin/main' into dev/shaqayeq/python-sdk-thread-run 93f5ebe
  7. Commit python-sdk: prefer final-answer phase in run results 4c52a5d
  8. Commit python-sdk: split convenience helpers out of api 49ff282
  9. Commit python-sdk: inline turn handles into api facade a32b804
  10. Commit python-sdk: make run final_response optional 7f5e539

Added a standalone exec-server binary with JSON-RPC protocol scaffolding

PR #15089 adds a new codex-exec-server crate and standalone binary with shared protocol types, Rust client APIs, and stdio/websocket transport support, while keeping exec and filesystem methods stubbed for later PRs.

This creates a separate execution-server boundary that future Codex integrations can build on without coupling everything to the main CLI process. It is a real new capability, but still an early one: the transport and handshake are in place before the full remote execution surface lands.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • The PR title and body explicitly frame this as an "initialize-only" exec-server stub slice with protocol docs, not a full execution feature.
  • codex-rs/Cargo.toml, codex-rs/exec-server/Cargo.toml, and codex-rs/Cargo.lock add a new codex-exec-server workspace crate and binary target.
  • codex-rs/exec-server/README.md documents a standalone server, shared JSON-RPC wire protocol, and two supported transports: ws://IP:PORT and stdio://.
  • codex-rs/exec-server/src/bin/codex-exec-server.rs, src/protocol.rs, src/rpc.rs, and src/server/transport.rs provide the new server entrypoint, initialize protocol types, RPC plumbing, and transport parsing/runtime support.
  • Smoke tests in codex-rs/exec-server/tests/stdio_smoke.rs and codex-rs/exec-server/tests/websocket_smoke.rs verify the initialize flow over both transport modes, which confirms the stub is functional at the protocol layer.
  1. PR Add exec-server stub server and protocol docs #15089
  2. Commit Add codex-exec-server crate 144c359
  3. Commit docs(exec-server): add protocol README 949932c
  4. Commit Add Bazel package for exec-server 40cc199
  5. Commit Trim exec-server PR to stub server slice 2958067
  6. Commit Keep first exec-server PR initialize-only 7607197
  7. Commit Add generic RPC server glue to exec-server stub 16ff474
  8. Commit Add generic exec-server RPC foundation 0a846a2
  9. Commit Wire notification sender into exec-server RPC foundation c5dbe42
  10. Commit Remove outer handler mutex from exec-server RPC base 66f49ea
  11. Commit Test generic exec-server RPC response matching 43b112c
  12. Commit exec-server: simplify stub json-rpc transport shape 2661dc5
  13. Commit exec-server: address transport review feedback 3b4a522
  14. Commit exec-server: keep malformed-json connections alive 2ed509d
  15. Commit exec-server: trim unused stub dependencies 866743d

Harden plugin listing/read behavior with resolved feature gating

PR #15104 updates plugin-related flows to use requirement-resolved config for the plugin feature gate, passes config-aware context through skill loading, and makes marketplace discovery tolerate malformed files instead of failing hard.

This change makes plugin commands more reliable for users by preventing a single broken marketplace file from breaking plugin list/read operations, while ensuring plugin enablement is consistently driven by resolved configuration.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • The PR body states three user-visible objectives: use requirement-resolved config.features as the plugin gate, guard plugin list/read flows behind that gate, and skip bad marketplace.json files instead of failing the entire list.
  • codex-rs/core/src/plugins/marketplace.rs now wraps marketplace loading in a match that warns and continues on failure, and adds a test for skipping failing marketplaces.
  • codex-rs/app-server/src/codex_message_processor.rs changes plugin request handling to load latest config (load_latest_config) before continuing and treats plugin-disabled as a distinct case instead of treating marketplace/config issues as a hard plugin failure.
  • codex-rs/core/src/skills/manager.rs and call sites in codex-rs/core/src/codex.rs, codex-rs/core/src/codex_tests.rs, and codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs now pass config into skills_for_cwd, making behavior follow the active config state.
  1. PR fix: harden plugin feature gating #15104
  2. Commit fix: read plugin feature flag from requirement-resolved config. 62b5fbc
  3. Commit guard plugin/*** with the feature flag. fdd9ab9
  4. Commit Fail open to marketplace.json fail. 2f834ba
  5. Commit Cleanup configured_plugin_states 801f834

Code-mode apply_patch now returns an explicit result object

Merged PR #15100 changes Codex's code-mode apply_patch path to return a dedicated result object instead of flowing through the generic function-tool output path.

This makes nested apply_patch calls easier to handle programmatically in code mode. Automation can treat a successful patch as a deterministic tool result rather than relying only on side effects or generic output handling.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • The PR-level narrative is explicit: openai/codex#15100 is titled "Add apply_patch code mode result" and shipped as a merged PR-first change on 2026-03-18.
  • codex-rs/core/src/tools/context.rs adds ApplyPatchToolOutput, including a dedicated code_mode_result implementation that returns an empty JSON object for code-mode callers.
  • codex-rs/core/src/tools/handlers/apply_patch.rs switches ApplyPatchHandler from FunctionToolOutput to ApplyPatchToolOutput, wiring the new result behavior into the actual tool handler.
  • codex-rs/core/tests/suite/code_mode.rs adds an integration assertion that the nested tool's second text item is {}, confirming the new result shape is intentional and tested.
  1. PR Add apply_patch code mode result #15100
  2. Commit Implement apply_patch code mode dd37904
  3. Commit test(core): assert apply_patch code mode result in integration fa4e595

Code-mode update_plan now returns a structured result

This merged PR updates the plan tool path so code-mode calls to tools.update_plan now yield a parseable result payload, and adds a regression test for the nested call shape.

It makes scripted workflow updates in code mode more reliable by allowing the caller to inspect and act on update_plan output instead of treating the call as opaque.

Try now In code mode, run an update_plan call like const result = await tools.update_plan({ plan: [{ step: 'Run update_plan', status: 'in_progress' }] }); text(JSON.stringify(result)); and check the response parses as JSON.

If the behavior is present, code-mode workflows can consume update_plan return data programmatically instead of only relying on side effects.

Sources and evidence 4 proof points
  • PR openai/codex#15103 is explicitly titled "Add update_plan code mode result" and the sole commit is message "Implement code-mode plan result," indicating a focused behavioral change.
  • codex-rs/core/src/tools/handlers/plan.rs changed imports and added PlanToolOutput, with new payload/output/model types (FunctionCallOutputPayload, ResponseInputItem, ToolOutput, serde_json::Value) tied to plan/update handling.
  • codex-rs/core/tests/suite/code_mode.rs adds code_mode_update_plan_nested_tool_result_is_empty_object, explicitly executing tools.update_plan(...) from code mode and asserting the nested tool call is successful plus parseable JSON handling.
  • The change is confined to plan-tool and code-mode test surfaces, matching the PR title and no unrelated files in the bundle.
  1. PR Add update_plan code mode result #15103
  2. Commit Implement code-mode plan result e1b3f11

Realtime V2 handoff now skips transcript handoff

This PR changes realtime handoff handling so transcript entries are only assigned during V1 handoff flow, leaving V2 handoff events to preserve existing transcript state.

It prevents v2 realtime sessions from clearing transcript buffers when a handoff is requested, reducing the chance of transcript disruptions during handoff transitions and keeping message context more stable for applications that consume realtime events.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • Primary PR metadata shows the intent explicitly: #15111 is titled “don't add transcript for v2 realtime” and was merged on 2026-03-18.
  • The changed file is codex-rs/codex-api/src/endpoint/realtime_websocket/methods.rs, in the RealtimeEvent::HandoffRequested branch that previously always moved active_transcript.entries into handoff.active_transcript.
  • Patch logic now wraps that move in if self.event_parser == RealtimeEventParser::V1, so the transcript move is conditional on V1 instead of always happening.
  • The bundle contains a single small commit (e8232d32911ee5d246ecc482010c748021bc065e) and no other changed files, which supports this as a narrow behavior fix rather than a broader feature.
  1. PR don't add transcript for v2 realtime #15111
  2. Commit don't add tranacript e8232d3

thread/resume now preserves persisted model defaults

This PR changes thread/resume to prefer persisted thread metadata over current config when no explicit resume overrides are provided, so resumed threads inherit the prior model and model_reasoning_effort values by default. It also updates the README to document the resume fallback behavior.

Resuming a thread now continues with the same model behavior it used before, reducing surprising drift in output style/performance and avoiding accidental configuration shifts between sessions.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • Primary PR 14888 states the behavioral change explicitly: thread/resume now reads persisted thread metadata and uses persisted model and model_reasoning_effort as resume-time defaults before normal config resolution.
  • codex-rs/app-server/src/codex_message_processor.rs was modified in this bundle, including the resume/config path (request_overrides handling and persisted metadata reuse path), which is the runtime site for the documented precedence behavior.
  • codex-rs/app-server/README.md was updated with resumed-session behavior and docs around thread/resume, providing user-facing evidence of the intended behavior change.
  • The change is supported by five related commits in PR 14888 (0c30c5, ed0708, 719028, 634de3, 82375e) and merged on 2026-03-18, showing this behavior update was implemented as a coherent thread-resume fix rather than isolated cleanup.
  1. PR Feat: reuse persisted model and reasoning effort on thread resume #14888
  2. Commit Reuse persisted model and reasoning effort on thread resume 0c30c52
  3. Commit cleanup ed07087
  4. Commit Address review comments 719028d
  5. Commit Address review comment 82375e8

SQLite feedback logs now preserve rendered output behavior

The PR updates Codex’s SQLite logging path so feedback exports persist a rendered log body and apply retention/truncation against that rendered content, aligning exported log output with existing in-memory formatting semantics.

Users relying on /feedback now get clearer, more consistent exports: structured log fields and span prefixes are retained, newlines are preserved, and truncation works on export content rather than silently cutting useful context from retained rows.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 5 proof points
  • PR body explains the core behavior change: store a pre-rendered feedback_log_body in SQLite so /feedback exports keep span prefixes and structured event fields, and perform SQL-side budgeted loading followed by whole-line Rust truncation.
  • codex-rs/state/logs_migrations/0002_logs_feedback_log_body.sql renames the old logs table, creates a new schema with feedback_log_body, backfills from existing message values, and reinserts rows into the updated layout.
  • codex-rs/state/src/runtime/logs.rs begins writing feedback_log_body and bases estimated_bytes on persisted export-facing content for partition retention accounting.
  • codex-rs/state/src/log_db.rs and codex-rs/state/src/model/log.rs expand log persistence structures to keep formatter-relevant fields (rendered names/fields and feedback_log_body) available for export workflows.
  • Tests and client-side handling (codex-rs/core/tests/suite/sqlite_state.rs, codex-rs/state/src/bin/logs_client.rs) were updated to match rendered-body matching/assertions and wording, confirming behavior-level alignment rather than backend-only refactoring only.
  1. PR Align SQLite feedback logs with feedback formatter #13494
  2. Commit Align SQLite feedback logs with feedback formatter 6116209
  3. Commit Count feedback_log_body in pruning budget 63b06d2
  4. Commit Simplify feedback log export truncation e739af2
  5. Commit Clarify retained log content budget 6191162
  6. Commit Clarify estimated_bytes comment 9e3e50f
  7. Commit Preserve feedback export trailing newlines 460b877
  8. Commit Adapt feedback log migration to dedicated logs DB 81b8f9e
  9. Commit Drop message column from logs DB b86efe6
  10. Commit codex: address PR review feedback (#13494) 608118a
  11. Commit codex: fix rendered ToolCall log test (#13494) f62896a
  12. Commit Drop redundant logs process_uuid index 46ceae1

Realtime handoff output now labels the agent's final message

Merged PR #15077 changes realtime handoff payloads so the emitted assistant text is prefixed with an "Agent Final Message": label instead of sending the raw message body alone.

Clients that display or post-process realtime handoff output now get an explicit label marking the delegated agent's final response. This is a small but user-visible protocol change, and integrations that expect the old raw string format may need to adjust.

Try now Run a Codex build that includes PR #15077, trigger a realtime conversation handoff, and inspect the emitted conversation.handoff.append payload in either the v1 or Realtime v2 websocket stream.

The handoff text payload should begin with "Agent Final Message": followed by a blank line before the assistant's actual message content.

Sources and evidence 3 proof points
  • The PR title and body explicitly say realtime handoff output should be prefixed with the agent final message label for both realtime v1 and v2.
  • methods_common.rs adds a shared AGENT_FINAL_MESSAGE_PREFIX constant and prepends it inside conversation_handoff_append_message, which is the code path that builds the outbound handoff message.
  • Realtime websocket and core conversation tests were updated to expect "Agent Final Message":\n\n... in both output_text and delegated output fields, confirming this is an intentional behavior change rather than a test-only refactor.
  1. PR Add final message prefix to realtime handoff output #15077
  2. Commit Add final message prefix to realtime handoff output 26e0227

Custom app-server session sources were rolled back

Merged PR #15102 removes the newly introduced custom session_source path from Codex's app-server, protocol schemas, and plugin/skill filtering flow.

This closes off a just-landed integration path for tagging app-server threads as custom products and using that product identity to filter plugins or skills. Most users will see no change, but anyone testing custom app-server product sources loses that behavior for now.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 4 proof points
  • The PR title and body explicitly mark this as a revert of PR #15020 because changes were merged before review was finished.
  • The protocol and generated schemas remove SessionSource::Custom(...), drop the custom thread source kind, and delete the --session-source app-server CLI argument.
  • App-server docs now say the default interactive sourceKinds set is only cli and vscode, no longer including custom product sources.
  • Core and app-server changes remove session-source-based skill and curated-plugin filtering helpers, and related plugin-list/plugin-install tests are deleted.
  1. PR Revert "fix: harden plugin feature gating" #15102
  2. Commit Revert "fix: harden plugin feature gating (#15020)" c5281d1

Codex TUI now warns at startup when legacy custom prompts are present

Merged PR #15076 adds a startup deprecation notice in the Codex TUI when it finds custom prompts under $CODEX_HOME/prompts, with guidance to migrate them to skills.

Users still relying on legacy custom prompts now get an explicit migration warning before that path disappears. That reduces surprise from the deprecation and points them at the supported replacement instead of leaving the breakage to a later release.

Try now Run a Codex build that includes PR #15076, place at least one custom prompt file under $CODEX_HOME/prompts, start the TUI, and confirm a deprecation notice appears at startup telling you to convert prompts into skills with $skill-creator.

The TUI should show a startup warning only when one or more custom prompts are present, including the detected prompt count and migration guidance toward skills.

Sources and evidence 3 proof points
  • The PR title and body explicitly frame the change as a startup deprecation warning for custom prompts, shown only when prompts are detected in $CODEX_HOME/prompts.
  • The main code change is in tui/src/app.rs, where startup now counts discovered custom prompts and inserts a deprecation notice that tells users to use the $skill-creator skill.
  • The bundle includes a new snapshot showing the rendered warning text, and the PR body says tests were added for present, missing, and empty prompts directories, which supports this as an intentional user-visible behavior change.
  1. PR Add a startup deprecation warning for custom prompts #15076
  2. Commit Warn about deprecated custom prompts at startup 3c62fb0

Code mode can now pass view_image results straight into image()

Merged PR #15072 makes Codex code mode treat view_image as a structured image producer, so scripts can hand its result directly to image() instead of manually extracting a URL string.

This removes glue code from image-handling scripts and makes local-image flows more predictable. Users can reuse a view_image result directly, with detail metadata preserved when available, instead of reformatting the tool output by hand.

Try now Run a Codex build that includes PR #15072 in code mode, call const img = await tools.view_image({ path: "/absolute/path/to/local-image.png" }); image(img);, and confirm the script can attach the local image without manually pulling out img.image_url.

view_image should return a structured payload that image() accepts directly, so the image is attached successfully and any returned detail hint can flow through with it.

Sources and evidence 3 proof points
  • The PR title and body frame the change as a semantic cleanup: view_image now returns an object with image_url, and image() now accepts either a string or that structured object.
  • The changed tool docs and spec add a typed view_image output schema with image_url and detail, and update the code-mode helper signature from image(string) to image(string | { image_url, detail? }).
  • The bundle includes a dedicated test, code_mode_can_use_view_image_result_with_image_helper, which verifies the direct handoff path, and companion view_image test updates switch non-image inputs from placeholder output to an error, tightening the behavior around invalid files.
  1. PR Return image URL from view_image tool #15072
  2. Commit Handle view_image output b48f93d
  3. Commit Restore view image detail handling c0c2b71
  4. Commit Replace debug panic with assertion in code mode test b157203
  5. Commit codex: fix CI failure on PR #15072 1733c87
  6. Commit protocol: remove unused mime_guess dependency ce202b8

Code mode now surfaces tool failures as exceptions

Merged PR #15075 changes Codex code mode so nested tool-call failures propagate as errors you can catch, instead of being folded into normal tool output.

Code-mode scripts can now distinguish real tool failures from successful results. That makes error handling more predictable and avoids silently treating a broken nested tool call as ordinary output.

Try now Run a Codex build that includes PR #15075, execute a code-mode script that wraps an invalid nested tool call such as await tools.exec_command({}) in try/catch, and confirm the catch block receives the error.

The failing nested tool call should throw into the script's catch path with the tool error message, rather than returning a normal result payload.

Sources and evidence 3 proof points
  • PR #15075 explicitly says it pushes FunctionCallError up to the dispatcher so code mode can surface failures as exceptions.
  • The code-mode protocol adds an error_text field, and runner.cjs rejects the pending call when that field is present, which turns backend tool failures into script exceptions instead of resolved values.
  • The router and parallel tool runtime switch to a code-mode-aware dispatch path, and the added test code_mode_exec_surfaces_handler_errors_as_exceptions verifies a failing tools.exec_command({}) call is caught by try/catch.
  1. PR Propagate tool errors to code mode #15075
  2. Commit Handle code-mode tool errors b2f2dc2
  3. Commit Update tool call error handling e62bd04
  4. Commit Merge remote-tracking branch 'origin/main' into pakrym/add-tests-for-respondtomodel-errors a07b1c7
  5. Commit Fix post-merge code mode worker and custom output shape 68f228c

Codex CI now stages npm packages from a newer retained release artifact

Merged PR #15092 updates the PR CI workflow so the "Stage npm package" step pulls artifacts from Codex 0.115.0 instead of the older 0.74.0 release whose workflow history appears to have aged out.

This is mainly a contributor-facing reliability fix: PRs should be less likely to fail in the npm-package staging check just because the workflow was pinned to an older release artifact that GitHub no longer retains.

Watch only. No safe try path is published for this signal yet.

Sources and evidence 3 proof points
  • The PR body explicitly says the failing CI step is fixed by switching from release 0.74.0 to 0.115.0 because the older workflow history was likely reaped.
  • The only changed file is .github/workflows/ci.yml, where CODEX_VERSION for the "Stage npm package" step is bumped from 0.74.0 to 0.115.0.
  • The bundle contains a single merged commit and no product-code changes, which supports reading this as a scoped CI behavior fix rather than a broader feature update.
  1. PR fix: try to fix "Stage npm package" step in ci.yml #15092
  2. Commit fix: try to fix "Stage npm package" step in ci.yml ee651d1

App-server TUI now restores composer history

Merged PR #14945 brings prompt-history recall and persistence to the app-server TUI, so Up/Down navigation and cross-session history now work like the legacy TUI.

Users on the app-server TUI can recover previous prompts instead of hitting a stubbed "not available" path, and new submissions now persist to the shared history file for later sessions.

Try now Run a Codex build that includes PR #14945 in app-server TUI mode, submit a prompt, then press Up in the composer or restart the session and press Up again to recall earlier entries.

Previously entered prompts should be available through composer history in the app-server TUI, including entries persisted in $CODEX_HOME/history.jsonl from earlier sessions.

Sources and evidence 3 proof points
  • The PR description says the app-server TUI previously showed a stub for Up/Down history recall and dropped new submissions from the shared history file, and that this change restores both behaviors locally.
  • codex-rs/tui_app_server/src/app.rs and related TUI files add local handling for GetHistoryEntryRequest and AddToHistory, routing history lookups and writes through codex_core::message_history instead of the unsupported RPC path.
  • Tests were updated to verify async history navigation, per-thread routing of history responses, and bootstrap population of history_log_id / history_entry_count, confirming the restored behavior is exercised end to end.
  1. PR feat(tui): restore composer history in app-server tui #14945
  2. Commit feat(tui): restore composer history in app-server tui 4d02185