Skip to content

[codex-login] Serialize managed ChatGPT token refreshes#24663

Closed
cooper-oai wants to merge 1 commit into
cooper/codex-cli-eager-chatgpt-token-refreshfrom
cooper/codex-cli-managed-chatgpt-refresh-lock
Closed

[codex-login] Serialize managed ChatGPT token refreshes#24663
cooper-oai wants to merge 1 commit into
cooper/codex-cli-eager-chatgpt-token-refreshfrom
cooper/codex-cli-managed-chatgpt-refresh-lock

Conversation

@cooper-oai
Copy link
Copy Markdown
Contributor

Stack

Summary

  • serialize managed ChatGPT refresh-token redemption across Codex processes sharing the same CODEX_HOME
  • make waiters reuse credentials another process already refreshed and persisted
  • apply the same serialization to proactive near-expiry refresh and reactive managed refresh recovery

Why

Managed ChatGPT refresh tokens rotate when used. The base PR expands the existing pre-request refresh predicate to include a five-minute near-expiry window. Without serialization, multiple Codex processes can observe the same token in that window, redeem the same refresh token concurrently, and cause an avoidable reuse failure.

The pre-existing semaphore protects callers within one AuthManager only; this PR adds a file lock for managed refreshes across processes and rechecks stored auth after waiting on that lock.

Validation

  • bazel test //codex-rs/login:login-all-test
  • just fix -p codex-login
  • just fmt runs Rust formatting successfully, then its Python SDK Ruff step cannot install openai-codex-cli-bin==0.131.0a4 on this Linux environment because no compatible wheel is published.

@cooper-oai
Copy link
Copy Markdown
Contributor Author

Closing this follow-up for now. We are holding off on the cross-process serialization change because we do not currently suspect cross-process refresh races are a root cause of the refresh errors under investigation. We can revisit this if evidence points to concurrent refresh-token redemption as a contributing factor.

@cooper-oai cooper-oai closed this May 28, 2026
cooper-oai added a commit that referenced this pull request May 28, 2026
…#23546)

## Summary

- refresh managed ChatGPT auth during auth resolution when its access
token is inside ChatGPT web's five-minute near-expiry window
- cover refresh-window decisions while preserving the existing
expired-token refresh path

## Why

Codex already resolves managed ChatGPT auth before outbound requests and
refreshes expired access tokens there. This change adjusts the existing
predicate to refresh a still-valid access token once it is within the
same five-minute refresh window used by ChatGPT web, avoiding a request
with a token about to expire.

A cross-process serialization follow-up was explored in #24663 and
closed for now; we do not currently suspect cross-process refresh races
are a root cause of the refresh errors under investigation.

External-token, API-key, and Agent Identity auth modes remain unchanged.

## Validation

- `bazel test //codex-rs/login:login-all-test`
- `just fmt` runs Rust formatting successfully, then its Python SDK Ruff
step cannot install `openai-codex-cli-bin==0.131.0a4` on this Linux
environment because no compatible wheel is published.
wallentx added a commit to wallentx/codex-termux that referenced this pull request May 29, 2026
#176)

