## What changed
Add the disabled-by-default `guardian_recorded_items` feature to forward recorded reviewer items and interruptions through the parent's raw-event subscription, preserving reviewer thread and turn IDs without modifying the parent's history or completing its turn.
Emit reviewer items as `rawResponseItem/completed` notifications and interruptions as interrupted `turn/completed` notifications. Mark opted-in reviewer requests with `guardian_recorded_items` metadata.
## Testing
Extend Guardian integration tests to cover reviewer identity, recorded-item metadata replay, concurrent reviewer interruptions, independent parent completion, and behavior without the feature enabled.
GitOrigin-RevId: beb4dbf6c6f2a800a2fbf3cfd11ae174a1382386
## Why
Local administrators need to require managed configuration from a specific customer-hosted server before a session can start.
## What changed
- Add a local managed `config_server` requirement with an HTTPS base URL and optional OAuth settings. Validate endpoints and derive the bundle route as `codex/config/bundle` beneath the base URL.
- Replace the entire `config_server` block when a higher-priority requirements layer supplies one, keeping the endpoint and OAuth settings together. Reject this setting in fetched policy.
- Track the applied server through configuration snapshots, role overrides, and refreshes. Reject session startup and managed refreshes when the applied server does not match the requirement; user refreshes retain the session's managed configuration.
## Testing
Add coverage for missing, mismatched, and matching server configuration at session startup, whole-block replacement, rejection of server settings in fetched policy, and preservation across role overrides and refreshes.
GitOrigin-RevId: 51e8a1738dabdb117ae858120f6fb09ae2ff1261
## Why
Enterprise-managed MCP authentication previously required public OAuth clients at both the identity provider and the MCP authorization server, preventing use of registrations that require client secrets.
## What changed
- Accept separate `client_secret` and `token_endpoint_auth_method` settings for the enterprise IdP and MCP server OAuth registration. Support `client_secret_basic` and `client_secret_post`, defaulting to Basic when a secret is configured.
- Validate the registered method against server metadata and use it for enterprise login and both ID-JAG exchanges.
- Require a configured `oauth.authorization_server_issuer` for confidential MCP registrations and reject empty secrets or authentication methods without secrets.
- Require the account OAuth client to match the configured IdP client before reusing an account grant with a provisioned secret; otherwise use dedicated enterprise login.
## Testing
Extend configuration, login, exchange, and app-server lifecycle tests to cover confidential registrations, separate IdP and resource credentials, authentication method validation, and exclusion of client secrets from authorization URLs, stored login grants, and logs.
GitOrigin-RevId: b3be378c2b1bb67e6a3652c648e72fd2e21e956d
## What changed
- Store `logs_2.sqlite` in `log_dir` when explicitly configured, unless a managed `sqlite_home` requirement applies. Keep other databases in `sqlite_home` and preserve the existing SQLite log location when `log_dir` is unset.
- Initialize and lock the selected log directory only when opening its database, so an unavailable directory does not prevent authentication commands from loading configuration. Share the cleanup lock across configuration clones and allow failed initialization to be retried.
- Leave existing logs in place. Read legacy logs for diagnostic submissions when the current query returns no logs, attaching them as `codex-logs-legacy.log`. Continue retention cleanup and page reclamation for both locations, with independent maintenance locks and filesystem checks.
## Testing
Add coverage for configuration routing and managed requirements, deferred initialization and lock lifetimes, authentication with an unavailable log directory, legacy log attachments, and cleanup of current and legacy databases.
GitOrigin-RevId: 48216694596d738eff1b3c5eef6c4e7ada6d0137
## What changed
- Add `application.storage.default_project_parent` and `application.storage.projectless_workspace_root` requirements for new Desktop workspaces. Require absolute paths and reject unknown storage keys.
- Apply managed paths to `desktop.defaultProjectParent` and `desktop.projectlessWorkspaceRoot`, overriding local preferences and rejecting writes to managed settings or their containing table while preserving unrelated Desktop settings.
- Expose storage requirements through `config/requirements/read` and update generated JSON schemas, TypeScript types, and Python models.
## Testing
Add coverage for storage validation, per-setting layer precedence, config overrides, write protection, and requirements API responses. Adjust daemon shutdown test deadlines and TUI test synchronization, paste handling, and future allocation.
GitOrigin-RevId: 44b93fe69e6a471c3f485cbf5f9c9ebd34ac3234
## Why
Installed-plugin inventory fetches could keep following pagination cursors
without an overall bound, delaying release of the plugin mutation gate.
## What changed
- Limit each inventory fetch to 60 seconds and 100 pages, and reject repeated
pagination cursors.
- Request 200 items per page for scoped inventory fetches as well as all-scope
fetches.
- Report overall fetch timeouts as `remote_catalog_timeout`.
## Testing
Add coverage for cursor cycles, completion at the page limit, and overall
timeout cancellation after successful pages. Verify that failed pagination
preserves the cached inventory and plugin files and releases the mutation gate.
GitOrigin-RevId: e8429dd804581041d102defa9d19db02bcb1739b
## What changed
Add a save RPC that accepts the existing report options and an absolute `savePath` on the server host. Save the report, selected attachments, and a manifest without uploading, and return `savedPath`, `threadId`, and `promptHash`. Local exports remain available when uploads are disabled by configuration.
Publish archives atomically without replacing existing files. Bound uncompressed contents to 200 MiB and attachments to 128, preserve duplicate attachment names safely, and fail without publishing a partial ZIP when a selected file cannot be read. Honor `includeLogs` and omit automatic rollouts for untouched threads without materializing them.
Update protocol schemas and generated TypeScript and Python types.
## Testing
Add coverage for local-only saves, disabled uploads, path validation, overwrite protection, log consent, archive budgets, duplicate names, missing files, and rollout selection before materialization and after writer shutdown.
GitOrigin-RevId: 222c0fe7ab923904de9c8a9f12ad27f7a0104875
## Why
Resuming a thread can replace saved model settings with global defaults. A selected service tier can also be lost when the current model does not support it.
## What changed
- Restore saved service tier, reasoning summary, and personality on resume unless the caller explicitly overrides them, respecting thread ownership of settings snapshots.
- Retain the selected service tier for persistence, settings notifications, and resume comparisons while filtering the effective tier against the current model's capabilities.
- Carry the runtime model, service tier, and personality into thread revert reconstruction.
- Persist initial thread settings before user input during MCP startup so an interrupted first turn retains its settings checkpoint.
## Testing
Extend regression coverage for cold resume and explicit overrides, unsupported service tiers, settings preservation during revert, and settings checkpoints before user input when MCP startup is interrupted.
GitOrigin-RevId: e5ec012a5678048c5eedd443e524f38c142bf9fd
## What changed
- Prefer an eligible account grant over saved enterprise credentials, with a fallback to saved enterprise sign-in during initial connection if the account grant is rejected.
- Remember rejected account grants per enterprise MCP registration across threads and report authentication failures as requiring reauthentication. Keep administrator configuration errors distinct from sign-in failures.
- Compare account grants independently of access and ID token rotation, recheck the latest identity eligibility after exchange, and retry once when the refresh grant changes.
- Make MCP authentication status reflect usable account grants, saved enterprise credentials, and completed connection failures.
## Testing
Extend regression coverage for enterprise sign-in failures and recovery, MCP authentication status, account grant identity across token refreshes, and retries after transient credential failures.
GitOrigin-RevId: eeac65f668d5d2d55e9d8bf4547fbcbdd6a6c42d
## What changed
Store `RolloutItem::SessionMeta` and `RolloutItem::Compacted` payloads in `Box` values and update their producers, consumers, and test fixtures. Preserve the existing serialized rollout format.
GitOrigin-RevId: 59fcc4beb47d23160872dcb6e95ace9b142d3d11
## Why
Configuration reloads must cancel stale enterprise MCP startups while preserving access for running threads that still pass validation. Replacing a runtime during `thread/revert` must also leave the replacement able to use enterprise tools.
## What changed
- Separate pending startup cancellation from published thread lifetimes, with independent startup state for forks and replacement runtimes.
- Retain eligible enterprise MCP connections across refreshes and explicit reconnects while applying updated tool restrictions and approvals. Do not create replacement enterprise connections after initial startup.
- Revoke enterprise authorization when a thread is removed, drain requests when access is disabled, and revoke a connection's authority when token renewal requires authentication.
## Testing
Extend regression coverage to verify enterprise tool calls survive `thread/revert`, inherited fork configurations are cancelled after a reload, and enterprise calls fail after logout while ordinary MCP calls remain available.
GitOrigin-RevId: 2d634be3011854b57f73c741bd1ec6b5aed94ee5
## Why
A persisted login replacement can leave the auth cache holding the previous login, even for the same account. Enterprise MCP authorization must detect that replacement before continuing to use enterprise credentials.
## What changed
- Check cached and persisted account login ownership before enterprise MCP connections and around token exchanges, revoking authorization when ownership changes.
- Recheck account ownership and login generation before committing enterprise sign-in credentials.
- Compare complete token data when checking whether an account OAuth grant is still current, and expose grant token access and credential comparison helpers.
## Testing
Add regression coverage for detecting a same-account login replacement without updating cached auth, rejecting enterprise MCP use after replacement, and keeping ordinary MCP usable while an enterprise account storage read is blocked.
GitOrigin-RevId: 6303f88a9cbcc84c99e453dc281b23d66930f518
## Why
Agent Plugin manifests previously skipped app declarations, including service-generated declarations installed with remote curated plugins. This prevented those plugins from using app routing and suppressing matching direct MCP connections.
## What changed
- Recognize app declarations for Agent Plugins from `openai-curated-remote` across loading, capability summaries, plugin details, tool suggestions, and install authentication.
- Apply app routing to suppress same-name MCP servers when an app route is available. Keep unrelated MCP servers available and preserve direct MCP access in API-key mode.
- Keep app declarations inactive for Agent Plugins from other marketplaces.
## Testing
Add coverage for marketplace and authentication routing, service-generated app declarations during installation with both manifest formats, and app tools reaching turns. Verify that disabling Apps does not restore matching direct MCP connections.
GitOrigin-RevId: 791739569f0e01c898040bc2d028cf517f767e00
## What changed
Add `experimentalDisablePredictionMcp` to `thread/fork` and `disableMcp` to `thread/sample`. Disable MCP servers when requested and the inherited history contains incremental tools on Responses Lite. The fork option requires `experimentalPredictionMode: true`.
Apply disablement through a thread-local policy that excludes configured MCP servers and runtime contributions, including after MCP refresh. Preserve the inherited history prefix and append tool-removal instructions without changing the parent's tools.
## Testing
Add coverage for prediction forks with legacy and paginated history, flag validation, conditional disablement, MCP refresh, and sample/fork request parity. Add a request-history snapshot covering preserved history, tool removal across child turns, and unchanged parent tools.
GitOrigin-RevId: e31d602480e6550ed130d8152f538b8668280fa0
## What changed
Add the experimental `thread/sample/cancel` request with a `requestId` identifying a `thread/sample` request on the same connection. Cancellation returns an empty response, stops the matching sample with `sample canceled`, and cleans up its ephemeral fork. Repeated cancellation and unknown request IDs are harmless no-ops; other request types are unaffected.
## Testing
Add coverage for connection and request ID isolation, request type filtering, and repeated cancellation. Extend the sample integration test to verify cancellation keeps the parent responsive and reclaims the child thread.
GitOrigin-RevId: 92d12e5c0190e1d3b06cb482543615a3ec77bdc8
## Why
Enterprise-managed MCP authentication requires the thread's admitted connection. Bulk `mcpServerStatus/list` requests need to use that connection to report the enterprise server's catalog consistently with single-server requests.
## What changed
- Read enterprise server metadata from the thread runtime when listing all MCP servers, preserving ordinary server discovery.
- Check the expected server registration before discovery so edited or disabled registrations cannot reuse an old connection's catalog.
## Testing
Add coverage for bulk and single-server status consistency, catalog metadata, and registration changes. Extend enterprise authentication lifecycle tests to cover bearer renewal, grant replacement, and logout during a pending exchange. Add a scenario asserting that enterprise sign-in failure preserves ordinary MCP tool schemas, calls, and model history.
GitOrigin-RevId: 3bf3bd672511d0c753cd95ec777892f72bd6eb89
## What changed
Add `thread/sample` to collect one model response on an ephemeral fork that inherits a loaded thread's context and configuration. Return the source turn ID, response ID, assistant text, and available token usage without modifying the source conversation.
Require an idle, persistent root thread and an `expectedTurnId` matching its latest completed turn. Reject results if the source history changes during sampling. Keep the parent responsive while sampling, hide sample forks from `thread/loaded/list`, and reclaim them after completion or timeout.
Intercept responses before tool execution or Stop hooks can run, returning null text for tool calls or responses without text. Apply optional reasoning-effort updates only when the provider and model support cache-preserving updates.
## Testing
Add integration coverage for inherited context and reasoning effort, source preservation, tool and Stop hook suppression, invalid requests, stream errors, parent responsiveness, and timeout cleanup.
GitOrigin-RevId: 08f4867e53ec7f6c8f4428d5542eeea4e6dadd0b
## What changed
- Connect directly configured MCP servers using account-scoped enterprise grants stored in the keyring, with token exchange and authenticated HTTP requests.
- Retain authorization for the thread across MCP refreshes and revoke it when the account owner changes, cloud configuration becomes invalid, or an enterprise login replaces the grant.
- Negotiate the enterprise-managed authorization extension with the `2026-07-28` protocol, bypass shared tool catalog caching for enterprise servers, and report credential status with enterprise sign-in guidance.
GitOrigin-RevId: c0f96d37194212758a211ae6a4107205df96df26
## What changed
Add `codex app-server --print-startup-config` to validate local and cloud-backed configuration and emit the app-server version and configuration requirements as JSON without initializing environments, thread storage, or plugins. Configuration failures produce structured JSON errors and a nonzero exit status.
Support `--startup-sign-out` to remove account credentials and reload signed-out requirements, including recovery when cloud policy is unavailable. Reject sign-out for host-owned external authentication. Accept `--startup-client-info` to identify configuration and authentication requests.
Reuse configuration loading and account cleanup logic between startup discovery and the running app server.
## Testing
Add CLI integration coverage for configuration validation, project login restrictions, managed cloud requirements and failures, sign-out recovery, external authentication protection, and independence from locked or invalid history databases.
GitOrigin-RevId: 636ccb095b684b6136cf9e408f3f8613cb776e16
## Why
Configuration loading can finish before a pending startup is visible to the thread manager. Reloads need a cancellation scope that also covers these configuration snapshots.
## What changed
- Capture an enterprise managed authentication (EMA) cancellation token before loading configuration and carry it through config layers, role overrides, runtime refreshes, and `McpConfig`.
- Cancel the previous scope on MCP or user configuration reloads and cloud config loader changes, then create a fresh scope for subsequent loads.
- Cancel the session's token when enterprise MCP authentication is disabled or a refresh leaves it unavailable.
## Testing
Extend the MCP reload test to verify that existing thread and pending startup tokens are cancelled while a fresh startup receives an uncancelled token.
GitOrigin-RevId: 5fc0658b74c360e7dc9ab3488339fcf19bfe9fae
Record whether an event is `ShutdownComplete` before moving it into
`apply_bespoke_event_handling`, preserving shutdown drain notification without
cloning the event.
GitOrigin-RevId: 9e4ca8c657d4d5b98056de8c7aba1391233994c1
## Why
Thread unload timing used the server-wide delay, ignoring per-thread configuration overrides. Clients need to control how long individual idle, unsubscribed threads remain loaded.
## What changed
- Resolve unload timing from each loaded thread's `thread_unload_delay_secs` configuration. Setting it to `0` allows immediate unloading once the thread has no subscribers or activity.
- Allow this runtime retention override in `experimentalPredictionMode` forks while continuing to reject other configuration overrides. Reject negative values and delays too large to schedule.
- Replace the source-specific immediate-unload behavior with explicit configuration.
## Testing
Extend integration coverage for per-thread delays, unloading after active turns finish, fork overrides, and invalid prediction-fork delays. Verify that immediate unloading preserves persistent history and that cold resumes and ordinary nested forks use their default delay instead of retaining the previous runtime's override.
GitOrigin-RevId: fcb82bd73a101260c51e2a8476f94320c23ac929
## What changed
Set the app server's unload delay to zero for ephemeral threads whose `thread_source` is `composer_predictions`, excluding subagent sessions. These threads unload once they are idle and have no subscribers, while active turns continue to completion.
## Testing
Extend integration coverage to check immediate unloading after an active prediction turn finishes and after unsubscribing from a fork that inherits the prediction configuration. Verify that persistent threads and ephemeral threads without the prediction source retain the configured delay.
GitOrigin-RevId: 04a0e405b666c689ccf6f482055d24692b18ead0
## What changed
- Add `PreModelRequest` and `PostModelRequest` hooks around model request attempts, including retries. Pass model, session, turn, and optional subagent context; report completion, failure, or cancellation with errors and token usage when available.
- Treat hook output as diagnostic data without allowing it to veto requests or alter model context. Wait for synchronous post-request hooks before dispatching tools, while asynchronous hooks allow streaming tool dispatch to continue.
- Apply memory-consolidation hook filtering and expose the new events through configuration, protocol schemas, generated clients, and the hooks browser.
## Testing
Add integration coverage for failures and retries, ignored control directives, cancellation, synchronous and asynchronous tool ordering, interrupted-turn resume and token accounting, and memory-consolidation filtering. Update hook schema fixtures and hooks browser snapshots.
GitOrigin-RevId: 6ed7b39fc8bb94cf467e350d07d97fcc729c21ce
## Why
MCP tool discovery discarded response-level `_meta`, leaving server-status clients unable to inspect metadata associated with the tool catalog.
## What changed
- Preserve opaque `_meta` from the first `tools/list` page through catalog refreshes and caches.
- Expose it as `toolListMeta` in `McpServerStatus`, with `null` when unavailable, and update generated schemas and bindings.
- Scope cached Apps catalog metadata to discovery settings, including client capabilities and extensions, while retaining tools from older caches without metadata.
- Restrict server capabilities in status snapshots to the selected servers.
## Testing
Add regression coverage for listing legacy cached Apps tools during failed startup, and update protocol serialization expectations for nullable `toolListMeta`.
GitOrigin-RevId: 62335e2fd8c482067a7a78a7612b58c3eaa9fb55
## What changed
Add `ThreadStoreError::Retryable` for transient failures known to be safe to retry and `ThreadStoreError::OutcomeUnknown` for writes that may already have committed. Recovery remains the operation owner's responsibility; neither category automatically triggers retries.
Preserve existing app-server error mappings and fatal session startup behavior, and report the new categories in shutdown diagnostics without exposing raw error payloads.
## Testing
Add coverage for conservative SQLx error classification, mutation error mappings, session initialization categories, and shutdown diagnostics that omit raw error payloads.
GitOrigin-RevId: 259a9bfaa6ff3cbfa2ee61a01a1f1e744c90f118
## Why
A plugin's scripts can change without changing its hook declaration. Declaration-only approval therefore lets changed plugin code run under an existing hook approval.
## What changed
- Fingerprint plugin bundle contents and include the content hash in the approval value returned by `hooks/list`. Persist it as `trusted_content_hash`, keeping `trusted_hash` compatible with older clients.
- Verify contents before each command or MCP hook execution, within the hook's timeout, and require renewed approval when approved contents change.
- Migrate legacy declaration-only approvals to a shared, immutable content baseline per plugin and config home.
- Exclude generated Python bytecode, `.venv`, and `.egg-info` entries from fingerprints. Run app-server hook listing on blocking tasks.
## Testing
Extend integration coverage for plugin upgrades and rollbacks requiring approval, same-turn script changes preventing further hook execution, shared legacy approval baselines, and generated Python artifacts preserving trust.
GitOrigin-RevId: faaf7658210d8adb2534ddd614c72ec993920840
## What changed
Add optional `inputImages` metadata containing each referenced local image's path and SHA-256 hash of the bytes read before normalization. Compute the hash from the same bytes used to prepare the edit request.
Preserve this metadata through completion events, persisted thread history, resume, and legacy rollout migration. Update app-server schemas and generated TypeScript and Python types; older items continue to deserialize without the field.
## Testing
Add coverage for input ordering, changed contents at the same path, unreadable or invalid references, serialization, persisted history and resume, and legacy migration.
GitOrigin-RevId: 522be8ec1e39c9b2bbe5b9ccb37ea67d17f0e21a
## What changed
- Upload generated images to the attachment store and expose `fileId` in image-generation items when available, with inline `result` fallback on upload or decoding failure.
- Preserve file references through legacy events, persisted rollouts, thread history, and task output summaries. Keep model-facing image preparation separate.
- Add attachment request tags and mark generated-image uploads with `usage=image_gen`, preserving the thread's ephemeral setting.
- Update public schemas and SDK types to accept either image representation, retain the Python `ImageGenerationThreadItem` alias, and prefer `fileId` when reading records containing both fields.
## Testing
Add coverage for file-backed generation and rollout persistence, legacy history replay, inline and transitional serialization, task output visibility, and Python SDK alias compatibility.
GitOrigin-RevId: f7a2bb5707e2f277348a547a988bc33c8e96d891
## Why
The app server retained its startup model provider for catalog requests, so signing in or out could leave `model/list` using stale provider settings or requiring a restart after managed provider requirements changed.
## What changed
- Invalidate the catalog after successful login and logout, then reload the effective configuration on the next model list or background refresh. Rebuild the models manager when the provider or catalog changes, while preserving existing threads' routes.
- Retain the original project context and the TUI's `--oss` provider selection across reloads. Retry configuration loading after falling back to defaults so temporary failures do not pin the fallback catalog.
- Keep provider policy checks for cached catalogs and apply runtime `api_key_model_discovery` toggles to the active catalog manager.
## Testing
Add and extend tests for provider selection and definition changes after login, catalog reloads after logout, OAuth gateway transitions, fallback recovery, project context, and runtime model discovery toggles.
GitOrigin-RevId: bce2e23ff567e1a52eac2b6ad736a6e63ff61e2b
## Why
Clients need a way to update individual turn metadata entries without replacing the existing client metadata map.
## What changed
Add the experimental `responsesapiClientMetadataPatch` field to `turn/start` and `turn/steer`. Patches add or overwrite entries while retaining other keys and apply after `responsesapiClientMetadata` when both are supplied. The existing field retains replacement semantics, including clearing unprotected entries with an empty map.
Continue protecting reserved metadata keys and preserving targeted `misalignment_override` continuations across updates.
## Testing
Extend the app-server metadata integration test to cover replacement and patch steering, patch precedence at turn start, preservation of unrelated entries during patches, and protection of targeted continuations.
GitOrigin-RevId: 8c4da3ba1b87329da20b5295846bdcf3a88126de
## Why
Workspace routing reported generic requirements load and reload failures, hiding the cause. Raw configuration errors can contain secrets, so exposing their messages directly is unsafe.
## What changed
Include a safe reason in configuration load and reload errors: file locations or non-file line and column numbers, cloud error categories and HTTP status codes, known network policy denials, or OS error details. Exclude raw parser messages, configuration contents, and backend-supplied policy names and IDs.
## Testing
Add regression coverage for configuration locations, cloud failures, and network policy denials. Verify that malformed local and cloud configuration reports useful errors without exposing secret values or policy identifiers, and still prevents workspace routing from falling back to startup configuration.
GitOrigin-RevId: a71484c700d32662ced9e19041dbedda5d1da8a5
## What changed
Add optional `voiceSessionId` to realtime start parameters and forward it as the `voice-session-id` header for WebSocket, WebRTC, and existing-call transports. Keep this client-generated voice session identifier distinct from `realtimeSessionId`, which uses `x-session-id`.
## Testing
Extend serialization tests and add coverage for distinct session ID headers, WebRTC request forwarding, and existing-call handshake forwarding.
GitOrigin-RevId: cb558dbb9d438f2d34e281199a7e81fe5d33b879
## Why
Prediction forks need to retain their parent's context even when it exceeds the automatic compaction threshold. Compaction or context resets can otherwise replace the history used for the prediction.
## What changed
- Apply a thread-local `AutoCompactionDisabled` policy to experimental prediction forks without changing model or skill budgets.
- Skip automatic compaction before, during, and after turns, including context-limit recovery, and suppress new token-budget reminders.
- Reject `new_context` requests for these threads and report context-limit failures without compacting their history.
## Testing
Add regression tests for legacy and paginated prediction forks across compaction thresholds, unchanged parent compaction and skill/tool inputs, context-limit failures, and rejected context resets. Add a request-history snapshot verifying inherited context and reminders survive without compaction or additional reminders after a tool call.
GitOrigin-RevId: 7df374287f4142f776981bb6c22e5caa564d74a5
## Why
Restoring unnamed thread permissions after configuration loading leaves network proxy initialization and permission validation using the configured default. A saved read-only thread should also resume when that default is incompatible with current managed requirements.
## What changed
Apply eligible saved permission profiles during configuration loading, before network preparation and final validation. Keep explicit permission overrides and managed requirements authoritative, preserve managed deny-read restrictions, and reject saved external enforcement or materialized filesystem grants. Include the saved profile in the app-server's prepared resume configuration state.
## Testing
Add regression coverage for resuming saved read-only permissions with an incompatible full-access default and for retaining managed, remembered, and newly approved network domains in the restored profile's proxy allowlist.
GitOrigin-RevId: 73e32b0a31ac678fd3f60a8ccf8fa9df627f16c3
## Why
Cold resume can replace saved unnamed permissions with current configuration defaults or recover an executor's permissions from turn context. A first-turn context can also predate an acknowledged settings update.
## What changed
- Restore eligible unnamed permission profiles from settings snapshots owned by the resumed thread, honoring explicit caller overrides and current managed requirements.
- Use owned snapshots as the authority for named permission profiles and reapply workspace permissions for the resumed workspace roots.
- Persist a thread-owned settings checkpoint after the first turn's context, serialized with settings updates so older checkpoints cannot supersede newer settings.
## Testing
Extend regression coverage for cold resume with changed defaults, managed permission restrictions, workspace-root overrides, foreign snapshots, and settings updates during first-turn processing.
GitOrigin-RevId: e411d9fd3d586a4162498c9c77c4184459071bd1
## What changed
Add an optional `retain` flag to `TurnToolOutput` for `turn/start`. When set to `true`, pass the output to the core with a retention annotation to request retention in the thread's model history. The flag defaults to `false`, preserving existing behavior.
Update the generated JSON schemas, TypeScript types, and Python bindings to expose the flag.
## Testing
Add an integration test verifying that a retained tool output reaches the model and preserves client-authored sender metadata in persisted history, including the receiver message ID.
GitOrigin-RevId: 52893a8fcb308f26e77ba8f0bee9990073b26d54
## What changed
Add `thread/items/read` to retrieve persisted items by `threadId`, `turnId`, and 1–100 `itemIds`. Return matching items in canonical stored order, omitting missing IDs and items outside the requested turn.
Add item ID filtering to the thread store while preserving inherited history and fork cutoffs. Require the experimental API capability for the new endpoint.
## Testing
Add coverage for stored ordering, turn scoping, missing IDs, request size limits, experimental capability gating, and inherited items across fork cutoffs.
GitOrigin-RevId: 9b243dd87577bd4fe36900c388a386b2e26ff2e0
## Why
Background workspace routing reads reload configuration even when signed out or using an API key, although routing requires ChatGPT authentication.
## What changed
Check cached authentication before reading accounts for workspace routing at app-server startup and connection initialization. Skip these background reads without ChatGPT authentication, while preserving configuration reloads for explicit `account/read` requests.
## Testing
Add regression tests covering signed-out and API-key startup and connection initialization, explicit `account/read` configuration reloads, and routing after ChatGPT sign-in, including propagation of configuration errors.
GitOrigin-RevId: 8b90ee609ed24f8618cd21f160eb7001703b8bd1
## Why
Clients need to mark threads read or unread without overwriting unseen results or another window's explicit mark.
## What changed
Add `thread/readState/update` for eligible durable local threads, gated by `initialize.capabilities.experimentalApi`. Requests include `threadId`, `expectedRevision`, and an operation of `{type:"read"}` or `{type:"unread"}`.
Marking read clears `firstUnread`; marking unread sets it to `threadStart`. Successful updates return the read state and notify subscribers through `thread/readState/changed`. Both operations require an exact revision match. Stale requests return `-32600` with `readStateConflict` and the current read state, requiring a fresh user action rather than a blind retry. Updates do not change thread recency.
## Testing
Add app-server coverage for experimental capability gating, explicit unread marks and notifications, conflicts for both stale operations, and marking read with a fresh revision.
GitOrigin-RevId: 775f6e9584dc91bd3c2ee9a309144b5baf0edffa
## What changed
Add the experimental `thread/readState/changed` notification with `threadId` and the committed `readState` receipt. Send it to existing thread subscribers when terminal activity updates read state or a revert clears a removed unread position. Emit terminal read-state updates before `turn/completed` so completion remains the last notification for that result.
Expose the notification in generated JSON schemas, TypeScript types, and Python SDK models. Document experimental capability gating, subscription lifetime, notification opt-out, and refreshing receipts when concurrent responses disagree.
## Testing
Extend the read-state integration test to assert that the notification receipt matches the receipt returned by `thread/read` after terminal activity.
GitOrigin-RevId: 28935352a881b7a5e2e7f629173c3b2061bd7941
## What changed
- Add experimental `readState` to `thread/read` and a thread-ID-keyed `readStates` map to `thread/list` for eligible durable local user threads. Each receipt contains `firstUnread` and an opaque `revision`.
- Publish new visible terminal results before `turn/completed`, after flushing the rollout. Reading snapshots leaves activity unread; replayed history does not publish new activity.
- Clear unread positions removed by a paginated thread revert while preserving explicit thread-start marks and concurrent receipt updates.
## Testing
Add an integration test covering completed-turn receipts, repeated reads without acknowledgement, matching list receipts, and revert cleanup with a changed revision.
GitOrigin-RevId: e7f6ddfbb1fc2fa95d1ef2876d7f0f7b9f99ff65
## Why
Durable remote-control RPC changes need to update the managed daemon's launch settings so future launches use the saved preference.
## What changed
- Save non-ephemeral `remoteControl/enable` and `remoteControl/disable` requests to `remoteControlEnabled` in `app-server-daemon/settings.json` for managed daemons.
- Preserve other settings and write updates atomically. Skip persistence when `daemon.lock` is held so concurrent lifecycle operations take precedence without blocking the RPC.
- Leave daemon settings untouched for ephemeral requests and unmanaged servers.
## Testing
Add integration coverage for durable enable and disable, ephemeral requests, and lock contention. Extend the unmanaged-server test to verify that no daemon settings file is created.
GitOrigin-RevId: 2baf261ed62f7c7ad87c9779ffb91c59e923f0f8
## What changed
- Add optional `websocketRequestId` to `environment/add` and send it as `X-Request-ID` on direct WebSocket upgrades, including reconnects. It requires a secure transport or a loopback destination.
- Echo a supplied `X-Request-ID` in the exec-server WebSocket upgrade response.
## Testing
Add coverage for `websocketRequestId` serialization and for handshake header forwarding and echoing, both with and without a request ID.
GitOrigin-RevId: 235303ff7e1150405b7e1158d6024223144e0cc3
## What changed
Support `plugins._default.enabled` with explicit per-plugin `enabled` overrides. Omission preserves existing source and account enablement; configuration cannot activate a plugin disabled at its source. Plugin settings such as remembered tool approvals inherit the default unless `enabled` is explicitly set.
Apply the policy to plugin skills, MCP servers, Apps, and hooks, including selected executor roots and runtime configuration refreshes. Preserve the latest plugin policy when adding MCP dependencies and rebuild hooks when concurrent configuration updates replace their inputs.
Report effective enablement in `plugin/list`, `plugin/installed`, `plugin/read`, and `plugin/share/list`. Remote installation still installs disabled packages, but skips MCP and Apps authentication setup without writing an enablement override.
## Testing
Add regression coverage for default inheritance and explicit overrides, source-disabled plugins, policy refreshes during active turns, disabled or malformed selected plugin roots, and remote installation authentication behavior.
GitOrigin-RevId: 83b70c5b47fc95474fec292f248683f1f887221e
## What changed
Add `windows.require_mxc` to managed requirements. When set to `true` on Windows, reject configurations whose effective local sandbox backend is not MXC without changing the selected backend.
Validate after cloud configuration loads and outside startup recovery fallbacks. Apply the check to app-server startup and configuration loads, in-process bootstrap, session creation, sandbox debugging, and runtime configuration refreshes.
## Testing
Extend configuration tests to cover required and optional MXC selection, separately loaded policy requirements, and runtime refresh validation. Expand app-server startup tests to cover local and cloud MXC requirements, cloud preference selection, and failures without default-config recovery.
GitOrigin-RevId: 16456611bfd9df77e7f959b52515f1885b59ac75
## What changed
- Use the standard shell executor and remove the zsh fork escalation runtime, `codex-execve-wrapper`, and `shell-escalation` crate.
- Ignore `shell_zsh_fork` and `unified_exec_zsh_fork`, emit migration notices for legacy configuration, and warn when ignoring managed requirements for these flags.
- Keep the active session's `apply_patch` alias directory readable under restricted filesystem permissions.
## Testing
Add coverage for legacy configuration startup and shell execution, migration notice rendering, active alias directory selection, and nested `apply_patch` execution while other files in `CODEX_HOME` remain unreadable.
GitOrigin-RevId: 43af461fea32b4980550ee7237effd2bc0646ed8
## Why
Persisted multi-agent v2 children created after the client disconnects need lifecycle listeners so their runtimes can be released once idle. Listener attachment must also wait for an earlier runtime's cleanup to finish.
## What changed
- Start lifecycle listeners for persisted v2 children even when no initialized clients are connected, and defer attachment until pending unload cleanup completes.
- Keep ephemeral children loaded so follow-up tasks retain their model context.
- Raise the default `thread_unload_delay_secs` from 60 seconds to 1800 seconds (30 minutes), updating the configuration documentation and sample.
## Testing
Add regression coverage for children spawned after disconnect with zero- and one-second unload delays, including waiting for pending cleanup, keeping running threads loaded, releasing idle runtimes, and preserving an ephemeral child's earlier reply across a follow-up. Update configuration tests for the new default and explicit overrides.
GitOrigin-RevId: 2fecc77b5c03237aa8fd7eacc4bd119b99d36e0a
## What changed
- Route app-server idle unloading of multi-agent v2 children through local eviction that preserves unread mail and environment selections for reload.
- Hold residency pins through input submission so newly reloaded children cannot be evicted before receiving their work.
- Guard listener cleanup against replacement runtimes and subscriptions, and reject local eviction of host-controlled threads.
## Testing
Add coverage for unsubscribe-driven eviction followed by `followup_task`, verifying restored conversation context and exactly-once delivery of queued mail. Extend tests to check that residency pins block eviction and that rejected host eviction preserves the thread and mailbox.
GitOrigin-RevId: e36723730af683d2081e495e637f0e6d23548b8d
## What changed
Record local MXC availability and the selected Windows sandbox backend at app-server and session startup. Log the backend again when an accepted session settings update changes the Windows sandbox level, using a blocking task for the log write.
Selection entries distinguish `mxc`, `disabled`, `unelevated`, and `elevated` in the sandbox logs under `.sandbox` in Codex home.
## Testing
Update the remote thread persistence assertion to allow the `.sandbox` directory on Windows, since startup logs are not thread persistence artifacts.
GitOrigin-RevId: 4130b59ac7761223775ac9b6afb096abb7fb4615