Commit Graph

3552 Commits

  • feat: mem v2 - PR2 (#11365)
    # Memories migration plan (simplified global workflow)
    
    ## Target behavior
    
    - One shared memory root only: `~/.codex/memories/`.
    - No per-cwd memory buckets, no cwd hash handling.
    - Phase 1 candidate rules:
    - Not currently being processed unless the job lease is stale.
    - Rollout updated within the max-age window (currently 30 days).
    - Rollout idle for at least 12 hours (new constant).
    - Global cap: at most 64 stage-1 jobs in `running` state at any time
    (new invariant).
    - Stage-1 model output shape (new):
    - `rollout_slug` (accepted but ignored for now).
    - `rollout_summary`.
    - `raw_memory`.
    - Phase-1 artifacts written under the shared root:
    - `rollout_summaries/<thread_id>.md` for each rollout summary.
    - `raw_memories.md` containing appended/merged raw memory paragraphs.
    - Phase 2 runs one consolidation agent for the shared `memories/`
    directory.
    - Phase-2 lock is DB-backed with 1 hour lease and heartbeat/expiry.
    
    ## Current code map
    
    - Core startup pipeline: `core/src/memories/startup/mod.rs`.
    - Stage-1 request+parse: `core/src/memories/startup/extract.rs`,
    `core/src/memories/stage_one.rs`, templates in
    `core/templates/memories/`.
    - File materialization: `core/src/memories/storage.rs`,
    `core/src/memories/layout.rs`.
    - Scope routing (cwd/user): `core/src/memories/scope.rs`,
    `core/src/memories/startup/mod.rs`.
    - DB job lifecycle and scope queueing: `state/src/runtime/memory.rs`.
    
    ## PR plan
    
    ## PR 1: Correct phase-1 selection invariants (no behavior-breaking
    layout changes yet)
    
    - Add `PHASE_ONE_MIN_ROLLOUT_IDLE_HOURS: i64 = 12` in
    `core/src/memories/mod.rs`.
    - Thread this into `state::claim_stage1_jobs_for_startup(...)`.
    - Enforce idle-time filter in DB selection logic (not only in-memory
    filtering after `scan_limit`) so eligible threads are not starved by
    very recent threads.
    - Enforce global running cap of 64 at claim time in DB logic:
    - Count fresh `memory_stage1` running jobs.
    - Only allow new claims while count < cap.
    - Keep stale-lease takeover behavior intact.
    - Add/adjust tests in `state/src/runtime.rs`:
    - Idle filter inclusion/exclusion around 12h boundary.
    - Global running-cap guarantee.
    - Existing stale/fresh ownership behavior still passes.
    
    Acceptance criteria:
    - Startup never creates more than 64 fresh `memory_stage1` running jobs.
    - Threads updated <12h ago are skipped.
    - Threads older than 30d are skipped.
    
    ## PR 2: Stage-1 output contract + storage artifacts
    (forward-compatible)
    
    - Update parser/types to accept the new structured output while keeping
    backward compatibility:
    - Add `rollout_slug` (optional for now).
    - Add `rollout_summary`.
    - Keep alias support for legacy `summary` and `rawMemory` until prompt
    swap completes.
    - Update stage-1 schema generator in `core/src/memories/stage_one.rs` to
    include the new keys.
    - Update prompt templates:
    - `core/templates/memories/stage_one_system.md`.
    - `core/templates/memories/stage_one_input.md`.
    - Replace storage model in `core/src/memories/storage.rs`:
    - Introduce `rollout_summaries/` directory writer (`<thread_id>.md`
    files).
    - Introduce `raw_memories.md` aggregator writer from DB rows.
    - Keep deterministic rebuild behavior from DB outputs so files can
    always be regenerated.
    - Update consolidation prompt template to reference `rollout_summaries/`
    + `raw_memories.md` inputs.
    
    Acceptance criteria:
    - Stage-1 accepts both old and new output keys during migration.
    - Phase-1 artifacts are generated in new format from DB state.
    - No dependence on per-thread files in `raw_memories/`.
    
    ## PR 3: Remove per-cwd memories and move to one global memory root
    
    - Simplify layout in `core/src/memories/layout.rs`:
    - Single root: `codex_home/memories`.
    - Remove cwd-hash bucket helpers and normalization logic used only for
    memory pathing.
    - Remove scope branching from startup phase-2 dispatch path:
    - No cwd/user mapping in `core/src/memories/startup/mod.rs`.
    - One target root for consolidation.
    - In `state/src/runtime/memory.rs`, stop enqueueing/handling cwd
    consolidation scope.
    - Keep one logical consolidation scope/job key (global/user) to avoid a
    risky schema rewrite in same PR.
    - Add one-time migration helper (core side) to preserve current shared
    memory output:
    - If `~/.codex/memories/user/memory` exists and new root is empty,
    move/copy contents into `~/.codex/memories`.
    - Leave old hashed cwd buckets untouched for now (safe/no-destructive
    migration).
    
    Acceptance criteria:
    - New runs only read/write `~/.codex/memories`.
    - No new cwd-scoped consolidation jobs are enqueued.
    - Existing user-shared memory content is preserved.
    
    ## PR 4: Phase-2 global lock simplification and cleanup
    
    - Replace multi-scope dispatch with a single global consolidation claim
    path:
    - Either reuse jobs table with one fixed key, or add a tiny dedicated
    lock helper; keep 1h lease.
    - Ensure at most one consolidation agent can run at once.
    - Keep heartbeat + stale lock recovery semantics in
    `core/src/memories/startup/watch.rs`.
    - Remove dead scope code and legacy constants no longer used.
    - Update tests:
    - One-agent-at-a-time behavior.
    - Lock expiry allows takeover after stale lease.
    
    Acceptance criteria:
    - Exactly one phase-2 consolidation agent can be active cluster-wide
    (per local DB).
    - Stale lock recovers automatically.
    
    ## PR 5: Final cleanup and docs
    
    - Remove legacy artifacts and references:
    - `raw_memories/` and `memory_summary.md` assumptions from
    prompts/comments/tests.
    - Scope constants for cwd memory pathing in core/state if fully unused.
    - Update docs under `docs/` for memory workflow and directory layout.
    - Add a brief operator note for rollout: compatibility window for old
    stage-1 JSON keys and when to remove aliases.
    
    Acceptance criteria:
    - Code and docs reflect only the simplified global workflow.
    - No stale references to per-cwd memory buckets.
    
    ## Notes on sequencing
    
    - PR 1 is safest first because it improves correctness without changing
    external artifact layout.
    - PR 2 keeps parser compatibility so prompt deployment can happen
    independently.
    - PR 3 and PR 4 split filesystem/scope simplification from locking
    simplification to reduce blast radius.
    - PR 5 is intentionally cleanup-only.
  • feat: mem v2 - PR1 (#11364)
    # Memories migration plan (simplified global workflow)
    
    ## Target behavior
    
    - One shared memory root only: `~/.codex/memories/`.
    - No per-cwd memory buckets, no cwd hash handling.
    - Phase 1 candidate rules:
    - Not currently being processed unless the job lease is stale.
    - Rollout updated within the max-age window (currently 30 days).
    - Rollout idle for at least 12 hours (new constant).
    - Global cap: at most 64 stage-1 jobs in `running` state at any time
    (new invariant).
    - Stage-1 model output shape (new):
    - `rollout_slug` (accepted but ignored for now).
    - `rollout_summary`.
    - `raw_memory`.
    - Phase-1 artifacts written under the shared root:
    - `rollout_summaries/<thread_id>.md` for each rollout summary.
    - `raw_memories.md` containing appended/merged raw memory paragraphs.
    - Phase 2 runs one consolidation agent for the shared `memories/`
    directory.
    - Phase-2 lock is DB-backed with 1 hour lease and heartbeat/expiry.
    
    ## Current code map
    
    - Core startup pipeline: `core/src/memories/startup/mod.rs`.
    - Stage-1 request+parse: `core/src/memories/startup/extract.rs`,
    `core/src/memories/stage_one.rs`, templates in
    `core/templates/memories/`.
    - File materialization: `core/src/memories/storage.rs`,
    `core/src/memories/layout.rs`.
    - Scope routing (cwd/user): `core/src/memories/scope.rs`,
    `core/src/memories/startup/mod.rs`.
    - DB job lifecycle and scope queueing: `state/src/runtime/memory.rs`.
    
    ## PR plan
    
    ## PR 1: Correct phase-1 selection invariants (no behavior-breaking
    layout changes yet)
    
    - Add `PHASE_ONE_MIN_ROLLOUT_IDLE_HOURS: i64 = 12` in
    `core/src/memories/mod.rs`.
    - Thread this into `state::claim_stage1_jobs_for_startup(...)`.
    - Enforce idle-time filter in DB selection logic (not only in-memory
    filtering after `scan_limit`) so eligible threads are not starved by
    very recent threads.
    - Enforce global running cap of 64 at claim time in DB logic:
    - Count fresh `memory_stage1` running jobs.
    - Only allow new claims while count < cap.
    - Keep stale-lease takeover behavior intact.
    - Add/adjust tests in `state/src/runtime.rs`:
    - Idle filter inclusion/exclusion around 12h boundary.
    - Global running-cap guarantee.
    - Existing stale/fresh ownership behavior still passes.
    
    Acceptance criteria:
    - Startup never creates more than 64 fresh `memory_stage1` running jobs.
    - Threads updated <12h ago are skipped.
    - Threads older than 30d are skipped.
    
    ## PR 2: Stage-1 output contract + storage artifacts
    (forward-compatible)
    
    - Update parser/types to accept the new structured output while keeping
    backward compatibility:
    - Add `rollout_slug` (optional for now).
    - Add `rollout_summary`.
    - Keep alias support for legacy `summary` and `rawMemory` until prompt
    swap completes.
    - Update stage-1 schema generator in `core/src/memories/stage_one.rs` to
    include the new keys.
    - Update prompt templates:
    - `core/templates/memories/stage_one_system.md`.
    - `core/templates/memories/stage_one_input.md`.
    - Replace storage model in `core/src/memories/storage.rs`:
    - Introduce `rollout_summaries/` directory writer (`<thread_id>.md`
    files).
    - Introduce `raw_memories.md` aggregator writer from DB rows.
    - Keep deterministic rebuild behavior from DB outputs so files can
    always be regenerated.
    - Update consolidation prompt template to reference `rollout_summaries/`
    + `raw_memories.md` inputs.
    
    Acceptance criteria:
    - Stage-1 accepts both old and new output keys during migration.
    - Phase-1 artifacts are generated in new format from DB state.
    - No dependence on per-thread files in `raw_memories/`.
    
    ## PR 3: Remove per-cwd memories and move to one global memory root
    
    - Simplify layout in `core/src/memories/layout.rs`:
    - Single root: `codex_home/memories`.
    - Remove cwd-hash bucket helpers and normalization logic used only for
    memory pathing.
    - Remove scope branching from startup phase-2 dispatch path:
    - No cwd/user mapping in `core/src/memories/startup/mod.rs`.
    - One target root for consolidation.
    - In `state/src/runtime/memory.rs`, stop enqueueing/handling cwd
    consolidation scope.
    - Keep one logical consolidation scope/job key (global/user) to avoid a
    risky schema rewrite in same PR.
    - Add one-time migration helper (core side) to preserve current shared
    memory output:
    - If `~/.codex/memories/user/memory` exists and new root is empty,
    move/copy contents into `~/.codex/memories`.
    - Leave old hashed cwd buckets untouched for now (safe/no-destructive
    migration).
    
    Acceptance criteria:
    - New runs only read/write `~/.codex/memories`.
    - No new cwd-scoped consolidation jobs are enqueued.
    - Existing user-shared memory content is preserved.
    
    ## PR 4: Phase-2 global lock simplification and cleanup
    
    - Replace multi-scope dispatch with a single global consolidation claim
    path:
    - Either reuse jobs table with one fixed key, or add a tiny dedicated
    lock helper; keep 1h lease.
    - Ensure at most one consolidation agent can run at once.
    - Keep heartbeat + stale lock recovery semantics in
    `core/src/memories/startup/watch.rs`.
    - Remove dead scope code and legacy constants no longer used.
    - Update tests:
    - One-agent-at-a-time behavior.
    - Lock expiry allows takeover after stale lease.
    
    Acceptance criteria:
    - Exactly one phase-2 consolidation agent can be active cluster-wide
    (per local DB).
    - Stale lock recovers automatically.
    
    ## PR 5: Final cleanup and docs
    
    - Remove legacy artifacts and references:
    - `raw_memories/` and `memory_summary.md` assumptions from
    prompts/comments/tests.
    - Scope constants for cwd memory pathing in core/state if fully unused.
    - Update docs under `docs/` for memory workflow and directory layout.
    - Add a brief operator note for rollout: compatibility window for old
    stage-1 JSON keys and when to remove aliases.
    
    Acceptance criteria:
    - Code and docs reflect only the simplified global workflow.
    - No stale references to per-cwd memory buckets.
    
    ## Notes on sequencing
    
    - PR 1 is safest first because it improves correctness without changing
    external artifact layout.
    - PR 2 keeps parser compatibility so prompt deployment can happen
    independently.
    - PR 3 and PR 4 split filesystem/scope simplification from locking
    simplification to reduce blast radius.
    - PR 5 is intentionally cleanup-only.
  • Use thin LTO for alpha Rust release builds (#11348)
    We are looking to speed up build times for alpha releases, but we do not
    want to completely compromise on runtime performance by shipping debug
    builds. This PR changes our CI so that alpha releases build with
    `lto="thin"` instead of `lto="fat"`.
    
    Specifically, this change keeps `[profile.release] lto = "fat"` as the
    default in `Cargo.toml`, but overrides LTO in CI using
    `CARGO_PROFILE_RELEASE_LTO`:
    - `rust-release.yml`: use `thin` for `-alpha` tags, otherwise `fat`
    - `shell-tool-mcp.yml`: use `thin` for `-alpha` versions, otherwise
    `fat`
    
    Tradeoffs:
    - Alpha binaries may be somewhat larger and/or slightly slower than
    fat-LTO builds
    - LTO policy now lives in workflow logic for two pipelines, so
    consistency must be maintained across both files
    
    Note `CARGO_PROFILE_<name>_LTO` is documented on
    https://doc.rust-lang.org/cargo/reference/environment-variables.html#configuration-environment-variables.
  • Strip unsupported images from prompt history to guard against model switch (#11349)
    - Make `ContextManager::for_prompt` modality-aware and strip input_image
    content when the active model is text-only.
    - Added a test for multi-model -> text-only model switch
  • include sandbox (seatbelt, elevated, etc.) as in turn metadata header (#10946)
    This will help us understand retention/usage for folks who use the
    Windows (or any other) sandboxes
  • fix(core): canonicalize wrapper approvals and support heredoc prefix … (#10941)
    ## Summary
    - Reduced repeated approvals for equivalent wrapper commands and fixed
    execpolicy matching for heredoc-style shell invocations, with minimal
    behavior change and fail-closed defaults.
    
    ## Fixes
    1. Canonicalized approval matching for wrappers so equivalent commands
    map to the same approval intent.
    2. Added heredoc-aware prefix extraction for execpolicy so commands like
    `python3 <<'PY' ... PY` match rules such as `prefix_rule(["python3"],
    ...)`.
    3. Kept fallback behavior conservative: if parsing is ambiguous,
    existing prompt behavior is preserved.
    
    ## Edge Cases Covered
    - Wrapper path/name differences: `/bin/bash` vs `bash`, `/bin/zsh` vs
    `zsh`.
    - Shell modes: `-c` and `-lc`.
    - Heredoc forms: quoted delimiter (`<<'PY'`) and unquoted delimiter (`<<
    PY`).
    - Multi-command heredoc scripts are rejected by the fallback
    - Non-heredoc redirections (`>`, etc.) are not treated as heredoc prefix
    matches.
    - Complex scripts still fall back to prior behavior rather than
    expanding permissions.
    
    ---------
    
    Co-authored-by: Dylan Hurd <dylan.hurd@openai.com>
  • Extract tool building (#11337)
    Make it clear what input go into building tools and allow for easy reuse
    for pre-warm request
  • Sanitize MCP image output for text-only models (#11346)
    - Replace image blocks in MCP tool results with a text placeholder when
    the active model does not accept image input.
    - Add an e2e rmcp test to verify sanitized tool output is what gets sent
    back to the model.
  • Always expose view_image and return unsupported image-input error (#11336)
    - Keep `view_image` in the advertised tool list for all models.
    - Return a clear error when the current model does not support image
    inputs, and cover it with a unit test.
  • Compare full request for websockets incrementality (#11343)
    Tools can dynamically change mid-turn now. We need to be more thorough
    about reusing incremental connections.
  • core: remove stale apply_patch SandboxPolicy TODO in seatbelt (#11345)
    The `TODO` in `core/src/seatbelt.rs` claimed that `apply_patch` still needed to honor `SandboxPolicy`. That was true when the comment was added, but it is no longer true.
    
    Analysis:
    - The TODO was introduced in #1762, when seatbelt code was split out of `exec.rs`.
    - `apply_patch` sandboxing was later implemented in #1705.
    - Today, `apply_patch` calls are routed through the tool orchestrator and delegated to `ApplyPatchRuntime`, which executes via `execute_env()` using the active sandbox attempt policy.
    - On macOS, the sandbox transform path for that execution still builds seatbelt args with `create_seatbelt_command_args(command, policy, sandbox_policy_cwd)`, so the same `SandboxPolicy` gates `apply_patch` writes and network behavior.
    
    Because this behavior is already enforced, the TODO is stale and removing it avoids implying missing sandbox coverage where none exists.
    
    No functional behavior change; comment-only cleanup.
  • test(core): stabilize ARM bazel remote-model and parallelism tests (#11330)
    ## Summary
    - keep wiremock MockServer handles alive through async assertions in
    remote model suite tests
    - assert /models request count in remote_models_hide_picker_only_models
    - use a slightly higher parallel timing threshold on aarch64 while
    keeping existing x86 threshold
    
    ## Validation
    - just fmt
    - targeted tests:
    - cargo test -p codex-core --test all
    suite::remote_models::remote_models_merge_replaces_overlapping_model --
    --exact
    - cargo test -p codex-core --test all
    suite::remote_models::remote_models_hide_picker_only_models -- --exact
    - cargo test -p codex-core --test all
    suite::tool_parallelism::shell_tools_run_in_parallel -- --exact
    - soak loop: 40 iterations of all three targeted tests
    
    ## Notes
    - cargo test -p codex-core has one unrelated local-env failure in
    shell_snapshot::tests::try_new_creates_and_deletes_snapshot_file from
    exported certificate env content in this workspace.
    - local bazel test //codex-rs/core:core-all-test failed to build due
    missing rust-objcopy in this host toolchain.
  • # Use @openai/codex dist-tags for platform binaries instead of separate package names (#11339)
    https://github.com/openai/codex/pull/11318 introduced logic to publish
    platform artifacts as separate npm packages (for example,
    `@openai/codex-darwin-arm64`, `@openai/codex-linux-x64`, etc.). That
    requires provisioning and maintaining multiple package entries in npm,
    which we want to avoid.
    
    We still need to keep the package-size mitigation (platform-specific
    payloads), but we want that layout to live under a single npm package
    namespace (`@openai/codex`) using dist-tags.
    
    We also need to preserve pre-release workflows where users install
    `@openai/codex@alpha` and get platform-appropriate binaries.
    
    Additionally, we want GitHub Release assets to group Codex npm tarballs
    together, so platform tarballs should follow the same `codex-npm-*`
    filename prefix as the main Codex tarball.
    
    ## Release Strategy (New Scheme)
    
    We publish **one npm package name for Codex binaries** (`@openai/codex`)
    and use **dist-tags** to select platform-specific payloads. This avoids
    creating separate platform package names while keeping the package size
    split by platform.
    
    ### What gets published
    
    #### Mainline release (`x.y.z`)
    
    - `@openai/codex@latest` (meta package)
    - `@openai/codex@darwin-arm64`
    - `@openai/codex@darwin-x64`
    - `@openai/codex@linux-arm64`
    - `@openai/codex@linux-x64`
    - `@openai/codex@win32-arm64`
    - `@openai/codex@win32-x64`
    - `@openai/codex-responses-api-proxy@latest`
    - `@openai/codex-sdk@latest`
    
    #### Alpha release (`x.y.z-alpha.N`)
    
    - `@openai/codex@alpha` (meta package)
    - `@openai/codex@alpha-darwin-arm64`
    - `@openai/codex@alpha-darwin-x64`
    - `@openai/codex@alpha-linux-arm64`
    - `@openai/codex@alpha-linux-x64`
    - `@openai/codex@alpha-win32-arm64`
    - `@openai/codex@alpha-win32-x64`
    - `@openai/codex-responses-api-proxy@alpha`
    - `@openai/codex-sdk@alpha`
    
    As an example, the `package.json` for `@openai/codex@alpha` (using
    `0.99.0-alpha.17` as the `version`) would be:
    
    ```
    {
      "name": "@openai/codex",
      "version": "0.99.0-alpha.17",
      "license": "Apache-2.0",
      "bin": {
        "codex": "bin/codex.js"
      },
      "type": "module",
      "engines": {
        "node": ">=16"
      },
      "files": [
        "bin"
      ],
      "repository": {
        "type": "git",
        "url": "git+https://github.com/openai/codex.git",
        "directory": "codex-cli"
      },
      "packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264",
      "optionalDependencies": {
        "@openai/codex-linux-x64": "npm:@openai/codex@0.99.0-alpha.17-linux-x64",
        "@openai/codex-linux-arm64": "npm:@openai/codex@0.99.0-alpha.17-linux-arm64",
        "@openai/codex-darwin-x64": "npm:@openai/codex@0.99.0-alpha.17-darwin-x64",
        "@openai/codex-darwin-arm64": "npm:@openai/codex@0.99.0-alpha.17-darwin-arm64",
        "@openai/codex-win32-x64": "npm:@openai/codex@0.99.0-alpha.17-win32-x64",
        "@openai/codex-win32-arm64": "npm:@openai/codex@0.99.0-alpha.17-win32-arm64"
      }
    }
    ```
    
    Note that the keys in `optionalDependencies` have "clean" names, but the
    values have the tag embedded.
    
    ### Important note
    
    **Note:** Because we never created the new platform package names on npm
    (for example,
    `@openai/codex-darwin-arm64`) since #11318 landed, there are no extra
    npm packages to clean up.
    
    ## What changed
    
    ### 1. Stage platform tarballs as `@openai/codex` with platform-specific
    versions
    
    File: `codex-cli/scripts/build_npm_package.py`
    
    - Added `CODEX_NPM_NAME = "@openai/codex"` and platform metadata
    `npm_tag` values:
    - `darwin-arm64`, `darwin-x64`, `linux-arm64`, `linux-x64`,
    `win32-arm64`, `win32-x64`
    - For platform package staging (`codex-<platform>` inputs), switched
    generated `package.json` from:
      - `name = @openai/codex-<platform>`
      to:
      - `name = @openai/codex`
    - Added `compute_platform_package_version(version, platform_tag)` so
    platform tarballs have unique
    versions (`<release-version>-<platform-tag>`), which is required because
    npm forbids re-publishing
      the same `name@version`.
    
    ### 2. Point meta package optional dependencies at dist-tags on
    `@openai/codex`
    
    File: `codex-cli/scripts/build_npm_package.py`
    
    - Updated `optionalDependencies` generation for the main `codex` package
    to use npm alias syntax:
    - key remains alias package name (for example,
    `@openai/codex-darwin-arm64`) so runtime lookup behavior is unchanged
      - value now resolves to `@openai/codex` by dist-tag
    - Stable releases emit tags like `npm:@openai/codex@darwin-arm64`.
    - Alpha releases (`x.y.z-alpha.N`) emit tags like
    `npm:@openai/codex@alpha-darwin-arm64`.
    
    ### 3. Publish with per-tarball dist-tags in release CI
    
    File: `.github/workflows/rust-release.yml`
    
    - Reworked npm publish logic to derive the publish tag per tarball
    filename:
      - platform tarballs publish with `<platform>` tags for stable releases
    - platform tarballs publish with `alpha-<platform>` tags for alpha
    releases
    - top-level tarballs (`codex`, `codex-responses-api-proxy`, `codex-sdk`)
    continue using
    the existing channel tag policy (`latest` implicit for stable, `alpha`
    for alpha)
    - Added fail-fast behavior for unexpected tarball names to avoid silent
    mispublishes.
    
    ### 4. Normalize Codex platform tarball filenames for GitHub Release
    grouping
    
    Files: `scripts/stage_npm_packages.py`,
    `.github/workflows/rust-release.yml`
    
    - Renamed staged platform tarball filenames from:
      - `codex-linux-<arch>-npm-<version>.tgz`
      - `codex-darwin-<arch>-npm-<version>.tgz`
      - `codex-win32-<arch>-npm-<version>.tgz`
    - To:
      - `codex-npm-linux-<arch>-<version>.tgz`
      - `codex-npm-darwin-<arch>-<version>.tgz`
      - `codex-npm-win32-<arch>-<version>.tgz`
    
    This keeps all Codex npm artifacts grouped under a common `codex-npm-`
    prefix in GitHub Releases.
    
    ### 5. Documentation update
    
    File: `codex-cli/scripts/README.md`
    
    - Updated staging docs to clarify that platform-native variants are
    published as dist-tagged
      `@openai/codex` artifacts rather than separate npm package names.
    
    ## Resulting behavior
    
    - Mainline release:
      - `@openai/codex@latest` resolves the meta package
    - meta package optional dependencies resolve
    `@openai/codex@<platform-tag>`
    - Alpha release:
      - users can continue installing `@openai/codex@alpha`
    - alpha meta package optional dependencies resolve
    `@openai/codex@alpha-<platform-tag>`
    - Release assets:
    - Codex npm tarballs share `codex-npm-` prefix for cleaner grouping in
    GitHub Releases
    
    This preserves platform-specific payload distribution while avoiding
    separate npm package names and
    improves release-asset discoverability.
    
    ## Validation notes
    
    - Verified staged `package.json` output for stable and alpha meta
    packages includes expected alias targets.
    - Verified staged platform package manifests are `name=@openai/codex`
    with unique platform-suffixed versions.
    - Verified publish tag derivation maps renamed platform tarballs to
    expected stable and alpha dist-tags.
  • Treat first rollout session_meta as canonical thread identity (#11241)
    During thread/fork, the new rollout includes the fork’s own session_meta
    plus copied history that can contain older session_meta entries from the
    source thread. thread/list was overwriting metadata on later
    session_meta lines, so a fork could be reported with the source thread’s
    thread_id. This fix only uses the first session_meta, so the fork keeps
    its own ID.
  • feat: opt-out of events in the app-server (#11319)
    Add `optOutNotificationMethods` in the app-server to opt-out events
    based on exact method matching
  • [apps] Improve app installation flow. (#11249)
    - [x] Add buttons to start the installation flow and verify installation
    completes.
    - [x] Hard refresh apps list when the /apps view opens.
  • Fix: update parallel tool call exec approval to approve on request id (#11162)
    ### Summary
    
    In parallel tool call, exec command approvals were not approved at
    request level but at a turn level. i.e. when a single request is
    approved, the system currently treats all requests in turn as approved.
    
    ### Before
    
    https://github.com/user-attachments/assets/d50ed129-b3d2-4b2f-97fa-8601eb11f6a8
    
    ### After
    
    https://github.com/user-attachments/assets/36528a43-a4aa-4775-9e12-f13287ef19fc
  • fix(protocol): approval policy never prompt (#11288)
    This removes overly directed language about how the model should behave
    when it's in `approval_policy=never` mode.
    
    ---------
    
    Co-authored-by: Dylan Hurd <dylan.hurd@openai.com>
  • tui: keep history recall cursor at line end (#11295)
    ## Summary
    - keep cursor at end-of-line after Up/Down history recall
    - allow continued history navigation when recalled text cursor is at
    start or end boundary
    - add regression tests and document the history cursor contract in
    composer docs
    
    ## Testing
    - just fmt
    - cargo test -p codex-tui --lib
    history_navigation_leaves_cursor_at_end_of_line
    - cargo test -p codex-tui --lib
    should_handle_navigation_when_cursor_is_at_line_boundaries
    - cargo test -p codex-tui *(fails in existing integration test
    `suite::no_panic_on_startup::malformed_rules_should_not_panic` because
    `target/debug/codex` is not present in this environment)*
  • Remove ApiPrompt (#11265)
    Keep things simple and build a full Responses API request request right
    in the model client
  • Fix pending input test waiting logic (#11322)
    ## Summary
    - remove redundant user message wait that could time out and cause
    flakiness
    - rely on the existing turn-complete wait to ensure the follow-up
    request is observed
    
    ## Testing
    - Not run (not requested)
  • feat: phase 2 consolidation (#11306)
    Consolidation phase of memories
    
    Cleaning and better handling of concurrency
  • Extract hooks into dedicated crate (#11311)
    Summary
    - move `core/src/hooks` implementation into a new `codex-hooks` crate
    with its own manifest
    - update `codex-rs` workspace and `codex-core` crate to depend on the
    extracted `hooks` crate and wire up the shared APIs
    - ensure references, modules, and lockfile reflect the new crate layout
    
    Testing
    - Not run (not requested)
  • feat: align memory phase 1 and make it stronger (#11300)
    ## Align with the new phase-1 design
    
    Basically we know run phase 1 in parallel by considering:
    * Max 64 rollouts
    * Max 1 month old
    * Consider the most recent first
    
    This PR also adds stronger parallelization capabilities by detecting
    stale jobs, retry policies, ownership of computation to prevent double
    computations etc etc
  • memories: add extraction and prompt module foundation (#11200)
    ## Summary
    - add the new `core/src/memories` module (phase-one parsing, rollout
    filtering, storage, selection, prompts)
    - add Askama-backed memory templates for stage-one input/system and
    consolidation prompts
    - add module tests for parsing, filtering, path bucketing, and summary
    maintenance
    
    ## Testing
    - just fmt
    - cargo test -p codex-core --lib memories::
  • feat: retain NetworkProxy, when appropriate (#11207)
    As of this PR, `SessionServices` retains a
    `Option<StartedNetworkProxy>`, if appropriate.
    
    Now the `network` field on `Config` is `Option<NetworkProxySpec>`
    instead of `Option<NetworkProxy>`.
    
    Over in `Session::new()`, we invoke `NetworkProxySpec::start_proxy()` to
    create the `StartedNetworkProxy`, which is a new struct that retains the
    `NetworkProxy` as well as the `NetworkProxyHandle`. (Note that `Drop` is
    implemented for `NetworkProxyHandle` to ensure the proxies are shutdown
    when it is dropped.)
    
    The `NetworkProxy` from the `StartedNetworkProxy` is threaded through to
    the appropriate places.
    
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/11207).
    * #11285
    * __->__ #11207
  • chore: put crypto provider logic in a shared crate (#11294)
    Ensures a process-wide rustls crypto provider is installed.
    
    Both the `codex-network-proxy` and `codex-api` crates need this.
  • feat(sandbox): enforce proxy-aware network routing in sandbox (#11113)
    ## Summary
    - expand proxy env injection to cover common tool env vars
    (`HTTP_PROXY`/`HTTPS_PROXY`/`ALL_PROXY`/`NO_PROXY` families +
    tool-specific variants)
    - harden macOS Seatbelt network policy generation to route through
    inferred loopback proxy endpoints and fail closed when proxy env is
    malformed
    - thread proxy-aware Linux sandbox flags and add minimal bwrap netns
    isolation hook for restricted non-proxy runs
    - add/refresh tests for proxy env wiring, Seatbelt policy generation,
    and Linux sandbox argument wiring
  • chore(tui) cleanup /approvals (#10215)
    ## Summary
    Consolidate on the new `/permissions` flow
    
    ## Testing
    - [x] updated snapshots
  • feat: add SkillPolicy to skill metadata and support allow_implicit_invocation (#11244)
    Tested by setting the policy in agents/openai.yaml to true, false, and
    leaving it unset (default).
    ```
    policy:
      allow_implicit_invocation: false
    ```
    <img width="847" height="289" alt="Screenshot 2026-02-09 at 3 42 41 PM"
    src="https://github.com/user-attachments/assets/d3476264-3355-47cf-894a-4ffba53e3481"
    />
  • [apps] Add thread_id param to optionally load thread config for apps feature check. (#11279)
    - [x] Add thread_id param to optionally load thread config for apps
    feature check
  • feat: reserve loopback ephemeral listeners for managed proxy (#11269)
    Codex may run many per-thread proxy instances, so hardcoded proxy ports
    are brittle and conflict-prone. The previous "ephemeral" approach still
    had a race: `build()` read `local_addr()` from temporary listeners and
    dropped them before `run()` rebound the ports. That left a
    [TOCTOU](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use)
    window where the OS (or another process) could reuse the same port,
    causing intermittent `EADDRINUSE` and partial proxy startup.
    
    Change the managed proxy path to reserve real listener sockets up front
    and keep them alive until startup:
    
    - add `ReservedListeners` on `NetworkProxy` to hold HTTP/SOCKS/admin std
    listeners allocated during `build()`
    - in managed mode, bind `127.0.0.1:0` for each listener and carry those
    bound sockets into `run()` instead of rebinding by address later
    - add `run_*_with_std_listener` entry points for HTTP, SOCKS5, and admin
    servers so `run()` can start services from already-reserved sockets
    - keep static/configured ports only when `managed_by_codex(false)`,
    including explicit `socks_addr` override support
    - remove fallback synthetic port allocation and add tests for managed
    ephemeral loopback binding and unmanaged configured-port behavior
    
    This makes managed startup deterministic, avoids port collisions, and
    preserves the intended distinction between Codex-managed ephemeral ports
    and externally managed fixed ports.
  • Disable dynamic model refresh for custom model providers (#11239)
    The dynamic model refresh feature (`https://api.openai.com/v1/models`
    endpoint) is currently gated on a runtime check for an auth method other
    than API Key. It should be gated on a check specifically for ChatGPT
    Auth because some custom model providers (e.g. for local models) use no
    auth mechanism. A call to `self.auth_manager.auth_mode()` will return
    `None` in this case.
    
    Addresses #11213
  • chore(deps): bump regex from 1.12.2 to 1.12.3 in /codex-rs (#11138)
    Bumps [regex](https://github.com/rust-lang/regex) from 1.12.2 to 1.12.3.
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    href="https://github.com/rust-lang/regex/blob/master/CHANGELOG.md">regex's
    changelog</a>.</em></p>
    <blockquote>
    <h1>1.12.3 (2025-02-03)</h1>
    <p>This release excludes some unnecessary things from the archive
    published to
    crates.io. Specifically, fuzzing data and various shell scripts are now
    excluded. If you run into problems, please file an issue.</p>
    <p>Improvements:</p>
    <ul>
    <li><a
    href="https://redirect.github.com/rust-lang/regex/pull/1319">#1319</a>:
    Switch from a Cargo <code>exclude</code> list to an <code>include</code>
    list, and exclude some
    unnecessary stuff.</li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/rust-lang/regex/commit/b028e4f40eac8959d05e82abf8404906b1c565c0"><code>b028e4f</code></a>
    1.12.3</li>
    <li><a
    href="https://github.com/rust-lang/regex/commit/5e195de266e203441b2c8001d6ebefab1161a59e"><code>5e195de</code></a>
    regex-automata-0.4.14</li>
    <li><a
    href="https://github.com/rust-lang/regex/commit/a3433f691863d80300dfd6a52e332cb5a568e895"><code>a3433f6</code></a>
    regex-syntax-0.8.9</li>
    <li><a
    href="https://github.com/rust-lang/regex/commit/0c07fae444adf0802d84455e689f1143d2dd7790"><code>0c07fae</code></a>
    regex-lite-0.1.9</li>
    <li><a
    href="https://github.com/rust-lang/regex/commit/6a810068f030c023a12c93ccae49bc5fd907c4f6"><code>6a81006</code></a>
    cargo: exclude development scripts and fuzzing data</li>
    <li><a
    href="https://github.com/rust-lang/regex/commit/4733e28ba4f281f643ce93e4089eccbb9a9d5a5a"><code>4733e28</code></a>
    automata: fix <code>onepass::DFA::try_search_slots</code> panic when too
    many slots are ...</li>
    <li>See full diff in <a
    href="https://github.com/rust-lang/regex/compare/1.12.2...1.12.3">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=regex&package-manager=cargo&previous-version=1.12.2&new-version=1.12.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • chore(deps): bump anyhow from 1.0.100 to 1.0.101 in /codex-rs (#11139)
    Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.100 to
    1.0.101.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/dtolnay/anyhow/releases">anyhow's
    releases</a>.</em></p>
    <blockquote>
    <h2>1.0.101</h2>
    <ul>
    <li>Add #[inline] to anyhow::Ok helper (<a
    href="https://redirect.github.com/dtolnay/anyhow/issues/437">#437</a>,
    thanks <a
    href="https://github.com/Ibitier"><code>@​Ibitier</code></a>)</li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/dtolnay/anyhow/commit/80bfe291b16071c70f141e90e67e7032d966826b"><code>80bfe29</code></a>
    Release 1.0.101</li>
    <li><a
    href="https://github.com/dtolnay/anyhow/commit/dff8c432f95095cac19aa446da5047880b8ebdf3"><code>dff8c43</code></a>
    Merge pull request <a
    href="https://redirect.github.com/dtolnay/anyhow/issues/437">#437</a>
    from Ibitier/inline-ok-helper</li>
    <li><a
    href="https://github.com/dtolnay/anyhow/commit/85d9ea9a1c7d7490578865e16ff64787efc7d01d"><code>85d9ea9</code></a>
    Add #[inline] to anyhow::Ok helper</li>
    <li><a
    href="https://github.com/dtolnay/anyhow/commit/54036cc289b754775b884485f486e000bcda2875"><code>54036cc</code></a>
    Update ui test suite to nightly-2026-01-21</li>
    <li><a
    href="https://github.com/dtolnay/anyhow/commit/cce0579d85fd1f6352a5955a9c134fc8655c853d"><code>cce0579</code></a>
    Update actions/upload-artifact@v5 -&gt; v6</li>
    <li><a
    href="https://github.com/dtolnay/anyhow/commit/f2c598ca0e8ffd7ffcbcf93b8a6ad4df57c719fd"><code>f2c598c</code></a>
    Update actions/upload-artifact@v4 -&gt; v5</li>
    <li><a
    href="https://github.com/dtolnay/anyhow/commit/2c0bda4ce944d943e7141f0316b0ea996602238e"><code>2c0bda4</code></a>
    Update to 2021 edition</li>
    <li><a
    href="https://github.com/dtolnay/anyhow/commit/0d822681293d71c72440c9cdd635b4f15da064c4"><code>0d82268</code></a>
    Remove rustc version requirement from readme</li>
    <li><a
    href="https://github.com/dtolnay/anyhow/commit/67df01216d29bc3bede925ab4483353b66c159f2"><code>67df012</code></a>
    Merge pull request <a
    href="https://redirect.github.com/dtolnay/anyhow/issues/436">#436</a>
    from dtolnay/up</li>
    <li><a
    href="https://github.com/dtolnay/anyhow/commit/c8984880a87ae4fd4b04c956cfdc9af5f69eab55"><code>c898488</code></a>
    Raise required compiler to Rust 1.68</li>
    <li>Additional commits viewable in <a
    href="https://github.com/dtolnay/anyhow/compare/1.0.100...1.0.101">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=anyhow&package-manager=cargo&previous-version=1.0.100&new-version=1.0.101)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • chore(deps): bump insta from 1.46.2 to 1.46.3 in /codex-rs (#11140)
    Bumps [insta](https://github.com/mitsuhiko/insta) from 1.46.2 to 1.46.3.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/mitsuhiko/insta/releases">insta's
    releases</a>.</em></p>
    <blockquote>
    <h2>1.46.3</h2>
    <h2>Release Notes</h2>
    <ul>
    <li>Fix inline escaped snapshots incorrectly stripping leading newlines
    when content contains control characters like carriage returns. The
    escaped format (used for snapshots with control chars) now correctly
    preserves the original content without stripping a non-existent
    formatting newline. <a
    href="https://redirect.github.com/mitsuhiko/insta/issues/865">#865</a></li>
    </ul>
    <h2>Install cargo-insta 1.46.3</h2>
    <h3>Install prebuilt binaries via shell script</h3>
    <pre lang="sh"><code>curl --proto '=https' --tlsv1.2 -LsSf
    https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-installer.sh
    | sh
    </code></pre>
    <h3>Install prebuilt binaries via powershell script</h3>
    <pre lang="sh"><code>powershell -ExecutionPolicy Bypass -c &quot;irm
    https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-installer.ps1
    | iex&quot;
    </code></pre>
    <h2>Download cargo-insta 1.46.3</h2>
    <table>
    <thead>
    <tr>
    <th>File</th>
    <th>Platform</th>
    <th>Checksum</th>
    </tr>
    </thead>
    <tbody>
    <tr>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-aarch64-apple-darwin.tar.xz">cargo-insta-aarch64-apple-darwin.tar.xz</a></td>
    <td>Apple Silicon macOS</td>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-aarch64-apple-darwin.tar.xz.sha256">checksum</a></td>
    </tr>
    <tr>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-apple-darwin.tar.xz">cargo-insta-x86_64-apple-darwin.tar.xz</a></td>
    <td>Intel macOS</td>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-apple-darwin.tar.xz.sha256">checksum</a></td>
    </tr>
    <tr>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-pc-windows-msvc.zip">cargo-insta-x86_64-pc-windows-msvc.zip</a></td>
    <td>x64 Windows</td>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-pc-windows-msvc.zip.sha256">checksum</a></td>
    </tr>
    <tr>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-unknown-linux-gnu.tar.xz">cargo-insta-x86_64-unknown-linux-gnu.tar.xz</a></td>
    <td>x64 Linux</td>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-unknown-linux-gnu.tar.xz.sha256">checksum</a></td>
    </tr>
    <tr>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-unknown-linux-musl.tar.xz">cargo-insta-x86_64-unknown-linux-musl.tar.xz</a></td>
    <td>x64 MUSL Linux</td>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-unknown-linux-musl.tar.xz.sha256">checksum</a></td>
    </tr>
    </tbody>
    </table>
    </blockquote>
    </details>
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    href="https://github.com/mitsuhiko/insta/blob/master/CHANGELOG.md">insta's
    changelog</a>.</em></p>
    <blockquote>
    <h2>1.46.3</h2>
    <ul>
    <li>Fix inline escaped snapshots incorrectly stripping leading newlines
    when content contains control characters like carriage returns. The
    escaped format (used for snapshots with control chars) now correctly
    preserves the original content without stripping a non-existent
    formatting newline. <a
    href="https://redirect.github.com/mitsuhiko/insta/issues/865">#865</a></li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/mitsuhiko/insta/commit/13245901751701f45677b9cfe3537c182b47af02"><code>1324590</code></a>
    Release 1.46.3 (<a
    href="https://redirect.github.com/mitsuhiko/insta/issues/870">#870</a>)</li>
    <li><a
    href="https://github.com/mitsuhiko/insta/commit/b26bc7ffe1653d42e274077bb711559f2cd5a553"><code>b26bc7f</code></a>
    Fix escaped format inline snapshots not stripping formatting newline (<a
    href="https://redirect.github.com/mitsuhiko/insta/issues/869">#869</a>)</li>
    <li>See full diff in <a
    href="https://github.com/mitsuhiko/insta/compare/1.46.2...1.46.3">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=insta&package-manager=cargo&previous-version=1.46.2&new-version=1.46.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • fix(app-server): for external auth, replace id_token with chatgpt_acc… (#11240)
    …ount_id and chatgpt_plan_type
    
    ### Summary
    Following up on external auth mode which was introduced here:
    https://github.com/openai/codex/pull/10012
    
    Turns out some clients have a differently shaped ID token and don't have
    a chosen workspace (aka chatgpt_account_id) encoded in their ID token.
    So, let's replace `id_token` param with `chatgpt_account_id` and
    `chatgpt_plan_type` (optional) when initializing the external ChatGPT
    auth mode (`account/login/start` with `chatgptAuthTokens`).
    
    The client was able to test end-to-end with a Codex build from this
    branch and verified it worked!
  • Adjust shell command timeouts for Windows (#11247)
    Summary
    - add platform-aware defaults for shell command timeouts so Windows
    tests get longer waits
    - keep medium timeout longer on Windows to ensure flakiness is reduced
    
    Testing
    - Not run (not requested)
  • test: deflake nextest child-process leak in MCP harnesses (#11263)
    ## Summary
    - add deterministic child-process cleanup to both test `McpProcess`
    helpers
    - keep Tokio `kill_on_drop(true)` but also reap via bounded `try_wait()`
    polling in `Drop`
    - document the failure mode and why this avoids nondeterministic `LEAK`
    flakes
    
    ## Why
    `cargo nextest` leak detection can intermittently report `LEAK` when a
    spawned server outlives test teardown, making CI flaky.
    
    ## Testing
    - `just fmt`
    - `cargo test -p codex-app-server`
    - `cargo test -p codex-mcp-server`
    
    
    ## Failing CI Reference
    - Original failing job:
    https://github.com/openai/codex/actions/runs/21845226299/job/63039443593?pr=11245
  • chore: change ConfigState so it no longer depends on a single config.toml file for reloading (#11262)
    If anything, it should depend on `ConfigLayerStack`.
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/11262).
    * #11207
    * __->__ #11262
  • deflake linux-sandbox NoNewPrivs timeout (#11245)
    Deflake `codex-linux-sandbox::all
    suite::landlock::test_no_new_privs_is_enabled`.
    
    CI has intermittently failed with `Sandbox(Timeout)` (exit 124) because
    the sandboxed
    `grep '^NoNewPrivs:' /proc/self/status` can run close to the short
    timeout budget.
    
    This updates only this test to use `LONG_TIMEOUT_MS`, which removes the
    near-threshold timeout
    behavior while keeping the rest of the suite unchanged.
    
    Refs (previous failures):
    - PR:
    https://github.com/openai/codex/actions/runs/21836764823/job/63009902779
    - PR:
    https://github.com/openai/codex/actions/runs/21837427251/job/63012470353
    - main:
    https://github.com/openai/codex/actions/runs/21830746538/job/62988079964
    
    Validation:
    - Local: `cd codex-rs && cargo test -p codex-linux-sandbox` (non-Linux
    runs 0 tests)