## What changed
- Recognize `cua_repl` alongside `node_repl` when collecting Guardian review evidence, applying computer-use policy, and capturing transcript images.
- Render `cua_repl.js` results with the compact REPL history and transcript views.
- Preserve failed MCP call status and result content when replaying app-server history.
## Testing
- Cover both REPL server names across Guardian policy, evidence, image capture, history rendering, and failed-call replay tests.
GitOrigin-RevId: 8c13a721f718add403b07e727c1634b59203c51a
## What changed
- Cover object serialization through the `text()` helper directly in the code
mode runtime suite.
- Remove redundant core integration coverage for serialized text and rejected
image outputs.
GitOrigin-RevId: f465b8361e9d725a7246994d9c41e9d01c969011
## What changed
- Remove the legacy `shell_command` handler and runtime, leaving `exec_command`
and `write_stdin` as the shell execution tools.
- Treat legacy `shell_command` model metadata as `unified_exec`, and normalize
legacy user opt-outs so they do not disable command execution. Managed feature
requirements and `shell_tool` can still disable it.
- Preserve shell approvals, sandboxing, zsh-fork support, and output truncation
through the unified execution path.
## Testing
- Cover legacy configuration and model-metadata compatibility.
- Exercise unified shell execution, approvals, truncation, and `apply_patch`
serialization across the app-server and core test suites.
GitOrigin-RevId: 5c2fd6164fc3519cdae4944cb9db276b8467311c
## What changed
Replace the core integration test for allowed `globalThis` properties with an
in-process code-mode runtime test. The test continues to fail when the runtime
exposes a global outside the allowlist without requiring the core network test
harness.
GitOrigin-RevId: f33846ae2bb35e6779b5bec0a3f0ba5729eb707d
## What changed
- Add a focused Code Mode integration test with Guardian transcript images enabled and enhanced Node REPL transcripts disabled.
- Verify that the Guardian request and parent request omit both the screenshot and its surrounding transcript markers.
- Remove this configuration from the broader parameterized transcript-evidence test.
GitOrigin-RevId: 1309de12337a28a7e1d49eca509ba73207d4d9be
## What changed
Move circular-value coverage for the `text()` helper from the core integration
suite to the in-process code mode runtime tests. Verify that stringification
returns no content and surfaces the V8 circular-structure error without needing
a mock server or network access.
GitOrigin-RevId: d506591af5ae8ce0a8c7305d633a7b0f2e458335
## What changed
- Keep validating normalized dynamic tool visibility for both Responses and Responses Lite.
- Exercise the normalized dynamic tool call and its returned metadata only for Responses Lite.
- Let the standard Responses case complete in a single mocked response without expecting a dynamic tool request.
GitOrigin-RevId: 7793e6f6df07fc58c2976a773a1198496af08dfd
## What changed
Use a 2049-by-32 image in the Guardian transcript evidence test and verify that
it is resized to 2048-by-32 while preserving its aspect ratio.
GitOrigin-RevId: 4b1b404c0fc76c46739379ef154e629bf8d669f3
## Why
`node_repl` screenshots are nested tool results and do not appear in the parent
conversation history, so Guardian v2 transcript image collection could miss
them.
## What changed
- Allow Guardian v2 to enable bounded, thread-scoped `node_repl` image capture
when transcript images are configured.
- Add retained `node_repl` screenshots to review requests when transcript
sources include tool outputs, while deduplicating images and keeping them out
of the parent turn input.
## Testing
- Add an integration test covering screenshot capture without the synchronous
Guardian transcript feature flags and verifying that screenshots stay out of
the parent request.
GitOrigin-RevId: 5f70c5f2e80389aa8b2a286c3b7f9b1104865486
## Why
Code Mode rendered document-local `$ref` values as `unknown`, hiding referenced
input and structured-output shapes from generated TypeScript declarations.
## What changed
- Resolve fragment-only JSON Pointer references against the root schema,
including escaped and percent-encoded pointer segments.
- Preserve `$ref` siblings as intersections and parenthesize unions used in
`allOf` intersections.
- Bound recursive and repeated expansion, intermediate rendering work, and
final output size, falling back to `unknown` when a limit is reached or a
reference cannot be resolved safely.
## Testing
Add unit coverage for recursive, escaped, nested-resource, dangling, and
oversized references, plus integration coverage for generated Code Mode tool
descriptions and MCP structured output types.
GitOrigin-RevId: 95c6aa32e25325b5be9359dfac3b3328e5e7a499
## What changed
- Enable the stable `unified_exec` feature by default on every platform.
- Update cross-platform integration test expectations so `exec_command` and
`write_stdin` are exposed on Windows instead of `shell_command`.
GitOrigin-RevId: e5c864bacbde7eab109e7a0e399b8f7b843b384c
## What changed
- Preserve valid image content from completed `node_repl` Code Mode responses alongside text evidence for Guardian reviews.
- Enable multimodal evidence for models that require automatic `node_repl` review, or when both `guardian_enhanced_node_repl_transcripts` and `guardian_node_repl_transcript_images` are enabled.
- Bound retained and rendered evidence, deduplicate images already present in review history, and fall back to text-only evidence when the reviewer lacks image support or prompt capacity.
- Keep review evidence out of the parent turn input.
## Testing
- Cover feature gating, mixed text and image ordering, truncation and eviction, unsupported reviewers, prompt pressure, image detail normalization, and reused review sessions.
GitOrigin-RevId: a3e482402f7b3484401b231dadc662e6e3504fdf
## What changed
- Capture accepted, successful `node_repl` results from Code Mode and include them as bounded, untrusted evidence in Guardian review prompts.
- Enable the enhanced transcript through `guardian_enhanced_node_repl_transcripts` or when the selected model requires automatic Node REPL review.
- Keep this evidence out of the parent model history, exclude encrypted and failed results, and avoid resending admitted evidence when a Guardian session is reused.
- Clear retained evidence and invalidate review sessions when a thread is rolled back.
## Testing
- Add unit coverage for evidence ordering, escaping, truncation, and empty responses.
- Add an integration test covering feature-disabled, feature-enabled, and model-required behavior, including filtering and review-session reuse.
GitOrigin-RevId: edc3dca5d5b88d472a492f35531ec46889a89d72
## What changed
- Add `TurnInputRequest` and typed submission results for atomically starting a turn, steering the active turn, or declining input with a specific reason.
- Expose `start_or_steer_turn`, `start_turn_if_idle`, and `steer_turn` on `CodexThread`, and migrate Core consumers to these APIs.
- Make app-server `turn/start` steer an active regular turn and return that turn's ID. Reject incompatible output schemas and non-steerable turns without applying settings or enqueueing input.
## Testing
- Cover concurrent start-or-steer submissions, accepted and rejected settings updates, output-schema compatibility, idle-start rejection, and app-server steering.
GitOrigin-RevId: dd9b5528d76ec650c019e97af420bc13190ea86a
## What changed
- Reject invalid or unsupported image data before producing tool output, so
non-image file contents are not exposed through code mode.
- Preserve valid image bytes and metadata while leaving image preparation and
resizing to the history insertion path.
## Testing
- Cover invalid images in both code mode and standard `view_image` calls.
- Verify that code mode preserves PNG bytes, dimensions, EXIF orientation, and
metadata.
GitOrigin-RevId: 07343ed10b781d0ce0ffb5b24432658be4c046e3
## What changed
- Stop adding `code_mode_tool_names` to Responses Lite turn metadata.
- Keep `code_mode_tool_names` reserved so client metadata cannot reintroduce the removed, unbounded inventory.
- Use the opt-in `tool_namespaces_info` metadata, including each function's `code_mode_name`, when authoritative tool details are requested.
## Testing
- Update Responses Lite and code-mode tests to verify the opt-in namespace metadata and normalized code-mode names.
GitOrigin-RevId: cbfb9af984de71c7cc175d0cd47ae799a5275309
## Why
Interrupting a turn should also stop code-mode work that the turn left running.
## What changed
- Add the disabled-by-default `code_mode_interrupt` feature.
- When an interrupted turn has the feature enabled, terminate all active code-mode cells and propagate cancellation through nested tool calls.
- Keep the reusable code-mode session alive so its stored state remains available to later turns.
## Testing
Add an integration test that interrupts a long-running nested tool, verifies that active and background cells are removed, and confirms that session state is preserved.
GitOrigin-RevId: 2b8634776a89b636318a39b9e9ad2eefc07cead8
## Why
MCP tool handlers and their Code Mode definitions are immutable for the lifetime
of a stable MCP binding, so rebuilding them for every sampling step repeats schema
construction unnecessarily.
## What changed
- Cache MCP handlers per session and reuse them while the same binding remains
active, invalidating the cache when the binding changes.
- Lazily cache schema-free Code Mode definitions on MCP handlers while continuing
to rebuild definitions for step-local tools whose specifications may change.
- Reapply current app enablement, tool policy, exposure, and plugin schema budgets
whenever cached handlers are registered for a step.
## Testing
- Cover handler and Code Mode definition reuse, binding invalidation, changing app
policy, stable continuation schemas, and step-local custom tool updates.
GitOrigin-RevId: 69c5011fb97c08580ac476e7fb2286b1e92e0359
## What changed
- Add the gated `unified_image_budget` feature for models that support original image detail or Responses Lite.
- Apply one 6,000-pixel, 10,000-patch preprocessing limit regardless of legacy image detail hints.
- Hide detail controls from `view_image` and code mode while continuing to accept existing hints for compatibility.
- Preserve detail-based resizing and tool contracts for unsupported models.
## Testing
- Cover unified resizing limits, Responses Lite, legacy detail hints, unsupported models, and `view_image` integration in code mode.
GitOrigin-RevId: cb07bff1669a96599fdfd076b3d9ec80f2b6fff7
## What changed
- Group top-level function and custom tool definitions into a single `functions` namespace for Responses Lite providers that support namespaced tools.
- Normalize missing, empty, and explicit `functions` namespaces to the same tool identity across registration, routing, lifecycle hooks, configuration, and tool search.
- Keep default tool names unprefixed in code mode, display output, and dispatch traces while preserving explicit non-default namespaces.
## Testing
- Add coverage for Responses Lite serialization, tool search results, namespace normalization and collision handling, routing, lifecycle events, and code-mode namespace policies.
GitOrigin-RevId: d48414005b5d22d39b11a198e19c47814d3a19f2
## What changed
- Allow namespace tool specs to contain custom freeform tools alongside function tools.
- Include namespaced custom tools in deferred tool search and expose them to code mode with names such as `editor__apply_patch`.
- Route custom payloads to matching extension tools while preserving function-only payload validation.
## Testing
- Add serialization, tool search, code-mode definition, and end-to-end dispatch coverage for namespaced custom tools.
GitOrigin-RevId: be64d35f6ae54685c5a9fcf45a732320742ea7e5
## Why
Code-mode `wait` and `terminate` requests can remain pending when the host
transport stalls.
## What changed
- Add a 60-second transport allowance to the runtime timeout for `wait`, and
apply the same transport deadline to `terminate`.
- Return a model-visible timeout error and invalidate the connection when the
deadline expires, so the next execution reconnects to the host.
## Testing
- Cover queued `wait` and `terminate` requests that exceed their deadlines.
- Verify that a timed-out `wait` reports the error and reconnects on the next
code-mode execution.
GitOrigin-RevId: 5d772e5a6f3793aa8865a1160639b851fd4824fb
## Why
MCP tools can be exposed directly, discovered through tool search, or called
from Code Mode. Servers need to be able to opt out of any of these surfaces
without disabling their tools everywhere.
## What changed
- Add `omit_tools_from` to MCP server configuration, accepting any combination
of `direct`, `deferred`, and `code_mode`.
- Apply the exclusions independently when building direct, deferred, and Code
Mode tool surfaces while keeping omitted tools registered for permitted uses.
- Remove client-private `_meta` fields from MCP results returned to Code Mode.
- Include the new setting in the configuration schema and MCP config
serialization.
## Testing
- Cover every exposure combination across Code Mode, Code-Mode-only sessions,
tool search, direct-only namespaces, and prefixed and unprefixed MCP names.
- Verify direct and nested execution paths, parallel-call support, config
round-tripping, and `_meta` filtering.
GitOrigin-RevId: 12dfcb78bb5c5ecf4d70f38a8b5022792463a27f
## What changed
- Move the V8 implementation into a dedicated `codex-code-mode-runtime` crate used by `codex-code-mode-host`, removing the embedded runtime fallback from the Codex process.
- Resolve the host executable from the active installation layout and check its availability before selecting tools.
- Fall back to direct tools with a one-time warning when optional code mode is unavailable. Keep `code_mode_only` and `disable_in_process_fallback` configurations fail-closed.
## Testing
- Cover host discovery for standalone and package layouts, including missing hosts and symlinks.
- Verify direct-tool fallback, one-time warnings, and fail-closed code-mode-only behavior.
GitOrigin-RevId: 5aa3c6f1db148b2231fc24089a2ee0e2b00dbddb
## What changed
- Add the opt-in `executed_tool_call_metadata` feature to record model-attempted direct and code-mode tool calls.
- Attach recorded names and arguments to the matching tool output in the next Responses request, preserving the metadata across sampling retries.
- Bound pending calls and argument sizes, and emit truncation metadata when limits are exceeded.
## Testing
- Cover disabled-by-default behavior, namespaced and nested calls, blocked or failed attempts, retry handling, and recorder limits.
GitOrigin-RevId: 5ce917b73e797b0f6904d46477b9d2cf8ea71bf2
## What changed
Update the code mode yield and termination integration test to generate a
bounded output backlog, then wait on a file-backed gate until the session is
terminated. Remove the timeout that previously guarded submission of the
infinite-loop workload.
GitOrigin-RevId: dd48307f18ab12bfbf02dc26b0f3715f073402a7
## What changed
- Track the first registered tool for each normalized code-mode identifier and use that tool consistently for dispatch metadata and model-facing code-mode declarations.
- Skip duplicate normalized names when building the code-mode executor while preserving shadowed tools in the registry and direct tool exposure where applicable.
- Cover collisions across dynamic and namespaced tools, direct and deferred exposure, code-mode-only operation, and Responses Lite metadata.
GitOrigin-RevId: a4acb57ce44e7de1398981b22af4b87e2a35870f
## Why
When the code mode host feature was disabled, thread startup always selected the in-process provider, even when `disable_in_process_fallback` was set.
## What changed
- Select a disabled provider when both the process host and in-process fallback are disabled.
- Return a clear tool error instead of running code mode in process for that configuration.
## Testing
Added an integration test covering code mode with the process host feature and in-process fallback both disabled.
GitOrigin-RevId: 3ed80afc23e0a5518c0133fe337a37b1fa545ead
## What changed
- Allow `features.code_mode_host` to use a configuration table with
`disable_in_process_fallback`. When enabled, failure to start the standalone
host is returned as tool output instead of falling back to embedded V8.
- Preserve the existing fallback behavior by default and continue accepting the
boolean feature toggle.
- Limit displayed host paths in spawn errors to 512 bytes while retaining the
executable-bearing suffix and valid UTF-8 boundaries.
## Testing
- Cover boolean and table-based feature configuration, fallback-disabled host
failures, and bounded ASCII and UTF-8 error paths.
GitOrigin-RevId: ab3d014e79054c2f8beef9a658915f01cca197b2
## What changed
- Add `StartThreadOptions::new` to provide the standard configuration for a new thread.
- Make `ThreadManager::start_thread` the single thread-start entry point and migrate callers from the previous convenience methods.
- Derive default environment selections when `environments` is `None`, while preserving explicit selections, including an empty list.
GitOrigin-RevId: 8977dc11aed54c5e1215a81eaed2b2cf5fc6087a
## What changed
- Accept image output from `image()` and `generatedImage()` only when its URL
uses the `data:` scheme.
- Preserve the dedicated error for remote HTTP URLs and report other malformed
or unsupported image URLs as invalid image output.
## Testing
- Add service-level coverage for rejecting invalid output from both image
helpers.
- Add an end-to-end code-mode test that verifies the tool call fails instead of
returning an invalid image item.
GitOrigin-RevId: beaf8c8830574150e8166b6ff5daf7f6dc4dc0a1
## What changed
- Allow parallel `write_stdin` tool calls to interact with independent terminal sessions.
- Serialize reads and writes within each session so its output buffer and process lifecycle remain consistent.
- Prevent active sessions from being pruned while a `write_stdin` interaction is in progress.
## Testing
- Added unified exec and code mode coverage that uses two terminal sessions concurrently and verifies output from both.
GitOrigin-RevId: 618f5503f4c4670421f680c0f0c27414bc6b2ddd
## Why
Not every Codex distribution currently includes the
`codex-code-mode-host` companion binary. Enabling the process-host
feature should not make code mode unavailable on those surfaces while
packaging support is being completed.
## What changed
- Fall back to an in-process code-mode session only when spawning the
companion binary returns `io::ErrorKind::NotFound`.
- Keep permission, handshake, timeout, and other host failures visible
instead of silently falling back.
- Store the provider's owned-process/in-process choice as one
enum-backed state so later sessions reuse the fallback decision.
- Preserve the underlying spawn `io::Error` while retaining the host
path in the displayed error.
- Update provider, `CodeModeService`, and end-to-end coverage to verify
successful fallback execution.
## Test plan
- `just test -p codex-code-mode`
- `just test -p codex-core missing_process_host`
## Why
When MCP tools are deferred behind `tool_search`, Code mode keeps them
callable but omits their individual declarations from the initial `exec`
description. The shared MCP `CallToolResult` types were derived only
from directly rendered tools, so deferring every MCP tool also removed
the common response contract that models need to interpret MCP results.
This restores that contract without undoing the context savings from
deferred tool definitions. This is a follow-up to #29486.
## What changed
- Track deferred Code-mode tool definitions separately from directly
rendered definitions.
- Render the shared MCP type preamble when either direct or deferred MCP
tools are available.
- Keep deferred tool declarations out of the initial prompt.
- Add unit and integration coverage for deferred MCP tools.
## Testing
- `just test -p codex-code-mode-protocol`
- `just test -p codex-core
code_mode_only_guides_all_tools_search_and_calls_deferred_app_tools`
## Summary
- Promote code_mode_host to stable and enable it by default.
- Preserve features.code_mode_host = false as an opt-out to the
in-process runtime.
- Run core code-mode tests through the standalone host.
- Keep explicit coverage for missing-host failures.
## Why
Code-mode tool results could return to the model while an MCP
elicitation was still waiting for user input. This differed from
parallel tool calling and could let the model continue before the user
resolved the request.
We need one session-level view of outstanding elicitations so tool
runtimes can consistently hold results until every pending elicitation
is resolved.
## What changed
- Added a counted, session-owned ElicitationService with RAII
registrations.
- Registered both core-originated and server-originated MCP elicitations
with the service.
- Migrated out-of-band elicitation tracking and unified exec timeout
pausing to the shared service.
- Made code-mode functions.exec and functions.wait capture their runtime
result normally, then hold it before returning while an elicitation is
outstanding.
- Kept terminate: true immediate; only its result is held.
- Preserved model-visible wall time across the elicitation hold.
- Kept the behavior session-scoped, with concurrent elicitations holding
the pause until all registrations are released.
## Summary
- add the `code_mode_host` feature flag and select
`ProcessOwnedCodeModeSessionProvider` in `CodeModeService` when enabled
- initialize code-mode sessions lazily so a missing host reports a tool
error without failing thread startup
- resolve `codex-code-mode-host` beside the running Codex binary by
default while preserving `CODEX_CODE_MODE_HOST_PATH` as an override
- add unit and end-to-end coverage for host resolution and graceful
missing-host behavior
## Why
This wires the process-owned session client from #30112 into the core
service behind an opt-in rollout gate. Packaged Codex installations can
place the helper in the same `bin` directory as the main executable
without relying on `PATH`, while development and custom installations
can continue to override the helper path.
## Stack
- Depends on #30112
- Base branch: `cconger/process-owned-session-runtime-4-client`
## Validation
Build `codex` and `codex-code-mode-host`
`CODEX_CODE_MODE_HOST_PATH="$PWD/target/debug/codex-code-mode-host"
./target/debug/codex --enable code_mode_host`
## Why
MCP authentication has distinct OAuth and ChatGPT-session flows.
Representing that choice as `use_chatgpt_auth` makes one flow implicit
and allows the configuration model to express the distinction only
through a boolean.
ChatGPT credential forwarding also needs a first-party trust boundary. A
configurable `chatgpt_base_url` controls routing, but must not grant an
MCP server permission to receive session credentials.
This change builds on #29733, where the boolean was introduced.
## What changed
- Replace `use_chatgpt_auth` with an `auth` field backed by the
exhaustive `McpServerAuth` enum.
- Support `auth = "oauth"` and `auth = "chatgpt"`, with OAuth remaining
the default.
- Trust only the origin derived from the existing hardcoded
`CHATGPT_CODEX_BASE_URL` when granting ChatGPT auth to an MCP server.
- Keep configured bearer tokens and authorization headers ahead of the
selected authentication flow.
- Update config writers, schema output, fixtures, and integration-test
setup to use the enum.
## Verification
Integration coverage exercises the complete streamable HTTP startup path
in two independent configurations:
- A directly constructed MCP configuration verifies that matching an
overridden `chatgpt_base_url` does not grant ChatGPT auth.
- A persisted `config.toml` containing an attacker-controlled
`chatgpt_base_url` and `auth = "chatgpt"` verifies the same boundary
through normal config parsing.
Both tests complete MCP initialization and tool listing and assert that
the full captured request sequence contains no authorization headers.
Separate integration coverage verifies that configured authorization
takes precedence over ChatGPT auth.
## Why
ChatGPT session authentication was inferred from the reserved Codex Apps
server name. That couples credential routing to Codex Apps-specific
behavior and prevents other MCP endpoints hosted by ChatGPT from
explicitly using the current session.
The opt-in also needs a clear security boundary: an arbitrary MCP
configuration must not be able to redirect ChatGPT credentials to
another origin.
## What changed
- Add `use_chatgpt_auth` to HTTP MCP server configuration, defaulting to
`false`.
- Honor the setting only when the parsed server URL has the same HTTP(S)
origin as the configured `chatgpt_base_url`; otherwise remove the
capability before startup.
- Resolve bearer tokens and static or environment-backed authorization
headers before selecting authentication, with configured authorization
taking precedence over ChatGPT session auth.
- Enable the setting for the built-in Codex Apps and hosted plugin
runtime endpoints while keeping Codex Apps caching and tool
normalization scoped to the reserved server.
- Persist the setting through MCP config rewrite paths and expose it in
the generated config schema.
- Load the current login state for `codex mcp list` so reported auth
status matches runtime behavior.
## Verification
Core integration coverage exercises the complete streamable HTTP MCP
startup path and verifies that:
- a same-origin opted-in server receives the current ChatGPT access
token;
- an explicitly configured authorization header takes precedence;
- a different-origin server completes MCP initialization and tool
listing without receiving any ChatGPT authorization header.
## Summary
- move sleep tool enablement from top-level `[features].sleep_tool` to
`[features.current_time_reminder].sleep_tool`
- remove the standalone `Feature::SleepTool` flag and gate `clock.sleep`
from resolved current-time configuration
- update config schema, config-lock materialization, and existing sleep
coverage
Stacked on #29907.
## Why
With `model_auto_compact_token_limit_scope = "body_after_prefix"`, the
persistent prefix should not count against the active body window.
`get_context_remaining` and the token-budget reminder should report the
same usable body-after-prefix window that auto-compaction uses, rather
than the total token count since the session began.
This is stacked on #29664 so the mechanical move from `turn.rs` is
isolated from the behavior fix.
## What
- Extends `ContextWindowTokenStatus` with `context_remaining_tokens`.
- Updates `get_context_remaining` to use the shared context-window
accounting.
- Adds integration coverage for body-after-prefix reminder timing and
`get_context_remaining` output.
## Testing
- `just test -p codex-core body_after_prefix_window`
- `just test -p codex-core auto_compact_body_after_prefix`
- `just fix -p codex-core`
## Summary
- rename `reminder_interval_model_requests` to
`reminder_interval_seconds`
- read the configured time provider before every model request and
inject a reminder only after the configured number of seconds has
elapsed
- preserve immediate first delivery and forced delivery after compaction
changes the context window
## Tests
- `just test -p codex-core current_time_reminder`
## What
- make Fjord's centralized response-item image preparation unconditional
for new and resumed history
- have local user images and `view_image` outputs always defer decoding
and resizing to that path
- retain `resize_all_images` as an ignored, removed compatibility key
for released clients
- delete the flag-off producer paths and obsolete policy-specific tests
## Why
Centralized preparation is now the intended image path. Keeping the
runtime feature checks also kept two image-processing implementations
alive and allowed client config to select the legacy behavior.
This is a clean replacement for #28975, rebuilt from the latest `main`.
## How
`prepare_response_items` now runs whenever items enter history and
whenever persisted history is reconstructed. Producers emit deferred
image data, so malformed images become the existing model-visible
placeholder instead of failing the session at the producer.
## Test plan
- `just fmt`
- `just fix -p codex-core -p codex-features`
- `just test -p codex-features` — 52 passed
- focused affected `codex-core` set — 20 passed
- `just test -p codex-core handle_accepts_explicit_high_detail` — 1
passed
- full `just test -p codex-core` attempt — 2,723 passed; 88 unrelated
environment failures from read-only `~/.codex` SQLite state and
unavailable integration helper binaries
## Summary
- Add `web_search = "indexed"` alongside `disabled`, `cached`, and
`live`.
- Use that same resolved mode for both hosted and standalone web search.
- For hosted search, send `index_gated_web_access: true` with external
web access enabled only when `indexed` is selected.
- For standalone search, preserve the existing boolean wire values for
existing modes (`cached` maps to `false` and `live` to `true`) and send
`"indexed"` only for `indexed`; `disabled` keeps the tool unavailable.
- Carry the mode through managed configuration requirements and
generated schemas.
## Why
Indexed search provides a middle ground between cached-only search and
unrestricted live page fetching. Search queries can remain live while
direct page fetches are limited to URLs admitted by the server.
The existing `web_search` setting remains the single source of truth, so
hosted and standalone executors cannot drift into different access
modes. Without an explicit `indexed` selection, the existing
model-visible tool and request shapes are unchanged.
```toml
web_search = "indexed"
[features]
standalone_web_search = true
```
## Validation
- `just fmt`
- `just test -p codex-api` (`126 passed`)
- `just test -p codex-web-search-extension` (`7 passed`)
- `just test -p codex-core
code_mode_can_call_indexed_standalone_web_search` (`1 passed`)
- Focused configuration, hosted request, standalone request, and
managed-requirement coverage is included in the PR; remaining suites run
in CI.
The full workspace test suite was not run locally.
## Summary
- expose `clock.curr_time` when current-time reminders are enabled
- query the session's configured time provider with the calling thread
id
- return the existing UTC reminder text for direct model calls
- return `{ "current_time": "YYYY-MM-DD HH:MM:SS UTC" }` in Code Mode
Clock lookup failures remain fatal, matching pre-inference reminder
behavior.
## Testing
- `just test -p codex-core current_time_tool_returns_the_latest_time`
- `just test -p codex-core
code_mode_current_time_returns_structured_result`
- `just fix -p codex-core`