## Why
Local `apply_patch` permission checks can treat a macOS system alias and its canonical spelling as different locations, sending writes covered by temporary-directory grants for unnecessary approval.
## What changed
- Normalize trusted top-level aliases in local policy roots and patch targets, reusing a prepared matcher for permission requests and patch safety checks.
- Share alias normalization with Seatbelt and the macOS executor sandbox while preserving mutable symlinks and missing descendants.
- Preserve read-only and deny precedence, protected metadata restrictions, and remote URI matching. Propagate normalization failures from fallible permission checks.
## Testing
Add macOS regressions for multi-file patches with missing parent directories through both direct `apply_patch` calls and shell interception, asserting automatic approval and file contents. Add unit coverage for alias restriction precedence, mutable symlink preservation, missing descendants, and remote permission isolation.
GitOrigin-RevId: 0822ff951eaab728cb1ad91281745fa1b8809f15
## What changed
Record `codex.thread.tools.namespaces_total` and `codex.thread.tools.fragment_bytes` histograms through session telemetry. Tag samples by `stage` (`before` or `after` the 4 KiB cap) and `kind` (`snapshot` or `delta`). Measure bytes after description normalization and XML escaping, including the `<tools>` wrapper, with explicit fragment-size buckets.
Delta counts include only changed entries, and unchanged state emits no samples.
## Testing
Extend rendering tests to verify snapshot and delta metrics, omission counts, byte sizes with Unicode and XML escaping, and no samples for unchanged state.
GitOrigin-RevId: 26543585e2bea54bff6d63263faa9a6ca5dca379
## What changed
Add `otel.log_guardian_assessments`, disabled by default and requiring an OTLP HTTP or gRPC log exporter. Emit `codex.guardian_assessment` when a synchronous Guardian review finishes, including review identifiers, status, risk level, user authorization, and rationale. Include `allow` or `deny` outcomes only for completed model assessments, not review errors, timeouts, or cancellations.
Cap exported rationales at 64 KiB on a UTF-8 character boundary and record their original byte length and truncation status. Use the log-only route to exclude assessment payloads from trace export, local state logs, and bug-report log buffers. Cached V2 approvals are not included.
## Testing
Add coverage for configuration gating, enabled and disabled denial logging, terminal statuses and outcomes, UTF-8 rationale truncation, export routing, and bug-report log buffer exclusion.
GitOrigin-RevId: dcbb5b429c8726a5a5c80ff82f9d625e81796ede
## What changed
- Resolve remote sandbox modes, writable roots, and denied read paths/globs using the executor's filesystem context, displaying paths in its native format. Preserve local filesystem resolution for local environments.
- Resolve remote read denials individually so missing executor facts omit only the unresolved entries.
- Apply a shared 32 KiB budget to displayed permission paths/globs, omitting whole entries and warning that all restrictions still apply, including omitted read denials.
## Testing
Add coverage for remote Windows writable roots and read denials, missing executor path facts, and whole-entry omission with multibyte paths under the shared budget.
GitOrigin-RevId: c61e7ddc8fa569dbc25e9990d90357c42315188f
## Why
Image and audio estimate cache misses computed values while holding the cache mutex, blocking access to unrelated keys during initialization.
## What changed
Add `BlockingLruCache::get_or_init` using `Arc<OnceLock<V>>` and migrate the image and audio estimate caches to it. Initialization and same-key waits run in a Tokio blocking region after releasing the cache mutex. Callers share initialization while an entry remains cached; eviction can allow another initialization, so factories must be deterministic.
## Testing
Add a concurrency test covering access to other keys during initialization, eviction of an in-flight entry, and successful completion of both the evicted initializer and its replacement.
GitOrigin-RevId: 079226a58828b854eddc2b501079527bcbe5e603
## Why
Unchanged scheduled heartbeat instructions should not become fresh authorization evidence that supersedes a later human override or floods Guardian review context.
## What changed
- Capture heartbeat provenance per input, including when steering an active turn, and persist it in history and retained context.
- Coalesce unchanged instructions for each automation at their original acceptance order. Preserve changed instruction versions and ordinary human messages.
- Represent repeated heartbeats as references to earlier instructions in Guardian transcripts, while tracking the latest input turn separately for trusted skill selection.
- Limit coalescing to recognized, bounded heartbeat envelopes with host-provided provenance.
## Testing
Add regression coverage for human overrides across repeated and steered heartbeats, instruction changes, checkpoint restoration, transcript references, envelope parsing, and latest-turn trusted skills in delegated reviews.
GitOrigin-RevId: 31e444ddb685a1a618be26d3cc32fb562296946b
## Why
Cold Rosetta translation and cache invalidation from hard-linked executables can interfere with timed CLI tests. Sampling the clock twice also makes local retry telemetry report a delay shorter than the selected backoff.
## What changed
- Warm CLI fixtures with `--version` on macOS x86_64 before timed checks, and use copies or Unix symlinks to avoid invalidating the shared executable's Rosetta cache.
- Use one clock sample to calculate the response retry deadline and recorded delay.
- Include the retry telemetry event in delay-range assertion failures for the headerless rate-limit stream test.
GitOrigin-RevId: fc573bfff912e999cf74b94a1c6e7ae1be07974b
## Why
Asynchronous Guardian scoring omitted the target environment's denied-read restrictions, and cached score authorization did not include that permission context. A score from one environment could therefore be reused for an action in another environment with different restrictions.
## What changed
- Share permission resolution between synchronous review and asynchronous scoring, including resolving `write_stdin` targets from the owning terminal session.
- Include environment identity and denied-read paths/globs in async scoring context and cached score authorization.
- Fall back to synchronous review when permission evidence cannot be resolved or exceeds the async limit of 3,000 bytes, rather than omitting restrictions.
## Testing
Add regression coverage for rejecting cached scores with different environments or denied paths, passing the target environment's restrictions to the classifier, and rejecting oversized async permission evidence.
GitOrigin-RevId: 14b6f3454bbea458be037560eb1da47d22874df1
## Why
New user input during a Guardian review invalidated an in-flight approval and aborted the pending action, even when the input was only a status inquiry. Review the action again against the latest authorization evidence so it can proceed or be denied based on the updated instructions.
## What changed
- Treat stale authorization as a retryable review error within the existing attempt budget and shared deadline.
- Refresh authorization evidence for each attempt while keeping the pending action fixed, and record evidence from the completed attempt.
- Preserve cancellation and history-reset aborts, and deny approval if stale authorization exhausts the retry budget.
## Testing
Add and update coverage for parent status updates, authorization revocation, repeated updates, cancellation, history resets, and retry deadlines. Verify that refreshed reviews see the latest input and that the pending action executes exactly once only after approval.
GitOrigin-RevId: c683e2efb6f07840b99d0d34acf0d38c9ddfe9bd
Use `notify_one()` instead of `notify_waiters()` in
`terminating_initial_exec_command_rechecks_initial_response_state` to retain
the release notification if the termination waiter has not registered yet.
This prevents the test from timing out due to a missed notification.
GitOrigin-RevId: d233ffc50e016eb75752fd360a4d846de0063683
## Why
Explicit user goal edits can restrict permitted actions, such as “Inspect only; do not publish.” Guardian needs these edits as authorization evidence even though they are recorded as contextual messages.
## What changed
- Add `UserGoalUpdate` and a recording API for objective, status, and clear updates without scheduling a model response.
- Use host annotations to retain goal updates in Guardian review history and root authorization evidence, and invalidate cached authorization when updates are recorded.
- Omit oversized objectives whole and mark their evidence incomplete so truncation cannot turn a restriction into a grant.
- Keep item injection from updating shared model and multi-agent metadata.
## Testing
Extend authorization, retained-context, and review snapshot tests to cover goal-edit cache invalidation, root goal visibility from child threads, and restrictive goals reaching Guardian alongside managed policies.
GitOrigin-RevId: 17b99d9fa8c1620840d6f408d79b405a78a778f8
## What changed
- Add `ThreadManager::with_agent_control_factory` to select a host-owned controller asynchronously using the final thread ID for new and cold-resumed threads. Keep local control as the default, reuse live controllers on warm resume, and preserve parent controllers for internal sessions.
- Fail startup on factory errors or when a provided controller's identity does not match the session identity.
- Defer root service-tier updates to host controllers until thread registration succeeds, preventing failed starts from changing settings on a shared controller.
GitOrigin-RevId: 095afbecfee5d47329038d2a97d0cc0081f181df
## Why
Passing extra descriptors to a PTY previously selected behavior intended for inherited escalation sockets: no EOF on stdin close, different signal exit statuses, and no default `SHELL`. Launch attachments need ordinary PTY behavior and must survive execution even when marked `FD_CLOEXEC`.
## What changed
- Add `ChildFds::Attached` alongside `ChildFds::Inherited` to distinguish launch attachments from legacy inherited descriptors.
- Preserve ordinary EOF, default `SHELL`, and signal exit status behavior for PTY attachments.
- Allow explicitly supplied close-on-exec descriptors through pipe and PTY launches without changing the parent's descriptor flags, using child-side flag updates and macOS spawn inheritance actions.
- Update existing callers to use `ChildFds::Inherited`.
## Testing
Add Unix coverage for attachment accessibility, unchanged parent descriptor flags, default `SHELL`, and signal exit statuses. Extend the PTY stdin-draining test to cover attachments and EOF delivery.
GitOrigin-RevId: 864aedc6c5717d8b43c9d71057c9f54409834509
## What changed
Use the model catalog's `send_user_message_async.parameters` override for the `request_user_input_async` tool schema. Fall back to the bundled schema when the override is absent or invalid, logging a warning for invalid overrides while preserving the catalog description.
## Testing
Extend integration coverage for catalog schemas, empty and invalid overrides, and schema updates during mid-turn model changes. Update the asynchronous question-and-answer scenario to verify that requests carry the catalog schema while work continues and the user's answer arrives.
GitOrigin-RevId: c51a90d3266daaba1e7001aa4026964f84dfb206
## Why
The 32 KiB per-result cap and 128 KiB aggregate budget discard tool metadata even when the outgoing request has room to retain it.
## What changed
- Remove the per-result capture cap and raise the aggregate executed-tool metadata budget to 2 MiB.
- Apply a 15 MiB soft budget to serialized HTTP requests and WebSocket messages, using the actual WebSocket delta. Trim optional result metadata on the wire copy while preserving ordinary content and logical history.
- Prioritize `openai/resource_access` metadata during trimming, and include `overage_bytes` in omission markers.
- Record bytes removed by metadata budgets in `codex.tool_metadata.shed_bytes`, tagged by stage.
## Testing
Add coverage for HTTP and WebSocket message boundaries, resource preservation, residual marker removal, unchanged history, and shedding metrics. Update direct-tool and code-mode tests to verify metadata survives beyond the previous limits.
GitOrigin-RevId: ed00996b77945300f60db1e52eff22b4de2707c1
## What changed
Use `KNOWN_PRODUCT_SKUS` in `SessionTelemetry::with_product_sku`, preserving the existing mapping: `codex` stays `codex`, missing or empty values omit the label, and all other values become `other`.
Remove the registry test `dispatch_uses_the_invoking_turn_product_sku` and its unused imports.
GitOrigin-RevId: b4ad6cbc6205aa35fb2866d72f7205814f5b3566
## Why
Repeated prewarm calls still prepared instructions, tools, and a prompt even when an existing WebSocket connection was already warm.
## What changed
Check for a previous request and a connection that is not known to be closed before startup prewarm preparation. Reuse this readiness check in `prewarm_websocket`, and record `ready` or `needs_prewarm` in the `codex.startup_prewarm.websocket_check` counter before preparation can fail.
## Testing
Extend the WebSocket resume test to verify that repeated prewarm calls skip instruction loading on a healthy connection, while a closed connection triggers preparation again.
GitOrigin-RevId: 6a1b361b36b4e7f16fb283e48a8ce4d4fb996ceb
## Why
Tool telemetry needs to distinguish product SKUs without turning arbitrary configuration values into metric labels.
## What changed
- Read `apps_mcp_product_sku` from the invoking turn when dispatching tools, replacing any stale SKU in the telemetry metadata.
- Add `product_sku` to tool call count and duration metrics and tool result log and trace events.
- Preserve `codex`, map other nonempty values to `other`, and omit the attribute for empty or missing values.
## Testing
Add coverage for SKU separation on a shared metrics client, normalization, and successful and failing dispatches with stale telemetry metadata. Extend export routing tests to check SKU attributes in logs and matching traces.
GitOrigin-RevId: 3fc58c9f7245fd5b65f7cba122e08d7ea838b2d6
## Why
Exceeding the aggregate metadata budget previously replaced all tool result metadata with omission markers, discarding small results unnecessarily. Oversized results also lost resource-access evidence even when that evidence alone would fit.
## What changed
- Raise the executed-tool-call metadata budget per request from 32 KiB to 128 KiB while retaining the 32 KiB per-result limit.
- Reduce the largest result metadata first and stop once the request fits, preserving smaller results.
- Retain `openai/resource_access` when full metadata exceeds capture, request, or direct-call retained-history limits. Keep resource lists intact, and discard optional result metadata before sacrificing call records, source evidence, or completion markers.
## Testing
Add regression coverage for selective reduction, resource-access retention, serialized request size, and direct-call and Code Mode behavior. Update compaction and truncation tests for the larger request budget.
GitOrigin-RevId: 698e47dcbdd3351e9a031e45ea39053608a5a0e4
## What changed
- Move `Provider` and `RetryConfig` into `codex-client`, retaining re-exports from `codex-api`, and switch `codex-model-provider-info` to depend on `codex-client`.
- Move feature-state metric emission into `codex-core`, preserving its behavior while removing the `codex-features` dependency on `codex-otel`.
- Explicitly enable TLS features for `tonic` in `codex-config` and `reqwest` in `codex-http-client`.
- Enable `png`'s `zlib-rs` feature directly in `codex-utils-image` to keep encoded PNG bytes stable when WebSocket dependencies are absent.
GitOrigin-RevId: 91fd63ab01b55d516b3e80e3644d06af8d5a01f6
## Why
Appending output to the completion transcript and pending polling buffer under separate locks allows cancellation to interrupt a chunk update between the two buffers.
## What changed
Store both buffers in `OutputBuffers` behind a shared mutex and append each chunk to both while holding that lock. Polling drains only the pending buffer, while completion events read the retained transcript. Apply this to both local and exec-server output handling.
## Testing
Extend the repeated-drain test to verify that the completion transcript preserves the expected bounded output after polling drains the pending buffer.
GitOrigin-RevId: ef8519582937b0d8c42e46375226501338df4a01
## What changed
Return completed startup prewarm sessions to the client cache and schedule resume prewarm through the normal session setup path. Keep in-flight warmups shared, remove the separate nonblocking prewarmed checks, and simplify the prewarm handle to own a single task.
## Testing
Update the resume prewarm integration test to assert `User-Agent` and `x-codex-window-id` handshake headers while retaining coverage for connection reuse, response continuation, and reconnection after closure. Remove the assertion that healthy resumes skip instruction preparation.
GitOrigin-RevId: a9b6d4810aca9aba2e6e41df181b7d9d90474230
## What changed
- Cast `POSIX_SPAWN_SETSID` to the inferred flag type in the `ProcessMode::NewSession` branch.
- Use `LoaderOverrides::without_managed_config_for_tests()` for both cases in `project_layers_disabled_when_untrusted_or_unknown` so host-managed configuration does not affect the test.
GitOrigin-RevId: 1b27ac3ea139507d3f9402f4c2e3e63933c4d05c
## Why
A previously used WebSocket can close while a thread is idle. Hosts need a way to prepare the connection before the next turn without repeating warmup on a healthy connection.
## What changed
- Expose `CodexThread::prewarm()` using the existing startup warmup and next-turn handoff.
- Reuse healthy connections and pending warmups, retry failed warmups, and repair closed connections. Treat a finished WebSocket reader task as a closed connection.
- Skip scheduling during an active turn or shutdown, and stop warmup admission before shutdown takes the pending task.
- Expose `active_turn_environment_selections()` so hosts can inspect the environments captured by the active turn, including those still starting or failed, when authorizing steering.
## Testing
Add regression coverage for repeated idle prewarm calls, healthy connection reuse with preserved response continuation, reconnection with `generate: false`, and warmup rejection after shutdown. Update delayed MCP discovery coverage to verify prewarm repairs an eagerly closed socket and the first turn reuses it.
GitOrigin-RevId: aa164b91a399de2375eda3bf28397725439fce93
## What changed
Call `ensure_rollout_materialized` after recording pending inter-agent communication, using the supplied persistence context. This also triggers the first execution checkpoint when an agent message starts the first turn.
## Testing
Extend the first-input persistence test to cover inter-agent communication, checking that the checkpoint is requested and sampling proceeds while durable metadata is blocked. Verify that prepared context precedes the agent message and that its author and recipient reach the model.
GitOrigin-RevId: 55779edb1a38fcf4d1c1cff24c09f5a810460c3d
## What changed
Remove the session-level capture mode and make thread-owned retained context the default throughout history management. Simplify input ordering, compaction identity preservation, fork handling, and approval freshness checks by removing legacy capture branches.
Keep checkpoint compatibility review separate: unknown or incompatible checkpoints can still use legacy review while retaining user evidence. Set the already-removed `guardianv2.thread_context` feature's default to false and remove redundant opt-out test variants.
## Testing
Update checkpoint tests to exercise legacy review through restored checkpoint data. Adapt existing compaction, resume, rollback, and fork tests to use unconditional context capture.
GitOrigin-RevId: ab23a0d7aca71d5a103458cff8b0c68137dd9708
## What changed
Always use `GuardianContextMode::ThreadOwned` for session capture and subagent history forks, regardless of `guardianv2.thread_context`. Continue selecting reviewer policy from saved checkpoints, preserving legacy review for incompatible checkpoints and removing the feature gate from reviewer compaction compatibility checks.
## Testing
Update coverage for unconditional retained context across compaction, resume, and subagent forks. Exercise legacy review with saved checkpoints, and verify that local and managed opt-outs do not disable sender context capture or checkpoint migration.
GitOrigin-RevId: cd74e2029c83f12bc655b6563242d06f29dd46af
## What changed
Use retained root context for subagent authorization reviews, removing the separate legacy history path. Remove the runtime `request_user_input` answer buffer and its response counter; authorization versions now track the user-message revision and retained-context completeness.
## Testing
Update authorization and input-handler tests to exercise retained context, and add coverage for the `user_messaging` connector in subagent reviews.
GitOrigin-RevId: 00ad151cf71b843af0e82ae90cbcf559d0c65f89
## What changed
- Deprecate and ignore `features.guardianv2.thread_context`, including profile overrides, with a migration notice. Ignore managed requirements for the removed flag with a warning.
- Preserve surviving legacy root instructions across compaction and resume when retained instructions are incomplete. Include unmatched instructions in worker authorization context with an explicit unknown-ordering notice, without replacing newer retained facts or expanding the reviewer's model window.
- Use surviving source calls to roll back verified answers from older checkpoints that lack acceptance-order metadata.
## Testing
Add regression coverage for legacy instruction recovery, compaction and resume, source matching, and answer rollback around same-turn user input. Update configuration and Guardian review tests to verify that the deprecated opt-out still uses thread-owned context and rejects incompatible compaction evidence.
GitOrigin-RevId: a65936c9e0b912e7667d1385a2ec53df726565de
## What changed
Add `ModelRequestContributor` and `ModelResponseInterceptor` to the extension API. Contributors can add filtered `client_metadata` without overwriting existing or reserved fields and create interceptors for individual requests.
Wire contributors into HTTP and WebSocket requests, distinguishing generation from warmup. Apply response interceptors in registration order before tracing and response bookkeeping so transformed output is recorded consistently. Interceptors can inspect, buffer, or transform events, with stream ownership carrying request state and cancellation.
## Testing
Add tests for metadata protection, incremental event transformation, interceptor ordering, upstream cancellation, and consistency between delivered output, traces, and WebSocket bookkeeping. Integration tests cover output gating and interruption over HTTP and WebSocket, including a contributor that bypasses gating for warmup requests.
GitOrigin-RevId: d4bc1745d2cacf8636728dbc0a58ab9f250e9392
## Why
MCP resource helpers use fixed descriptions and parameter schemas, preventing the model catalog from supplying model-specific guidance.
## What changed
Add `model_messages.tools.mcp_resources` entries for `list_mcp_resources`, `list_mcp_resource_templates`, and `read_mcp_resource`. Resolve these entries for the current model when constructing tool specs for direct calls and Code Mode.
Descriptions and parameter schemas override independently. Preserve bundled defaults for missing fields and fall back to bundled parameters with a warning when a supplied schema is invalid. MCP resource execution remains unchanged.
## Testing
Add unit coverage for independent overrides, literal descriptions, and invalid-schema fallback. Add integration coverage for resource discovery and reading through direct calls and Code Mode, plus assertions that resource tool specs follow model changes between steps.
GitOrigin-RevId: 40b5beddb38b2b61c19dc9cd6013d6ba5d756dbc
## Why
Channel tools use bundled descriptions even when the model catalog supplies tool messages. Let their descriptions follow the active model, including model changes within a turn.
## What changed
- Add channel tool entries to `MultiAgentToolMessages` and pass them to the message board extension for each step.
- Apply catalog descriptions while retaining bundled text for missing or null values and honoring empty strings. Ignore parameter overrides with a warning and keep bundled schemas.
- Clarify bundled descriptions for channel discovery, thread reading, posting, and subscription notifications.
## Testing
Add coverage for full and partial overrides in namespaced and Code Mode tools, preserving Code Mode declarations and parameter schemas. Extend the mid-turn model-change test to verify that the `post` description follows the active model.
GitOrigin-RevId: fca20bed1203d5214713f82cb16a91eeebb38f56
## Why
Output produced before the streaming subscriber attaches can be missing from command completion events, even when it was returned to the model.
## What changed
Record the bounded completion transcript directly in `UnifiedExecProcess` as local and exec-server output arrives. Keep it independent of output polling and streaming delta delivery, and use it for completion events.
## Testing
Add regression coverage for output collected before subscription, both with and without later output. Strengthen the lifecycle test to assert that `aggregated_output` includes both early and late output.
GitOrigin-RevId: 9825acbd706dc4845837c8b4ab1347d8267ce0af
## Why
Tool lifecycle observers need visibility into calls rejected before execution starts and timing that remains available on cancellation, independently of tracing settings.
## What changed
- Add `on_tool_dispatch` and `on_tool_timing` callbacks to `ToolLifecycleContributor`, with thread, turn, and call IDs for correlation.
- Report direct calls before readiness, dispatch waiting, and hooks. Report handler duration when dispatch completes or is dropped, excluding readiness and gate waiting and returning zero if the call never passes the gate.
- Expose code-mode host durations as a separate `HostOperation` timing boundary. Exclude nested code-mode calls from dispatch and handler timing observations to avoid double counting.
## Testing
Add tests for callback ordering on completed and rejected calls, timing on cancellation, zero handler duration before gate admission without tracing, and code-mode host timing without nested dispatch or handler timing observations.
GitOrigin-RevId: 97998b5094564c13cb2cfad089bb0a9d6615eb5c
## What changed
Add `otel.log_agent_responses`, disabled by default and requiring an OTLP HTTP or gRPC log exporter. Emit `codex.agent_response` for completed `final_answer` messages from main agents and spawned task agents, with session, turn, item, and available parent/root attribution.
Strip memory citations from exported text, preserve the stored answer, and cap responses at 64 KiB on a UTF-8 character boundary. Include the original byte length and a truncation flag, and suppress duplicate item completions within each turn. Exclude commentary and non-task agents.
## Testing
Extend configuration tests for default-off and explicit opt-in behavior, the agent execution test for main/subagent response attribution, and the log-buffer test for response-event exclusion.
GitOrigin-RevId: eacda1150de2e6bac2c667d71b57214b0a086f1a
## Why
The Browser connector on `codex_apps` needs the computer-use policies and review handling already applied to `node_repl` and `cua_repl`.
## What changed
- Classify `connector_openai_browser` using registered tool metadata and preserve its computer-use scope through Guardian review.
- Extend confirmation-policy forwarding, review evidence capture, JavaScript execution tracking, and initial-call approval handling to the Browser connector.
- Correlate Browser elicitations with live invocations so nested actions retain their own review identity while assessments are attributed to the originating call. Require verified Browser identity for strict nested review.
- Include the Browser connector in computer-use policy prompts and bundled model messages.
## Testing
Add integration coverage for ordinary and strict Browser nested reviews, including policy injection and action attribution. Verify strict review declines requests with missing or unknown invocation correlation or a non-Browser registration.
GitOrigin-RevId: b04af6fb9db1bac2203dc4265913d210746df90b
## What changed
Add `model_messages.tools.indirect_description_prefixes` with selectors for exact namespaces and configured MCP server names. Apply the selected model's guidance to namespace documentation embedded in `CodeModeOnly` prompts, `ALL_TOOLS` descriptions, and namespaces returned by tool search.
Trim prefix values, treat empty values as no prefix, and reject conflicting selectors for the same namespace. Apply prefixes during rendering so model changes take effect without altering direct tool specifications, search ranking, or tool dispatch.
## Testing
Add unit tests for prefix normalization, namespace grouping, MCP server mapping, and conflicts. Add scenarios covering both Code Mode variants, clearing prefixes on model changes, unchanged tool dispatch, and conflict rejection before a model request.
GitOrigin-RevId: 0c7ce6d418c775945c2ccfdab3c605fa4d431b55
## Why
HTTP retries used local backoff even when the server supplied `Retry-After`. Relative retry delays also failed to account for time spent propagating errors or reporting retries.
## What changed
- Parse `Retry-After` delay seconds and HTTP dates into a monotonic deadline captured when response headers arrive.
- Honor that deadline for HTTP retries, falling back to local backoff when valid advice is absent.
- Preserve deadlines through API and Bedrock error mapping, stream retries, and exhausted retry state. Expired advice remains a zero delay instead of triggering local backoff.
## Testing
Add coverage for header parsing, deadline countdown and expiry, error mapping after exhausted HTTP retries, and delayed stream retry notifications. Update Responses and remote compaction tests to verify that HTTP retries honor `Retry-After`.
GitOrigin-RevId: a2eff02946e5524f29e06f7ba1431e3d339261a4
## What changed
- Add `tui.copy_on_select` with `auto` (default), `always`, and `never` modes, and apply it to the fullscreen transcript, transcript overlay, and resume/fork previews.
- Enable `auto` in tmux and Zellij, and in direct macOS terminals except Ghostty and Kitty. On other platforms, enable it in direct terminals identified as iTerm2 or Terminal.app.
- Copy nonempty mouse selections on release, including word and line selections, while retaining their highlight. Preserve link activation and ignore empty selections.
- Clear composer selections after confirmed keyboard copies, matching right-click copies, while preserving the draft and cursor. Keep selections when copying fails or delivery is unconfirmed.
## Testing
Add coverage for terminal defaults and configuration overrides, copying on release, retained highlights, repeated clicks, link activation, and empty drags. Extend composer coverage to verify selection clearing for `Cmd-C`, `Ctrl-C`, and right-click across clipboard outcomes.
GitOrigin-RevId: 24e6f9e267ef3ab249c5356db736e094127f68b8
## Why
Startup prewarm waited for tool discovery before opening its WebSocket connection. Slow MCP startup therefore delayed connection setup even though the handshake could proceed independently.
## What changed
- Run the WebSocket handshake concurrently with tool capture, then send `generate=false` with the discovered tools and finalized request metadata.
- Include model and effective service-tier routing hints in preconnect, including the inherited tier for spawned subagents. Omit routing hints for guardian reviewer requests.
- Recover authentication failures during preconnect and switch to HTTP fallback on `426 Upgrade Required`.
## Testing
Add and extend regression coverage for handshake overlap with delayed MCP discovery, cancellation before warmup, finalized Responses Lite tool metadata, socket reuse and reconnection, service-tier changes and inheritance, and authentication recovery during preconnect.
GitOrigin-RevId: ecb53540765df8227e55e79910a13a05260a4c8d
## What changed
Use `agent_control.resolve` for message board agent lookups and path validation instead of accessing `local_agent_runtime` directly. Derive paths from the session source, with a root fallback, and verify that each path resolves to the agent that owns it.
Validate the requested caller's thread for path and clock queries, and apply the same path ownership check to notification recipients.
GitOrigin-RevId: 92632a31b493b6519d2154f49e9d1d4a1019b394
## Why
Actions targeting a secondary environment could be reviewed with the primary environment's denied-read restrictions. Each review needs the permission context of the environment that owns the action, including when a Guardian session is reused across environments.
## What changed
- Carry `environment_id` through environment-scoped approval requests and their planned-action JSON.
- Select and label permission context using the target environment, explicitly stating when it has no denied-read paths or globs.
- Reject reviews for unavailable target environments and reject environment IDs longer than 256 bytes before Guardian inference, while preserving manual approval routing for oversized IDs.
## Testing
Add coverage for `exec_command`, `apply_patch`, and `request_permissions` reviews switching environments while preserving the existing review prefix. Extend tests for environment-specific restrictions, unavailable environments, action serialization, and the 256-byte ID boundary.
GitOrigin-RevId: ad3292edddb1c6f5b180142c6857cba6f1308328
## What changed
Add `AgentControl::ensure_child_loaded` and use the parent's configured agent control in `ThreadManager` to reload recorded V2 children. The local implementation delegates to the existing loader using the live parent's current configuration, preserving parent-controlled restoration without sending input.
GitOrigin-RevId: 67cadf79cbc034eb271c5ae13145f1a42722fe69
## Why
Enabling `features.token_budget.use_history_notes_extension`, explicitly or through model defaults, rejected session startup when the model lacked `supports_experimental_context`, even with experimental mode disabled.
## What changed
Remove that startup restriction so token-budget history and notes can be used independently of the model's experimental context capability.
## Testing
Extend core tests to cover explicit configuration and model defaults on startup and cold resume, checking `new_context`, token-budget contexts, and `history_ingest_requested` metadata. Add app-server coverage for native history and notes tools and context-window hints without experimental context capability.
GitOrigin-RevId: 6157479aeb75ffd785b8d4b2f48b11c6f46e8f35
## Why
Messages sent through the singular `user_message` connector were omitted from Guardian's delivered assistant message evidence because only `user_messaging` tool names were recognized.
## What changed
Accept both namespaced and flat `user_message` forms of `send_message` alongside the existing `user_messaging` forms.
## Testing
Extend Guardian subagent authorization tests to cover the singular connector and flat tool names, including blocked post-tool hooks and cancellation before confirmation. Add a negative case ensuring `send_message_to_thread` is not treated as delivered message evidence.
GitOrigin-RevId: 68495642ef4b78eec71df4fee2bacfda407adc47
## What changed
Add `resolve_root_git_project_uri_for_trust` to resolve repository trust roots through `ExecutorFileSystem` using executor path conventions. Share repository and linked-worktree validation with native lookup while preserving native ancestry for paths with opaque URI representations.
Extract `ProjectTrustLookup` to match merged project settings using supplied path spellings and an explicit path convention. Preserve canonical-before-original and cwd-before-repository-root precedence, including cwd entries without a trust level, with ASCII case-insensitive matching for Windows.
## Testing
Add coverage for POSIX, Windows drive and UNC trust roots, project-key precedence and case handling, and native/URI lookup parity. Extend environment-config coverage to verify returned `projects` entries include entries without a trust level.
GitOrigin-RevId: 315434802e86cceee85b14bc1c3767a45e3139f5
## What changed
Launch Unix shell snapshot commands through `codex_utils_pty::Command` with `ProcessMode::NewSession`, replacing the custom `pre_exec` hook. Pass the complete, scrubbed child environment and preserve the original command arguments so NUL bytes are rejected before execution.
## Testing
Add a Unix regression test asserting that a snapshot script containing a NUL byte returns `InvalidInput` without creating the file it would otherwise write.
GitOrigin-RevId: ef68a6c9f64d7a541498d3ecc4113fad8ff7ed14
## Why
A realtime call can start or end while a text turn is still running. Using call activity captured at turn creation leaves subsequent model requests with stale realtime context.
## What changed
Capture realtime activity and mode instructions together in a `StepContext` snapshot for each model request. Use that snapshot to build realtime instructions and persist `realtime_active` in the request's turn context. Store the conversation and mode instructions under one mutex so they are installed together when a call starts.
## Testing
Extend the realtime handoff integration test to start and close a call during one text turn, verifying that successive requests include the appropriate start and end instructions.
GitOrigin-RevId: 4c5c2b47b7c0c06ae28167013218dc2e3cd72c42
## Why
Guardian authorization reviews need the assistant message that prompted a user’s approval, even when a post-tool hook blocks the messaging result or compaction removes the original tool call.
## What changed
Retain confirmed delivered assistant text from tool-output metadata at the original call’s position in thread-owned Guardian context. Recover these messages when restoring checkpoints and respect the call’s inherited-context status.
## Testing
Extend authorization coverage to verify that a delivered message remains in the Guardian root snapshot after a blocked tool result, compaction, and resume, and update checkpoint expectations to preserve assistant/approval ordering.
GitOrigin-RevId: df30ec8a3ef21443210a937ab6db119de8a5fd51
## Why
A user can reply to a streamed question before its completed message is recorded. Assigning the assistant message's order at completion can place the reply before the question in retained context.
## What changed
Reserve an assistant message's order when its source stream starts in thread-owned Guardian context, then reuse that reservation when recording the message. Reserve completion-only messages before publishing their text, and give text and plan output from the same source message a single order.
## Testing
Add streaming regression coverage that accepts a reply before the question completes and verifies question-before-reply ordering both live and after resume. Cover server-provided and generated message IDs, plan output, and text combined with a plan.
GitOrigin-RevId: cb67e7459c804df7beb0841908244202448c655a