## 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
## Why
Custom-provider sign-in previously required a saved gateway configuration and stopped at an error when none existed.
## What changed
- Add “Create a custom provider or gateway” to the sign-in picker, reusing the settings form and provider-write handling.
- Return to the picker after saving, highlight the new provider, and require explicit selection before setting it as the default and completing sign-in.
- Preserve entered fields after validation failures and keep the focused field or Save action visible in short terminals.
- Use consistent custom-provider and gateway wording across sign-in, settings, and validation messages.
## Testing
Add onboarding tests and snapshots for an empty picker, creation, validation retries, short-terminal rendering, and explicit default selection. Extend app-server coverage for rejecting the reserved `ollama-chat` provider ID.
GitOrigin-RevId: 339ac5807c5eecdae08df4dbd89874ea7c764d35
## What changed
- Add configurable `sidebar_up` and `sidebar_down` actions to cycle through tabs with wraparound while the sidebar has focus. Default leader shortcuts use `Shift-Tab` / `Tab`, `Up` / `Down`, and `k` / `j`.
- Support mouse-wheel tab switching over the tab strip and clickable overflow arrows when tabs do not fit.
- Show previous/next tab shortcuts in the leader HUD and keymap picker, and preserve pane zoom when switching tabs.
## Testing
Extend sidebar interaction tests and snapshots to cover overflow arrows, mouse-wheel navigation, leader shortcuts, repeated custom bindings, draft preservation, and scroll handling where the leader HUD overlaps the tab strip.
GitOrigin-RevId: 39ccb40f40560d1be850397f9597e765caa996a3
## Why
Skill completion inserts a trailing space, leaving unwanted whitespace when the next typed character is punctuation, such as `$rustdoc ,`.
## What changed
Replace the space inserted by skill completion when immediately followed by common closing punctuation, producing `$rustdoc,` instead. Support both skill mention pickers, including full-width punctuation and `》`, while preserving skill bindings.
Preserve existing draft whitespace and keep the separator for pasted text or punctuation entered after cursor navigation. Classify buffered punctuation as typing or a paste burst before deciding whether to remove the space.
## Testing
Add regression tests for punctuation, existing spacing, cursor navigation, and paste bursts, plus a snapshot covering `》`, recovery state, and preserved skill bindings.
GitOrigin-RevId: 8988add8092e8cb5f0618ef834590d52a81ad576
## What changed
Count tool and namespace-instruction entry deltas in `codex.tools.exec_entry_updates`, tagged by `added`, `schema_changed`, or `removed`. Entry replacements count as `schema_changed`; full catalog declarations do not count as entry deltas.
Record rendered UTF-8 batch sizes in `codex.tools.exec_update_bytes`, including hints and framing but excluding full declarations and removal notices.
## Testing
Extend the namespace transition test to verify action counts, UTF-8 byte totals, and metric behavior when exec is hidden, restored, or unchanged.
GitOrigin-RevId: 22070b84230296d78a67b83641cbc02157d84419
## What changed
- Cover incremental exec tool settings and catalog changes across resume, fork, tool mode switches, and compaction.
- Verify that adopting background compaction preserves live exec declarations, tool metadata updates, and retained conversation order after a model catalog refresh.
- Include an `exec` namespace in the top-level tool catalog ordering and snapshot round-trip test.
GitOrigin-RevId: 3df603b98a006abb55a5095b299080f036576242
## Why
Recovered answer history needs presentation instructions alongside the moderation flag so clients can apply the intended display behavior.
## What changed
- Add optional `display` metadata with an `action` and optional `blockType`, `cyberTrustedAccess`, and `checkTrustedContacts` fields.
- Carry display metadata through final answers, legacy events, thread history reconstruction, and legacy rollout migration.
- Expose the metadata in the app-server protocol and update generated JSON schemas, TypeScript types, and Python SDK models. Missing display fields remain compatible with existing stored moderation data; the app-server emits absent optional values as `null`.
## Testing
Extend the final-answer moderation test to cover display metadata in answer items and legacy events. Add serialization coverage for missing display data, nullable fields, and preservation of an explicit `false` value.
GitOrigin-RevId: b798a2ecc53c2a94c7659ef3d9663b3143b70a1a
## Why
Changes to nested tools should update the model's catalog without repeating the full `functions.exec` declaration or rewriting retained context.
## What changed
Pass structured exec definitions through the tool router into the session's tool world state. Enable granular updates for Responses Lite in `CodeModeOnly` when both `IncrementalTools` and `IncrementalExecTools` are enabled.
Append changed tool definitions, namespace instructions, and removals as developer messages. Keep common exec instructions and shared types frozen until compaction, then install the latest full catalog.
## Testing
Add feature-gating coverage and a scenario snapshot covering tool additions and removals, namespace instruction changes, eager/deferred transitions, re-enabling tools, retained context, and catalog restoration after compaction.
GitOrigin-RevId: bbf850d4e5018388eeb4c09345d885d776962e09
## What changed
Render stable entries for nested tool definitions and namespace instructions alongside the full `functions.exec` description. Add optional catalog tracking that emits complete replacements for added or changed entries and explicit notices for removed entries, while keeping the existing exec declaration unchanged.
Preserve entry hashes while exec is unavailable, then restore the full catalog and withdraw removed entries when it returns. Keep the existing snapshot format for ordinary tool catalogs.
This change provides the rendering and state support; runtime activation remains disabled.
## Testing
Add tests for definition rendering and namespace identity, batched additions and changes, removal notices, unchanged catalogs, and full catalog restoration after exec is hidden.
GitOrigin-RevId: f472bd3e8e770a8cad9663c72e290abe7d0473be
## What changed
- Save side chats as attachments to their parent conversation when local workspace history supports them, and let users reopen them from the sidebar after a restart.
- Show chat names or first-prompt previews in sidebar labels, and allow saved side chats to be renamed with `/rename`.
- Add tab close buttons, middle-click closing, and the configurable `close_sidebar_tab` shortcut, defaulting to `Ctrl-X W`. Closing a saved chat keeps it available in the picker; archiving removes it from Side chats.
- Confirm actions that stop running work, discard unsent input, or lose temporary history. Delete saved TUI side chats when deleting their parent conversation.
## Testing
Add coverage for reopening saved side chats after restart, archive handling, close confirmations, and preventing close-confirmation keys from accepting a replacement approval dialog.
GitOrigin-RevId: 3d47533d007286a7354660c08df13a83dd48d5d7