## Why
An MCP server can belong to a different environment from the turn's primary environment. An early Guardian score based on the issuing context must not bypass review when the server owner's permissions differ.
## What changed
- Capture the owning environment's permissions when preparing an MCP call and retain them for server-initiated approvals tied to that still-running call.
- Use the captured permissions consistently in Guardian review prompts and permission context.
- Require a fresh synchronous review when the captured owner permissions do not match the early score's authorization.
## Testing
Extend regression coverage for MCP score reuse across environments and for follow-up approvals from a local MCP server during a remote-primary turn. Assert that reviews use the owner's denied paths and require a fresh review when permissions differ.
GitOrigin-RevId: eb5eeb1259732c57f39765c38e34148fa0787dae
## What changed
- Expose `PromptCacheTtl` through `TurnStartOptions` and `RecoverTurnRequest`, supporting `30m` and `12h` minimum cache lifetimes.
- Carry the selected TTL through turn execution and compaction into `prompt_cache_options.ttl` on Responses HTTP and WebSocket requests. Omit the field when unset and keep the selection scoped to the turn.
- Include prompt cache options in WebSocket request reuse checks.
## Testing
Add coverage for both TTL values and omission on a subsequent turn without an override, and extend WebSocket serialization coverage to include prompt cache options.
GitOrigin-RevId: 8529306e6ad6030fe77c5e6bf19f3810717c0c5e
## What changed
Add `user_input_extension_data` to `TurnInputRequest` and carry it with each queued user input through completion, including inputs that steer an active turn. Expose the data to lifecycle contributors through `on_item_completed_with_metadata`, whose default implementation forwards to `on_item_completed` for compatibility. Keep this data out of model input and preserve the existing serialized input shape when no extension data is present.
## Testing
Add serialization round-trip coverage and extend the concurrent submission test to verify that inputs sharing a client ID retain their own metadata, report completion in the accepting turn, and omit extension data from model requests.
GitOrigin-RevId: f880cf812994a030cb1be9418280ba69e2885808
## Why
Tests need to distinguish slow subprocess startup from operation timeouts and wait for asynchronous work before asserting results or cleaning up fixtures.
## What changed
- Synchronize subprocess readiness, queued-turn completion, and matching UI events; allow more time for cold startup and separate startup from shutdown deadlines.
- Adapt Windows fixtures and permission expectations, provide the voice-host test runtime DLL path, and normalize platform paths and animated status snapshots.
- Use current configuration permissions when changing directories in embedded TUI sessions, while retaining saved permissions for remote sessions.
- Allow the release prompt-prefix comparison to accept the exact image-tool description update that removes image detail options, and refresh the corresponding tool snapshot.
## Testing
Extend inherited-session metadata coverage to both legacy and paginated thread history, including persisted history mode and revision-aware resume.
GitOrigin-RevId: 0afb38403fc0adb0d83175344749584f0cdf9979
## What changed
Introduce `ItemIdGenerator` and pass the runtime-owned generator through sessions, model clients, history, hooks, tool outputs, and memory requests. Keep UUIDv7 generation as the default and replace direct calls to `ResponseItemId::new` with the shared callable.
Preserve existing item IDs and backfill missing or empty IDs through the same generator, including forked history before reconstruction and persistence.
## Testing
Extend coverage for UUIDv7 IDs on user messages, agent messages, and additional tools, and assert that forked model context matches the backfilled items persisted to history.
GitOrigin-RevId: 0dd9ccf0f46f0f1005a6acfc740133b03ce82259
## What changed
- Record `codex.skills.read.result` and `codex.skills.installations.result` counters with bounded outcome labels for successes and failures.
- Tag both counters with `discovery_version` and installation listings with `source_filter`.
- Make session telemetry available through the step store so skill tools emit metrics with the current step's model metadata.
## Testing
Add coverage for read metrics in both discovery versions, installation listing outcomes and source filters, and extension metrics retaining the current model metadata after a model switch.
GitOrigin-RevId: 0b5418e2b94a89149a20877f32ca2b2e196884e7
## Why
Direct executor skill discovery used unrestricted filesystem access, bypassing the turn's permission context. Cached catalogs also needed to account for changes in filesystem access within a turn.
## What changed
- Bind selected capability roots to callback-scoped filesystem access through `AccessedSelectedCapabilityRoot`.
- Pass accessors built with the turn's granted permissions into skill preparation and discovery, removing the executor skill provider's environment lookup and unrestricted accessor.
- Include filesystem access keys in the direct discovery cache so permission changes trigger rediscovery.
## Testing
Extend tests to verify that restricted discovery returns no skills when sandbox access is unavailable, restoring access restores discovery, and changing or restoring access invalidates the catalog cache.
GitOrigin-RevId: 0f7aa7646f65923f65f0cfc0b387d94bd7f2db05
## What changed
Mark `unified_image_budget` stable and enable it by default. Supported models now use unified image preparation with `original` detail, and `view_image` omits the `detail` parameter from its advertised schema.
## Testing
Update image input, MCP output, history replay, and tool schema expectations for the new default. Keep explicit coverage of the disabled feature and models that do not support original image detail.
GitOrigin-RevId: 2d6fc8019149fcf18b5813db2d2082ba95de2241
## Why
Repository skill discovery must reflect current filesystem access, including newly approved grants and narrower permissions. Previously listed skills can remain in conversation history after a turn-scoped grant expires, so catalog updates need to tell the model when availability changes.
## What changed
- Discover repository skills through the selected executor's permission-aware filesystem accessor and refresh snapshots when the working directory or access changes. Use the current step's snapshot for skill selection and invocation.
- Preserve repository boundaries even when project markers are hidden by read restrictions, and report unsupported sandbox backends as skill-loading errors.
- Track grant-dependent catalog entries and emit availability notices when skills disappear or return, even when the metadata budget is exhausted.
- Resolve implicit skill paths through their owning filesystem and exclude remote repository skills from local implicit command attribution.
## Testing
Add coverage for turn and session grants, grant expiry and restoration, hidden and newly created repository markers, cached read denials on Windows, unsupported remote sandboxes, and executor-backed implicit skill paths.
GitOrigin-RevId: ac1af483e73e3130524aeeabe218630435054028
## Why
Skill discovery and metadata loading used raw filesystem handles with unrestricted reads, and cache keys distinguished filesystems without accounting for captured permissions.
## What changed
- Pass borrowed `EnvironmentAccess` accessors through skill root resolution, discovery, canonicalization, and metadata reads.
- Include captured permissions in skill snapshot and empty remote root cache keys.
- Add fixed-path watches to `EnvironmentAccess`, falling back to live discovery when read restrictions prevent using unsandboxed executor watches.
- Keep user and plugin roots under host filesystem authority independently of the selected repository executor.
## Testing
Extend remote root cache coverage to verify that changing captured permissions triggers a fresh scan and that restricted accessors decline unsandboxed watches.
GitOrigin-RevId: 97d4bfdfcba78a93fc8845773c6397d4364494e3
## Why
Cached repository skill metadata must not authorize reads after access is revoked or a skill file or directory becomes a symlink to a denied location.
## What changed
Read repository skill instructions through a current environment accessor for the filesystem that discovered them. Reject reads when no matching accessor is available, and cache filesystem identity instead of retaining unrestricted read access.
## Testing
Add regression coverage for revoked permissions, file and directory symlink replacements, and missing or mismatched filesystem accessors.
GitOrigin-RevId: 8dad83b7c7893e0d66e2fe1c0c240715db582005
## Why
Uploaded audio was rejected even for audio-capable models. Invalid or expired recordings also need to be excluded from later requests so users can continue the conversation.
## What changed
- Accept uploaded audio when the selected model supports audio; otherwise, preserve valid sibling input and report the unsupported attachment before inference.
- Track successful audio decoding by model and provider, and attribute provider rejections against the exact submitted request. Preserve attachments when attribution is ambiguous.
- Persist confirmed rejected file IDs across compaction and resume, omitting them from future requests without rewriting retained user history.
- Check audio availability before remote compaction and retry once without an unambiguously rejected recording. Include guidance to remove or replace affected attachments in audio errors.
## Testing
Add unit and scenario coverage for uploaded audio across follow-up turns, compaction, cold and paginated resume, model switching, ambiguous rejections, expired files, and queued or interrupted input.
GitOrigin-RevId: e701901e7b1c0865c9f2a5918197215f549b06c0
## What changed
Map provider `budget_reached` errors to `SessionBudgetExceeded` for HTTP 400 responses and streaming failures. End SSE streams immediately on this error, ignoring retry headers and later completion events, and display `budget reached` in the TUI.
## Testing
Add coverage for HTTP error classification, immediate SSE termination without retries, WebSocket error delivery and subsequent request recovery, and TUI error rendering and task-state cleanup.
GitOrigin-RevId: 6a62d699cdb9cb446214cacfacd0c9ed68bf21a6
Update the reviewer configuration test to call
`ManagedFeatures::from_configured_with_warnings` and pass
`parent_config.startup_warnings`, avoiding the crate-private
`from_configured` constructor.
GitOrigin-RevId: 2ba41ba6918e1007b3af013b7146940d919e4560
## What changed
- Share a lazily registered runtime across threads, model discovery, and extension clients when `runtime_agent_instances` is enabled, while honoring each thread's authentication mode and credential owner.
- Bind model catalogs to the effective provider and authentication context while preserving cache policy and live API-key discovery settings.
- Resolve credentials, routing, and transport policy together for each request. Preserve proxy and TLS settings, validate runtime account selectors, and prevent pooled connections from crossing runtime identities.
- Accept supported ChatGPT subdomains when selecting the registration environment.
## Testing
Add integration coverage for shared runtime registration, dual-header and assertion-only modes, disabled and third-party providers, credential replacement, subagents, and delegated review. Add coverage for catalog cache policy and runtime-aware connection reuse.
GitOrigin-RevId: 99dd9d987c29c93597a648f6586f98ac6a932c3c
## What changed
Move the board host adapter and `install_agent_message_board` from `codex-core` to `codex-app-server`, using public core runtime interfaces. Update extension registration, test callers, dependencies, and installation documentation to use the new location.
Format `CHANNEL_POST` notification payloads in the host adapter and retain recognition of legacy board notices in core. Expose `MULTI_AGENT_V2_NAMESPACE_DESCRIPTION` for host extensions to share with native tools.
GitOrigin-RevId: 679b5751de102bff80e6b9d4b0728a84fbdedd85
## What changed
- Move approval-request and prompt-composition tests from `core` to `guardian-reviewer`.
- Move transcript collection, budgeting, and approval-reason truncation tests to `guardian-context`, removing the test-only rendering helper from `core`.
- Move the managed-feature reviewer configuration test to `guardian-v2`.
GitOrigin-RevId: 1886a10cd6aba07b7ca2bcce28d45e0a698111a6
## What changed
Introduce `GuardianReviewResponse` to retain both the parsed assessment and the original response text. Reuse the stored result for authorization checks, denial reconsideration, review record capture, and final assessment extraction instead of reparsing the response.
Preserve raw text for review records and keep invalid responses as completed turns so history and session reuse remain unchanged.
## Testing
Extend review record coverage to wrapped denials and invalid responses, and verify that invalid assessments remain retryable while missing assessments do not.
GitOrigin-RevId: 50c19e788a8d57f951c6140d66306b3538515adc
## Why
A timeout during denial reconsideration replaced an already completed Guardian denial with a timeout outcome, losing the original assessment.
## What changed
Keep the original denial when reconsideration times out, including its risk level, user authorization, and rationale. Discard the review session while preserving cancellation behavior.
## Testing
Add a reconsideration timeout scenario that verifies the original assessment and denial rationale are preserved and the requested file write remains blocked.
GitOrigin-RevId: 448a6d2d1e779c58076091384fe1215b8c02bde2
## What changed
Add the disabled-by-default `guardian_denial_reconsideration` feature to reconsider a synchronous Guardian denial once before publishing the final decision. The follow-up uses the same review session, evidence, model settings, and original deadline, without compacting the retained context.
Only a valid second assessment replaces the denial. Invalid or failed follow-ups keep the original denial and discard the review session; cancellation and timeout retain their normal outcomes.
Allow a custom developer message through `auto_review.experimental_denial_reconsideration_prompt`, limited to 1,000 UTF-8 bytes. Omitted or blank values use the built-in prompt, which grants no new authorization and preserves the security policy.
## Testing
Add scenario coverage for feature gating, unchanged approvals, reconsidered approvals and denials, invalid assessments, failed follow-ups, custom prompts, and retained context. Extend cancellation coverage to reconsideration and config tests to prompt normalization and byte-limit validation.
GitOrigin-RevId: 61c45d5a948e3e5684c4b4048d6e90fd3f1f2476
## What changed
- Gate GIF output behind `features.image_generation_animation`, disabled by default.
- Accept `gif` options for generation and editing, with optional `frame_count` and `frame_duration_ms` controls. Use `gif: {}` for API defaults.
- Preserve animated output with `.gif` filenames and `image/gif` data URLs while providing a still preview to the model.
- Add guidance for simple animations and spritesheet-based GIF edits.
## Testing
Add integration coverage for GIF generation and editing, explicit frame controls and API defaults, saved animation bytes, and still-preview replay across follow-up turns.
GitOrigin-RevId: 08afa0316ae3675921652157836191a649f563cf
## What changed
- Remove automatic BuildBuddy configuration and credential forwarding from Bazel CI, release, SDK, and voice builds. Strip remote execution CI configs in the shared wrapper while retaining explicit remote configurations for local use.
- Use native Windows host tools and audio dependencies for Windows Bazel actions, forwarding the required toolchain and environment settings.
- Initialize message-board MCP servers through a per-session `OnceCell` so server startup does not hold the shared registry lock across an await.
- Expose the message-board test helper to the core Bazel package and update the runtime-auth test call for the `reauth` argument.
GitOrigin-RevId: 5d5c1f4d71fa841090dea8eec8006380981fb65b
## Why
An MCP server's environment permissions can change after a tool step captures its context. Guardian reviews of direct MCP calls could therefore miss denied paths present in the permissions used to prepare the call.
## What changed
Pass the prepared server environment's sandbox context through MCP approvals and use it to build Guardian's permission evidence, including denied paths and globs resolved for that environment. Keep the sandbox context out of serialized approval actions.
## Testing
Add a regression test that updates a remote MCP owner's permissions after the step starts and verifies that Guardian sees the owner's denied temporary directory. Extend the approval JSON test to verify that supplying sandbox context preserves the serialized action shape.
GitOrigin-RevId: cab0d7c60112a97adf98e5548cdc066b260bb073
## Why
Elastic entry caps can shorten review framing and authorization warnings along with supporting evidence. Those boundaries and warnings need to remain intact when evidence is truncated.
## What changed
- Preserve protected framing, host notices, and exact planned actions during elastic entry preparation.
- Carry protection metadata through root conversation, trusted answer, and `node_repl` evidence composition while allowing supporting text to be capped.
- Wrap sender evidence in protected boundaries and a warning that partial context does not transfer permission.
## Testing
Extend elastic-budget regression coverage to verify that exact action JSON, permission boundaries, and sender evidence warnings survive while supporting text is capped.
GitOrigin-RevId: 0b4bebb5a9da3611c92d8176cec99c504e8b7b7b
## What changed
Add `BoardBackend` so the core adapter selects the configured backend and supplies a `MessageBoardHost`, while the extension opens MCP, connected, remote, in-memory, and local boards at thread startup.
Move remote credential handling, HTTP client construction, and backend installation into `codex-agent-message-board-extension`, preserving existing notification delivery semantics.
GitOrigin-RevId: 98fa5525f142596c6cc6b203198fd537546c01d5
## What changed
Enable `multi_agent_v2` and the new `agent_message_board_mcp` feature to automatically start a temporary, tree-scoped HTTP MCP message board without plugin or endpoint configuration. The MCP feature defaults off and takes precedence over `agent_message_board`.
Share board state across parent and child agents while retaining each caller's host binding. Keep the server alive while participating threads remain, and serialize board tool calls through the MCP server configuration.
## Testing
Extend the HTTP board integration scenario to cover automatic discovery, parent-child message sharing, child subscriptions and posts after the parent unloads, serialized mutations, and absence of a persistent board database.
GitOrigin-RevId: 613183c14b2ab67dfb1aaf3a3abf338376d1cc05
## Why
Host-provided context such as budget reminders can become stale while compaction runs. Replaying a captured value or retaining its comparison snapshot can prevent the next step from emitting a fresh reminder, even when the remaining budget has changed.
## What changed
- Add `WorldStateSectionContribution::without_full_context()` to omit a section's fragment and comparison snapshot from initial and compacted context rebuilds while preserving ordinary step updates.
- Reset comparison state after prefix compaction for sections excluded at either capture or installation, including when their messages survive in the live suffix.
- Include step World State updates when building debug prompt input.
## Testing
Add regression coverage for budget reminders refreshing after remote compaction within the same threshold, unchanged request prefixes within a context window, refreshes with a retained live suffix, and step reminders in debug prompts.
GitOrigin-RevId: ea4456755e16c93b5d16e8c762b26a33f8571a86
## What changed
Register Guardian evidence-board cleanup with the app server's thread store when Guardian V3 is enabled. Leave Guardian storage untouched when the feature is disabled, and report cleanup failures as thread-store errors.
## Testing
Extend deletion tests to cover feature gating, preservation of unrelated boards and a surviving main thread's board, and corrupt-database recovery. Expand message-board tests to verify namespace isolation and persistent deletion markers that prevent later writes.
GitOrigin-RevId: d9119d22607769c92448d0f3cacbbfd03fbdf943
## What changed
- Thread `ContextBudgeting` through synchronous context and image preparation. Elastic mode preserves candidates for later entry capping and allocation; existing reviewer callers continue to use `Fixed`.
- Defer transcript selection, supporting-text caps, and image budget admission in elastic mode while preserving exact planned actions. Mark host framing as protected and distinguish optional user messages from required manual approvals.
- Add `ElasticBudgetConfig` validation requiring section minimums, including fallback policies, to sum to `DEFAULT_MAX_INPUT_TOKENS`.
## Testing
Extend tests for elastic transcript preservation, deferred native tool-call limits, oversized planned actions, image allocation, and section minimum totals above and below the required budget.
GitOrigin-RevId: 46a4605e12e2bab5973097eb1caf5fd99f6640aa
## What changed
- Build native voice SDK and runtime artifacts with Bazel for Linux GNU, macOS, and Windows on x64 and ARM64, then configure Cargo jobs to consume them. Keep musl builds in a separate job without these inputs.
- Validate artifact receipts against the target, source commit, and source manifest; verify SDK file hashes and relocate pkg-config metadata. Package the runtime and plugins with nextest archives and restore `CODEX_TEST_VOICE_RUNTIME` when running shards.
- Prepare native Windows voice tools for argument-comment linting and install ARM64 DotSlash on Windows ARM64. Reduce archive disk usage, bound Linux ARM64 build concurrency, and correct the JUnit artifact path.
- Recognize TLS errors wrapped directly in `io::Error`. Make TLS fallback fixtures select the native backend explicitly, allow the MCP test server's non-loopback address, and isolate skill-root tests from ancestor Git markers. Install `git` in remote test containers and filter MCP discovery assertions to POST requests.
## Testing
Add tests for relocated voice inputs, Windows ARM64 import libraries with host-native pkgconf, and rejection of mismatched receipts or corrupt SDK files. Extend untrusted-certificate coverage to an explicitly selected rustls backend.
GitOrigin-RevId: da3ff690b94906edc1f8f60a3c7feda1bf66134a
## What changed
Introduce `ContextBudgeting::Elastic` to prepare captured root conversation and Node REPL evidence without the fixed per-section request caps. Elastic preparation preserves message text and candidates for later allocation while retaining storage omission notices and legacy source deduplication.
Keep `ContextBudgeting::Fixed` as the default and use it at existing call sites.
## Testing
Add tests covering elastic root message preservation and legacy source deduplication, plus REPL text, images, and omission counts in text-only and multimodal modes.
GitOrigin-RevId: ce4fae9d725694456525a413fb511166df6f5e2c
## What changed
Map audio size, data, format, and sample-rate validation failures to `InvalidAudioInput` for HTTP 400 responses and streamed errors. Preserve the provider's message, falling back to `Invalid audio input.` when it is absent or blank.
Classify these errors as non-retryable and expose them as `BadRequest`. Redact their messages in doctor diagnostics and group them as invalid requests in telemetry.
## Testing
Add coverage for all six audio validation codes across HTTP errors, streamed `error` events, and `response.failed` events, checking error classification, message preservation, and the absence of retries. Extend doctor diagnostic redaction coverage for `InvalidAudioInput`.
GitOrigin-RevId: 0a59964bcabd83997bdb32fc9318a5482dac33b0
## What changed
- Allow audio inputs to carry uploaded file references via `fileId` in the app-server API and `file_id` in model content, preserving existing inline audio shapes and Python class names.
- Preserve mixed inline and file-backed audio ordering through history reconstruction and migration, and budget file-backed audio conservatively when duration is unknown.
- Keep uploaded audio disabled at runtime: reject it before inference or raw history injection, preserve accompanying text, and prevent rejected attachments from reaching follow-up or resumed requests.
## Testing
Add coverage for wire-format round trips, SDK compatibility, mixed audio history ordering, and rejection during turn start, steering, task completion, and raw injection.
GitOrigin-RevId: 70895c47a2494c0c9936348ad1250eb1b7b892a6
## What changed
Mark `deferred_tool_world_state` as stable and enable it by default. Deferred tool namespaces now appear in the developer `<tools>` context instead of the `tool_search` description. Explicitly disabling the feature preserves discovery metadata in the search description.
## Testing
Update tool discovery tests to cover the default behavior and explicit opt-out, and refresh request snapshots for the deferred namespace context.
GitOrigin-RevId: d58e369ea22754cee593c26a5ca011e41ba56e79
## What changed
- Add `StartThreadOptions` setters for captured thread instructions and execution policy snapshots. Captured instructions replace the live thread provider; empty text clears the thread contribution. Hosts must supply inherited settings again on cold resume.
- Install inherited policies in independent managers only when the destination ignores user and project rules, has no additional policy files, and has matching managed requirements. Preserve managed command restrictions, host executable mappings, and network denials, including restrictions that absolute-path rules could otherwise bypass.
- Reject inherited startup settings for isolated sessions and reject combining local and transported execution policies.
## Testing
Add coverage for policy inheritance through children and grandchildren, incompatible or weakened policies, absolute-path amendments, and captured instructions overriding or clearing live instructions on startup and resume. An execution integration test checks that an inherited allow rule runs without approval while a managed denial still blocks execution.
GitOrigin-RevId: c1147992fe5bb5ba4bcf981c08fcfcb6f6bca8a1
## What changed
Return `CatalogModel` from model lookups, keeping metadata together with its `Bundled`, `Provider`, `ExplicitConfig`, or `Synthetic` origin through config overrides and runtime snapshots. Replace `used_fallback_model_metadata` checks with explicit `Synthetic` origin checks.
Share the underlying `Arc<ModelInfo>` with extension stores and use copy-on-write for metadata changes. Keep origin tracking outside serialized model metadata.
## Testing
Extend coverage for origin retention across cache reloads, namespaced model lookups, catalog fallback, and config overrides. Verify that step snapshots and extension stores share the same model metadata allocation.
GitOrigin-RevId: bb6130c94a7a795aa168ee24664a1dd453579fba
## Why
Plugin and skill catalog reads currently wait for the Apps server's initial `tools/list` to finish, even after its MCP transport is initialized.
## What changed
Add the disabled-by-default `features.apps_early_resource_discovery` flag. When enabled, host-owned Apps requests for `mcp/plugin` and `mcp/skill` resources can use the initialized transport while the initial tool inventory is pending. Server readiness still waits for the inventory to complete, and retries use normal readiness.
Bound early client acquisition by the configured startup timeout, propagate startup failures and cancellation, and reject pages if the connection, authentication scope, or resource cache generation changes during discovery.
## Testing
Add coverage for gated discovery, concurrent plugin and skill reads, startup timeouts and failures, cancellation, cache invalidation, and account switches. Verify that early discovery reuses a single handshake and tool inventory, including with the newer MCP protocol and connection sharing enabled.
GitOrigin-RevId: 955b1f6d43b733bdf9763c1caf2ce6913c686c81
## Why
Standalone web search must use the same permission mode as hosted search. Permission changes during a turn should take effect on the next turn, without changing web access for searches in the active turn.
## What changed
Pass the turn's `WebSearchMode` to the web search extension and use it to determine tool availability and `external_web_access`, while retaining provider support checks and thread-level search settings.
## Testing
Add an app-server regression test that switches from cached search to Full Access while a turn is paused. Searches before and after the update keep `external_web_access` disabled in that turn; the next turn enables it.
GitOrigin-RevId: 9e3b8598f2e491388b7e7d4840c849155ae95e88
## Why
Standalone web search errors currently abort the turn as fatal failures, preventing the model from responding to them.
## What changed
Return client setup errors to the model and represent failed search requests as unsuccessful tool outputs. Failed requests still emit search completion events and retain external-context handling. Limit error messages to 1,024 bytes, truncating at a UTF-8 character boundary with a truncation marker.
## Testing
Add coverage for failure status reporting and UTF-8-safe error truncation. Extend workspace routing tests to verify that a rejected redirect returns a bounded diagnostic to the model, allows the turn to complete, emits search lifecycle events, and marks thread memory as polluted.
GitOrigin-RevId: 9fb308990afa2ce0db5d9beed9bc66d9c1500418
## Why
Standalone web search could send requests to the bootstrap backend instead of the discovered workspace backend, bypassing workspace routing.
## What changed
Use the thread's shared `WorkspaceRoutingContext` when preparing search requests so they use the resolved backend, authentication, residency, and account routing headers. Reject redirects when required by the resolved routing policy or account routing header, and preserve the established routing context across configuration changes.
## Testing
Add an app-server integration test that verifies search reaches the discovered HTTPS backend with the expected credentials and routing headers, without contacting the bootstrap search endpoint. Add a regression test that verifies configuration changes preserve the thread's routing context.
GitOrigin-RevId: 67160f1b3e54231dc100ce3ed4cfcea965b56d26
## What changed
- Match final serving assessments to their response and output item, then retain them with tool invocations and code cells across waits.
- Use matching assessments instead of asynchronous scoring for adaptive review: low-risk actions can skip synchronous review, while elevated-risk actions require it.
- Revalidate captured authorization and policy before approval. Require fresh review for stale or incomplete authorization, preserve explicit review requirements, and discard assessments when hooks rewrite tool input.
- Keep asynchronous scoring as the fallback when an assessment is missing or does not match.
## Testing
Add integration coverage for direct and nested tool calls, hook rewrites, explicit escalation, interrupted responses, catalog-driven policy, incomplete authorization, and assessment retention across code-cell yields and waits.
GitOrigin-RevId: 4346a227204137f018c03c34b302d6f1e9592c96
## Why
Resuming or forking a thread loses the session flag indicating that reported token usage already includes retained reasoning. Counting that reasoning again can trigger automatic compaction too early.
## What changed
Persist `last_usage_includes_reasoning` with `TokenUsageInfo` and use it when estimating context usage. Record the flag with completed sampling and compaction usage, and mark local estimates as including reasoning. Older records without the field retain the existing accounting behavior.
## Testing
Add coverage for saved inclusive, exclusive, and legacy token counts. Extend the encrypted-reasoning compaction test to verify the compaction threshold for live, forked, and cold-resumed threads.
GitOrigin-RevId: 9f22262a693111ec0406dce11804eb4844ad8983
## What changed
Add an output schema for `image_gen.imagegen` so its code-mode declaration returns `Promise<{ image_url: string; output_hint?: string; }>`. Direct API tool serialization remains unchanged.
## Testing
Add coverage for the generated return type and unchanged direct API serialization, assert the full declaration in the app-server integration test, and verify that code-mode results omit oversized output hints.
GitOrigin-RevId: b3cee52a6b68c881f0c7507e791cc0fe86ca0d24
## What changed
Add `ReviewInput` to bundle an approval request with its captured parent history and review context. Its `assess_isolated` method runs a fresh reviewer without publishing a live approval, honors deadlines and cancellation, and returns a `GuardianAssessment` or review error.
Share review parameter construction with the live review path and extract assessment parsing and error conversion into `GuardianReviewSessionOutcome::into_assessment`.
## Testing
Add a mock-backed test that verifies the isolated assessment is returned and the reviewer receives the captured history without instructions added after capture.
GitOrigin-RevId: 10dd5fddf5fc58bfab124f5962a6b7f45d435c83
## What changed
- Separate evidence collection from prompt preparation and pass reviewer history, model limits, and image preparation policy through shared `guardian-context` APIs.
- Detect captured images before composition and measure reviewer history tokens only when images and a valid context window require it.
- Share instruction and native-message delivery filtering across budget checks, including restoration of retained evidence after history changes.
GitOrigin-RevId: 65ef53cf0bc22e1bde9abfb7a9ffce65cfab6f1c
## Why
Guardian's `write_stdin` approval requests lacked the command used to launch the receiving terminal, leaving reviews without that context.
## What changed
- Carry `original_command` from the terminal's launch command into the approval request and Guardian action JSON. This describes the original launch, not the terminal's current state.
- Exclude `original_command` from the 8,000-byte stdin approval size check so launch context does not consume the budget for input, permission details, and the approval reason. Launch context remains subject to Guardian's normal request budget.
## Testing
Extend serialization coverage to check `original_command` and the strict stdin review integration test to verify that a launch command longer than 8,000 bytes reaches Guardian intact.
GitOrigin-RevId: cc765a6bf80d080baf94c959eafa6227b2889e1f
## What changed
Decode `response.metadata` Guardian assessments into typed `GuardianAssessment` events over SSE and WebSocket, carrying `response_id`, `item_id`, and `requires_review`. Ignore assessments with missing, empty, or incorrectly typed required fields while preserving independent delivery of other metadata.
Expose the assessment type to request-scoped extension interceptors. Keep assessments out of conversation history; they do not authorize tool execution.
## Testing
Add SSE coverage for assessment ordering, malformed metadata, and mixed metadata delivery. Extend model request tests to cover SSE and WebSocket interceptor delivery and exclusion from subsequent model input.
GitOrigin-RevId: 282b8817ee97346d76b40bcb412eef023df60ff1
## What changed
Extract MCP approval elicitation parsing and review-decision response conversion from `core/src/session/mcp.rs` into `codex-guardian-reviewer`. Export the helpers and `GuardianElicitationReview` for the session code to use, while keeping session lookup, provenance checks, and approval enforcement in the host.
## Testing
Move the existing elicitation tests into the reviewer crate, retaining coverage for request construction, opt-in requirements, unsupported forms, decision mapping, and model-specific timeout instructions.
GitOrigin-RevId: fb745fa0e49a29f015bbda16c14b5fc2b12278b9
## What changed
Export `ReviewAction` and its conversion from `GuardianApprovalRequest` from
`codex-guardian-reviewer`. Keep host-specific approval preparation and environment
validation in core as standalone functions, and update callers accordingly.
## Testing
Move the `write_stdin` serialization and tool-call provenance test into the
reviewer crate, preserving coverage for input, Windows working directories, and
sandbox permission modes.
GitOrigin-RevId: 9a1caf9bbb67ba017e4950a2da9ef2543b013007
## What changed
Move review evidence storage, authorization snapshots, sender exchange selection,
and bounded Node REPL evidence into `codex-guardian-reviewer`. Update core to
call or re-export these APIs while retaining host-specific context rendering and
capture-mode selection.
Move the existing Node REPL evidence and text truncation tests alongside their
implementations in the reviewer crate.
GitOrigin-RevId: d851cd353cf9f31eb47ce13f43f6f935dc2f5d93