## Why
Locally configured MCP servers may differ from those reported by the app server. Waiting for unreported servers can leave startup progress busy after the observed servers have finished.
## What changed
- Track startup progress from received server status updates, settling when no observed starts remain pending. Handle standalone outcomes after attachment or lag, deduplicate repeated diagnostics, and reactivate progress on new starts.
- Read effective MCP configuration through `config/read` to prevent task tools from shadowing the `codex_tui` namespace, including when configuration changes after startup.
- Use the same configuration reader to disable MCP servers for temporary structured threads.
- Remove client-side MCP requirement checks for the task-tools server and MCP requirements from debug configuration output, leaving enforcement to the app server.
## Testing
Update regression coverage for unreported local servers, startup rounds after lag, diagnostic handling, namespace conflicts, and server-enforced managed requirements.
GitOrigin-RevId: 370767b90ee55f8b0b1403872ef437d53257586b
## Why
`thread/sample` previously required the source's latest turn to finish before it could be sampled.
## What changed
Add `allowInProgressTurn`, defaulting to `false`, to sample a snapshot of the latest turn while the source continues running. The requested turn must still be the latest, but source history changes during sampling no longer invalidate the result when this option is enabled.
For an in-progress snapshot, include a context note explaining that the source was not stopped and pending tool calls may appear as `aborted` in the copy. Suppress the copy's default interruption message.
## Testing
Add coverage for sampling running turns in legacy and paginated history modes, including pending tool calls and mid-turn compaction. Verify that the source continues independently and that finished-turn samples retain their existing context.
GitOrigin-RevId: 771b979bf677e4ff0686476bfaf21aff92f7e7ac
## What changed
Allow GCP Responses requests to use `incremental_tools_legacy`. When enabled, tool declarations are sent through `additional_tools` inputs instead of the top-level `tools` array.
## Testing
Extend Vertex request coverage to check incremental tool declarations, including namespaces, tool search, and `exec_command`. Add GCP cases to the scenario that verifies tool catalog updates are appended without rewriting history, with incremental tools enabled and disabled.
GitOrigin-RevId: 8f4c02f8d62575e24e695d6fae0472a09625409f
## What changed
- Show a refusal status while preparing alternative suggestions and remove the pending notice above the composer.
- Clarify that choosing a rewrite starts a new chat with earlier context, and update overview suggestions to explicitly say users can ask Codex.
- Add an option to report safety-check concerns through the consent flow when reporting is enabled.
## Testing
Update safety recourse snapshots and extend coverage for reporting consent, returning to the picker, and Daybreak notices when enabled or unavailable for the selected model.
GitOrigin-RevId: 99f565ebec7064ec55d388e73acede2dfe639474
## Why
Opening a saved side chat waits for thread resume and history loading. Keep the chooser usable during that work and switch conversations only if the user still wants to open the chat.
## What changed
- Prepare saved chats in the background and show opening, waiting, and retry states in the sidebar. Allow cancellation and keep only the latest queued destination, with at most two preparations in flight.
- Ignore stale completions after navigation, archiving, disconnects, or backend changes, and release unclaimed subscriptions on their original connection.
- Preserve live events, settings, read receipts, and pending approvals received during loading. Anchor paginated history to the resumed snapshot to avoid overlap with live events.
- Carry held-key suppression across conversation switches.
## Testing
Add regression tests for retry and supersession, cancellation, stale completions, subscription cleanup, live updates during attachment, and held keys, plus snapshots for waiting and retry rows.
GitOrigin-RevId: 2c7d94482078f16895049ce79b242d3eb0d92f40
## What changed
Expose `discover_authorization_metadata` using RMCP and the existing OAuth HTTP adapter with a caller-supplied HTTP client. Return published authorization-server metadata, including discovery through protected-resource metadata, while excluding synthesized legacy endpoints. Return `None` when authorization metadata is unavailable and propagate discovery errors.
## Testing
Add tests for published versus synthesized endpoints, discovery failures and issuer mismatches, and discovery through a separate authorization server without sending credentials.
GitOrigin-RevId: b273067bb3b33d11301ae0e2017b28cd8e25b548
## Why
Title and content searches exclude attached threads, preventing clients from finding their saved conversations alongside ordinary threads.
## What changed
- Add `includeAttachedThreads` to `thread/list` and `thread/search`. For `thread/list`, require a non-empty `searchTerm` and preserve the usual provider and source filters.
- Expose `attachedToThreadId` on thread responses to identify the owning parent independently of fork and subagent lineage.
- Support inclusive searches through SQLite and filesystem fallback, repairing missing database entries with saved thread names during title searches.
## Testing
Add regression coverage for opt-in title and content searches, attached-parent metadata after restart, default search filters, filesystem searches without SQLite, and discovery and repair of unindexed title matches.
GitOrigin-RevId: ac12ec3c730ad7f1722bdf8e21600d17f12017f0
## Why
The existing loopback listener mode does not provide the stdin/stdout transport needed by OpenSSH's `ProxyCommand`.
## What changed
- Relay one SSH session over HTTP/3 CONNECT with `--environment-id ENV --port PORT`, defaulting to the public Portals gateway and port 22. Also accept an explicit `--proxy-url` with `--target ENV:PORT`.
- Require ChatGPT OAuth login, enforce cloud configuration and application network policy, and restrict OAuth credentials to the built-in gateway origin. Leave SSH authentication and host-key verification to OpenSSH.
- Preserve binary stdio, propagate input half-close, exit on gateway EOF, and report rejected CONNECT requests by HTTP status without exposing arbitrary peer error text.
- Require ERS-issued v2 tunnel JWTs for Portals listener mode unless OAuth mode is selected, and reject older ERS tunnel JWTs during credential updates.
- Disable UDP segmentation offload for SSH tunnels on Linux to avoid stalled bulk transfers on affected paths. Document an OpenSSH configuration example.
## Testing
Add coverage for argument validation, gateway routing, credential boundaries, JWT startup and renewal checks, binary relay and half-close behavior, gateway EOF and rejection, and cloud policy enforcement before gateway connection.
GitOrigin-RevId: 0d9afbddef01748efcc1c4b88f7e19923deff7e1
## Why
The Windows `notify` backend wakes every 100 ms even when idle.
## What changed
- Patch `notify` 8.2.0 in Bazel to wait indefinitely for events or control requests.
- Wake the watcher when configuration requests are queued and share ownership of the wakeup semaphore with `Arc<OwnedHandle>`.
## Testing
Add a Windows regression test that verifies file changes are reported after unregistering one directory and registering another on the same watcher.
GitOrigin-RevId: b53b3c8bc514008554fdeffaef3f7bf8305a4803
## Why
Reference-backed forks can lack a local opening user message, causing them to disappear from thread listings or lose their inherited preview when a new turn is written. Compaction can also remove the opening message from the model context used to prepare a fork.
## What changed
- Persist inherited previews and preserve them when recording new turns and merging thread-list metadata.
- Include reference-backed forks with inherited history in thread listings before their first local message.
- Recover opening previews from transcript history within the requested fork boundary when compaction omits them from model context.
- Use the shared `user_message_preview` helper when deriving previews from rollout items.
## Testing
Extend thread-fork integration tests to check previews in listings before and after a new turn, after reopening, and when forking at a boundary after compaction.
GitOrigin-RevId: 5962cf71ea7104f07c9013cc77259b105e4c60d7
## Why
A failed side chat's opening prompt and image attachments could be restored into the parent chat's draft when dismissing the failure.
## What changed
Clear the pending opening message when sidebar chat creation fails, and stop restoring the opening message when side conversation creation returns an error.
## Testing
Update the sidebar chooser test to verify that dismissing a failed creation preserves the parent draft and a subsequent prompt without restoring the failed prompt or its image attachment.
GitOrigin-RevId: 1423786b2209e9441e0bc1504ffcf51e74ba7cde
## What changed
- Fold earlier commentary, reasoning, and tool activity beneath an expandable prompt control in the full-screen transcript, keeping partial and final answers visible.
- Label the control with completion timing when available, or a previous-message count otherwise. Keep tool groups independently expandable within the turn.
- Preserve assistant message phases during live completion and replay, and retain untimed completion markers to identify completed turns.
## Testing
Add transcript coverage for nested expansion, keyboard and mouse controls, narrow viewports, search anchor preservation, detailed mode, and legacy messages without phase or timing metadata.
GitOrigin-RevId: b17d9d7c870990178d76d12a13d463ff9c32b96c
## What changed
- Combine adjacent tool calls into one expandable summary, including calls that move from live output into history. Label successful command groups with summaries such as `Explored files` and `Ran 2 commands`.
- Include web searches in tool groups, hide duplicate provisional search entries, and show a single completed search directly. Preserve its reading position when it completes.
- Refresh summaries as history changes while preserving pinned content during selection and reading.
## Testing
Add regression coverage for web search completion, grouped search expansion, loading older history during selection, and command completion with an expanded summary.
GitOrigin-RevId: 98f4e0c49cbf8014c25874cf47d1c0c92ee6b30d
## What changed
- Add summary labels for MCP and dynamic tools, computer activity, terminal interactions, file edits, images, plan updates, agent calls, and historical tool fallbacks.
- Keep tool output out of summaries and give summaries disclosure identities even when their cells have no activity IDs.
- Bring focused disclosure headers into view and show `expand` or `collapse` in the footer, including for search-expanded entries.
## Testing
Add assertions for tool labels, a transcript snapshot verifying that image-generation output stays hidden, and coverage for expanded and collapsed footer hints.
GitOrigin-RevId: 076b8d74c17f26b10aa8221c65b8b38dbb5ad5ea
## What changed
- Add `tui.collapse_turn_details`, disabled by default, and a “Collapse turn details” toggle in the full-screen settings panel.
- Summarize command executions with output-free labels, grouping multiple calls behind an expandable row. Keep full details available through transcript search and detailed view.
- Restore interruption notices at their turn boundaries when resuming and loading older history, including turns split across pages.
## Testing
Add coverage for live summary updates, expansion controls, search access to hidden output, settings visibility, and interruption ordering across history pages.
GitOrigin-RevId: 68987fb0239e39414dac383098acac190fc4f516
## What changed
- Let users press `Ctrl+S` in the report note editor to save a diagnostic ZIP locally without sending it to OpenAI, including when uploads are disabled. Keep `Enter` for sending reports when uploads are enabled.
- Apply the attachment consent choice to both destinations, clarify the disclosures, and show the saved archive path on completion.
- Require a local app server for ZIP saves, report unsupported servers with an upgrade hint, and stop before collecting a note when no report destination is available.
## Testing
Add coverage for ZIP creation with and without log consent, no upload requests on save success or failure, destination availability, keyboard actions, and saved-path receipts. Update report UI snapshots.
GitOrigin-RevId: cbc0142988840e5e3f6475f31678915bf25d56a2
## What changed
Use eligible installed marketplaces as Git clone references to avoid fetching objects already available locally. Limit fetch negotiation to the recorded installation commit so local branch revisions are not advertised, and use `--dissociate` to keep the upgraded checkout self-contained.
Enable reuse only with Git 2.20 or newer and a recognized release version. Fall back to a fresh clone if reference cloning fails, and retain existing ref and sparse-checkout behavior.
## Testing
Add coverage for installation-commit negotiation, exclusion of local branch revisions, self-contained object stores, fallback with older or unknown Git versions and shallow references, and Git release parsing.
GitOrigin-RevId: 8d0f6a4bed7e7e2a3136e3912ba2f92150be9354
## Why
Switching to a model whose access metadata excludes Daybreak can leave Daybreak enabled and block subsequent turns.
## What changed
Automatically turn Daybreak off when a model switch or catalog refresh confirms that it is unavailable for the selected model. Persist the disabled preference for the thread and new threads, and warn that prior cybersecurity context may still cause refusals. Switching back to a compatible model leaves Daybreak off until the user re-enables it with `/daybreak`.
Require explicit access metadata before disabling Daybreak, and recheck the selected model before applying a queued change.
## Testing
Extend session lifecycle coverage for pending model discovery, supported and unknown models, persisted disabling, and subsequent turns using the standard access program. Add a snapshot of the model-switch warning.
GitOrigin-RevId: 6c294939d854c7176ed9a346e8ea806ffcf6f715
## What changed
Return first-party provider models in catalog order while retaining priority-based default selection and existing filtering. Apply this ordering only to provider-origin catalogs for the OpenAI provider using Codex backend routes or `model_catalog_url`. Bundled, configured, and third-party catalogs retain priority ordering.
## Testing
Add coverage showing that catalog display order can differ from priority order while the recommended model remains the default. Update custom-provider coverage to verify priority ordering with a reversed catalog response.
GitOrigin-RevId: 9c2361e070ba424c092a282ca7f1cf9952d270b3
## What changed
Move `ThreadMetadataBuilder` into its own module, make its fields private, and replace direct field assignments with fluent `with_*` methods. Initialize `updated_at` and `recency_at` from the creation time and default the approval mode to `OnRequest`.
Update `apply_rollout_items` to accept a boxed `ThreadMetadata` seed, keeping callers' async frames small while preserving existing database fields except for the seed rollout path. Add `build_thread_metadata` to use the state runtime's configured provider, and use `thread_id_from_rollout_path` directly for the doctor's filename fallback.
GitOrigin-RevId: a27e4c6b22832e902922dbdd60d7f5c11b4a1a83
## Why
Allowing a hostname must not bypass deny or review rules on its resolved IP addresses. Forwarding DNS resolution to an upstream proxy also requires checking whether those address restrictions can still be enforced.
## What changed
- Add `TcpUpstreamProxy` and `set_tcp_upstream_proxy` to require a configured HTTP `CONNECT` next hop for opaque SOCKS TCP traffic. Wait for a successful response before forwarding payloads and preserve bytes read past the response headers.
- Enforce resolved IP deny and review rules at direct connection time, carry destination-scoped authorization through HTTP, SOCKS, and MITM forwarding, and report blocked resolutions as policy denials.
- Recognize equivalent numeric IP spellings for restrictive rules. Permit remote TCP DNS only when local binding is allowed and no deny or review pattern can restrict IP addresses; reject upstream proxy loops.
- Restrict Linux proxy bridges to managed proxy environment keys and supplied loopback ports. Bound concurrent bridge workers and release them after connection failures while allowing queued responses to drain.
- Add test-only Linux DNS name mapping and SOCKS relay helpers with stable synthetic addresses and validation before opening upstream connections.
## Testing
Add regression coverage for CONNECT refusal and buffered tunnel data, resolved-address policy denials, approval handling across policy refreshes, equivalent IP literals, DNS mapping stability, rejected relay requests, and bridge cleanup after resets.
GitOrigin-RevId: bdd6e16de3373d0eb39995f689dad0230680b99e
## What changed
Send Responses text messages larger than 1 MiB as a single WebSocket message split into frames of at most 1 MiB, awaiting each frame send to apply backpressure. Keep smaller text messages and non-text messages on the existing send path.
Update the `tokio-tungstenite` and `tungstenite` fork revisions and associated Cargo and Bazel lockfiles.
## Testing
Add a unit test covering the 1 MiB boundary, continuation opcodes, the final-frame flag, and preservation of payload bytes when a multibyte UTF-8 character crosses a frame boundary.
GitOrigin-RevId: 372ee31b77e185b963d3bdca11847e50e9018421
## Why
Forked and recovered sessions can restore a tool call before its output has been recorded. Missing outputs for these calls should be treated as interrupted work rather than an error.
## What changed
Track the restored history's sequence cutoff so custom tool and local shell calls in that history can receive synthetic `aborted` outputs without reporting a missing-output error. Keep the existing checks for newly recorded calls and clamp the cutoff when history is replaced.
## Testing
Extend the active-turn fork test with a pending `apply_patch` call and verify that the fork's model input includes its `aborted` output.
GitOrigin-RevId: d989fa0991db72f0f8fa8a6d5de403fb307c40c7
## What changed
- Use `SandboxManager` to prepare `codex sandbox` commands, including permission profiles, workspace roots, and managed network proxy settings.
- Return a `WrappedSandboxCommand` that can produce an execution request or a configured process command, preserving native executable paths and Linux helper `argv[0]`. Require the session launcher for native Windows token sandboxes.
- Move macOS inherited-terminal policy handling into the shared manager, retaining Unix socket grants and the terminal input injection denial.
- Prepare managed network context alongside proxy environment variables and pass it through sandbox transformation.
## Testing
- Extend sandbox network proxy tests to macOS, covering blocked direct loopback access and explicitly allowed requests.
- Add coverage for Linux helper executable paths and dispatch names, including non-UTF-8 paths.
GitOrigin-RevId: 8b7396d21b2f34122699388f16047329a3f5e5c6
Add `McpRefreshReason::SessionPermissionsGranted` and pass it when marking the
MCP runtime dirty after a session-scoped permission grant. This supplies the
required reason argument and identifies the refresh cause in CLI diagnostics.
GitOrigin-RevId: 2ff8f6b9e1a40d68e1f799d0414c2d45e2576a1a
## Why
An explicit denial from a workspace inference hook should stop the request, including retries and compaction model fallback.
## What changed
Recognize `inference_hook_denied` provider errors and preserve the provider's message, with a fallback when none is supplied. Expose the distinct `inferenceHookDenied` error through the app-server protocol and generated schemas and SDK types. Treat the denial as non-retryable during turns, compaction, and guardian review.
## Testing
Add coverage for terminal denials over HTTP, SSE, and WebSocket, error serialization and persistence in `thread/read`, and compaction failures that preserve token usage and history without retrying or falling back to another model.
GitOrigin-RevId: 2ebd480f01e52f4e6bd3db8a0f92d5814d18ccb1
## Why
Windows MSVC builds relied on installed C++ toolchains, and V8 snapshot generation required native Windows execution. Cross-compiling V8 also needs a Windows snapshot generator to preserve Windows unwind metadata.
## What changed
- Use the registered hermetic LLVM toolchain and declared Microsoft SDK for Windows MSVC builds, with static CRT linkage and the toolchain's declared `lld-link` for Rust.
- Run Windows V8 snapshot generators natively or through `rules_wine` on Linux, preserving target CPU, OS, and sandbox settings. Keep separate archive and binding pairs for the workspace's ISO stdio ABI and the distributed MSVC stdio ABI.
- Update build dependencies and bindgen, scope V8's Chromium libc++ settings to its own targets, and adapt native voice dependencies for clang-cl and Windows ARM64.
- Build SQLite directly with Bazel and give `openssl-sys` an explicit build using Bazel's OpenSSL.
- Remove build-worker source-directory dependencies from Bazel resource lookup, schema output discovery, and snapshot paths; embed assets in debug builds as well.
GitOrigin-RevId: fd224d9d28d73a67baf90f6d73c6079d60f20351
## Why
MCP requests need to retain inbound W3C trace context even when no OpenTelemetry tracing layer is installed.
## What changed
- Carry validated request trace context through app-server MCP tasks, connection startup, and resource listing tasks, while preferring active span context.
- Forward fallback `traceparent` and `tracestate` headers for MCP HTTP requests, including discovery and initialization.
- Use HTTP trace headers as a fallback for exec-server RPC calls when active span context is unavailable.
## Testing
Add an app-server integration test that disables trace exporting and verifies that `mcpServer/resource/read` forwards the inbound `traceparent` and `tracestate` to the MCP server.
GitOrigin-RevId: c886a55ce0a3992f1b2e04614efec80a20cb4b49
## What changed
- Track and log `McpRefreshReason` values for runtime refreshes, including invalidations received during thread startup and forced refreshes. Restore claimed reasons when a refresh is cancelled before publication, while preserving concurrent invalidations.
- Correlate installed-plugin metadata invalidations with downstream MCP refreshes using a shared change ID. Log changed field names by plugin ID, additions, removals, and reordering without logging field values.
- Record whether background installed-plugin bundle updates were requested by startup, plugin listing, or installation.
## Testing
Add coverage for metadata change attribution across membership changes and reordering, and for retaining refresh causes across cancellation and concurrent invalidation.
GitOrigin-RevId: 3d4485ccfcc1d8788eb9909a060ac200c467af13
## What changed
Compute the `sandbox_policy` label for `codex.conversation_starts` from the effective `PermissionProfile` without constructing a legacy `SandboxPolicy`. Preserve the historical labels and native-path compatibility fallbacks, including `workspace-write` for writable profiles that cannot be represented by a legacy policy.
Share the full-disk write compatibility check with session startup and the write-intent check with legacy policy conversion.
## Testing
Extend telemetry tests to assert sandbox labels in both logs and traces across disabled, external, read-only, workspace-write, and full-disk profiles, including unrenderable writable URIs and read restrictions. Add protocol assertions for legacy write-intent detection.
GitOrigin-RevId: 00f11d763c366453e7bb0899546a4ebbdb93c4d5
## Why
Asynchronous Guardian collection applied entry caps and compressed heartbeat messages before request preparation, while synchronous collection preserved originals. Preserve the captured evidence so request-time profiles and budgeting determine what is delivered.
## What changed
- Replace `prepare_sync_context` with a shared `prepare_context` entry point for synchronous and asynchronous presentations.
- Defer text caps, native-message omission, and heartbeat compression to preparation, preserving heartbeat reference numbering across transcript deltas.
- Support elastic transcript preparation for both reviewer profiles.
- Borrow collected asynchronous context instead of cloning the full transcript, and filter previous reviews against reviewer history during preparation.
## Testing
Add coverage for collection preserving originals, fixed preparation truncating text and omitting oversized native entries, and elastic preparation deferring entry caps for both profiles. Update heartbeat tests to cover full and delta preparation without mutating collected evidence.
GitOrigin-RevId: 4d4e448acf5dc8880a05c3c9a9754378135f61eb
## Why
Session-opening failures were returned as strings, preventing callers from inspecting the terminal gRPC admission status directly.
## What changed
- Add `GrpcCodeModeSessionProvider::open_session` returning `GrpcSessionOpenError`, distinguishing admission status codes, admission timeouts, and other setup failures.
- Keep string errors for the existing `CodeModeSessionProvider` trait API.
- Re-export `ProcessOwnedGrpcCodeModeSessionProvider` from `codex-core`.
## Testing
Extend admission tests to assert terminal status codes, cover exhausted `ResourceExhausted` retries, and verify that `DeadlineExceeded` is not retried.
GitOrigin-RevId: 9d7f2e733e12b8bb7def368fa5fc5a09ea2a374e
## What changed
- Recognize `claude-code-local-skills` as a migration source that excludes the home skills directory's `synced` folder from detection and import.
- Exclude the home skills directory's `.trash` folder from Claude Code skill detection and import in all modes.
- Keep importing `synced` skills in the default mode while excluding `.trash` directories within that tree.
## Testing
Extend the skill import regression test to cover local-only imports, default imports of synced skills, and exclusion of both top-level and nested trash directories.
GitOrigin-RevId: 2c036319d022820659a60179bf58c37621f6ba14
## Why
`codex app-server daemon start` ignored CLI feature overrides, while `restart` already parsed and applied them.
## What changed
Parse and validate feature overrides for `start` using the same handling as `restart`, including `--enable`, `--disable`, and `-c features.<name>=<bool>`. Pass the overrides through to daemon startup so they are saved when launching a stopped daemon. Starting an already running daemon preserves its process and saved overrides.
## Testing
Add coverage for applying overrides on a fresh start and preserving them on a subsequent `start`. Extend validation coverage to ensure both `start` and `restart` reject non-toggle feature keys without changing settings or the running process.
GitOrigin-RevId: 9edbfdfc723146674051a9f0713e528b552eeb00
## What changed
Route MCP elicitations through the standard handling paths for Xcode 26.4 clients. Remove the client-specific auto-deny flag and the synthetic acceptance of session elicitation requests without dispatching them to the client.
Simplify `request_mcp_server_elicitation` to return the optional response directly, and remove telemetry guards that depended on whether the workaround bypassed dispatch.
GitOrigin-RevId: ab540dcd67f8fa6d16c69bc7629f436e4b5aa73a
## What changed
Mark `untrusted_as_tool_output` as stable and enable it by default. Untrusted additional context, such as browser information and goal objectives, now reaches the model as `function_call_output` items in the `agent` namespace instead of user messages. Setting `features.untrusted_as_tool_output = false` preserves the message format.
## Testing
Update core, app-server, TUI, and Python SDK test expectations for the default output format. Cover context persistence, deduplication, goal continuation, and explicit opt-out behavior.
GitOrigin-RevId: 30828351e2ed584928f6055b6dcf276d8288c0fb
## What changed
- Advertise `supportsDeviceAuth` in `account/gatewayOAuth/read` and accept `deviceAuth: true` in `account/gatewayOAuth/login`.
- Return a device prompt with `verificationUrl`, `userCode`, and `loginId` before approval, then notify the initiating connection of success or failure with the matching `loginId`.
- Reuse or refresh saved credentials when possible, returning `prompt: null` without another device authorization. Update protocol schemas, generated bindings, and documentation.
## Testing
Add an integration test covering the device prompt, correlated completion notification, capability reporting, and token refresh without another device grant.
GitOrigin-RevId: 6ecc38c9baadcfda3272654ed71e4aaa431421bf
## Why
HTTP 400 responses with `context_length_exceeded` need to reach context-window recovery so manual compaction can retry with less history. Streaming context-window failures should end the stream immediately.
## What changed
- Map `context_length_exceeded` through the shared terminal provider error parser for HTTP 400 responses and events without an HTTP status.
- Return SSE context-window failures immediately.
- Preserve retryable handling for WebSocket errors carrying HTTP 503, even when their code is `context_length_exceeded`.
## Testing
Add coverage for WebSocket status handling and immediate SSE termination with retry headers. Update the manual compaction test to verify recovery from an HTTP 400 context-window error by dropping one history item and retrying.
GitOrigin-RevId: 56d8c831c2fad2ca1318318a3b4258fcc516d689
## Why
An `invalid_access_program` or `unsupported_access_program` streaming error should end the stream immediately, even if a later `response.completed` event arrives or the error includes a retry header.
## What changed
Map both error codes to `ApiError::InvalidRequest` and stop processing the response stream on invalid requests. Preserve a nonblank provider message, falling back to an explanation that the requested access program cannot be used with the model.
## Testing
Extend the terminal-error test to cover both codes in `error` and `response.failed` events, verifying that retry headers are ignored and the stream ends before a later completion event.
GitOrigin-RevId: 5431a2babec64eae5cdf6c138b98e91e84778e79
## Why
A `403` with `codex_workspace_access_denied` indicates that the account cannot use Codex in the selected workspace. Retrying or falling back to HTTP does not resolve that denial.
## What changed
Map `codex_workspace_access_denied` and `invalid_workspace_selected` responses to a shared workspace access denial error, and rename the error variant to reflect its broader scope. Keep workspace denials excluded from compaction model fallback.
## Testing
Extend API error mapping tests to cover the new code on `403` and preserve ordinary handling for `503`. Add WebSocket coverage verifying that an explicit workspace access denial does not trigger HTTP fallback.
GitOrigin-RevId: e601a22a0fa783a4ce5401a98ff9c8d3d9d1b074
## What changed
Recognize `content_policy_violation` in HTTP 400 responses and streamed errors as a dedicated, non-retryable error. Preserve the provider's message and available HTTP status, use a fallback message when needed, and report `CodexErrorInfo::InvalidPrompt` to clients.
End the response stream immediately on this error and stop compaction from falling back to the current model after a content policy rejection. Add redacted diagnostic output and a dedicated sampler failure reason.
## Testing
Extend coverage for HTTP and wrapped WebSocket errors, missing or blank provider messages, terminal stream failures with retry headers, and content policy rejections during local and remote compaction on model downshift.
GitOrigin-RevId: 592170ac30c07b0b303a8d5cb15bd35c8f821b55
## What changed
Recognize `access_program_not_enabled` in HTTP 403 responses and response stream errors as a dedicated, non-retryable error. Preserve HTTP diagnostic details and provider stream messages, with a default message when none is supplied.
Stop SSE streams immediately on this error and avoid triggering WebSocket fallback for explicit access program denials. Add a fixed diagnostic label for doctor output and telemetry.
## Testing
Extend coverage for HTTP and WebSocket denials, immediate SSE termination despite retry headers, and doctor diagnostic redaction.
GitOrigin-RevId: 3a41f7bb80ad5e13a87e831b458d17cdd19a4b62
## Why
HTTP 403 responses with `invalid_workspace_selected` were treated as unexpected status errors, allowing retries and compaction fallback to another model after the server rejected the selected workspace.
## What changed
Recognize the code in `detail.code` or `error.code`, falling back to the `x-error-json` header when the body has no code. Classify these 403 responses as `InvalidWorkspaceSelected` and disable retries and compaction model fallback while preserving the response details and HTTP status. Other 403 responses retain their existing retry behavior.
## Testing
Add coverage for body and header error codes, code precedence, HTTP and WebSocket retry behavior, and local and remote compaction during a model downshift.
GitOrigin-RevId: f44a3bee5ef06e601909839868ab99cea6dd7d03
## Why
Local compaction retried invalid requests and server overload errors without retry advice, and used local backoff even when the server supplied `Retry-After`.
## What changed
Use `CodexErr::retry_delay` to decide whether and when to retry local compaction. Honor the original `Retry-After` deadline when present, while retaining the configured retry limit and context-window trimming behavior.
## Testing
Add coverage verifying that manual local compaction does not retry invalid requests or overload responses without retry advice, but retries overload responses with `Retry-After`.
GitOrigin-RevId: abe6cbba661f701b97f8b1ab83b1fe86979f03c0
## What changed
Initialize thread metadata's `sandbox_policy` with a serialized `PermissionProfile::read_only()`, matching the format used by turn contexts and session settings. Remove the legacy `SandboxPolicy` field from `ThreadMetadataBuilder` and redundant rollout metadata defaults.
## Testing
Extend thread-store tests to cover reading the default read-only permission profile from SQLite and accepting both string and serialized legacy `danger-full-access` policies.
GitOrigin-RevId: ec9b88a47799a20529e28ef8ca6f5f7c2c8faf9e
## Why
Failure to open the diagnostic logs database should not disable thread storage or database-only history listing. Thread deletion must still preserve saved conversations when diagnostic log cleanup cannot complete.
## What changed
- Allow state initialization to continue after non-corruption errors opening the logs database, while preserving corruption recovery.
- Report the original diagnostic database error after tracing is installed in the TUI and app server, and return it from log operations.
- Reject thread deletion before destructive cleanup when diagnostic storage failed to initialize.
- Continue periodic cleanup of legacy logs when the current logs database is unavailable.
## Testing
Extend coverage for unavailable log directories, database-only history listing, startup diagnostics, deletion preserving saved conversations, corrupt log headers, and periodic legacy log cleanup during a diagnostic storage outage.
GitOrigin-RevId: a5184580ae6c39ed0c4eefa8cb48ee7731a991c3
## What changed
Submit asynchronous question answers through Cloud's start-or-steer admission path when a turn is running, and use start-if-idle submission otherwise. Resolve the submission intent against the session mode so local and remote sessions retain their existing behavior.
Apply normal message admission handling to Cloud answers, clearing accepted replies and restoring rejected replies to the composer.
## Testing
Add a regression test covering accepted and rejected Cloud question replies, including the submitted answer and client message ID, composer state, and absence of extra requests.
GitOrigin-RevId: 757556e8a11bc148a92cde8ca05fe06aa291ee2c
## Why
Approved filesystem access should make executor skills discoverable and readable for the lifetime of the grant. Turn-scoped access must not authorize persistent plugin servers or hooks, or bypass disabled-plugin policy.
## What changed
- Apply environment-specific session grants to capability discovery and refresh MCP after session grants change.
- Use a separate discovery inventory for skills with turn-scoped grants, keeping plugin servers and hooks on the session inventory. Reuse discovery results across unchanged model steps.
- Preserve disabled-plugin checks for unreadable manifests and symlinked manifest files or directories, including ancestor markers, while retaining standalone skill roots.
## Testing
Add coverage for V1 and V2 skill discovery before approval, after approval, and on the next turn; disabled-plugin ownership checks; discovery cache reuse; and session hooks surviving turn-scoped discovery failure.
GitOrigin-RevId: 929a7f8cb01f4bcfb4bee2c50ae02cd762066b2d
## Why
The macOS clipboard reader requests TIFF even when PNG or JPEG data is available, causing clipboard owners to generate a large TIFF just for a paste. Pasted image files also need their orientation metadata applied before encoding attachments.
## What changed
- Read native macOS pasteboard representations before falling back to `arboard`, preferring PNG within each item while respecting item order and JPEG/TIFF ordering.
- Keep copied image files ahead of clipboard previews and apply orientation metadata when decoding files and native PNG/JPEG data.
- Share orientation-aware decoding with transcript thumbnails while preserving allocation limits.
## Testing
Add tests for pasteboard item ordering, all EXIF orientations in PNG and JPEG images, and rejection of images exceeding the allocation budget.
GitOrigin-RevId: 088f37a3205e49c805a09a84bbbb00b74dd6cb78
## What changed
Update `openssl` from `0.10.75` to `0.10.82` and `openssl-sys` from
`0.9.111` to `0.9.118` in `codex-rs/Cargo.lock` and `MODULE.bazel.lock`.
GitOrigin-RevId: ec77f18ccdcec89a17c390672b42f3f99d09a1c5