Expose effective web-search mode and structured search results in `codex exec --json`

Open 💬 0 comments Opened Jul 26, 2026 by teru-murata

Problem

codex exec --json is documented to emit events as JSONL (cli.rs:L63-L70), but its web-search events omit metadata that Codex already has internally.

The search API returns structured results separately from the model-facing output (search.rs:L297-L304). The web-search tool preserves those results in both the completed WebSearchItem and WebSearchEndEvent (tool.rs:L138-L177); both internal types explicitly carry opaque, forward-compatible result JSON (web_search.rs:L13-L22, protocol.rs:L2502-L2510).

However, the exec JSONL event processor projects a completed web-search item into only id, query, and action, dropping results (event_processor_with_jsonl_output.rs:L297-L310). The public exec JSONL type likewise has no results field (exec_events.rs:L296-L302).

There is a related observability gap for the effective web-search mode. Codex resolves the configured mode against the effective permission profile (config/mod.rs:L2979-L3012) and applies that result to the per-turn configuration (turn_context.rs:L465-L480). The resulting disabled, cached, indexed, or live value is not present in SessionConfiguredEvent (config_types.rs:L352-L363, protocol.rs:L3904-L3968). In JSONL mode, the corresponding thread.started event exposes only the thread ID (exec_events.rs:L39-L43, event_processor_with_jsonl_output.rs:L391-L395). Consequently, a headless client cannot determine the resolved mode from the structured output.

Why this matters

We use codex exec --json in automation that asks the model to identify candidate web sources, independently retrieves the cited URLs, and records provenance.

Independent retrieval can establish that a URL exists and capture its current content, but it cannot establish whether that URL was actually present in the search result set seen by Codex. Because the structured results are discarded by the JSONL projection, the automation cannot distinguish a search-backed citation from an unsupported URL appearing only in model output (event_processor_with_jsonl_output.rs:L297-L310).

The missing effective mode also prevents provenance records from stating whether the run used disabled, cached, indexed, or live search after Codex applied its permission-aware resolution logic (config/mod.rs:L2979-L3012).

High-level proposal

Would it be reasonable to add two backward-compatible pieces of structured output?

  1. Add an effective_web_search_mode field to SessionConfiguredEvent and surface it in the exec session-start JSONL representation. It could use the existing WebSearchMode type and existing resolver rather than introducing a second mode-resolution path (config_types.rs:L352-L363, config/mod.rs:L2979-L3012).
  1. Add an optional results field to the exec JSONL web-search item and copy through the opaque structured metadata already carried by the internal item. Keeping it opaque would preserve the forward-compatibility approach already used at the extension boundary (web_search.rs:L17-L22).

Both changes could be additive, with compatibility defaults for older serialized events and consumers that ignore unknown fields.

Alternatives considered

RUST_LOG is useful for diagnostics, but it is not a stable structured provenance interface. Exec sends diagnostics separately from its JSONL output (exec/lib.rs:L232-L237) and may log entire session or protocol payloads (exec/lib.rs:L873-L883, responses.rs:L531-L537). Those payloads can contain sensitive or PII-bearing data such as working-directory paths and response content; SessionConfiguredEvent, for example, includes cwd (protocol.rs:L3947-L3949).

Independent URL fetching remains useful for validating current availability and content, but it cannot reconstruct or prove membership in Codex’s original search result set once the JSONL adapter has discarded that metadata.

If this direction fits the project, I would be happy to prepare an implementation and tests if invited.

View original on GitHub ↗