## What changed
Add `approved_prefixes` to catalog permission messages, with `{{ approved_prefixes }}` substitution for the approved command list. An empty template suppresses the section; missing or null values retain the bundled template.
For `on-request` approvals, append an explicitly supplied prefix template even when the catalog also supplies approval instructions. Use the template for bundled `on-request` and granular approval instructions as well.
## Testing
Extend the remote model catalog integration test to cover custom prefix rendering alongside catalog approval instructions and suppression with an empty template.
GitOrigin-RevId: 82dd6f83caa56cab0a2f6343bf912efe2cb97d64
## Why
Skill tools depended on World State rendering to initialize their catalogs and could return `skill catalog is not ready for this step` before rendering completed.
## What changed
- Add an asynchronous `ToolContributor::prepare_for_step` hook and await all contributors before constructing tools.
- Prepare immutable skill catalogs, aliases, plugin policy, and configuration for each step. Tools, invocation detection, and World State rendering consume the prepared state without relying on rendering to perform discovery.
- Apply configuration reloads to subsequent steps while preserving live authorization checks for skill reads.
## Testing
Add coverage for preparation completing before tool construction and World State rendering, skill tools working before rendering, catalogs remaining stable across steps, and configuration reloads during discovery.
GitOrigin-RevId: 1fb95c58c412488353f3bd4403824d6d1476d3d0
## What changed
Stop emitting the warning about long threads and repeated compactions after successful context compaction. Update compaction, resume/fork, and window-header tests to wait for turn completion without expecting the warning.
GitOrigin-RevId: 707dc2dd21765ec46522276715c96cf7a112654d
## What changed
- Record review attempt counts and final outcomes with a `retried` tag.
- Measure retry waits by failure reason and whether the wait ends in a retry, cancellation, or deadline; count retries only when another attempt will run.
- Count required synchronous reviews with the `required_sync` route.
- Use the originating turn's telemetry for Guardian reviews so metrics retain that turn's model attribution.
## Testing
Add metric assertions for attempt counts, retry outcomes, and waits interrupted by cancellation or deadlines. Extend the delayed cached-score integration test to verify route and retry-wait metrics use the originating turn's model after a model override.
GitOrigin-RevId: 681a719ad5dd9e4436cb37b6f5f972cb11a5c890
## What changed
- Remove `subagent_thread_environments` and the separate configured environment bindings. Spawned agents inherit the invoking step's environment snapshot.
- Retain environment selections across child eviction without retaining executor bindings. Reload V2 children against the parent's captured environments, requiring matching environment IDs, working directories, and workspace roots while preserving permission validation.
GitOrigin-RevId: d820c63ea20f5834ed88071d16c60683f2545406
## Why
Temporary environment attachments for a parent's turn should not become a child's persistent environment configuration or survive child eviction.
## What changed
- Add the default-disabled `subagent_thread_environments` feature flag. When enabled, subagents inherit configured thread environments captured with the spawning step instead of active turn selections.
- Track configured bindings separately from turn attachments, preserving pending configuration ownership when turn selections change.
- Retain configured bindings across child eviction and reload, excluding temporary attachments. Preserve the child's workspace when the parent switches workspaces, while enforcing current roots and permissions when the parent still configures the same workspace.
## Testing
Extend coverage for both multi-agent versions, forked children, empty configured environments, pending configuration, and legacy inheritance. Add eviction and reload cases covering temporary attachments, workspace changes, deferred executor startup, and permission validation.
GitOrigin-RevId: 4533645503d5f863a9ccc064386ed7ca169d98b7
## What changed
- Build executor skill catalogs from discovery V2 inventories without reopening host paths or falling back to legacy discovery.
- Merge Cloud and executor skills by remote plugin identity and skill name, retaining Cloud metadata and accepted provider read routes. Apply plugin selection and disablement before merging.
- Share a stable catalog across each step's rendering, list/read tools, and explicit and implicit skill invocations.
- Preserve unmatched executor entries when Cloud catalogs are unavailable or partial; only complete Cloud catalogs disable unmatched remote entries.
- Bind discovery caches to captured environments and executor sessions, and refresh MCP when V2 inventories change. Preserve pending invalidations when forced MCP refreshes fail.
## Testing
Add regression coverage for V2 inventory sharing and refresh, environment isolation, catalog merging, partial Cloud results, disabled plugins, and catalog consistency across steps and read routes.
GitOrigin-RevId: 842bdcbc9e19364dd69a9abf9e48330b7425a76c
## What changed
- Use V2 discovery inventories for plugin MCP contributions when supplied, including empty or failed inventories; retain legacy discovery when no V2 snapshot is supplied.
- Merge plugins by canonical identity, using cloud metadata and enablement for remote plugins and attaching executor installations only when versions match. Preserve configured executor-local plugins and executor enablement when cloud data is unavailable.
- Keep installation order stable across refreshes and run merged MCP declarations on the first retained executor installation while preserving attribution for the others.
- Carry local and remote identities through selected-plugin snapshots, skill attribution, and active-plugin telemetry. Track disabled plugin IDs alongside disabled roots.
- Preserve a complete cloud catalog when a partial refresh arrives, and cap tool-description plugin attribution at 1,024 bytes while retaining all plugin associations.
## Testing
Add coverage for catalog parsing and reconciliation, enablement and discovery-mode selection, installation refresh ordering, executor-specific MCP normalization, selected-plugin snapshots, and bounded UTF-8 attribution text.
GitOrigin-RevId: a8ad352de6a2b8dc4bfd1ff6a5c62ee8ed1d1664
## Why
Turn recovery and retries after a server overload can leave consecutive reasoning effort updates in history when settings change without an intervening message. Requests should use the latest update in each consecutive run.
## What changed
Coalesce adjacent `configuration_update` items when building Responses requests with reasoning effort overrides enabled, retaining the latest update. Preserve saved history and updates separated by other input items.
## Testing
Extend integration coverage for recovery with unchanged or changed effort, retries after a server overload, and WebSocket continuation and replay after coalescing. Verify that requests retain the latest adjacent update while saved history keeps all updates.
GitOrigin-RevId: bcf97db4c93dac5f466bd276176ac9d238329ecd
## 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
## 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
## Why
MCP tool hooks need to invoke model-hidden tools even when a subagent's cached server has not started. Their timeout must also cover server startup.
## What changed
- Let cached servers with allowed model-hidden tools remain dormant until called.
- Wait for the selected server when executing an MCP hook, leaving unrelated cached servers dormant, and apply the hook timeout to the entire operation.
- Capture tool namespace attribution after startup and retain it only while catalog revisions remain unchanged.
- Validate the server, environment, and tool filter before starting a server or capturing attribution.
## Testing
Extend integration coverage for cached subagent hooks under both startup readiness modes, startup timeouts without context injection, and namespace attribution for hook and token-budget context while keeping tools hidden from the model. Verify that a direct call starts a cached server whose tools are hidden from model exposure.
GitOrigin-RevId: 7a54b69aa2515722aeb925e03e1667bf63aa67ca
## What changed
Store dynamic tool specifications in an `Arc<[DynamicToolSpec]>` so session configuration and turn snapshots share the list fixed at thread startup instead of copying it on each clone.
Keep the `dynamic_tools()` accessor returning a `Vec<DynamicToolSpec>`, but copy the specifications after releasing the session state lock.
GitOrigin-RevId: 092c5f9ea6cc390d948c27cd11340aeb12bd6037
## Why
Guardian request counts grouped by input size should reflect admitted sampling inputs without counting synchronous transport retries more than once.
## What changed
- Add a shared `token_bucket` label to admitted total-input observations in `codex.guardian.context.request_tokens` for synchronous and asynchronous reviews. Use inclusive upper bounds in 20k-token steps through 240k, followed by 256k and overflow buckets.
- Record synchronous request tokens after budget admission, once per sampling step, including the complete input. A fresh step counts again even when its input is identical.
- Preserve asynchronous component histograms for oversized classifications, but omit `token_bucket` so rejected inputs do not contribute to counts grouped by that label.
## Testing
Add coverage for bucket boundaries, synchronous retry deduplication and budget rejection, asynchronous retained-history reuse and reset, and admitted versus oversized classification metrics.
GitOrigin-RevId: fac2f102a4c48c5fd21d56bfa701b95a1ff852d0
## 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
A worker can finish after its parent has returned a final answer. Agent messages without `trigger_turn` previously needed an outstanding durable sleep to wake an idle session.
## What changed
Add the disabled-by-default `wake_on_agent_messages` feature to start a new root turn when agent mail arrives through direct delivery or the host mailbox. Reuse the previous turn context for messages without `trigger_turn`. Keep these automatic wakes disabled for interrupted sessions, Plan mode, and child agents.
## Testing
Add coverage for both delivery paths waking a completed root exactly once, child completion waking a parent after its final answer, and the interruption, Plan mode, and child-agent boundaries.
GitOrigin-RevId: f1a4fc7c22be8ca46b2173a85445126cbdd6c4b6
## Why
Cloning `ResponseItem::AdditionalTools` deep-copies its tool declarations for history and request copies.
## What changed
Store `tools` in an `Arc<[serde_json::Value]>` so clones share immutable declarations. Update constructors and existing test fixtures to use the shared representation.
GitOrigin-RevId: eb8831774afb45fe8431a796f34ae9d1243e884a
## Why
Contextual fragments and extension-owned world-state sections currently return strings, limiting them to text content.
## What changed
- Return `ContentItem` from fragment bodies and rendering, preserving classification and attribution. Apply text markers only to `InputText`; pass other content through unchanged.
- Allow extension prompt and world-state contributions to carry typed content, and preserve media in context-window hints.
- Hash non-text world-state fragments by their serialized content and role while retaining the existing text hashing behavior.
- Add shared content-to-tool-output conversion that preserves image references, image detail, and audio.
## Testing
Add coverage for typed world-state hashing and preservation of image content and attribution. Expand code-mode output tests to cover input text, output text, file-backed and inline images, and audio.
GitOrigin-RevId: 2ed00d466a3f169b151202f3eef71e667ea64be1
## Why
Unknown fields in TUI keymaps and profile TUI settings fail deserialization even when strict config validation is disabled.
## What changed
Remove Serde's `deny_unknown_fields` from these settings so unknown fields are ignored during deserialization and reported by the shared strict-config policy. Keep `schemars(deny_unknown_fields)` so the generated schema continues to disallow unknown fields.
GitOrigin-RevId: 06985161bc3bbb35648712288c1d00bdd50953ba
## Why
Schema strings and sequences do not grow after construction, and most schema nodes do not contain maps. Retaining collection capacity and inline optional maps adds unnecessary memory overhead.
## What changed
Store `JsonSchema` strings and sequences as boxed strings and slices, and box optional property and definition maps. Adapt constructors, schema consumers, and existing test expectations to the new representation while preserving the serialized JSON Schema format.
GitOrigin-RevId: 0a249b1ae32932cbbfe3c575c32bfd20b060c303
## Why
MCP tool calls reported every aborted approval as "user cancelled MCP tool call", including interrupted requests and automatic cancellations in `exec` mode.
## What changed
Carry `user`, `interrupted`, or `non_interactive` cancellation reasons through MCP approval metadata and resolution. Mark explicit TUI cancellations as user actions, interrupted requests as interruptions, and automatic `exec` cancellations as non-interactive.
Use the reason to report when a call was cancelled before approval or because interactive approval is unavailable in `exec` mode. Preserve the existing cancellation message for clients that omit the reason.
## Testing
Update tests to verify that a closed approval response carries the interruption reason and that `exec` cancellation responses include the non-interactive reason.
GitOrigin-RevId: be2a5f7fef539b5db2add53b46aea27e2b8a66fc
## 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
MCP servers can expose new tools during discovery. Refreshing the catalog after a tool-list notification lets Codex discover and call those tools in the same turn.
## What changed
- Add the disabled-by-default `mcp_tool_list_changed` feature for ordinary MCP servers.
- Track notifications in transport order and refresh catalogs before subsequent discovery or tool binding. Coalesce concurrent refreshes and retry listings invalidated by notifications, including during pagination.
- Retain the previous catalog on refresh failure, apply a retry cooldown, and invalidate affected startup caches. Allow notification refreshes to proceed while admitted calls finish.
## Testing
Add coverage for same-turn discovery and invocation in direct and Code Mode, notifications during startup and pagination, disabled behavior, cache invalidation, and concurrent refreshes with timeout recovery.
GitOrigin-RevId: 9afee8deba00dd9851b5f32625f61f96965aa00c
## Why
Dynamic tool calls should remain independent while waiting for client responses, so one pending call does not block another from reaching the client.
## What changed
Enable parallel execution in `DynamicToolHandler`, allowing code mode programs to issue concurrent dynamic tool calls with `Promise.all`.
## Testing
Add a code mode regression test that waits for two dynamic tool requests before responding, resolves them in reverse order, and verifies that `Promise.all` preserves the expected result order.
GitOrigin-RevId: c93c1fea720f76c772b0e3452ddc8c01fb1a08d8
## What changed
Recognize `codex_app.create_thread` deliveries when capturing sender context so Guardian receives the sender's recent user messages and assistant context for delegated tasks.
## Testing
Extend the sender-context integration test to cover `create_thread`, including reviewer-only context and clearing the snapshot on a subsequent delivery without sender provenance.
GitOrigin-RevId: 7a47c3ac5b9c9405e6728010c494529274b7b73d
## Why
Remote credential masking previously supported only Bash commands without login startup or shell snapshots, leaving Zsh commands with unmasked credentials.
## What changed
- Enable masking for Zsh login commands using shell snapshots on Linux and macOS.
- Capture trusted startup profiles per launch, bind the credential broker to the resulting environment, and replace credentials and supported aliases with placeholders before snapshot replay.
- Preserve explicit environment overrides, credential unsets, and launcher-managed proxy settings during replay.
- Warn and fall back to unmasked startup when a snapshot cannot safely replay credentials; stop execution if protected snapshot restoration fails.
## Testing
Extend remote execution tests for inherited and profile-defined credentials, overrides, destination changes, and unsupported-profile fallback. Add a Zsh scenario snapshot showing a credential placeholder in command output.
GitOrigin-RevId: 83193d6cbc05f3deb0d6d0b9ae80974b353ce900
## 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
## Why
Live descendants previously blocked suspension of an unfinished root turn, requiring callers to stop and unload them before recovering the root elsewhere.
## What changed
Allow `suspend_turn_and_shutdown` to suspend the root and initiate shutdown of all sessions sharing its local agent runtime, fencing new starts. Remove `SuspendTurnOutcome::HasLiveDescendants`.
Success confirms that the root has stopped and its history writer is flushed and closed; descendant cleanup completes separately. Callers must finish tree shutdown or fence and terminate the tree's persistence writers before transferring ownership. Interrupted descendants are not automatically recovered.
## Testing
Extend integration coverage to verify child shutdown, recovery under the original root turn ID without restarting children, and separate reporting of child writer failures.
GitOrigin-RevId: 5adc240ae6e34654209154ee9324621a2bd604d5
## 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
## What changed
Add `tui.presets` entries keyed by a single digit from `0` to `9`, each with an `input` prompt or slash command and an optional `label`. Expose presets in the configuration schema, load them into runtime configuration, and preserve them in TUI local settings.
Reject invalid slots, blank inputs, shell commands beginning with `!` after leading whitespace, and inputs exceeding 8,000 UTF-8 bytes.
## Testing
Extend the runtime configuration test to verify loading both a slash command with a label and a prompt without one.
GitOrigin-RevId: d2911e540bc50f05b4a5224abf17ce4ef5a18ea3
## What changed
Replace duplicated content-kind strings with constants shared by fragment producers and consumers, including authorization checks, forked-history filtering, and memory instructions. Share the compaction summary kind between core and Guardian's transcript filter.
## Testing
Add a regression test verifying that Guardian excludes compaction summaries while retaining surrounding user messages, including a user message with identical text.
GitOrigin-RevId: 36dbdf0f82c61b52d2571ac1c392fb151c98151b
## What changed
Negotiate executor support for `credential_masking` and enable built-in credential brokerage in executor-local network proxies. Supported non-login Bash commands on Linux and macOS receive credential placeholders, with real credentials injected by the proxy for matching destinations.
Retain credential mappings across process launches within the same executor session, scoped by environment, conversation, and broker configuration. Keep credentials and destination context on the executor.
Fall back to unmasked execution for unsupported shells or shell startup, and for configured credential providers. Emit warnings when masking is unavailable, preserving shell profiles and snapshots.
## Testing
Add coverage for capability negotiation, fallback behavior, mapping reuse and isolation, proxy credential injection, and keeping executor credentials out of model-visible request history. Test warning, removal, and rejection modes for credentials left unmasked during preparation.
GitOrigin-RevId: f64e916a5de8350fa0d289d3440ec29761accd75
## What changed
- Add `ComposedContext::retain_new_images` and use it in Guardian review sessions and the async scorer. Compare host-prepared image references against admitted history, ignoring image detail, and skip scanning history when no images need checking.
- Restore `ConversationState` directly from a checkpoint, retaining committed history for rollback or transferring it with `take_history` for ephemeral forks.
## Testing
Extend tests for prepared-image matching across differing detail levels, image-free continuations that avoid scanning history, and checkpoint restoration and history transfer.
GitOrigin-RevId: bafeb6de9babc721182be43d0eb1a653955a0ebb
## Why
A failed Guardian inference can retain its input in a reusable session. Tracking transcript progress only after successful reviews can admit the same evidence again on retry.
## What changed
Advance transcript progress when a failed turn has retained its input and the session remains reusable, without counting it as a completed review or changing the committed fork checkpoint. Leave progress unchanged when failure occurs before input admission.
## Testing
Extend regression coverage for encrypted agent messages across review retries, pending evidence after compaction failures, and fork checkpoints after transcript admission without a completed review.
GitOrigin-RevId: 36239ec9d47f484bcfe68d65e7c8d8ab8660db0d
## Why
Guardian approval covers the permissions of the reviewed action. A retry outside the sandbox needs a fresh review of its broader permissions.
## What changed
- Track the initial approval source so Guardian approval does not preapprove an escalated retry, while preserving existing user and hook approval behavior.
- For exec retries that can run without the sandbox, set the approval action to `RequireEscalated` and clear `additional_permissions` so review and caching reflect the retry's actual permissions.
GitOrigin-RevId: 06f8d53745a7bcfe9fdb5628ff9e85da6060547d
## What changed
- Remove feature-flag checks from managed worktree creation and repository-aware session discovery, while retaining local workspace and trust checks.
- Make TUI voice availability follow platform support instead of `features.realtime_conversation`.
- Ignore `features.worktrees` and `features.realtime_conversation` configuration overrides, warn when managed requirements reference them, and hide both flags from `/experimental`, including catalogs from older servers.
## Testing
Add coverage for ignored configuration overrides and managed requirements, and update session filtering, worktree grouping, and experimental feature discovery tests for the retired flags.
GitOrigin-RevId: 1d64e890e6e2f8a78926a9ea163126c0890b068e
## What changed
Tag `codex.tools.incremental_updates` counters with the qualified tool name alongside the action. Continue excluding initial catalogs and namespace headers, while counting each removed namespace member.
Add `codex.tools.spec_description_bytes` to measure UTF-8 description bytes when an existing tool definition is replaced. Skip definitions without descriptions and use logarithmic histogram boundaries up to 1 MiB.
## Testing
Extend namespace transition tests to check per-tool counts and description sizes. Add scenario assertions for replacement metrics with incremental tool updates and their absence on the non-incremental request path.
GitOrigin-RevId: e20e6d81f21a867b285df1f0da005c2806dd03c6
## Why
With granular sandbox approvals disabled, `write_stdin` rejected input to terminals retaining additional permissions even when those permissions were still granted.
## What changed
Let input reach approval review when the terminal's retained permissions match active grants for its environment. Require identical filesystem grants, including entry order, and an active network grant when retained permissions enable network access. Each input still requires review.
Keep rejecting input when retained authority is no longer covered or the approval policy changes to `Never`.
## Testing
Add regression coverage for user and Guardian review, turn grant expiry, session grants, and switching to `Never`. Cover filesystem restrictions, protected metadata, symlinks, and ordered denials, and verify that rejected input never reaches the terminal.
GitOrigin-RevId: 9abf7da8d03b1526d26ca2a718e36349a255330b
## What changed
Wait for the subprocess readiness marker before cancelling in
`process_exec_tool_call_cancellation_allows_sigterm_cleanup`, removing the
one-second polling cutoff. Poll readiness alongside execution under the existing
five-second timeout, then cancel and await execution if that timeout expires so
cleanup completes before the test fails.
GitOrigin-RevId: ba47dad9ba87fb5dc3bd087380811655387f825a
## Why
Environment tool availability and selectors should remain stable as selected environments become ready.
## What changed
- Keep configured environment tools advertised even when no execution environment is ready, and derive `environment_id` selectors from all selected environments.
- Return guidance to wait when an environment is unavailable, while preserving errors for unknown environment IDs. Require a usable primary environment for `write_stdin`.
- Always include `shell` and `login` in the `exec_command` schema and mark `stable_environment_tools` as removed.
## Testing
Update integration tests to expect environment tools with empty or starting environments, and remove explicit feature opt-ins from affected scenarios.
GitOrigin-RevId: 1590c1b5be16a39e4a370663c552b881602545b5
## Why
MCP request failures and tool errors reported only through `codex/telemetry` metadata previously received an `unknown` error code, obscuring the failure category.
## What changed
- Classify typed request failures into bounded codes such as `request_timeout`, `transport_closed`, and `protocol_error`, and carry them into MCP call metrics and spans before errors become strings.
- Preserve typed timeouts when a prepared tool call exhausts its deadline during trusted access lookup.
- Accept allowlisted `error_code` values from `codex/telemetry` as a fallback after structured content and connector authentication metadata. Keep model output unchanged and ignore unrecognized metadata codes.
## Testing
Add coverage for typed errors wrapped in context, prepared-call timeout classification, metadata precedence and rejection, unchanged model output, and exported span error attributes.
GitOrigin-RevId: d7a440a6c9119b8a07a7f1fad697eb25af506f00
## Why
PowerShell safety checks can mistake a literal `start` argument for a URL-launch command, or combine a process launch with a URL from a separate command.
## What changed
Classify independently parsed literal PowerShell commands separately so commands such as `Write-Output start 'https://example.com'` do not trigger URL-launch checks. Retain conservative checks for pipelines, script state, executable strings, and shell or terminal wrappers, while continuing to detect actual URL launches and destructive commands.
## Testing
Add policy regression coverage for literal arguments, separate commands, URL launches, wrappers, and destructive commands, plus a Windows integration test covering execution and policy rejection.
GitOrigin-RevId: 2878aa86bc36b44c60230cc1de3430922b28b81a
## Why
Thread stores need a way to reuse history and writer state loaded while preparing a resume, rather than loading them again during session startup.
## What changed
- Add an opaque, single-use `ThreadStoreResumePreparation` and an optional preparation in `StartThreadOptions`.
- Pass preparation through session startup to `ThreadStore::resume_thread_with_preparation`, which defaults to an unsupported-operation error.
- Reject preparation for ephemeral threads or threads without resumed history. Continue using `resume_thread` when no preparation is supplied.
## Testing
Add a regression test verifying that supplied preparation selects the prepared store path and propagates its unsupported-operation error instead of falling back to ordinary resume.
GitOrigin-RevId: 26537d9b83443bd56341d6afc713f32b999dc67c
## Why
Native extensions need configured Responses metadata for request attribution, but extension calls used the MCP metadata template, which omits it. Image requests also did not forward the turn metadata to the backend.
## What changed
Use the Responses metadata template for native extension calls while continuing to exclude tool inventory. Forward the resulting metadata in the `x-codex-turn-metadata` header on image generation and edit requests.
## Testing
Extend metadata tests to cover configured values in extension calls and app-server tests to verify `display_name` and `turn_trigger` on image generation and edit requests, including a Unicode display name.
GitOrigin-RevId: a2ffaa4d15259c662917612391b8717ee34b9c6c
## 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
## What changed
- Preserve approval resolution sources through tool errors and tag cancelled MCP approvals with `error_type=approval`, `error_code=cancelled`, and `approval_source` (`guardian`, `user`, `hook`, or `unknown`). The source identifies the reviewer, not who caused cancellation.
- Record `context_changed` when validating a Guardian allow against changed authorization or review context, even when a concurrent stop or history reset determines the outcome. Retain the flag across retries and fresh-checkpoint recovery, and include it in the Guardian review counter.
GitOrigin-RevId: a19a986a7565f9a78a9bb2eaabdb5651834d28b8
## Why
A remote primary environment could supply its working directory and workspace roots to host plugins and MCP processes, breaking relative MCP executable resolution and applying the wrong workspace permissions.
## What changed
- Build host configuration from the local environment, falling back to the session's host working directory and runtime workspace roots when no local environment is selected. Preserve explicitly empty local roots.
- Use the same host configuration for MCP startup and refresh, and refresh MCP state when runtime workspace roots change.
- Keep repository skill discovery paired with the primary executor's working directory and filesystem.
- Box skill warmup and turn context construction futures to reduce enclosing future sizes.
## Testing
Extend the MCP integration test to cover a remote primary with populated, empty, or absent local roots; relative executable resolution before and after refresh; workspace-root revocation; and remote repository skill discovery.
GitOrigin-RevId: 21a73c90507b55fd94261e7bf348695ff8466a24
## Why
Compaction could record partial output before the response completed, leaving failed summaries in conversation history and persisted rollouts.
## What changed
Buffer compaction output until `response.completed` so failed or incomplete attempts leave no partial output in history. Record successful output before the response completion notification, preserving its compaction metadata.
## Testing
Add regression coverage for preserving messages, tool results, and token usage after a disconnected compaction stream, including after restart. Verify incomplete compaction output is excluded from subsequent requests and successful output remains observable and persisted.
GitOrigin-RevId: 8651200b2aae616000c55c1ed63283f3e2c1b8d5
## Why
Standalone thread settings updates cleared the running turn's continuation lineage, preventing recovery after a daemon restart.
## What changed
Preserve continuation lineage while a task is registered. Continue invalidating pending continuations for idle, reserved, and finishing turns, and record started-turn lineage atomically with task registration.
## Testing
Extend settings invalidation coverage to idle, reserved, and finishing turns. Exercise an in-flight reasoning effort update before compaction, then verify cold resume preserves the turn's frozen settings and allows continuation. Wait for thread idle before testing idle continuation.
GitOrigin-RevId: d7c316af6a4c871790bb57f0af9892bb30871ac8
## Why
Incremental-tool windows recorded base instructions only at setup, so a catalog refresh for the same model could leave active instructions stale. Instruction changes need to reach the model without rewriting the existing history prefix.
## What changed
- Track model identity and instruction content independently, appending a `model_instructions` developer message when either changes. Explicitly mark replacement or removal of base instructions, and avoid repeating unchanged updates.
- Start new windows after compaction with the latest model instructions while preserving custom base instructions.
- Preserve the recorded window base during local compaction retries, including empty instructions, and rebuild current model instructions when reconstructing child context.
## Testing
Add integration tests and request snapshots for catalog refreshes, instruction removal, model switches, compaction, restart, and forks. Extend regression coverage for legacy snapshots and local compaction retries.
GitOrigin-RevId: eeca69067b4d9cd91c817732d79b4d5c1faa18b9