* fix(linux-sandbox): preserve shell cleanup on interruption (#22729)

## Why
Interrupted `shell_command` calls can race with the outer tool-dispatch
cancellation path. When that happens, the runtime future may be dropped
before the spawned process gets a chance to run `SIGTERM` cleanup. For
bwrapd-backed Linux sandbox commands, that can leave synthetic
protected-path mount bookkeeping such as `.git/.codex` registrations
under `/tmp` behind after a TUI interruption.

The relevant cancellation points are the outer dispatch race in
[`core/src/tools/parallel.rs`](https://github.com/openai/codex/blob/bd184ba84703cc924921ed883f0cf17d3dba60ff/codex-rs/core/src/tools/parallel.rs#L91-L132)
and the process shutdown logic in
[`core/src/exec.rs`](https://github.com/openai/codex/blob/bd184ba84703cc924921ed883f0cf17d3dba60ff/codex-rs/core/src/exec.rs#L1367-L1393).

## What changed
- Keep `shell_command` dispatch alive long enough for the runtime to
finish cancellation cleanup instead of immediately returning the
synthetic aborted response.
- Fold shell-turn cancellation into the existing `ExecExpiration` path
in
[`core/src/tools/runtimes/shell.rs`](https://github.com/openai/codex/blob/bd184ba84703cc924921ed883f0cf17d3dba60ff/codex-rs/core/src/tools/runtimes/shell.rs#L267-L274),
so cancellation and timeout behavior stay centralized.
- On cancellation, send `SIGTERM` first, wait briefly for cleanup to
run, then hard-kill any remaining descendants in the original process
group.
- Treat `ESRCH` as an already-gone process-group cleanup case in
`codex-utils-pty`, which keeps best-effort teardown from surfacing a
stale-process race as an error.

## Verification
- `cargo test -p codex-core cancellation`
- Added regression coverage for:
  - `shell_tool_cancellation_waits_for_runtime_cleanup`
  - `process_exec_tool_call_cancellation_allows_sigterm_cleanup`

* feat(tui): add OSC 8 web links to rich content (#24472)

## Why

Wrapped URLs in rich TUI output, especially URLs rendered inside
Markdown tables, are split across terminal rows. In terminals that
support OSC 8 hyperlinks, treating each visible fragment as part of the
complete destination enables reliable open-link and copy-link actions
even after table layout wraps the URL.

This addresses the semantic-link portion of #12200 and the behavior
described in
https://github.com/openai/codex/issues/12200#issuecomment-4535452980. It
does not change ordinary drag-selection across bordered table rows.

## What Changed

- Added shared TUI OSC 8 support that validates `http://` and `https://`
destinations, sanitizes terminal payloads, and applies metadata
separately from visible line width/layout.
- Added semantic web-link annotations to assistant and proposed-plan
Markdown, including explicit web links and bare web URLs in prose and
table cells while excluding code and non-web Markdown destinations.
- Preserved complete URL targets through table wrapping, narrow pipe
fallback, streaming, transcript overlay rendering, history insertion,
and resize replay.
- Routed intentional Codex-owned links in notices,
status/setup/app-link, feedback, onboarding, MCP/plugin help, memories,
and update surfaces through the shared hyperlink handling.

## How to Test

1. Run Codex in a terminal with OSC 8 link support, such as Ghostty, and
request an assistant response containing a Markdown table whose last
column contains a long `https://` URL.
2. Make the terminal narrow enough for the URL to wrap across multiple
bordered table rows.
3. Use the terminal's open-link or copy-link action on more than one
wrapped URL fragment and confirm each fragment resolves to the complete
original URL.
4. Resize the terminal after the table is rendered and repeat the link
action to confirm the destination survives scrollback replay.
5. Open the transcript overlay while rich output is present and confirm
web links remain interactive there.
6. As a regression check, render inline/fenced code containing URL text
and a Markdown link such as
`[https://example.com](mailto:support@example.com)`; confirm these do
not acquire a web OSC 8 destination.

Targeted automated coverage exercised Markdown links and exclusions,
wrapped and pipe-fallback tables, streaming/transcript overlay
propagation, status-link truncation, and rendered word-wrapping cell
alignment. `just test -p codex-tui` was also run; it passed the
hyperlink coverage and reproduced two unrelated existing guardian
feature-flag test failures.

* feat(tui): render cramped markdown tables as key-value records [2 of 2] (#24636)

## Stack

- **Base: #24489 [1 of 2]** - render markdown tables in app style.
- **Current: #24636 [2 of 2]** - render cramped markdown tables as
key/value records.

Review this PR against `fcoury/app-style-markdown-tables`; it contains
only the fallback behavior for cramped tables.

## Why

The row-separated markdown table rendering in #24489 remains readable
while columns have usable room. Once long links or multiple prose-heavy
columns are compressed into narrow allocations, however, the grid can
turn words and paths into tall vertical strips that are difficult to
scan. In those cases the content matters more than preserving the grid
shape.

## What Changed

<table>
<tr><td>
<p align="center"><b>
Normal
</b></p>
<img width="1722" height="619" alt="CleanShot 2026-05-27 at 14 32 57"
src="https://github.com/user-attachments/assets/d04f5fbd-6064-4acd-91bd-072d19b983df"
/>
</td></tr>
<tr><td>
<p align="center"><b>
Narrow
</b></p>
<img width="863" height="1013" alt="CleanShot 2026-05-27 at 14 33 12"
src="https://github.com/user-attachments/assets/6a7d2968-0a68-48fd-ab5d-209b3dbaf03e"
/>
</td></tr>
<tr><td>
<p align="center"><b>
Very narrow
</b></p>
<img width="435" height="746" alt="CleanShot 2026-05-27 at 14 33 47"
src="https://github.com/user-attachments/assets/f6a59e30-b1d2-4063-9c05-43933abc77d6"
/>
</td></tr>
</table>

- Detect tables whose grid allocation causes systemic token
fragmentation or starves multiple prose-heavy columns.
- Render those tables as repeated key/value records instead of retaining
an unreadable grid.
- Use aligned label/value records when there is useful horizontal room,
and switch to a stacked narrow-record layout where each label is
followed by a full-width value when width is especially constrained.
- Preserve the themed label color, rich inline formatting, links, and
the existing grid presentation for tables that remain readable.
- Add snapshot coverage for path-heavy narrow tables, prose-heavy issue
tables, systemic compact fragmentation, and a control case that should
continue to render as a grid.

## How to Test

1. Start Codex from this branch and render a normal multi-column
markdown table at a comfortable terminal width. Confirm it still appears
as the styled row-separated grid from #24489.
2. Render a table containing a long linked record identifier or
file-like value, then narrow the terminal until the grid would split the
value into vertical fragments. Confirm it switches to key/value records,
with labels above values at very narrow widths.
3. Render a table with multiple prose-heavy columns, such as an issue
summary table with `Issue`, `Activity`, `Complexity`, and `Why start`.
Confirm a cramped width switches to records rather than wrapping several
columns into hard-to-read strips.
4. Render a compact table where only one value wraps mildly. Confirm it
stays in grid form rather than switching prematurely.

## Validation

- Ran `just test -p codex-tui` while developing the fallback and
reviewed/accepted the intended new markdown-render snapshots. The
command still reports two unrelated existing guardian feature-flag test
failures outside this diff.
- Ran `just fix -p codex-tui` and `just fmt` after the Rust changes were
complete.
- `just argument-comment-lint` cannot reach source linting locally
because Bazel fails while resolving LLVM sanitizer headers; touched
positional literal callsites were inspected manually and annotated where
needed.

* Allow API-key auth for remote exec-server registration (#24666)

## Overview
Allow remote `codex exec-server` registration to use existing API-key
auth while restricting where those credentials can be sent.

- Accept `CodexAuth::ApiKey` for the normal `--remote` registration
path.
- Restrict API-key remote registration to HTTPS `openai.com` and
`openai.org` hosts and subdomains, with explicit HTTP loopback support
for local development.
- Disable registry registration redirects so credentials cannot be
forwarded to an unvalidated destination.
- Retain `--use-agent-identity-auth` as the explicit Agent Identity
path.
- Document remote registration using `CODEX_API_KEY`.

## Big picture
Callers can now provide an API key directly to `exec-server`
registration without first establishing ChatGPT login state:

```sh
CODEX_API_KEY="$OPENAI_API_KEY" \
codex exec-server \
  --remote "https://<host>.openai.org/api" \
  --environment-id "$ENVIRONMENT_ID"
```

## Validation
- `cargo fmt --all` (`just fmt` is not installed on this host)
- `cargo test -p codex-cli -p codex-exec-server`

* Update rmcp to 1.7.0 (#24763)

WIll make it easier to uprev when the new draft spec is supported.

Also updates reqwest where needed for compatibility but doesn't update
it everywhere since this is already a large diff.

The new version of rmcp handles certain kinds of authentication failures
differently, this patch includes support for identifying the failing scope
in a WWW-Authenticate header.

* [codex] Fix hyperlink-aware key-value table rendering (#24825)

## Why

The key/value markdown table renderer added in #24636 still operates on
`Line` values, while table cells and rendered table output now carry
`HyperlinkLine`. That mismatch breaks `codex-tui` compilation on `main`
and would risk losing semantic web-link annotations if corrected by
flattening the values.

## What changed

- Make key/value record rendering wrap and emit `HyperlinkLine` values
consistently with the existing grid renderer.
- Remap wrapped hyperlink ranges and shift them when value content is
prefixed by record-mode indentation or labels.
- Add focused coverage verifying key/value fallback output preserves
web-link destinations.

## Verification

- `just test -p codex-tui -E
'test(key_value_table_keeps_web_annotations) |
test(/table_renders_(key_value_records_when_compact_fragmentation_is_systemic_snapshot|stacked_key_value_records_when_path_column_becomes_too_narrow_snapshot|records_when_multiple_prose_columns_are_starved_snapshot)/)'`

* [codex] Rename Python SDK AppServerConfig to CodexConfig (#24800)

## Why

`AppServerConfig` is exported as part of the ergonomic Python SDK
surface and passed to `Codex(...)` and `AsyncCodex(...)`. That name
exposes the underlying app-server transport at the same layer where
users are configuring the Codex client. `CodexConfig` makes the common
callsite read naturally and names the object it configures.

## What changed

- Renamed the public configuration dataclass from `AppServerConfig` to
`CodexConfig`.
- Updated `Codex`, `AsyncCodex`, and the transport clients to accept
`CodexConfig`.
- Updated binary-resolution messages, package exports, docs, examples,
and related coverage to use the new public name.

## API impact

```python
from openai_codex import Codex, CodexConfig

with Codex(config=CodexConfig(codex_bin="/path/to/codex")) as codex:
    ...
```

Callers should now import and construct `CodexConfig`; `AppServerConfig`
is no longer part of the Python SDK surface.

## Validation

- `uv run --frozen --extra dev ruff check src/openai_codex scripts
examples tests`
- Tests are deferred to online CI for this PR.

* [codex] Remove redundant SQLite dynamic tool storage (#24819)

## Why

Dynamic tools are defined at thread start and already stored in rollout
`SessionMeta`, which restores resumed and forked sessions. Persisting
the same tools through SQLite creates a second runtime persistence path
that is unnecessary prework for the explicit namespace refactor.

## What changed

- Restore missing thread-start dynamic tools directly from rollout
history, including when SQLite is enabled.
- Remove SQLite dynamic-tool reads, writes, backfill, and thread
metadata patch plumbing.
- Add SQLite-enabled resume integration coverage that verifies a
rollout-defined dynamic tool is still sent after resume.

## Compatibility

The existing `thread_dynamic_tools` table is intentionally not dropped
even though it's now unused. Older Codex binaries are allowed to open
databases migrated by newer binaries and still reference this table;
dropping it would break that mixed-version path. See
[here](https://github.com/openai/codex/blob/main/codex-rs/state/src/migrations.rs#L10-L11).

## Verification

- `just test -p codex-state -p codex-rollout -p codex-thread-store`
- `just test -p codex-core --test all
resume_restores_dynamic_tools_from_rollout_with_sqlite_enabled`

* [codex] Add independent beta release for the Python SDK (#24828)

## Why

`openai-codex` needs a beta release lifecycle without requiring beta
releases of its pinned runtime package. Previously, SDK staging rewrote
its runtime dependency to the SDK version, which made an SDK-only beta
impossible.

## What changed

- Set the initial SDK beta version to `0.1.0b1` and pin it to published
stable `openai-codex-cli-bin==0.132.0`.
- Decoupled SDK release staging from runtime versioning so it preserves
the reviewed exact runtime pin.
- Added a `python-v*` tag workflow that builds and publishes only
`openai-codex` through PyPI trusted publishing.
- Removed the Beta classifier from runtime package metadata for future
runtime publications.
- Regenerated protocol-derived SDK models from the selected stable
runtime package.

`0.132.0` is the newest stable runtime admitted by the checked-in
dependency date fence and retains the Linux wheel family currently used
by SDK CI.

## Release setup

Before pushing `python-v0.1.0b1`, configure PyPI trusted publishing for
the `openai-codex` project with workflow `python-sdk-release.yml`,
environment `pypi`, and job `publish-python-sdk`.

## Validation

- `uv run --frozen --extra dev ruff check src/openai_codex scripts
examples tests`
- Parsed `.github/workflows/python-sdk-release.yml` with PyYAML.
- Built staged release artifacts locally:
`openai_codex-0.1.0b1-py3-none-any.whl` and
`openai_codex-0.1.0b1.tar.gz`.
- Verified wheel metadata pins `openai-codex-cli-bin==0.132.0`.
- Tests are deferred to online CI for this PR.

* [codex] Prepare Python SDK beta documentation and package metadata (#24836)

## Why

The initial public `openai-codex` beta should read and install like a
normal published Python package before a release tag is created. This
follows merged PR #24828, which establishes the independent SDK beta
release plumbing and exact runtime dependency.

## What changed

- Rewrote `sdk/python/README.md` as a compact PyPI-facing beta package
page: published installation, one quickstart, short login examples,
built-in help, and links to deeper guides.
- Updated the getting-started guide, API reference, FAQ, and examples
index to present the published beta consistently without repeating
onboarding in the package landing page or reference page.
- Made `pip install openai-codex` the primary install path while beta
releases are the only published SDK releases, with `--pre` documented
for opting into prereleases after a stable release exists.
- Added curated `help()` / `pydoc` docstrings across the public API and
generated public convenience methods through
`scripts/update_sdk_artifacts.py`.
- Declared the repository `Apache-2.0` license expression and
Documentation URL in package metadata, without introducing a duplicated
SDK-local license file.
- Kept the source distribution focused on installable package material
(`src/openai_codex`, `README.md`, and `pyproject.toml`); the repository
docs and runnable examples remain linked from the PyPI README.
- Built release artifacts in an Alpine container on the Ubuntu runner,
matching Python SDK CI and allowing type generation to install the
published `musllinux` runtime wheel.
- Added `twine check --strict` to the release workflow so malformed PyPI
metadata or rendered README content fails before publishing.
- Added focused SDK assertions for beta metadata, the exact runtime pin,
source distribution contents, and the built-in Python documentation
surface.

## Validation

- Ran `uv run --frozen --extra dev ruff check
scripts/update_sdk_artifacts.py src/openai_codex
tests/test_public_api_signatures.py
tests/test_artifact_workflow_and_binaries.py` before the final
README-only reductions and review-fix follow-ups.
- Built `openai_codex-0.1.0b1-py3-none-any.whl` and
`openai_codex-0.1.0b1.tar.gz` before the final README-only reductions
and review-fix follow-ups.
- Ran `python -m twine check --strict` on both built artifacts before
the final README-only reductions and review-fix follow-ups.
- Verified artifact metadata reports `Apache-2.0` without a duplicated
SDK-local license file.
- Verified `inspect.getdoc(...)` resolves documentation for the package,
`Codex`, `CodexConfig`, and key generated thread methods.
- Rebased the documentation/readiness change onto merged PR #24828
without changing the intended SDK or workflow file contents.
- Final verification is delegated to online CI for this PR.

* Treat refresh_token_reused 400s as relogin-required (#24830)

## Summary
- classify known refresh-token terminal failures from `/oauth/token` as
permanent even when the backend returns `400`
- preserve the existing relogin-required message for
`refresh_token_reused` instead of retrying and collapsing into a generic
cloud requirements error
- add regression coverage for `400 refresh_token_reused`

## Testing
- `just fmt`
- `cargo test -p codex-login`

* [codex] Simplify Python SDK install guidance (#24866)

## Summary
- Remove the exact-version install snippet from the PyPI-facing Python
SDK README.
- Remove the release-selection explanation so the install section
presents the standard `pip install openai-codex` path directly.

## Validation
- Not run locally; relying on online CI for this documentation-only
change.

* [codex] Remove Python SDK language classifiers (#24868)

## Summary
- Remove the Python language classifiers from the Python SDK package
metadata.
- Keep `requires-python = ">=3.10"` as the package's interpreter
compatibility constraint.
- Avoid presenting a curated version-support list in PyPI metadata.

## Validation
- Not run locally; relying on online CI for this metadata-only change.

## Release
- Land this change before publishing the next Python SDK beta.

* [codex] Remove Python SDK beta warning note (#24870)

## Summary
- Remove the beta warning callout from the PyPI-facing Python SDK
README.
- Keep the existing Beta title and install/usage guidance unchanged.

## Validation
- Not run locally; relying on online CI for this documentation-only
change.

## Release
- Land this change before publishing the next Python SDK beta.

* [codex] Stage Python SDK beta versions from release tags (#24872)

## Summary
- Treat `sdk/python` as a development template with source version
`0.0.0-dev`, matching the existing Python runtime packaging pattern.
- Have `python-v*` tags supply the published SDK beta version through
the existing `stage-sdk --sdk-version` path.
- Remove the workflow check requiring a source version bump for each
beta release and remove its now-unused host Python setup step.
- Keep the reviewed runtime dependency pin at
`openai-codex-cli-bin==0.132.0`.
- Remove beta-number-specific documentation so it does not need editing
for each publish.

## Why
The package staging script already writes the release version into the
artifact. Requiring the checked-in SDK template version to match every
tag adds release-only source churn without changing the package users
receive.

## Validation
- Not run locally; relying on online CI for this workflow and metadata
change.

## Release
After this PR lands, publish the next beta by pushing tag
`python-v0.1.0b2` from merged `main`.

* Move memories root setup out of core config (#24758)

## Why

Config loading should not create or write-authorize the memories root
just because memory support exists. Memory startup is the code path that
actually materializes that tree.

## What

- Stop creating the memories root during Config load and remove it from
legacy workspace-write projections.
- Grant the memories root read access only when the memories feature and
use_memories are enabled.
- Create the memories root inside memories startup before seeding
extension instructions.
- Update config and startup tests around the ownership boundary.

## Tests

- just fmt
- just fix -p codex-core
- just fix -p codex-memories-write
- just test -p codex-core
memory_tool_makes_memories_root_readable_without_creating_or_widening_writes
workspace_write_includes_configured_writable_root_once_without_memories_root
permission_profile_override_keeps_memories_root_out_of_legacy_projection
permissions_profiles_allow_direct_write_roots_outside_workspace_root
default_permissions_profile_populates_runtime_sandbox_policy
- just test -p codex-memories-write memories_startup_creates_memory_root

Note: a broader just test -p codex-core run is not clean in this
sandbox; it hit missing test_stdio_server plus seatbelt, realtime, and
environment-sensitive failures. The changed config tests above pass.

* Stabilize Guardian client cache key handling (#24891)

Split from the Guardian prompt cache key change. This PR only updates
codex-rs/core/src/client.rs. Validation was not run per request; this
branch is expected to rely on the companion split PRs.

* Export Guardian prompt cache key helper (#24892)

Split from the Guardian prompt cache key change. This PR only updates
codex-rs/core/src/guardian/mod.rs. Validation was not run per request;
this branch is expected to rely on the companion split PRs.

* Add Guardian review prompt cache key (#24893)

Split from the Guardian prompt cache key change. This PR only updates
codex-rs/core/src/guardian/review_session.rs. Validation was not run per
request; this branch is expected to rely on the companion split PRs.

* Assert Guardian prompt cache key reuse (#24894)

Split from the Guardian prompt cache key change. This PR only updates
codex-rs/core/src/guardian/tests.rs. Validation was not run per request;
this branch is expected to rely on the companion split PRs.

* Thread Guardian cache key through session (#24895)

Split from the Guardian prompt cache key change. This PR only updates
codex-rs/core/src/session/session.rs. Validation was not run per
request; this branch is expected to rely on the companion split PRs.

* Use stable Guardian prompt cache keys (#24803)

## Why

Guardian review sessions are reusable across forks when their
`GuardianReviewSessionReuseKey` is unchanged, but the underlying
Responses request was still using the child thread ID as
`prompt_cache_key`. That meant forked Guardian reviews that should share
cache context produced different cache keys, reducing prompt cache reuse
and weakening the reuse invariant.

## What Changed

- Adds a `ModelClient` prompt cache key override and uses it for
`ResponsesApiRequest.prompt_cache_key`.
- Computes Guardian review cache keys as
`guardian:<sha1(parent_thread_id:reuse_key)>`, scoped to the parent
thread plus the reuse-sensitive Guardian config.
- Wires session construction to apply that override only for Guardian
sub-agent sessions.

## Testing

- Added coverage that Guardian cache keys are stable for the same
parent/reuse key, change when either the parent thread or reuse key
changes, fit within the Responses API length limit, and are absent for
non-Guardian sessions.
- Extended the parallel review test to assert forked Guardian reviews
send the same `prompt_cache_key`.

* [codex] Fix Guardian argument comment lint (#24902)

## Summary
- Add the required `/*parent_thread_id*/` argument comment at the
Guardian review session test callsite flagged by CI.

## Validation
- `just fmt`
- Not run: clippy/tests, per request; CI will cover them.

* Fix memories namespace for Responses API tools (#24898)

## Why

Dedicated memories tools are exposed through a Responses API namespace
tool. The namespace itself has to be a valid tool identifier, so
`memories/` can fail validation before the model ever gets a chance to
call the memory tools.

## What changed

- Changed `MEMORY_TOOLS_NAMESPACE` from `memories/` to `memories`.
- Added `memory_tool_namespace_matches_responses_api_identifier` so the
namespace stays non-empty and limited to Responses-safe identifier
characters.

## Verification

- Added unit coverage for the namespace identifier shape in
`codex-rs/ext/memories/src/tests.rs`.

* Add Guardian review metrics (#24897)

## Why

Guardian reviews already emit analytics events, but we do not expose
aggregate OpenTelemetry metrics for review volume, latency, token usage,
or terminal outcomes. That makes it harder to monitor Guardian behavior
during rollouts and to compare review outcomes by source, action type,
session kind, model, and failure mode.

## What Changed

- Added Guardian review metric names for count, total duration, time to
first token, and token usage in `codex-rs/otel`.
- Added `core/src/guardian/metrics.rs` to convert
`GuardianReviewAnalyticsResult` into sanitized metric tags covering
decision, terminal status, failure reason, approval request source,
reviewed action, session kind, risk/outcome, model, reasoning effort,
and context/truncation state.
- Emitted the new metrics from `track_guardian_review` for each terminal
Guardian review result.

## Testing

- Added
`guardian_review_metrics_record_counts_durations_and_token_usage`, which
verifies the emitted count, duration, TTFT, token usage histograms, and
tag set through the in-memory metrics exporter.

* [codex-cli] Refresh near-expiry ChatGPT access tokens before requests (#23546)

## Summary

- refresh managed ChatGPT auth during auth resolution when its access
token is inside ChatGPT web's five-minute near-expiry window
- cover refresh-window decisions while preserving the existing
expired-token refresh path

## Why

Codex already resolves managed ChatGPT auth before outbound requests and
refreshes expired access tokens there. This change adjusts the existing
predicate to refresh a still-valid access token once it is within the
same five-minute refresh window used by ChatGPT web, avoiding a request
with a token about to expire.

A cross-process serialization follow-up was explored in #24663 and
closed for now; we do not currently suspect cross-process refresh races
are a root cause of the refresh errors under investigation.

External-token, API-key, and Agent Identity auth modes remain unchanged.

## Validation

- `bazel test //codex-rs/login:login-all-test`
- `just fmt` runs Rust formatting successfully, then its Python SDK Ruff
step cannot install `openai-codex-cli-bin==0.131.0a4` on this Linux
environment because no compatible wheel is published.

* Add thread start contributor facts (#24915)

Summary: add session source and persistent-state availability to
ThreadStartInput; populate them from session init; update existing goal
test harness constructors. Tests: just fmt; git diff --check. No full
tests or clippy run per request.

* Add turn error lifecycle contributor (#24916)

Summary
- Add TurnErrorInput and TurnLifecycleContributor::on_turn_error to the
extension API.
- Emit the turn-error lifecycle from core turn error paths, including
usage limit failures.
- Add direct lifecycle coverage for the emitted error facts and stores.

Tests
- just fmt
- git diff --check
- Not run: full tests or clippy (per instructions)

* [codex] Store pending response items directly (#24865)

* [codex] Update OpenAI Docs skill (#24914)

## Summary
- update the bundled `openai-docs` system skill to match the latest
`openai-docs-plus` content from `skills-internal`
- add the cached Codex manual fetch helper and expand the skill routing
for Codex self-knowledge
- keep the stable local skill identity and labels as `openai-docs`

## Why
The built-in OpenAI Docs skill needed to reflect the current upstream
guidance from `skills-internal` while preserving the local system-skill
name used by Codex.

## Impact
Codex now ships the newer OpenAI Docs skill behavior for Codex
self-knowledge and manual-first documentation lookups.

## Validation
- `just test -p codex-skills`
- exact directory diff against transformed `skills-internal`
`origin/main` was clean

* Add app-server startup benchmark crate (#24651)

## Summary
- Add a new `app-server-start-bench` crate to measure app-server startup
performance
- Wire the benchmark into the workspace and Bazel build so it can be run
consistently
- Update lockfiles and repo automation to account for the new package

* Gate goal tools by thread eligibility (#24925)

## Why

Goal tools create and update goal state for a persistent thread. The
extension was only checking whether goals were enabled before
advertising those tools, which meant they could be surfaced in contexts
that should not receive thread goal controls: ephemeral threads without
persistent thread state and review subagents.

Those sessions can still run the goal extension lifecycle, but the
thread tools should only be visible when the current thread can safely
use them.

## What changed

- Adds a `GoalRuntimeConfig` that separates goal enablement from whether
goal tools are available for the current thread.
- Computes tool eligibility on thread start from
`persistent_thread_state_available` and `SessionSource`, hiding tools
for review subagents.
- Uses `GoalRuntimeHandle::tools_visible()` when contributing thread
tools so enabled runtime state does not automatically imply tool
exposure.
- Adds backend coverage for hiding goal tools on ephemeral threads and
review subagents.

## Testing

- Added `goal_tools_hidden_for_ephemeral_threads`.
- Added `goal_tools_hidden_for_review_subagents`.

* Remove libubsan CI workaround (#24782)

It seems that this was added to allow rustc to load proc macros that had
been compiled with UBSan enabled, which zig does for debug and
`ReleaseSafe` builds. When zig drives the link of the final binary it
knows to include the ubsan runtime, but our zig-built artifacts are
being linked into a binary whose linking rustc drives. This removes the
libubsan workaround we have and replaces it with
`-fno-sanitize=undefined` passed to zig.

The new argument is passed at the end of zig's args so should take
precedence over any earlier arguments from the script's caller.

* extension-api: add TurnItemEmitter to tool calls (#24813)

## Why
Extension-contributed tools need to emit visible turn items through
Codex's normal event and persistence pipeline.

## What
- Add `TurnItemEmitter` to extension `ToolCall`s and route the core
implementation through `Session::emit_turn_item_*`.
- Hold weak session and turn references so retained tool calls cannot
keep host state alive.
- Provide a no-op emitter for extension test callers.

## Test Plan
- `just test -p codex-core -E
'test(passes_turn_fields_and_scoped_turn_item_emitter_to_extension_call)'`

---------

Co-authored-by: jif-oai <jif@openai.com>

* feat(app-server): include turns page on thread resume (#23534)

## Summary

The client currently calls `thread/resume` to establish live updates and
immediately follows it with `thread/turns/list` to hydrate recent turns.
This lets `thread/resume` return that page directly, eliminating a round
trip and the ordering/deduplication gap between the two calls.

Experimental clients opt in with `initialTurnsPage: { limit,
sortDirection, itemsView }`. The response returns `initialTurnsPage` as
a `TurnsPage`, including cursors for paging further back in history.
Keeping the controls in a nested opt-in object provides the useful
`thread/turns/list` knobs without spreading page-specific parameters
across `thread/resume`.

## Verification

- `just fmt`
- `just write-app-server-schema --experimental`
- `just write-app-server-schema`
- `cargo test -p codex-app-server-protocol`
- `cargo test -p codex-app-server
thread_resume_initial_turns_page_matches_requested_turns_list_page
--tests`
- `cargo test -p codex-app-server
thread_resume_rejoins_running_thread_even_with_override_mismatch
--tests`
- `just fix -p codex-app-server-protocol -p codex-app-server`

* Expose MCP server info as part of server status (#24698)

# Summary

Expose MCP server info via App Server (when available) so apps can
render a richer MCP experience

* Reap stale multi-agent slots (#24903)

## Summary

- Let `close_agent` clean up an agent that is still registered in
`AgentRegistry` even when its underlying thread is already missing.
- Preserve the explicit-close boundary: for known stale thread-spawn
agents, mark the persisted spawn edge `Closed`, then treat
`ThreadNotFound` / `InternalAgentDied` as a successful close so the
registry slot can be released.
- Add a regression for MultiAgentV2 task-name targets where
`close_agent("worker")` succeeds after the worker thread has already
disappeared.

## Motivation

A worker can disappear from `ThreadManager` while its metadata still
exists in the root `AgentRegistry`. Before this change, the close tool
failed while trying to subscribe to the missing thread status, so it
never reached the cleanup path that releases the registered agent slot.
With `agents.max_threads = 1`, an explicit close of that stale task-name
agent could fail and leave the session unable to spawn a replacement.

## Scope

This PR intentionally does not add automatic stale-agent reaping to
`spawn_agent`, `resume_agent`, or `list_agents`. A thread being missing
from `ThreadManager` is not the same as an explicit close: persisted
open spawn edges are still the durable source of truth for resume and
task-name ownership until `close_agent` is called.

## Validation

- `just test -p codex-core -E
'test(multi_agent_v2_close_agent_reaps_stale_task_name_target) |
test(resume_agent_from_rollout_reopens_open_descendants_after_manager_shutdown)'`
- `just fix -p codex-core`

* Fix extension turn item emitter test event ordering (#24936)

## Why

PR #24813 added extension `TurnItemEmitter` coverage and introduced a
test that records a conversation history item before asserting
extension-emitted turn item events.

`record_conversation_items()` also emits a `RawResponseItem` event to
observers. The test was reading from the same event receiver and
expected the next event to be `ItemStarted`, so the test failed reliably
once the setup history item was present.

## What Changed

Update
`passes_turn_fields_and_scoped_turn_item_emitter_to_extension_call` to
consume and assert the expected setup `RawResponseItem` before checking
the extension `ItemStarted`, `WebSearchBegin`, `ItemCompleted`, and
`WebSearchEnd` events.

This is test-only and does not change extension runtime behavior.

## Verification

- `cargo nextest run --no-fail-fast -p codex-core
tools::handlers::extension_tools::tests::passes_turn_fields_and_scoped_turn_item_emitter_to_extension_call`

* [codex] Support ui visibility meta for tools (#24700)

## Summary

Adds support for the same ui.visibility metadata as resources

[spec](https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/draft/apps.mdx#resource-discovery)

* chore: add GPT-5.5 to the Amazon Bedrock catalog (#24701)

## Summary

Amazon Bedrock should expose GPT-5.5 alongside GPT-5.4, and the Bedrock
GPT entries should stay aligned with the canonical bundled OpenAI model
metadata instead of carrying a separate hand-written copy that can drift
over time. This change will be merged when the model is online.

This change:

- Adds the Bedrock Mantle model id for `openai.gpt-5.5`.
- Builds the Bedrock GPT-5.5 and GPT-5.4 catalog entries from the
bundled OpenAI model catalog, then overrides the Bedrock-facing slug,
explicit priority, and Bedrock-specific context windows.
- Hardcodes both `context_window` and `max_context_window` to `272000`
for Bedrock GPT-5.5 and GPT-5.4.
- Keeps `openai.gpt-5.5` as the default Bedrock model ahead of
`openai.gpt-5.4` and the Bedrock OSS models.

* TUI: Unified mentions tweaks + polish mentions rendering (#23363)

This change keeps unified @mentions behind the mentions_v2 gate, moves
the flag to under-development, and polishes mention rendering/history
behavior.

It also adds a few small improvements to the mentions feature around
mention rendering and history round-tripping for plugin/tool mentions in
message edit scenarios. Plugin selections now insert `@` mentions with
better casing, and saved history preserves the visible sigil so recalled
messages look the same as what the user typed.

- Preserves `@` sigils when encoding/decoding mention history for
tool/plugin paths.
- Improves plugin mention insertion so display names/casing are
reflected more cleanly in the composer.
- Update composer to render user-entered plugin mentions in the same
color as the mentions menu. ALso applies to recalled/edited messages.
- Left/right arrows no longer switch unified-mention search modes after
an @mention has already been accepted (Ex: arrowing left through a
composed message that contains @mentions).
- Keeps bound mentions stable around punctuation, so accepted `@`
mentions do not reopen the popup and punctuated `$` mentions still
persist to cross-session history.

**Steps to test**
- Ensure mentions_v2 is enabled through configuration or `--enable
mentions_v2`
- Type `@` in the TUI composer and verify filesystem/plugin/skill
results are displayed in the unified mentions menu.
- Select a plugin mention from the `@` popup and confirm the inserted
text is an `@...` mention with casing, then recall/edit the message and
confirm it still renders as `@...`.
- Mention a skill and verify that skills still insert as `$skill`
mentions rather than `@` mentions.
- Verify punctuated mentions such as `@plugin.` and `($skill)` keep
their bound mention behavior across editing and history recall.

* Revert "Add app-server startup benchmark crate" (#24937)

Reverts openai/codex#24651, broke musl job
https://github.com/openai/codex/actions/runs/26585495205/job/78330166927

* Wire task completion into thread-idle lifecycle (#24928)

## Why

#24744 introduced the thread idle lifecycle hook so idle continuation
can be owned by lifecycle contributors instead of hard-coded goal
runtime plumbing. Task completion still called
`goal_runtime_apply(GoalRuntimeEvent::MaybeContinueIfIdle)` directly, so
the post-turn idle transition remained goal-specific and did not notify
generic thread lifecycle contributors.

## What Changed

- Add `Session::emit_thread_idle_lifecycle_if_idle()` to gate idle
emission on both no active turn and no queued trigger-turn mailbox work.
- Call that helper when a task clears the active turn, replacing the
direct `GoalRuntimeEvent::MaybeContinueIfIdle` path.
- Cover the behavior with `codex-core` session tests for emitting after
task completion and suppressing idle emission while trigger-turn mailbox
work is pending.

## Verification

- New tests in `core/src/session/tests.rs` exercise the idle lifecycle
emission and trigger-turn mailbox guard.

* Add feature-gated standalone image generation extension (#24723)

## Why

Add a standalone image generation path that can be exercised
independently of hosted Responses image generation, while retaining the
hosted tool as fallback unless the extension is actually available to
the model.

## What changed

- Added the `codex-image-generation-extension` crate with standalone
generate/edit execution, prior-image selection for edits, model-visible
image output, and local generated-image persistence.
- Installed the extension in app-server behind the disabled-by-default
`imagegenext` feature and backend eligibility checks.
- Updated core tool planning so eligible `image_gen.imagegen` exposure
replaces hosted `image_generation`, while unavailable configurations
retain hosted fallback.
- Added coverage for extension behavior, edit history reuse, feature
gating, auth eligibility, and hosted-tool replacement.
- The extension is installed through app-server only in this PR; other
execution paths retain hosted image generation because hosted
replacement occurs only when the standalone executor is actually
registered and model-visible.
- The initial extension contract intentionally fixes the image model to
`gpt-image-2` and uses automatic image parameters.
- Native generated-image history/card parity and rollout persistence
cleanup are intentionally deferred follow-up work.

## Validation

- `just test -p codex-image-generation-extension`
- `just test -p codex-features`
- `just test -p codex-core
hosted_tools_follow_provider_auth_model_and_config_gates`
- `just test -p codex-app-server`
- `just fix -p codex-image-generation-extension -p codex-features -p
codex-core -p codex-app-server`
- `just fmt`
- `just bazel-lock-update`
- `just bazel-lock-check`

---------

Co-authored-by: jif-oai <jif@openai.com>

* Move Bazel Windows jobs onto codex-runners (#24952)

The codex-windows runner group should be much faster than the default
GHA runners. Since bazel jobs on windows are frequently the long pole
for PRs checks, this will hopefully get people landing a bit faster.

* Add `codex app-server --stdio` alias (#24940)

## Summary
- Add `--stdio` as a direct alias for `codex app-server --listen
stdio://`.
- Keep `--stdio` and `--listen` mutually exclusive.
- Update the app-server README to document both forms.

* fix(tui): prevent repository-configured code execution in /diff (#24954)

## Why

`/diff` is intended to display working-tree changes, but its Git
invocations honored repository-selected executable helpers. A repository
could configure diff/text conversion helpers, clean/process filters,
`core.fsmonitor`, or `post-index-change` hooks that execute when a user
runs `/diff`.

Fixes
[PSEC-4395](https://linear.app/openai/issue/PSEC-4395/codex-cli-diff-executes-repository-selected-diff-helpers).

## What Changed

- Pass `--no-textconv` and `--no-ext-diff` for tracked and untracked
diff generation.
- Discover configured `filter.<driver>.clean` and `.process` entries,
then neutralize the selected drivers through structured
`GIT_CONFIG_KEY_*` / `GIT_CONFIG_VALUE_*` overrides, including driver
names containing `=`.
- Run all `/diff` Git probes with `core.fsmonitor=false` and a null
`core.hooksPath`.
- Use short submodule reporting while ignoring dirty submodule
worktrees, since inspecting a checked-out submodule for dirtiness can
execute filters from that child repository. This intentionally omits
dirty-only submodule markers in order to preserve the non-executing
security boundary.
- Add real-Git marker tests covering filters, fsmonitor, hooks, and
configured helpers inside checked-out submodules.

## How to Test

1. In a repository with ordinary tracked and untracked edits, run
`/diff`.
2. Confirm the normal working-tree diff is shown for top-level files.
3. Run the targeted tests below; they configure executable marker
helpers for repository filters, fsmonitor, hooks, and a checked-out
submodule, then verify `/diff` does not invoke them.
4. Confirm a dirty-only submodule does not cause Codex to enter the
submodule and execute its configured helper.

Targeted tests:
- `just test -p codex-tui get_git_diff_`

Validation note: `just test -p codex-tui` runs the new coverage, but
this worktree currently also has two unrelated failing guardian tests:
`app::tests::update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default`
and
`app::tests::update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history`.

* [codex] Handle PowerShell UTF-8 setup failures (#24949)

Fixes #12496.

## Why

Windows sandboxed PowerShell commands can run under
`ConstrainedLanguage` on some machines, especially enterprise-managed
Windows environments. In that mode, our PowerShell command prelude could
fail before every command because it directly assigned
`[Console]::OutputEncoding` to UTF-8. The actual user command still ran,
but Codex surfaced noisy `Cannot set property. Property setting is
supported only on core types in this language mode.` output for every
shell call.

## What Changed

- Makes the PowerShell UTF-8 output encoding prelude best-effort by
wrapping the assignment in `try { ... } catch {}`.
- Keeps the existing UTF-8 behavior when PowerShell allows the
assignment.
- Adds focused tests for adding the prelude and avoiding duplicate
prelude insertion.

## Validation

- `cargo fmt -p codex-shell-command`
- `cargo check -p codex-shell-command`
- `git diff --check`
- Verified a local `ConstrainedLanguage` PowerShell probe prints only
the command output with no property-setting error.
- Verified `codex exec` from a temporary `chcp 437` context reports
`utf-8` / `65001` and preserves non-ASCII output (`café`, `漢字`).

* [codex] Remove Bedrock OSS models from catalog (#24960)

Remove the GPT OSS 120B and 20B entries from the Amazon Bedrock static
model catalog, as they are no longer supported.

* runtime: prepend zsh fork bin dir to PATH (#23768)

## Why

#23756 makes packaged Codex builds include and default to the bundled
zsh fork. The important reason to put that fork's directory at the front
of `PATH` is to keep executable-level escalation working after a command
leaves the original shell and later re-enters zsh through `env`.

The expected chain is:

1. The zsh fork runs the top-level shell command.
2. That command launches another program, such as `python3`, while
inheriting the `EXEC_WRAPPER` environment and the escalation socket fd.
3. That program spawns a shell script whose shebang is `#!/usr/bin/env
zsh` rather than `#!/bin/zsh`, and it does not close the escalation fd.
4. `/usr/bin/env` resolves `zsh` through `PATH`, so it must find the
packaged zsh fork before the system zsh.
5. Commands inside that nested script are intercepted by the zsh fork
and can still request escalation from Codex.

If `PATH` resolves `zsh` to the system shell instead, the nested script
loses zsh-fork exec interception. Commands that should request
escalation can then run only in the original sandbox, or fail there,
without Codex ever receiving the approval request.

Shell snapshots make this slightly more subtle: a snapshot can restore
an older `PATH` after the child shell starts. This PR treats the zsh
fork `PATH` prepend as an explicit environment override so snapshot
wrapping preserves it.

## What Changed

- Added shared zsh-fork runtime helpers that prepend the configured zsh
executable parent directory to `PATH` without duplicate entries.
- Applied the zsh fork `PATH` prepend to both zsh-fork `shell_command`
launches and unified-exec zsh-fork launches before sandbox command
construction.
- Kept the shell-command zsh-fork backend API narrow: it derives the
configured zsh path from session services and rebuilds its sandbox
environment from `req.env`, rather than accepting a second, competing
environment map or a separately threaded bin dir.
- Kept Unix-only zsh-fork `PATH` mutation out of Windows clippy-visible
mutability.
- Added coverage for duplicate `PATH` entries, for preserving the zsh
fork prepend through shell snapshot wrapping, and for the nested
`python3` -> `#!/usr/bin/env zsh` escalation flow.

## Testing

- `just fmt`
- `just fix -p codex-core`

I left final test validation to CI after the latest review-comment
cleanup. Before that cleanup, `just test -p codex-core zsh_fork` passed
locally for the zsh-fork-focused tests.

* Release 0.136.0-alpha.1

* Seed Termux release automation

* Termux rust-v0.136.0-alpha.1 (#175)

* Release 0.132.0-alpha.1

* ## New Features
- The Python SDK now supports first-class authentication, including API key login, ChatGPT browser and device-code flows, account inspection, and logout APIs. (#23093)
- Python turn APIs are easier to use for text-only workflows: you can pass a plain string as input, and handle-based runs now return a richer `TurnResult` with collected items, timing, and usage data. (#23151, #23162)
- `codex exec resume` now accepts `--output-schema`, so resumed automations can keep session context while still enforcing structured JSON output. (#23123)
- TUI startup is faster because terminal capability probes are now batched instead of waiting on several serial checks before the first interactive frame. (#23175)
- Remote executor registration can now use standard Codex auth instead of a separate registry credential flow. (#22769)
- App-server turns can preserve requested image fidelity, including original-resolution local images, across user inputs and image-producing tools. (#20693)

## Bug Fixes
- Goal continuations now stop when they hit usage limits or a repeated blocker instead of looping and burning more tokens, and completion responses phrase usage more naturally. (#23094, #22907)
- The session picker is easier to trust: renamed threads now show `name (thread-id)` in resume hints, and pasted text works in the picker search box. (#23234, #23338)
- Multi-session TUI flows are more reliable: in-progress MCP calls stay marked as active during replay, and elicitation replies are sent back to the thread that requested them. (#23236, #23241)
- Remote sessions now keep websocket connections alive and show repo-relative diff paths again instead of `/tmp/...`-prefixed paths. (#23226, #23261)
- Windows installs are more robust: `codex doctor` now detects npm-managed installs correctly, and MSVC release binaries no longer depend on separately installed VC++ runtime DLLs. (#22967, #22905)
- TUI polish fixes include immediate shutdown feedback on exit, hiding the ChatGPT usage link for non-OpenAI providers, and keeping a cleared Fast tier from reappearing after side-thread resume. (#23323, #23127, #23121)

## Documentation
- The Python SDK docs, FAQ, and examples were refreshed around the new auth flow and turn APIs, with clearer setup guidance and simpler text-only examples. (#22941, #23093, #23151, #23162)

## Chores
- Memory summaries are now versioned and rebuilt when the stored format is stale, which should keep long-lived memory context leaner and more predictable. (#23148)

## Changelog

Full Changelog: https://github.com/openai/codex/compare/rust-v0.131.0...rust-v0.132.0

- #20693 Preserve image detail in app-server inputs @fjord-oai
- #22891 tui: pass active permission profiles through app commands @bolinfest
- #22924 app-server-protocol: remove PermissionProfile from API @bolinfest
- #22941 [codex] Refine Python SDK user-facing docs @aibrahim-oai
- #22967 Fix Windows doctor npm root probe @etraut-openai
- #22920 core: set permission profiles from snapshots @bolinfest
- #22939 [codex] Split Python SDK helper logic @aibrahim-oai
- #22907 Improve goal completion usage reporting @etraut-openai
- #23030 test: construct permission profiles directly @bolinfest
- #22769 exec-server: support auth-backed remote executor registration @miz-openai
- #22946 [codex] preserve MCP result meta in McpToolCallItemResult @miaolin-oai
- #23069 multiagent: trim model-visible description, cap to 5 models @sayan-oai
- #22913 [1 of 4] tui: route primary settings writes through app server @etraut-openai
- #23093 sdk/python: add first-class login support @aibrahim-oai
- #23151 [codex] Return TurnResult from Python turn handles @aibrahim-oai
- #23147 Make multi-agent v2 tool namespace configurable @jif-oai
- #23036 test: reduce core sandbox policy test setup @bolinfest
- #23162 [codex] Accept string input for Python turns @aibrahim-oai
- #23226 Add exec-server websocket keepalive @starr-openai
- #23148 Densify and version memory summaries @jif-oai
- #22448 [codex] Add installed-plugin mention API @xli-oai
- #23288 chore: goal ext skeleton @jif-oai
- #23291 Make extension lifecycle hooks async @jif-oai
- #23293 feat: add extension event sink capability @jif-oai
- #23295 chore: isolate thread goal storage behind GoalStore @jif-oai
- #23301 chore: goal resumed metrics @jif-oai
- #23305 chore: make token usage async @jif-oai
- #23306 Emit goal update events from goal extension tools @jif-oai
- #23121 tui: keep cleared Fast tier from reappearing after side-thread resume @etraut-openai
- #23123 Support --output-schema for exec resume @etraut-openai
- #23128 Fix TUI stream cleanup after turn errors @etraut-openai
- #23127 Hide ChatGPT usage link for non-OpenAI status @etraut-openai
- #23175 [1 of 2] Optimize TUI startup terminal probes @etraut-openai
- #22706 [codex] Remove legacy shell output formatting paths @pakrym-oai
- #23332 nit: read prompt @jif-oai
- #22905 windows: link MSVC release binaries with static CRT @iceweasel-oai
- #23323 fix(tui): show shutdown feedback on exit @fcoury-oai
- #23261 Fix remote turn diff display roots @starr-openai
- #22569 Simplify legacy Windows sandbox ACL persistence @iceweasel-oai
- #23273 Upload rust full CI JUnit reports @starr-openai
- #22893 fix: harden plugin creator sharing validation @efrazer-oai
- #23094 goal: pause continuation loops on usage limits and blockers @etraut-openai
- #23234 Clarify resume hints for renamed threads @etraut-openai
- #23241 TUI: route elicitation responses to request thread @etraut-openai
- #23236 TUI: replay in-progress MCP calls as started @etraut-openai
- #23088 goals: keep pause transitions explicit @etraut-openai
- #23338 feat(tui): handle paste in session picker @fcoury-oai
- #23335 feat(app-server): add optional thread_id to experimentalFeature/list @owenlin0

* Apply Termux compatibility patch

* Disable realtime audio on Android builds

(cherry picked from commit 337303c72c5c624386937c5f2aa9dc3a8dcfa2b4)

* Update Termux v8 dependency

* Release 0.133.0-alpha.1

* Seed Termux release automation

* Prepare Termux rust-v0.132.0

* Seed Termux release automation

* Prepare Termux rust-v0.133.0-alpha.1

* Release 0.133.0-alpha.3

* Seed Termux release automation

* Prepare Termux rust-v0.133.0-alpha.3

* ## New Features
- Goals are now enabled by default, backed by dedicated storage, and track progress across active turns. (#23300, #23685, #23696, #23732)
- `codex remote-control` now runs like a foreground command, waits for readiness, reports machine status, and keeps explicit daemon-style `start`/`stop` commands. (#22878)
- Permission profiles gained list APIs, inheritance, managed `requirements.toml` support, runtime refresh behavior, and stronger Windows sandbox integration. (#22928, #23412, #22270, #23433, #22931, #23715)
- Plugin discovery is easier to inspect, with marketplace-aware list output, installed versions, visible marketplace roots, and remote collection support. (#23372, #23584, #23727, #23730)
- Extensions can observe more lifecycle events, including subagent start/stop, tool execution, turn metadata, and async approval/turn processing. (#22782, #22873, #23309, #23688, #23690, #23692)

## Bug Fixes
- Fixed TUI startup choosing the wrong working directory when reusing a local app-server socket. (#23538)
- Fixed plan-mode free-form answers so modified Enter keys, like Shift+Enter, no longer submit unexpectedly. (#23536)
- Removed stale background terminal poll events after a process exits. (#23231)
- Preserved raw code-mode exec output unless an explicit output token limit is requested. (#23564)
- Made AGENTS instruction loading more reliable, including local global reads and warnings for invalid UTF-8 instead of silent drops. (#23343, #23232)
- Fixed app-server startup/shutdown races, empty resume/fork paths, plugin upgrade failures, and realtime v1 websocket compatibility. (#23516, #23578, #23400, #23356, #23771)

## Documentation
- Added clearer plugin-creator guidance for updating and reinstalling local personal plugins. (#23542)
- Expanded app-server/API docs and schema coverage around managed permission profile requirements. (#23433, #23555)

## Chores
- Added a canonical Codex package archive pipeline and moved installers, npm packages, DotSlash, and SDK runtimes toward that shared layout. (#23513, #23582, #23586, #23596, #23635, #23636, #23637, #23638, #23786)
- Fixed Linux Python runtime wheel tags so glibc-based systems can install the runtime artifacts. (#21812)
- Improved release and CI reliability with package-builder tests, prebuilt resource packaging, DotSlash zstd handling, platform-sharded Rust tests, and Codex Linux release runners. (#23760, #23759, #23752, #23358, #23761)

## Changelog

Full Changelog: https://github.com/openai/codex/compare/rust-v0.132.0...rust-v0.133.0

- #23343 codex: route global AGENTS reads through LOCAL_FS @starr-openai
- #22380 fix: default unknown tool schemas to empty schemas @celia-oai
- #23309 Add tool lifecycle extension contributor @jif-oai
- #23253 Reduce rust-ci-full Windows nextest timeout flakes @starr-openai
- #22878 Improve `codex remote-control` CLI UX @owenlin0
- #21812 Publish Linux runtime wheels with glibc-compatible tags @aibrahim-oai
- #22709 [codex] Trim unused TurnContextItem fields @pakrym-oai
- #23353 Include plugin id in plugin MCP tool metadata @mzeng-openai
- #22728 [codex] Move pending input into input queue @pakrym-oai
- #23371 fix(tui): warn on unsupported iTerm2 pet versions @fcoury-oai
- #23376 [codex-analytics] preserve user thread source for exec threads @marksteinbrick-oai
- #23360 app-server: use profile ids in v2 permission params @bolinfest
- #23384 [codex] Remove external websocket session resets @pakrym-oai
- #22721 cleanup: Remove skill env var dependency prompting @xl-openai
- #23389 Remove ToolSearch feature toggle @sayan-oai
- #23080 [1 of 7] Add thread settings to UserInput @etraut-openai
- #23081 [2 of 7] Remove UserInputWithTurnContext @etraut-openai
- #23075 [3 of 7] Remove UserTurn @etraut-openai
- #23396 [codex] Extract turn skill and plugin injections @pakrym-oai
- #23356 fix(plugins): keep version upgrades additive @iceweasel-oai
- #22508 [5 of 7] Replace OverrideTurnContext with ThreadSettings @etraut-openai
- #22086 CI: Customize v8 building @cconger
- #23390 Remove explicit connector tool undeferral @sayan-oai
- #22928 core: expose permission profile picker metadata @viyatb-oai
- #23352 Preserve context baselines for full-history agent forks @jif-oai
- #23300 feat: dedicated goal DB @jif-oai
- #22835 Remove ToolsConfig from tool planning @jif-oai
- #22870 Add `body_after_prefix` auto-compact token limit scope @jif-oai
- #23144 Defer v1 multi-agent tools behind tool search @jif-oai
- #23409 [codex] Allow empty turn/start requests @pakrym-oai
- #23388 [codex] Move hook request plumbing into hook runtime @pakrym-oai
- #23405 [codex] Preserve steer input as user input @pakrym-oai
- #22914 [2 of 4] tui: route app and skill enablement through app server @etraut-openai
- #23397 [codex] Make contextual user fragments dyn-renderable @pakrym-oai
- #23475 chore: namespace v1 sub-agent tools @jif-oai
- #23493 Make `deny` canonical for filesystem permission entries @viyatb-oai
- #22929 Harden CLI rate limit window labels @ase-openai
- #22782 Add SubagentStart hook @abhinav-oai
- #23513 build: add Codex package builder @bolinfest
- #23369 Make local environment optional in EnvironmentManager @starr-openai
- #23327 Refactor exec-server websocket pump @starr-openai
- #23536 fix(tui): preserve modified enter in plan questions @fcoury-oai
- #23400 Fix empty rollout path app-server handling @wiltzius-openai
- #23551 Route local-only app-server gating through processors @starr-openai
- #23372 Split plugin install discovery into list and request tools @mzeng-openai
- #23516 fix: serialize unix app-server startup @efrazer-oai
- #22169 [codex] Honor role-defined spawn service tiers @aibrahim-oai
- #23555 Add CUA requirements subsection for locked computer use @adams-oai
- #23538 Fix: TUI starting in wrong CWD @canvrno-oai
- #23526 build: fetch rg for Codex packages @bolinfest
- #23573 Remove unused ARC monitor path @mzeng-openai
- #23576 test: fix multi-agent service tier assertion @bolinfest
- #23541 build: default Codex package target and output @bolinfest
- #23358 Fan out rust-ci-full nextest by platform @starr-openai
- #23593 feat: expose codex-app-server version flag @bolinfest
- #23412 feat: add permission profile list api @viyatb-oai
- #23535 Move plugin and skill warmup into session startup @aibrahim-oai
- #23231 Fix stale background terminal poll events @etraut-openai
- #23564 [codex] Preserve raw code-mode exec output by default @aibrahim-oai
- #23232 Warn on invalid UTF-8 in AGENTS.md files @etraut-openai
- #23584 feat: Add vertical remote plugin collection support @xl-openai
- #23586 build: package prebuilt Codex entrypoints @bolinfest
- #23582 ci: build Codex package archives in release workflow @bolinfest
- #23596 runtime: detect Codex package layout @bolinfest
- #23500 add encryptedcontent to functioncalloutput @sayan-oai
- #23633 Migrate exec-server remote registration to environments @richardopenai
- #23451 Add timeout for remote compaction requests @jif-oai
- #23667 feat: rename 1 @jif-oai
- #23669 feat: rename 3 @jif-oai
- #23668 feat: rename 2 @jif-oai
- #23675 fix: main @jif-oai
- #23685 feat: wire goal extension tools to the dedicated goal store @jif-oai
- #23690 feat: async approval contrib @jif-oai
- #23692 feat: async turn item process @jif-oai
- #23688 feat: expose turn-start metadata to extensions @jif-oai
- #23605 [codex] Hide deferred tools from code mode prompt @pakrym-oai
- #23634 runtime: use install context for bundled bwrap @bolinfest
- #23635 release: publish Codex package archive checksums @bolinfest
- #23592 feat: Add btw alias for side slash command @anp-oai
- #23696 feat: account active goal progress in the goal extension @jif-oai
- #23176 [2 of 2] Start fresh TUI thread in background @etraut-openai
- #23578 fix(app-server): speed up shutdown @fcoury-oai
- #22896 windows-sandbox: add resolved permissions helper @bolinfest
- #23502 Add thread/settings/update app-server API @etraut-openai
- #23507 Sync TUI thread settings through app server @etraut-openai
- #23666 feat: add turn_id and truncation_policy to extension tool calls @jif-oai
- #23636 install: consume Codex package archives @bolinfest
- #23717 [codex] Preserve failed goal accounting flushes @jif-oai
- #23655 add standalone websearch api client @sayan-oai
- #23724 Fix thread settings clippy failure @etraut-openai
- #23637 npm: ship platform packages in Codex package layout @bolinfest
- #23729 fix(config): resolve cloud requirements deny-read globs @viyatb-oai
- #23638 dotslash: publish Codex entrypoints from package archives @bolinfest
- #22918 windows-sandbox: send permission profiles to elevated runner @bolinfest
- #23735 windows-sandbox: share bundled helper lookup @bolinfest
- #18868 Add MITM hook config model @evawong-oai
- #22270 feat(permissions): resolve permission profile inheritance @viyatb-oai
- #23719 cli: add strict config to exec-server @bolinfest
- #23542 [skills] Create a personal update flow for plugin creator @caseychow-oai
- #21272 Support compact SessionStart hooks @abhinav-oai
- #20659 Wire MITM hooks into runtime enforcement @evawong-oai
- #23752 release: use DotSlash zstd for package archives @bolinfest
- #22923 windows-sandbox: drive write roots from resolved permissions @bolinfest
- #23761 chore: use Codex Linux runners for Rust releases @bolinfest
- #23759 release: package prebuilt resource binaries @bolinfest
- #23167 windows-sandbox: feed setup from resolved permissions @bolinfest
- #22931 core: refresh active permission profiles at runtime @viyatb-oai
- #22873 Add SubagentStop hook @abhinav-oai
- #23727 feat(plugins): tabulate plugin list output @caseychow-oai
- #23732 Make goals feature on by default and no longer experimental @etraut-openai
- #23537 Honor client-resolved service tier defaults @shijie-oai
- #23771 [codex] Fix realtime v1 websocket compatibility @guinness-oai
- #23764 Remove Windows sandbox resource stamping @iceweasel-oai
- #23730 [codex] List marketplaces considered by plugin discovery @caseychow-oai
- #23760 ci: run Codex package builder tests @bolinfest
- #23737 [codex] Add plugin id to MCP tool call items @mzeng-openai
- #18240 Use named MITM permissions config @evawong-oai
- #23774 [codex] Reject read-only fallback with approvals disabled @viyatb-oai
- #23714 windows-sandbox: add profile-native elevated APIs @bolinfest
- #23433 feat: support managed permission profiles in requirements.toml @viyatb-oai
- #23715 core: pass permission profiles to Windows runner @bolinfest
- #23786 sdk: launch packaged Codex runtimes @bolinfest

* Seed Termux release automation

* Prepare Termux rust-v0.133.0

* Release 0.134.0-alpha.2

* Seed Termux release automation

* Prepare Termux rust-v0.134.0-alpha.2

* Release 0.134.0-alpha.3

* Seed Termux release automation

* Prepare Termux rust-v0.134.0-alpha.3

* ## New Features
- Added search across local conversation history, including case-insensitive content matches with result previews. (#23519, #23921)
- Made `--profile` the primary profile selector across CLI, TUI permissions, and sandbox flows, with legacy profile configs rejected through migration guidance. (#23708, #23883, #23890, #24051, #24055, #24059, #24067, #24110)
- Improved MCP setup with per-server environment targeting and OAuth options for streamable HTTP servers. (#23583, #24120)
- Made connector tool sche…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant