## What changed
Allow API key sessions to send plugin-attributed `codex_plugin_used`,
`skill_invocation`, and `codex_mcp_tool_call_event` events. Continue to drop
events without a plugin ID and all other analytics events for these sessions.
## Testing
Add coverage that mixes plugin and non-plugin events and verifies that only the
three plugin-attributed event types are delivered without server-owned auth
fields.
GitOrigin-RevId: 1f47af5e9516723154f566ad032dba3ebd98abf9
## What changed
- Default `prompt_cache_key` to the session ID from response metadata instead of the thread ID.
- Preserve explicit prompt cache key overrides.
- Verify that API-key-authenticated root and subagent requests use the same session-based cache key even though they have different thread IDs.
GitOrigin-RevId: cb1bf21a3cb8fa2c5083c5c6afd4829ff2adcf1f
## Why
Exec-server JSON-RPC payloads can contain decimals, exponent notation, and
integers outside the native 64-bit range. Decoding these values should preserve
their original JSON representation without weakening the existing message
complexity limit.
## What changed
- Enable `serde_json` arbitrary-precision number and raw-value support for the
exec-server protocol.
- Decode serde's number and raw-value wrappers in the bounded JSON visitor,
charging nested raw values against the 256K-value limit.
- Select the JSON-RPC envelope variant from its fields after bounded decoding so
arbitrary-precision values survive message deserialization.
## Testing
Add coverage for exact arbitrary-precision number round trips and for enforcing
the value limit inside raw-value wrappers.
GitOrigin-RevId: a6e0a3fba6f88e4e8a6ff414832f078beb2d2a70
## What changed
- Return only each live agent's name and status from `list_agents`.
- Stop tracking the most recent task message in agent metadata.
GitOrigin-RevId: 91836fe8efad7ea6b7305f0b409081ec77419cfd
## What changed
Add `rawResponse/completed` and its `RawResponseCompletedNotification` payload
to the generated `ServerNotificationEnvelope` union, keeping the envelope type
aligned with the supported server notifications.
GitOrigin-RevId: 25a8b5e05a146a66ea65928eb6f0c3bd7b80f082
## Why
Compact JSON arrays can expand into millions of heap values during decoding, and duplicate object keys make a message ambiguous.
## What changed
- Limit exec-server JSON-RPC messages to 256K JSON values and reject duplicate object keys.
- Cap `fs/read_directory` results and retained `process/read` output at 50,000 entries or chunks so locally produced responses remain within the decoder budget.
## Testing
Add coverage for all JSON-RPC variants, large scalar payloads, duplicate keys, compact array amplification, and retained process output at the chunk limit.
GitOrigin-RevId: e31d1f25ab0a7e2272015c98174fd2b7cdd669d7
## Why
Full access significantly increases the risk of data loss, leaks, or unexpected behavior, so users should explicitly confirm each time they select it.
## What changed
- Always open the full access confirmation when user-reviewed approvals are active, regardless of `notices.hide_full_access_warning`.
- Remove the persistent "don't ask again" option and its acknowledgement events.
## Testing
- Update the TUI permission tests and confirmation popup snapshot to cover repeated confirmation.
GitOrigin-RevId: 0ee827332441e13d9445349ed6a5a92dc8fef4b2
## Why
Clients that account for individual upstream Responses API calls need the exact
usage for each completion rather than accumulated or estimated thread usage.
## What changed
- Add the opt-in `rawResponse/completed` app-server notification with the
`threadId`, `turnId`, `responseId`, and upstream `usage` payload.
- Emit the transient event for normal turns and compaction requests when
`experimentalRawEvents` is enabled. The event is not persisted or replayed,
and `usage` is `null` when the upstream response omits it.
- Export the notification in the app-server schemas and document its behavior.
## Testing
- Cover exact token breakdowns for turn and compaction completions.
GitOrigin-RevId: 49040a060bf1784c1ff1dd62112efb4a778428c4
## Why
Multi-environment turns can run against different filesystems, so a single
thread-wide workspace-root list cannot accurately describe every selected
environment.
## What changed
- Add optional `runtimeWorkspaceRoots` to each app-server environment selection.
Omitted roots default to that environment's `cwd`, while an empty list selects
no roots.
- Carry environment-native roots through turn selection, model-visible context,
permission materialization, and tool sandboxing.
- Keep the top-level `runtimeWorkspaceRoots` field as a compatibility input when
constructing default environment selections; explicit selections use their
own roots.
## Testing
- Cover thread and turn API defaults, overrides, empty roots, and schema
round-tripping.
- Verify foreign roots remain model-visible and remote execution applies the
target environment's roots before sandbox selection.
GitOrigin-RevId: c6e7a62883c45c676c153055f46a55ee15a323a4
## What changed
- Limit `request_plugin_install` guidance to explicitly requested plugins after tool search has been exhausted.
- Exclude adjacent capabilities, broad recommendations, and plugins that only seem potentially useful.
- Clarify that `plugin_id` is the parenthesized ID from `<recommended_plugins>` and prohibit parallel tool calls.
- Keep the recommendation context focused on listing available plugins while the tool specification owns the installation criteria.
## Testing
- Update tool specification tests to verify the stricter eligibility and serialization guidance.
GitOrigin-RevId: 6ebfdd864a76316ab59a0624dc4d7d3abda39a98
## What changed
- Limit Guardian reviewer sessions with an environment to `exec_command`,
`write_stdin`, and `view_image`.
- Exclude general tool sources from Guardian reviewer tool planning.
## Testing
- Extend the Guardian request snapshot test to assert the exact model-visible
tool list.
GitOrigin-RevId: 80ba7011c23c32d163aaad906087fac396cc70fa
## Why
Thread history JSONL is the durable source of truth, while SQLite is a rebuildable view. If a SQLite projection fails after a durable append, the next write must catch up the unprojected suffix instead of skipping it.
## What changed
- Start materialization at the byte offset stored in `thread_history_projection_state`.
- Project only complete newline-terminated rollout records, leaving a trailing partial record for a later pass.
- Preserve validation for missing files, invalid offsets, and missing or out-of-order ordinals without advancing projection state.
## Testing
Add coverage for catching up after projection failure, avoiding replay when already synchronized, retaining partial lines, and rejecting invalid suffixes without changing SQLite state.
GitOrigin-RevId: 8a7200a77edd5411ddf5fe31ab6af5ee287ed7d7
## What changed
- Project durable paginated rollout records into rebuildable SQLite tables for turns, items, and projection progress while keeping JSONL as the source of truth.
- Add cursor-based local reads for turn summaries and thread or per-turn items, including archived-thread and history-mode validation.
- Serialize writes, shutdown, and deletion per thread so projection updates cannot race cleanup, and remove projected rows when a thread is deleted.
- Preserve stable item ordering while updating repeated snapshots and expose structured turn error details.
## Testing
- Cover projection, snapshot updates, summary recovery, pagination, failure handling, shutdown flushing, legacy-mode rejection, and deletion races.
GitOrigin-RevId: 34533185ece7f1f5690004c7f12b0f1f34dc2640
## What changed
- Add the experimental `environment/status` request for inspecting a configured environment without starting or reconnecting it.
- Report `ready`, `pending`, `disconnected`, or `unknown`, including error details for disconnected and unknown environments.
- Probe ready remote environments over their existing exec-server connection.
## Testing
- Add an app-server integration test covering local and remote ready, pending, disconnected, and unknown environments.
GitOrigin-RevId: 397bba603aa9e0b59008ee6cb7cbde46e357652c
## Why
Embedding callers need to control whether model catalogs are persisted to disk.
## What changed
- Accept a shared models manager when constructing `ThreadManager` instead of always creating a cached manager internally.
- Add provider APIs for creating uncached model managers. OpenAI-compatible providers fetch on each `OnlineIfUncached` refresh without reading or writing `models_cache.json`.
- Keep existing app server, MCP server, sample, and test callers on the standard cached manager.
## Testing
- Verify an uncached manager fetches on every refresh.
- Verify an injected uncached manager controls thread refresh behavior and does not create `models_cache.json`.
GitOrigin-RevId: 8bb646054ecec4ccb865b2bf56249384916ea9db
## What changed
- Add an optional `emittedAtMs` field to server notification envelopes and expose the envelope in the generated JSON and TypeScript schemas.
- Populate the Unix timestamp when app-server emits a notification, before transport routing, so every connection in a fan-out receives the same value.
- Keep the field optional for clients decoding notifications from older app-server versions.
## Testing
- Verify notification serialization includes `emittedAtMs`.
- Verify targeted fan-out reuses one timestamp across connections.
GitOrigin-RevId: b379cb11e8e91c558bcd3d46ce459311a6e81e54
## What changed
- Add `session_id` to the shared tool item event payload, sourced from the
thread metadata.
- Preserve the parent session ID on tool events emitted by subagent threads.
## Testing
- Cover serialization of the session ID for command execution events,
subagent tool events, and every supported completed tool item type.
GitOrigin-RevId: 73afc0e1be1ddec4fb5a42f43a23f1e87360e68f
## Why
`TurnContext` stored model and reasoning settings both as resolved turn fields and inside `CollaborationMode`, requiring the copies to stay synchronized when the model changed.
## What changed
- Store the mode and collaboration-mode developer instructions directly on `TurnContext`.
- Reconstruct `CollaborationMode` from those values plus the turn's current model and reasoning effort when callers need it.
- Read the mode directly for plan-mode checks, lifecycle events, and telemetry.
GitOrigin-RevId: b8fccafdd5d5cbccc84bc70d542588087ddf0093
## What changed
- Add the initialized `environment/status` RPC, which reports `ready` when the exec server can handle requests.
- Expose environment IDs and `ready`, `pending`, or `disconnected` status through `EnvironmentManager` and `Environment`.
- Keep status checks non-mutating: they do not start or recover lazy remote environments, and probe only an existing connection.
## Testing
- Cover the status RPC over WebSocket and the in-process request processor.
- Verify that checking an unstarted stdio environment leaves it pending and that failed connections report as disconnected.
GitOrigin-RevId: 22febeb6a3457849292128a8991c6400c22b3fd8
## Why
Standalone web search can return structured result DTOs separately from its
model-facing text output. App-server clients need access to that data without
coupling Codex to every result type or field.
## What changed
- Preserve the optional `results` array from `/v1/alpha/search` as opaque JSON
through web-search completion events, thread history, and app-server
`webSearch` items.
- Keep responses from older endpoints compatible when `results` is absent, and
allow clients to ignore result types and fields they do not understand.
- Regenerate the protocol schemas and TypeScript definitions for the optional
field.
## Testing
- Cover responses with missing, empty, and forward-compatible result payloads.
- Verify standalone web-search results round-trip through app-server item
notifications and thread-item conversion.
GitOrigin-RevId: 739ef5694ece5733f7b8749ec41d6bfa3f33c8c5
## Why
Policy-blocked proxy requests must terminate the corresponding active tool call and preserve the correct approval result, including when multiple calls are running concurrently.
## What changed
- Resolve a blocked request's execution ID to its registered active network call before recording the policy denial.
- Preserve an outcome already recorded for that call, and cancel the owning call after storing a new denial.
## Testing
Expand network approval integration coverage for Guardian and user decisions, permission hooks, persisted policy amendments, concurrent calls, timeouts, cancellations, and unattributed proxy requests.
GitOrigin-RevId: 961901bbc07cc498309453ec78cda1a56ab00a4b
## Why
Reconstructing the latest model-visible context does not require replaying an
entire paginated rollout when a usable compaction checkpoint and the associated
completed-turn metadata are available.
## What changed
- Add `ThreadStore::load_latest_model_context` and `StoredModelContext` for
loading replay-ready model context independently of full thread history.
- Reverse-scan plain paginated JSONL rollouts until the newest safe bounded
suffix is found, while preserving canonical session metadata and chronological
replay order.
- Fall back to complete history for legacy or compressed rollouts and whenever
compaction or rollback records make a bounded cutoff unsafe.
## Testing
- Cover checkpoint selection, turn-metadata boundaries, agent messages,
contextual user fragments, and full-history fallbacks.
GitOrigin-RevId: 3572f4ecc7aa4099a6d9f0d3e72d0ef432cd9497
## What changed
- Mark `request_plugin_install` as not supporting parallel tool calls so install requests execute serially.
- Add a unit test covering the handler's parallel-call capability.
GitOrigin-RevId: 5f2c8184562bd776b0e527e5e258c61c604a0910
## What changed
- Include the active Codex Apps tools cache and connector directory cache, when available, in diagnostic uploads that include logs.
- Resolve cache paths from the current authentication context and use stable attachment filenames.
- List both optional cache files in the upload consent dialog.
## Testing
- Add coverage for selecting existing active cache files, including a directory cache without an account ID.
- Update consent dialog snapshots to include the optional attachments.
GitOrigin-RevId: 1d4ffbf2bcb96653f03dc25f91d80dd65038d585
## What changed
Add a `command_category` tag to tool result telemetry for `exec_command` and
`shell_command` invocations. Classify parsed commands as `read`, `list_files`,
`search`, or `unknown`; use `mixed` when a script contains multiple categories.
GitOrigin-RevId: 1edacb38c7be9b03af4f2fc86746184f19067592
## What changed
- Add an optional `source` selector to `externalAgentConfig/detect`, while preserving the existing behavior for omitted, `null`, and unrecognized values.
- Pass `claude-code` as the source for TUI detection and import requests.
- Move source-specific migration behavior behind an adapter boundary and consolidate session migration into `codex-external-agent-migration`.
## Testing
- Cover explicit, omitted, and unknown detection source values with app-server protocol tests.
- Add unit coverage for the extracted migration and hook helpers.
GitOrigin-RevId: 63bd3dcb485f3ad7bd996022db4e351506aeea77
## Why
Compacting a resumed conversation can fail when its previous model is no longer
available. Some model-specific failures, such as a model-not-found response, are
not represented as invalid requests and therefore did not trigger the existing
fallback to the currently selected model.
## What changed
- Share a retry predicate between both remote compaction implementations.
- Fall back to the current model for invalid requests, unexpected statuses,
context-window and usage-limit errors, server failures, and exhausted retries.
## Testing
Add an integration test that resumes a conversation whose previous model returns
model-not-found and verifies that compaction and the next turn use the renamed
model.
GitOrigin-RevId: c3857beae2ce79b50589deb13c2e59710ce14725
## What changed
- Add an `auto_review.policy` field to model catalog messages.
- Use the selected Guardian model's catalog policy for review-session instructions, while preserving the precedence of `guardian_policy_config` and falling back to the built-in policy when neither is present.
- Preserve auto-review messages when model instruction overrides remove catalog instruction templates.
## Testing
- Cover configured-policy precedence, explicit empty catalog policies, catalog-message preservation, and propagation of the catalog policy into a prewarmed Guardian session.
GitOrigin-RevId: 26b61ae2958ea8325a64834dcf91f47e140d74b3
## What changed
- Add the optional `connector_id` to `codex_mcp_tool_call_event` parameters.
- Populate it from the MCP tool call's `app_context` when available.
## Testing
- Extend the completed tool item analytics test to verify the connector ID is serialized.
GitOrigin-RevId: ea62202318dd492fa0ffd4ff1d48a66d1cc37e96
## What changed
Remove the image generation instruction that prohibited any response after an
image was generated.
GitOrigin-RevId: c779055da3142ba84cdbb9312e5f66b132f24b29
## Why
Concurrent callers can submit the same Windows sandbox setup payload while an
identical helper invocation is already running.
## What changed
- Share one in-flight helper invocation among setup and refresh requests with
identical serialized payloads.
- Return the shared success or failure to every waiter while preserving
structured setup error codes, then allow subsequent requests to run again.
## Testing
- Add a concurrency test that verifies identical requests execute the setup
operation once.
GitOrigin-RevId: 18ebbcb9b36de3eb5912b8bbbe153d39328b5e48
## What changed
- Make `Esc` dismiss the slash-command popup immediately without changing the draft or interrupting a running task.
- Keep the popup closed while the first-line command token is unchanged, and reopen it after the token is edited.
## Testing
- Cover dismissal while idle and while a task is running.
- Add a snapshot confirming that the dismissed popup remains hidden.
GitOrigin-RevId: f0ee84af080181e8d92c435f474ded1c8cb5b457
## Why
Network proxy enforcement on Windows requires the elevated sandbox backend. Silently selecting that backend for an unelevated configuration makes the effective sandbox differ from the configured mode.
## What changed
- Reject enabled network proxy configurations on Windows unless managed requirements allow only the elevated sandbox and `windows.sandbox` resolves to `"elevated"`.
- Preserve the configured sandbox backend during execution and validate proxy compatibility at config loading, sandbox setup, and process launch boundaries.
- Defer this validation during cloud-config bootstrap so authoritative managed requirements can be loaded first.
- Do not start or expose disabled Windows proxies, and render transitions to disabled networking as `<network enabled="false"></network>`.
## Testing
- Cover Windows requirement and sandbox compatibility matrices, bootstrap behavior, backend selection, disabled proxy handling, and environment-context updates.
GitOrigin-RevId: bfa1dda98594e0db61883f8e7f65bd560e3453e6
## What changed
- Add a console mode to the Windows sandbox process launcher.
- Launch `--codex-run-as-fs-helper` subprocesses with `CREATE_NO_WINDOW`.
- Preserve inherited-console behavior for regular sandboxed commands.
GitOrigin-RevId: 927be36b82903b6a5fb1a243ba7f406f9ed85f3f
## What changed
Add finer-grained buckets from 1 to 10 seconds and extend millisecond duration histograms with buckets up to 120 seconds.
GitOrigin-RevId: dee492de08db058444926d22281ef7bc4ba1cdeb
## Why
An app-server child started by a previous updater can remain as a zombie after
termination. Its PID then still appears active, causing daemon shutdown to wait
until its timeout instead of removing the stale PID file.
## What changed
- Poll `waitpid` with `WNOHANG` while waiting for a PID-managed process to stop.
- Check process state before enforcing the stop deadline so an exit at the
deadline can still be observed and cleaned up.
## Testing
Added a regression test that stops an untracked child and verifies that shutdown
finishes promptly and removes its PID file.
GitOrigin-RevId: b203cf860e4207716a6cfc36015f8ee77918d13a
## Why
After a cold resume, a Multi-Agent V2 root thread must still be able to
address its persisted descendants even though their runtimes are not reopened
eagerly.
## What changed
- Restore metadata for open descendant agents when resuming a V2 root thread.
- Preserve each descendant's path, nickname, and role while leaving its runtime
unloaded until a message targets it.
- Reuse the spawn metadata preparation path so restored identities retain the
same reservation and naming checks as newly spawned agents.
## Testing
Added an end-to-end cold-resume test that follows up with a persisted agent by
name and verifies that the original agent thread is loaded on demand.
GitOrigin-RevId: a1663c1ae60eefadb948cd39f933cd3bbb49a492
## What changed
- Add optional serialized Codex turn metadata to extension tool calls.
- Populate it from the current turn context and send it as the
`x-codex-turn-metadata` header on standalone web search requests.
## Testing
- Extend the app-server web search integration test to verify that client
metadata, including the model ID, reaches the standalone search request.
GitOrigin-RevId: c0950108d89a1d317ac94ccd23efcee72fffc6f0
## Why
OAuth metadata discovery for an optional HTTP MCP server can stall, delaying
`thread/start` even though that server is not required.
## What changed
- Remove eager MCP authentication-status discovery from session and connection
manager startup.
- When an MCP connection reports an authentication error, inspect configured and
stored credentials locally to preserve login and reauthentication failure
reasons without making another discovery request.
- Continue using server configuration directly for startup error messages and
timeout hints.
## Testing
Add an app-server regression test with an optional HTTP MCP endpoint that accepts
a connection but never responds, and verify that `thread/start` completes without
waiting for its configured startup timeout.
GitOrigin-RevId: 56fe0188cc1ceaf746b0b65e8b7dd1fd2e13420d
## Why
After switching from proactive delegation to explicit-request-only mode, an
earlier proactive instruction can remain in the conversation context. The new
mode must clearly supersede that instruction.
## What changed
Update the explicit-request-only developer message to cancel earlier proactive
delegation instructions before requiring delegation to be explicitly requested
by the user, `AGENTS.md`, or a skill.
## Testing
Update the multi-agent mode integration test expectation for the explicit-mode
instruction emitted after a cold resume.
GitOrigin-RevId: 0a6d18f38ef82d29cf4f3bfcfd4ac84738a39598
## What changed
- Extend the lock-contention test helper with a callback that runs while the
aggregate store lock is held.
- Use a scoped worker thread and return its result directly after releasing the
lock.
- Reuse the helper for concurrent update tests covering both file and secrets
credential stores.
GitOrigin-RevId: 74b8b5370456e90ecd39fc2af2f0853594ca4f60
## What changed
- Apply each server's `startup_timeout_sec` (or the default) while creating the
MCP client, so the deadline also covers transport setup.
- Launch local stdio servers on a blocking task so synchronous command
resolution and process creation do not prevent the deadline from firing.
- Recognize the new client-startup timeout error and show the existing
`startup_timeout_sec` configuration hint.
## Testing
- Extend the timeout error display test to cover the client-startup timeout.
GitOrigin-RevId: 1967c62f943d55f6aa18792d4488e52c22f1e717
## What changed
Mark `skill_search` as stable and enable it by default so the app server runs
shadow skill selection and emits its experiment metrics.
GitOrigin-RevId: ea9da3b71bfb3be2093aac89ad3d3e388931901d
## Why
Shadow selection can observe invocations from host and orchestrator skills, but
including executor skills in its candidates can skew the resulting metrics.
## What changed
Limit eligible shadow-selection candidates to enabled, prompt-visible skills
from host or orchestrator sources.
## Testing
Extend the implicit-invocation test to add matching executor candidates and
verify that the host skill remains the selected invocation hit.
GitOrigin-RevId: fd444fe27254b5a880ef5c03c29b5e195127cd97
## What changed
- Add an opt-in `skill_search` feature that ranks prompt-visible skills against each turn's user input with a bounded weighted lexical selector.
- Keep the ranked selection out of model-visible context and record metrics for selection cost, catalog reduction, and whether later implicit or `skills.read` invocations matched the ranked candidates.
- Include host-provided skills in the experiment catalog without changing the rendered skill catalog.
## Testing
- Add selector unit tests covering ranking, limits, truncation, stop words, and deterministic tie-breaking.
- Add extension tests covering turn-local invocation recording and host-skill shadow selection.
GitOrigin-RevId: 4d00a1c805ea8b391d6c6ac6a8450afa88ca3e25
## Why
Model overrides for `spawn_agent` must be compatible with the multi-agent backend used by the current turn.
## What changed
- Carry each model's multi-agent backend metadata into `ModelPreset`.
- Filter the advertised `spawn_agent` model overrides for multi-agent v2 and reject overrides assigned to another backend.
- Limit error suggestions to picker-visible, backend-compatible models.
## Testing
Added coverage for hiding incompatible models from the tool description and rejecting them during spawn validation.
GitOrigin-RevId: 22c12aba67df46e9743a74f019b72a1b8b76b308
## What changed
- Add the `features.multi_agent_v2.expose_spawn_agent_model_overrides` setting, enabled by default, to expose `model` and `reasoning_effort` on the v2 `spawn_agent` tool.
- Keep these controls available when other spawn metadata is hidden, while allowing them to be disabled independently.
- Add root-agent and subagent guidance that overrides require a partial or context-free fork and should only be used when explicitly authorized.
## Testing
- Cover configuration parsing and defaults, usage-hint preservation, and tool-schema behavior with override exposure enabled and disabled.
GitOrigin-RevId: 92370498108c96fbd51f32965624ce531e991d9a