## 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
## Why
A pending realtime connection handshake can hold up subsequent attachment requests. Callers need to cancel obsolete attempts or limit how long they may take to establish a connection.
## What changed
- Add `RealtimeAttachmentOptions` with an optional cancellation receiver and `start_before` deadline to `Op::RealtimeConversationAttach`.
- Interrupt pending connection work and finish cleanup before acknowledging cancellation. Reject cancelled or expired requests before replacing an existing conversation, and recheck cancellation and the deadline before publishing a connection.
- Preserve a successfully published connection when cancellation arrives later. Dropping a cancellation sender whose value is `false` lets the attempt continue.
- Prepare the daemon startup test's socket directory with `codex_uds::prepare_private_socket_directory`.
## Testing
Add integration coverage for cancelling a held handshake, skipping cancelled or expired queued requests, preserving the next usable call, and releasing a pending handshake when its deadline expires without a cancellation receiver.
GitOrigin-RevId: 7144c1237bcbe3b859f10b654d919ae9ff20cbbb
## Why
Account changes during asynchronous request setup can invalidate the credentials selected for a generation request.
## What changed
- Restart HTTP request setup if the auth owner changes during the budget check.
- Validate the WebSocket connection's retained auth owner with `AuthOwner::is_current()` after budget checks.
## Testing
Add regression coverage for account switches during HTTP budget checks and external credential changes before WebSocket request setup, in both dual-header and assertion-only runtime auth modes.
GitOrigin-RevId: 7a1e1475a40aa2d34cd94f60f729ad697f3f7028
## Why
The rate-limit model switch prompt can remain visible after account usage falls below the warning threshold.
## What changed
Use fresh account usage reads to clear pending prompts when all reported usage windows fall below 90%. If the prompt is already visible, replace it with a recovery notice that counts down for five seconds before dismissing. Users can also dismiss the notice with Enter or Esc.
Ignore stale account reads when detecting recovery and preserve the recovery state when backend banners replace the prompt.
## Testing
Add regression tests and a snapshot covering pending prompt cancellation, stale reads, the recovery notice countdown, automatic dismissal, and manual dismissal with Enter or Esc.
GitOrigin-RevId: 9408f7cc7b49c52535f00d8a476f208fe4872bdf
## Why
An error recorded before a turn starts can cause a successful turn to be reported as failed.
## What changed
Reset `TurnSummary` on `TurnStarted`, preserving the new turn's `started_at` timestamp while clearing accumulated errors, command start times, and the last agent message.
## Testing
Extend turn completion tests to cover clearing an error recorded before turn start and retaining an error recorded during the turn.
GitOrigin-RevId: 19989b55d20df7b9a265bd0a1dfb3f00b6e8a9c5
## Why
Matching API workload identity metadata alone can preserve a credential source across session-family or provider and mapping revision changes.
## What changed
- Compare API workload identity tokens using OAuth source claims so ordinary token refreshes preserve the source while session or identity changes retire it.
- Include `wif_runtime_authorization_version`, `wif_provider_revision`, and `wif_mapping_revision` in source comparisons.
- Reject API workload identity exchange tokens without parseable source claims and nonempty `iss` and `session_id` values. Evict rejected credentials so a subsequent resolve exchanges them again.
## Testing
Add regression coverage for refresh continuity, session-family and revision changes, and rejection and re-exchange of tokens with missing, empty, or whitespace-only `session_id` values.
GitOrigin-RevId: 67189c27efae8a233250a320e6d4fac71d865e90
## Why
SQLite 3.54 fixes `RUSTSEC-2026-0459` when opening a database with a WAL, while retaining the WAL-reset corruption fix.
## What changed
- Upgrade `libsqlite3-sys` to `0.39.1` and require SQLite 3.54 or newer with a compile-time assertion in `codex-state`.
- Pin `sqlx-core` and `sqlx-sqlite` to the same upstream revision that supports the newer SQLite dependency, and allow that Git source in `cargo-deny`.
- Refresh the Cargo and Bazel lockfiles.
GitOrigin-RevId: 768224af79de9b71b21d14912ff01a1176ad37c3
## Why
Aggregate resource listings omitted dormant MCP servers, leaving callers without their names for explicit queries.
## What changed
Include a sorted `deferredServers` list in aggregate `list_mcp_resources` and `list_mcp_resource_templates` results alongside resources from ready servers. Apply the listing filters to deferred servers and omit the field when empty. Discovery leaves dormant servers unstarted; callers can query them by passing `server` explicitly.
## Testing
Extend the resource discovery scenario for direct calls and Code Mode to verify deferred server names, confirm discovery leaves the server unstarted, and then list and read resources by server name.
GitOrigin-RevId: f95b8beb64bb1329f4ae3245e8c375614fcb3360
## Why
Background terminals kept the terminal program status at `Working` after a turn completed, preventing it from reporting `Done` or returning to `Idle` when acknowledged.
## What changed
Stop treating running background processes as active work when computing terminal program status. Background terminals remain visible in the TUI while the status follows the turn lifecycle.
## Testing
Update the lifecycle regression test to complete a turn with a background terminal still running and assert the `Done` → `Idle` transition on acknowledgment.
GitOrigin-RevId: cb995947e6868d6128736a621f268ebfe3891eec
## Why
URLs in fullscreen Markdown transcripts could split across rows even when the full URL would fit on its own row.
## What changed
Mark non-code Markdown lines containing URL-like text with the `UrlAware` wrap policy so transcript layout preserves fitting URLs on a single row.
## Testing
Add a regression snapshot showing a documentation URL moving intact to the next row after introductory text. Update the conversation snapshot and copy-on-select test dimensions for the changed wrapping.
GitOrigin-RevId: 4812c83483cff412406a71ae6745977c5384c7da
## Why
Custom providers with gateway OAuth and an explicit model catalog should be able to discover models without an API key or API key model discovery enabled.
## What changed
- Enable catalog refreshes for custom gateway providers when `model_catalog_url` and `base_url` have the same origin.
- Reuse gateway credentials without starting an interactive login during catalog refreshes.
- Keep an unrelated saved API key from making gateway catalog discovery depend on the API key discovery setting.
## Testing
Add an app-server test for discovering a gateway catalog after OAuth login with no API key. Update coverage for catalog invalidation after gateway credentials require login, including across manager restarts, with API key discovery disabled.
GitOrigin-RevId: b133c428cb45a9037e4b2ef13ff2f9473ed96636
## What changed
Simplify the post-denial rule in the Guardian policy template: user re-approval after seeing the concrete risk sets `user_authorization` to `high`. Remove repeated qualifiers about explicit approval of the exact action and certainty that approval came from the user; the authorization scoring guidance still covers those requirements.
Update the Guardian extra-policy review snapshot to match the revised prompt.
GitOrigin-RevId: 63643222e8f9c46c9d902ac8f5d1e11d24fafe9c
## What changed
Add experimental `deferOutput.mcpToolCall` support to `thread/items/list` requests scoped to a `turnId`. Successful, completed MCP calls with nonempty, unannotated plain-text results can return empty `result.content` with `outputDeferred: true`. Clients can retrieve the saved output through `thread/items/read`; connector identity remains on the listed item.
Keep rich results, JSON or fenced text, app UI results, and built-in `codex_app` results inline. Preserve plain-text output when creating bounded previews of oversized MCP results so those previews remain eligible for deferral. Reads return the saved preview when output exceeds the 64 KiB history limit.
## Testing
Extend thread history integration coverage for independent and combined command/MCP deferral, experimental capability gating, excluded result types, connector identity, oversized previews, and retrieval of deferred items.
GitOrigin-RevId: 5c160b30a4eac2a9b70e3fa65b6dbd83e935338b
## What changed
Set `plugins_mcp.product_sku` to `"codex"` in cloud thread prewarm requests for both default environments and selected projects.
## Testing
Update request payload assertions to verify the Codex plugins configuration alongside managed environment defaults, model overrides, and deferred project readiness.
GitOrigin-RevId: c4ab95aa8e3440c816c5cd136444a038f4532eb9
## What changed
- Pass goal objectives as untrusted `goal_objective` context instead of embedding them in continuation instructions. Direct the model to use `get_goal` if the objective is missing or truncated.
- Inject newly created objectives into their originating active turn without dropping unrelated client context. Render them as tool outputs when `UntrustedAsToolOutput` is enabled.
- Queue additional context together with automatic turn input so both reach the first model request.
## Testing
Extend app-server coverage to verify that model-written objectives appear as tool outputs at creation and continuation, without duplicating them in user messages. Update steering and Python SDK tests to check objective preservation and delivery alongside continuation instructions.
GitOrigin-RevId: 6f44f6d6c895bb4dc378c9cf84d6470ccc885c67
## Why
After Cloud thread history is replayed in the TUI, notifications for the same completed assistant items can render their text again.
## What changed
Track completed assistant items rendered from Cloud history by turn and item ID, and ignore subsequent starts, text deltas, and completions for those items. Apply this tracking when resuming threads and replaying thread snapshots, while allowing unfinished items and new turns to continue streaming.
## Testing
Extend the Cloud resume picker test to cover repeated notifications for completed messages, continued streaming in an active turn, and responses in a later turn. Retain coverage for queued user message reconciliation without resubmission.
GitOrigin-RevId: 1a829a2964586d876339c7c759022e4d366c8b2e
## Why
A queued cloud stream disconnect can outlive a successful reopen of the same conversation, causing an obsolete reconnect error to reach the TUI.
## What changed
Represent cloud reply stream losses with `AppServerEvent::ThreadStreamDisconnected` and filter queued losses superseded by a successful attachment to the same thread. Preserve losses for other threads and any newer disconnects; failed reopen attempts do not supersede pending losses.
Continue displaying current stream disconnects through the TUI's error notification handler.
## Testing
Add regression coverage for successful and failed reopens, disconnect ordering across threads, and TUI handling of disconnect events from the active and foreign backends.
GitOrigin-RevId: 640332b817970717fc816ab5a32bf658c01233bf
## Why
Failed Cloud turns can contain an error without any items. Loading history through item pages alone can omit these older failures from the full transcript.
## What changed
- Add a `FullTranscript` hydration scope that fetches remaining Cloud turn metadata in pages of 100 after loading items.
- Deduplicate overlapping turn pages while preserving chronological order and already loaded items.
- Use the new scope for session transcripts while retaining `Complete` hydration for exports.
## Testing
Add a regression test covering older itemless failures, overlapping turn pages, repeated pagination cursors, transcript ordering, and item-only exports.
GitOrigin-RevId: 51183e35984aa0183d044061768555bb6f5d1189
## What changed
- Show latest user-prompt previews beneath saved side-chat titles, fetching previews only for visible entries when the chooser refreshes.
- Keep cached chats available during discovery, show loading and refresh status, and offer an inline retry action on failure.
- Preserve the selected chat across list updates and prevent asynchronous changes or held activation keys from opening an unintended entry. Account for preview rows in paging and mouse selection.
- Explain that side chats become available after the first main-chat message, and let `Ctrl+C` dismiss the chooser while preserving the main draft.
- Separate tabs with noninteractive gaps and improve hover styling for tabs, overflow arrows, and the add button.
## Testing
Extend integration tests and snapshots for discovery failures and retries, refreshed prompt previews, activation guards, variable-height paging, draft preservation, and tab hover states across light, dark, and fallback colors.
GitOrigin-RevId: 34423f5aeccb566682f7aa219f54ca5c7c8304fb
## What changed
Set `deferred_environment` to `true` in cloud thread prewarm requests when a project is selected. Omit the field for default thread prewarming.
## Testing
Update the prewarm request encoding test to verify that only requests with a selected project include the deferred readiness flag.
GitOrigin-RevId: e10a646ebde9cc3acbdb01b304af0f73ecc1dbeb
## Why
Command center search only filtered tasks already loaded for browsing, leaving older tasks undiscoverable without manually loading more history.
## What changed
- Scan history on the active backend for case-insensitive matches in task names, previews, and working directories, using a separate paging cursor for each query.
- Add loading, retry, and `Show more matches` states. Cancel superseded searches and ignore stale results.
- Keep history matches separate from browse results and restore the previous selection when leaving search.
- Preserve the original task preview for search while displaying the latest prompt in task details.
## Testing
Extend discovery and command center tests to cover older history matches, fresh queries after browse pagination is exhausted, selection restoration, actions on search results, loading and retry states, and separate original previews and latest prompts.
GitOrigin-RevId: 9864ee006a14bd232e9cfd7ab2ee099c84667597
## Why
Clients attaching to a shared app server can miss startup notifications and have a different local MCP configuration. Waiting for locally configured servers can leave the TUI stuck in a busy state.
## What changed
- Track only reported MCP servers for shared app servers and subagents, settling startup once observed starts complete.
- Handle standalone terminal updates without reopening startup, while reporting failures and cancellations even when their starts were missed.
- Suppress duplicate diagnostics until an observed retry or notification lag, and include all received outcomes in each active round's summary.
## Testing
Add regression coverage for attachment before, during, and after startup; idle keyboard behavior after startup settles; terminal-only failures and cancellations; and repeated failures after retries or notification lag.
GitOrigin-RevId: e19f23c212f2f3cee1adeb5c3b94a508aa599242
## What changed
Only allow the cancel action to dismiss the agents overview when a chat is displayed or a startup thread is pending. Hide the `esc back` footer hint when there is no chat to return to, while retaining back hints for help and metadata editing.
## Testing
Add coverage for returning to a chat that is still starting and for pressing Escape in the overview after cancelling folder trust. Update snapshots and test setup to reflect whether a chat is available.
GitOrigin-RevId: af259330eb2a743fde449bbbd47c7f0eb6fa937e
## What changed
Show a startup warning when the active model matches the CLI model override but is missing from the ChatGPT model list, for ChatGPT accounts using the OpenAI provider. Suggest checking the spelling or choosing another model with `/model`, while preserving the selected model and submitting queued startup input.
Reuse the transcript-visible warning helper for this notice and existing usage warnings.
## Testing
Extend the startup test to check the warning text, preserved model selection, and queued input submission.
GitOrigin-RevId: bb1e8c415346bf271e25ef4e8571c13b4bc2c8c8
## What changed
- Add `CodexThread::agent_tree_id()` to identify a loaded agent tree. The root and native children share an ID; loading a new tree produces a new ID even when reusing a persisted thread ID.
- Add `EnvironmentManager::remove_environment()` to unregister an environment while preserving existing handles and the default environment ID.
## Testing
Extend tests to check tree IDs across child creation, forks, warm reuse, and cold reloads, and to verify environment removal and re-registration.
GitOrigin-RevId: 43944ed6766374508d9862cd5d333bc4cb67c338
## What changed
Add `exec_tools_update_hint` and `exec_tools_removed_definitions_header` to `model_messages.tools.incremental_tools` and use them when rendering Code Mode catalog updates and removals.
Overrides are literal strings limited to 512 UTF-8 bytes per field. Missing, null, or oversized values use the existing bundled wording. Empty strings omit the guidance while retaining changed definitions and removal keys. Wording changes alone do not trigger catalog updates.
## Testing
Extend unit coverage for defaults, null fields, independent fallback, and UTF-8 byte limits. Add scenario assertions and a snapshot covering custom and empty wording, model switches, catalog changes, and restoration after compaction.
GitOrigin-RevId: da9e00fdb5197a2b5fa39ce533ba87c76ff3e82c