## Why
Bubblewrap discovery probes executables before confinement. Excluding only the command's current directory leaves candidates in other writable roots eligible to run outside the sandbox.
## What changed
- Filter canonical `PATH` candidates using the filesystem policy and effective user permissions, including writable ancestors, symlinked roots, and full-disk write access. Preserve protected system installations while rejecting replaceable paths.
- Select the launcher with the command's permissions before the proc-mount preflight, retaining the bundled bubblewrap fallback.
- Use the effective permission profile and policy working directory for startup warning probes.
## Testing
Add unit coverage for writable roots, symlinks, read-only carveouts, replaceable parents, and full-disk policies. Add Linux integration tests showing writable `bwrap` candidates are neither probed nor launched, including when the command runs in a workspace subdirectory or uses managed networking with full-disk write access.
GitOrigin-RevId: 188c9f45e727eaace062f5abb1205dc23fdf3c51
## Why
A database can open successfully while containing corruption that startup previously missed. Detecting it before runtime initialization completes allows recoverable databases to be rebuilt while preserving the damaged files.
## What changed
- Run `PRAGMA quick_check(1)` when opening writable databases, with a 100 ms scan budget. Share attempts across cloned `SqliteConfig` instances by file identity so repeated opens skip validation and replacement files are checked again.
- Back up and rebuild runtime databases that support recovery. Report corruption without rebuilding thread history or other databases without an automatic recovery policy. Treat interrupted or locked checks as incomplete rather than confirmed corruption.
- Collect startup backups across recovery retries and include their locations in the app server warning. Explain that saved conversations can restore the thread list and history, while some database-only metadata may be unavailable.
- Record confirmed corruption in `codex.sqlite.corruption.count`.
## Testing
Add tests for recovery policies, backup preservation, validation caching and concurrency, cancelled and interrupted checks, and locked databases. Add app server coverage for recovery warnings and saved conversation restoration, a TUI warning snapshot, and message board post preservation.
GitOrigin-RevId: 43e26328888e0301def642d69bd324acee867566
## Why
Setting `auto_vacuum` on every connection can wait for a writer lock even when the mode is unchanged. Logging every span entry and exit can also block SQLx workers on undrained stderr while they hold a write transaction.
## What changed
- Set incremental vacuum only for empty databases or databases using full auto-vacuum, before enabling WAL. Preserve existing nonempty databases with auto-vacuum disabled.
- Emit span creation and closure events in app-server text and JSON stderr logs, preserving busy/idle timings and explicit events while omitting span entry and exit records.
## Testing
Add regression tests for opening and expanding writable pools while another connection holds a writer lock, and for transaction completion with undrained stderr in both log formats. Verify vacuum modes and retained log diagnostics.
GitOrigin-RevId: 40d4ef32c7efc49f4240b987277ba45551259335
## Why
Private IP destinations always bypassed inherited upstream proxies, preventing their use for private networks reachable through an upstream VPN proxy.
## What changed
- Add `codex exec-server --proxy-private-ips-via-upstream`, also configurable with `CODEX_EXEC_SERVER_PROXY_PRIVATE_IPS_VIA_UPSTREAM=true`. The setting defaults to disabled.
- Allow permitted RFC 1918, carrier-grade NAT, and IPv6 unique-local destinations to use an applicable upstream proxy. Loopback and link-local destinations retain direct routing, and destination access policy still applies.
- Keep connections direct when no valid upstream proxy applies or `allow_upstream_proxy=false`. Errors after selecting an upstream proxy do not trigger a direct retry.
- Rename `ExecServerRuntimePaths` to `ExecServerRuntimeOptions` and carry the routing setting from executor startup into the managed network proxy.
## Testing
Add routing coverage for private address ranges, special-use addresses, and public targets with the option enabled and disabled. Verify that HTTP and CONNECT requests still enforce destination allowlists and denylists, and update the CLI help snapshot.
GitOrigin-RevId: b7c9cc7da0e0f545694a6521b74c9b36b7b92769
## Why
Failed SQLite writes leave diagnostic logs incomplete. Notify users before they close Codex so they can submit logs or run `codex doctor`.
## What changed
- Add a best-effort warning on the first log write failure in standalone and in-process app servers, while continuing to retain failure diagnostics in memory.
- Handle failures that occurred before the in-process warning reporter was attached.
- Tailor the warning's guidance to whether submitting logs is enabled.
## Testing
Add coverage for warning deduplication, both guidance variants, retained diagnostics after the notification sender is dropped, and SQLite flush failures before and after reporter attachment. Extend log upload integration coverage and add a TUI warnings snapshot.
GitOrigin-RevId: 12a74126d13c3568430e539a180cca47fa931fa9
## Why
SQLite write failures can leave persisted logs incomplete, while log snapshots taken before collection miss errors raised during that collection.
## What changed
- Report SQLite flush failures directly to the in-memory log buffer without re-entering tracing, using an error category and batch size instead of raw error details.
- Track whether the log writer has lost a batch and make app-server diagnostic uploads use the memory buffer when SQLite logs are incomplete.
- Refresh log bytes after flushing and querying SQLite so the same submission includes collection failures, while preserving captured metadata and thread identity.
## Testing
Add regression tests for failure reporting without recursion, subsequent write recovery, metadata preservation, and healthy and failing SQLite collection. Add an upload integration test that captures attachments locally and checks failure diagnostics, memory-buffer fallback, and omission of raw SQLite error details.
GitOrigin-RevId: 51b0c4b69c977d9f4e74f2f245a9fd90fdb13761
## What changed
Move WebSocket authentication arguments, settings, credential loading, and upgrade authorization into a shared crate using `http` types. Update the app server, transport, and CLI to consume it directly, and remove the `AppServer` prefix from the shared types.
Hide token digests and JWT verification secrets from authentication policy `Debug` output.
## Testing
Move the existing argument validation, capability-token authorization, and signed bearer-token verification tests into the new crate.
GitOrigin-RevId: 1dd20043a3f8efbca55af7eda338b62a62e8fd68
## What changed
- Load `application.network` requirements at startup and explicit config/account reloads, applying local policy before authentication and cloud configuration bootstrap.
- Block traffic when policy loading fails, cancel requests that a new policy no longer permits, and reject configuration loads based on superseded policy snapshots. Local requirements edits take effect on the next explicit reload or restart.
- Bind authenticated clients to the current account and revoke them when account ownership changes. Carry policy enforcement through backend requests, realtime connections, workload identity exchanges, and code-mode gRPC streams while preserving gRPC trailers.
- Treat denied credential refreshes as policy errors without retrying them or invalidating stored credentials.
## Testing
Add regression coverage for startup restrictions, reload ordering, cancellation after restrictive or malformed requirements edits, account revocation, gRPC destination denial, workload identity cancellation, and credential preservation after denied OAuth refresh.
GitOrigin-RevId: 0cb4c720a906397e9df06675f01ecf60d741101f
## Why
Clients with a gateway sign-in UI need to control when browser authorization starts and inspect credential readiness before making authenticated requests.
## What changed
- Add `initialize.capabilities.explicitGatewayOauth` to require explicit login while allowing existing credentials to refresh. Preserve automatic authorization for clients that omit the capability, and prevent later connections from undoing explicit opt-in.
- Add `account/gatewayOAuth/read`, `account/gatewayOAuth/login`, and `account/gatewayOAuth/cancel`, plus `account/gatewayOAuth/changed` notifications. Send the authorization URL only to the initiating connection and cancel its login on disconnect.
- Check gateway authentication before returning cached results from `model/list`, with restart guidance when provider settings have changed.
- Update protocol schemas, TypeScript and Python bindings, and document capability probing and the sign-in lifecycle.
## Testing
Add tests for passive readiness reads, credential reuse after login, token exchange failures, cancellation and immediate retry, connection ownership, legacy versus explicit login, and model-list authentication checks.
GitOrigin-RevId: a26e116a62c9f3db84dc238a40b7f4e816eb1594
## Why
The app server retains its startup model provider, but managed provider requirements can change while it is running. Catalog reads and background refreshes must check those requirements even when models are cached.
## What changed
- Gate `model/list` and background refreshes through a shared catalog that validates the startup provider against current requirements.
- Return JSON-RPC error `-32600` with restart guidance when the provider no longer complies, and skip background requests to that endpoint. Requirement load failures also block catalog access.
- Log only the error kind for blocked refreshes to avoid exposing credentials in parser diagnostics.
## Testing
Add coverage for cached catalog access after provider selection or definition changes, invalid requirements, cloud configuration load failures, and recovery when requirements allow the retained provider again. Extend refresh tests to cover startup provider overrides, blocked endpoint requests, and credential-safe logging.
GitOrigin-RevId: 03127bba46f1f59f2a8b1dc37391eab75f9be23c
## Why
Network access and Unix-socket allowlists must not let commands with filesystem restrictions reach the privileged app-server RPC transport.
## What changed
- Bind Unix control sockets in a fixed, user-owned directory with mode `0700`, independent of environment settings, and expose the advertised paths as symlinks. Preserve existing parent permissions, reject unsafe parents, and serialize socket setup and publication.
- Mask the socket directory in Linux bubblewrap sandboxes after each bind that exposes it. Reject host mount aliases and nested mounts that compromise isolation.
- Deny access to the directory and outbound connections to its sockets in macOS Seatbelt policies, including when network access or Unix-socket allowlists grant broader access.
- Require bubblewrap for filesystem-restricted Linux execution. Users with `features.use_legacy_landlock` enabled must disable it for these policies.
## Testing
Add regression coverage for direct and symlink socket access, hardlink attempts, Linux host-process links and bind-mount aliases, and continued use of unrelated and sandbox-local sockets. Add transport coverage for parent permissions, concurrent restart after a stale symlink, and cleanup that preserves a replacement at the advertised path.
GitOrigin-RevId: 53372c27eea278d964f2cf68aed24323ef3b7082
## What changed
Keep `shutdown_signal()` pinned across `tokio::select!` iterations and reset it only when it completes, so other events do not cancel and recreate the pending signal listener.
## Testing
Update the WebSocket drain interruption test to use gated responses and keep a second turn active until the `turn/interrupt` reply arrives, preventing shutdown from racing the reply.
GitOrigin-RevId: c939d84ed0e09c2ee49229e81a3becdfa6a4c7f1
## Why
Managed daemon recovery snapshots previously saved only loaded thread IDs, without identifying active turns or preserving their turn-specific options.
## What changed
- Capture regular, uncanceled turns after their input is recorded, saving the turn ID, output schema, service tier, and cyber access program alongside persisted thread IDs.
- Store interruption metadata atomically in the existing candidate array format so older servers can still read thread candidates.
- Begin snapshotting once admitted operations drain, while turns may still be running. Run snapshot collection and thread listener attachment independently of the event loop to keep forced shutdown responsive.
## Testing
Add coverage for running, completed, canceled, and compacting turns; recovery readiness for automatic and user turns; admitted resumes during shutdown; forced shutdown with a blocked rollout writer and child listener attachment; and legacy candidate-array compatibility.
GitOrigin-RevId: ed46342c3a5c71b09c48fa9acece2f15ae748e2f
## What changed
- Capture `CODEX_WINDOWS_REGISTERED_CORE=1` at startup and propagate the selected runtime to sandbox wrappers.
- Launch registered runners through service-recorded execution aliases, validating ownership, OS package identity, and the staged runner image before sending commands. Require service provisioning without falling back to copied helpers or `PATH` lookup.
- Preserve package context for sandboxed child processes and descendants so they can launch executables from the protected package directory.
- Refresh stale package registrations during readiness checks without blocking unrelated RPCs, and reconcile effective proxy settings through the service.
- Resolve setup ownership from the process token and avoid treating the server directory as a writable workspace when setup omits `cwd`.
- Record startup and command outcomes by runtime.
## Testing
Add coverage for runtime selection, package query validation, helper resolution, setup roots, proxy reconciliation, and command result reporting. Add an ignored integration test for environment forwarding, output, and exit status that requires an installed test MSIX and service provisioning in a Windows VM.
GitOrigin-RevId: 976d64039d611be4406c3d0e354820775f8eb6e4
## Why
Stdio shutdown can hang on open pipes or blocked I/O, and Unix `SIGTERM` needs to run connection cleanup so owned commands terminate and session-end hooks execute.
## What changed
- Handle `SIGTERM` on a dedicated signal thread and close the stdio connection through the existing cleanup path.
- Move blocking stdin and stdout operations to dedicated threads so they do not hold the Tokio runtime open. Cancel message forwarding on `SIGTERM` to release blocked producers.
- When shutdown signal handling is enabled on Unix, start a shared 45-second watchdog on EOF or `SIGTERM`. Preserve the first deadline and exit with status `1` if cleanup or runtime teardown stalls, even when logging is blocked.
## Testing
Add Unix integration coverage for shutdown with open pipes, blocked stdout, blocked stderr, and a stalled filesystem write. Verify command and child-process termination, preserve the EOF deadline when `SIGTERM` follows, and extend session-end hook coverage to `SIGTERM`.
GitOrigin-RevId: 43a80b8277eb50519cdc293eb3b5dc2cad00b3aa
## Why
Remote-control connections and queued operations must not carry over to a different signed-in user or account. Token refreshes for the same identity should preserve the live relay connection.
## What changed
- Scope relay state and authentication recovery to a login lifetime. Retire the session on logout or identity changes and leave remote control disabled until enabled again.
- Reject stale incoming messages and queued RPCs, and cancel pending remote-control operations when their authentication owner changes.
- Start replacement sessions with fresh client, replay, and enrollment state, and prevent retired sessions from publishing status into their replacements.
- Serialize enrollment and preference persistence across sessions, retaining write permits through caller cancellation and draining admitted writes on shutdown.
## Testing
Add regression coverage for same-owner refreshes, user and account changes, stale pairing and client-revocation work, unauthorized enrollment recovery after logging in again, and persistence during cancellation.
GitOrigin-RevId: 5e6ecd23588aab1e2e6168a21f575fb24bbb341c
## Why
Saved threads need to resume after a managed daemon restart so active goals can continue without waiting for a client to reconnect.
## What changed
- Consume the recovery snapshot at startup and restore threads in the background through the shared cold-resume path.
- Trigger idle lifecycle work without attaching a client subscription, and leave already-loaded threads untouched.
- Continue recovery after individual thread failures and abort background recovery during shutdown.
## Testing
Extend the daemon restart integration test to verify goal continuation before client reconnection, restored conversation history and tools, idle-thread restoration, and recovery snapshot consumption. Include malformed snapshots and an invalid thread ID.
GitOrigin-RevId: 90e7b8f74ddc0ae327bacde1b2108b9749c65f2a
## What changed
- Atomically save successfully persisted, loaded root thread IDs to `app-server-daemon/loaded-threads.json` during graceful managed shutdown, excluding ephemeral threads and threads pending unload.
- Clear stale recovery state at startup and around daemon lifecycle operations, including explicit stops and fresh starts.
- Probe support for `--managed-daemon` before launching managed app servers, and clear recovery state best-effort when launching older binaries.
- Keep forced shutdown responsive while saving the snapshot and log snapshot failures without preventing shutdown.
## Testing
Add coverage for snapshots after active turns finish, forced shutdown without a snapshot, excluded threads, snapshot write failures, and recovery-state cleanup for stops, fresh starts, and legacy launches.
GitOrigin-RevId: 422dc32b85355510f7e4c57b7540597b47d9f0b2
## Why
Loaded threads, including idle threads whose rollout files are still deferred, need to survive a managed daemon restart. Shutdown must also remain forceable when rollout I/O is blocked.
## What changed
- Add a hidden `--managed-daemon` option for app-server Unix socket transports. After active turns and admitted requests drain, save loaded persistent root threads before exiting.
- Skip ephemeral threads, non-root agent threads, and threads pending unload. Log persistence failures and continue saving other threads.
- Apply shutdown admission checks to thread and turn settings updates, thread deletion, and archiving.
- Keep force signals and daemon shutdown requests responsive during persistence. Return `AppServerExit::Forced` so executables can exit without waiting for runtime teardown.
## Testing
Add integration coverage for resuming active and idle threads after restart, forcing shutdown during active work, and forcing shutdown with a blocked rollout writer. Extend shutdown rejection coverage to deletion and settings updates.
GitOrigin-RevId: 4344e97d39f9f80c5d84c41c17300fd6aa99b4cc
## Why
New client requests and automatic continuations can start more work while the app-server is draining. Shutdown also needs to account for requests still preparing or submitting work before they appear as running turns.
## What changed
- Close a shared admission gate when shutdown begins, rejecting new turn work and thread lifecycle changes with the server-draining error.
- Apply the gate to automatic turn starts, including queued work and goal continuations, and recheck serialized turn requests before execution.
- Wait for admitted requests and running turns to finish, while preserving forced shutdown. Keep reads and `turn/interrupt` available during drain.
## Testing
Add coverage for admission permit tracking, discarded queued requests, forced shutdown, and WebSocket drain behavior, including request rejection, interruption, and suppression of automatic continuations.
GitOrigin-RevId: 1bc108aa00a427cfa41974fa9ec60754c2b968c2
## Why
The existing `userVerification/*` handlers always returned unavailability, leaving local clients unable to use the native verification provider.
## What changed
- Dispatch status, enrollment, deletion, and challenge signing through an account-scoped provider. Enrollment creates or reuses a local key; it does not register credentials with a server.
- Restrict enrollment, deletion, and signing to stdio and in-process connections, rejecting WebSocket and remote-control callers before parameter validation.
- Bound native work to one operation per service with a 120-second timeout, and propagate in-process caller cancellation. Recheck connection, cancellation, and authentication state before delivering results, including after waiting for response queue capacity.
- Add device-gated verification capability wiring for the experimental in-process `codex-tui` client, with automatic activation still disabled by default.
## Testing
Add tests for local key reuse and deletion, decoded challenge signing, cancellation, authentication changes during verification and response queuing, concurrent worker rejection, and stdio/WebSocket RPC behavior.
GitOrigin-RevId: 7eac15a5ffb049d27bf8fedcfbae19a49a3f6a3d
## Why
Device-authenticated verification needs an app response outside automated approval and review. Previously, MCP user-verification requests were always cancelled.
## What changed
- Add typed `openai/userVerification` elicitations carrying a title, description, and challenge through core and app-server.
- Route verification to one connection enabled by trusted host activation. Restrict responses to that owner, exclude requests from replay, and cancel on disconnect or authentication changes, including account switches away and back.
- Return proofs in `content`, discard response metadata, and cancel malformed acceptances. Suppress verification response logging and analytics, and send only a generic verification notice to realtime.
- Keep the mode experimental and exclude it from stable schema exports. Capability advertisement remains disabled, and the TUI cancels verification requests.
## Testing
Add coverage for owner isolation, disconnect and authentication races, proof response handling, automated-review bypass, inactive-host cancellation, stable schema filtering, and realtime payload exclusion. Update the MCP integration test to verify that an activated request holds the tool until the client responds.
GitOrigin-RevId: c8c7b6691a3f7756682bbcca9def1df0d1feb906
## What changed
Route managed Windows app-server shutdown through `/daemon/shutdown` on the local control socket. Require the server's PID and acknowledge it before triggering shutdown through the existing drain logic. Enable the endpoint only for managed Windows launches via `CODEX_DAEMON_SHUTDOWN_SOCKET`.
Watch running-turn changes whenever shutdown is requested so socket-triggered shutdown can finish draining. Keep the updater's file-based shutdown mechanism and retain forced termination as the manager's timeout fallback.
## Testing
Add a transport test covering rejection of unmanaged shutdown requests and mismatched PIDs, plus acknowledgment before emitting the shutdown event.
GitOrigin-RevId: 3e95dc1914f61e8a131f9b6fd56b6c63688d1744
## What changed
Add `userVerification/status`, `userVerification/enroll`, `userVerification/delete`, and `userVerification/verify` behind the `experimentalApi` capability. Define request, response, proof, and typed error contracts, export their schemas, and document the API.
All four methods currently return `unavailable` with reason `providerUnavailable`; native verification operations are not implemented by this change.
## Testing
Add tests for experimental opt-in, typed provider unavailability, readiness serialization, and rejection of mismatched error reasons and native diagnostic payloads.
GitOrigin-RevId: a858ab41523c5acec7dbf3cfa7fcab693ac44a8c
## What changed
- Add the macOS-only `allow_symlinked_codex_home` user setting. When enabled in the execution host's `$CODEX_HOME/config.toml`, writable roots at or beneath that home may traverse symlinks.
- Keep the exception disabled by default and prevent project config, command-line overrides, and ignored user config from enabling it. Other writable roots remain subject to symlink checks.
- Propagate the resolved setting through local, interactive, and exec-server sandbox paths, including `CODEX_HOME` aliases.
- Explain the opt-out in symlink rejection errors, including that it trusts targets outside `CODEX_HOME` and targets that change between commands.
## Testing
- Add macOS coverage for shell commands, patches, filesystem helpers, process execution, and interactive startup with enabled, disabled, aliased, and out-of-scope homes.
GitOrigin-RevId: 99fcdf611200c9e1b7713cf06f7fdea5bfa7f089
## Why
A pending remote control enrollment could prevent the app server from exiting
after stdio EOF, leaving resources such as thread writers held by the process.
## What changed
- Give remote control its own child shutdown token and cancel it before draining
RPCs when the stdio connection closes.
- Interrupt enrollment requests that require network access after shutdown has
begun, while still allowing in-memory or persisted enrollments to be enabled
and durably saved.
## Testing
- Cover stdio shutdown during a blocked enrollment and verify that another app
server can acquire the released thread writer.
- Cover durable enablement after shutdown with in-memory, persisted, and missing
enrollments.
GitOrigin-RevId: ef9ab49672f273a4cf8257188454a154c03088bd
## Why
Detached Windows processes cannot receive console signals, so app-server daemons
need another way to enter the existing graceful and forced shutdown flow.
## What changed
- Watch the path in `CODEX_DAEMON_SHUTDOWN_FILE` for a request addressed to the
current process, and consume only a matching PID.
- Race daemon shutdown requests with Ctrl-C on Windows while leaving unmanaged
launches on the existing console-signal path.
- Exercise the SIGTERM-equivalent graceful and forced WebSocket shutdown cases
on Windows.
## Testing
Added unit coverage ensuring inherited control paths and malformed requests
cannot consume another process's shutdown request.
GitOrigin-RevId: 426a3c12edc344802395d4d26288f2bb015c484f
## Why
Configured Git marketplaces may be defined outside the user config, but those definitions could not download or update their snapshots.
## What changed
- Select marketplace source, ref, and sparse-path settings from the effective merged configuration for startup synchronization and explicit upgrades.
- Preserve the initiating operation's configuration loader and overrides when reloading before activation.
- Roll back activation if the marketplace definition changed or configuration can no longer be loaded, without copying settings into the user config.
## Testing
- Cover system-defined marketplaces, CLI overrides, startup fallback after invalid user configuration, and rollback after configuration changes.
GitOrigin-RevId: 53d1eecf68a91ce2aa8430e5749d78697bfcd821
## What changed
Add a `compression_enabled` attribute to each
`codex.app_server.codex_home.size_bytes` sample. The value reflects whether
`LocalThreadStoreCompression` is enabled in the effective startup configuration.
GitOrigin-RevId: c087d36b4e578245aee6cfe5257075dfd3bdd025
## Why
Realtime history should be recorded consistently for every Core host, including
when no app-server event listener is attached.
## What changed
- Move transcript segmentation, session boundaries, and backing-agent artifact
promotion into Core for paginated threads.
- Persist canonical realtime items through the thread store in event order and
emit dedicated history lifecycle events for hosts to present.
- Translate those Core events into the existing app-server realtime item
notifications without app-server persisting the items a second time.
## Testing
- Cover Core-only persistence across repeated sessions, ephemeral sessions,
accepted and rejected steering, typed input ordering, and artifact promotion.
- Verify app-server notifications correspond to the persisted timeline.
GitOrigin-RevId: 7cbef14129d77f6d6d7099b733be91f5279c55f5
## What changed
- Add the disabled-by-default `omit_app_server_notification_media` feature.
- When enabled, remove inline image and audio content from `item/started`,
`item/completed`, and `rawResponseItem/completed` notifications, including
tool output and image-generation results.
- Keep the media in model input; the filter only changes app-server
notifications.
## Testing
- Verify that image content is absent from all three notification types while
the model request still receives it.
GitOrigin-RevId: 9a4434d18a3dac6d67c2e0c3723ff4595a9b3797
## What changed
- Scan regular files under `CODEX_HOME` in a background blocking task when
standalone app-server metrics are enabled.
- Record `codex.app_server.codex_home.size_bytes` for the entire home and the
`sessions` and `archived_sessions` subdirectories.
- Avoid following symlinks, discard incomplete scans, and cancel scanning during
shutdown.
GitOrigin-RevId: 236fc0a5c156dbd4a99e9835135de194809b4a7b
## What changed
- Accept only `http://` and `https://` gRPC endpoints for app server
`--code-mode-host` connections.
- Limit the standalone code-mode host to stdio and gRPC listeners.
- Remove the WebSocket session provider, dual-WebSocket negotiation, transport
lanes, and related dependencies and tests.
- Keep coverage for shared and prewarmed gRPC hosts and reject WebSocket host
URLs in CLI parsing tests.
GitOrigin-RevId: 8792604e79ffd54ce776074a4dc3f7d55e63752a
## Why
Clients need a bounded view of realtime conversations that preserves the order of speech, agent work, and turn lifecycle events without loading the full thread history.
## What changed
- Persist realtime session boundaries, transcript segments, and promoted agent items in paginated thread rollouts.
- Add the experimental `thread/timeline/list` API to page ordinary items, realtime items, and turn boundaries in canonical rollout order. Include `activeRealtimeSessionAtPageStart` so each page can be rendered independently.
- Emit typed `thread/realtime/item/started`, `thread/realtime/item/transcript/delta`, and `thread/realtime/item/completed` notifications around durable realtime items.
- Keep the existing `thread/items/list` response and legacy thread history behavior unchanged.
## Testing
- Cover mixed timeline pagination, realtime-session state at page boundaries, rollout replay, subagent history prefixes, transcript streaming, steering, and promoted agent artifacts.
GitOrigin-RevId: faa2c420192d63e060e8fb32446e3c797422656e
## What changed
- Add experimental `mcpServer/event/stream/start` and `mcpServer/event/stream/stop` requests for hosted apps, plus `mcpServer/event/stream/notification` forwarding.
- Scope subscriptions to the owning app-server connection and subscribed thread, enforce unique IDs and a per-connection limit, and clean them up when the thread is unsubscribed or the connection closes.
- Wait for the MCP active notification before completing startup, retry streams that close immediately, and terminate them when authentication or hosted runtime ownership changes.
## Testing
- Add an app-server integration test covering activation, event forwarding, duplicate subscription rejection, and explicit cancellation.
GitOrigin-RevId: 8a6fc1615adfc5af7e67def3b824fa5909ab3e7b
## Why
Unsupported untrusted approval policies must remain startup errors even when
app-server is allowed to fall back from other invalid configuration. Likewise,
compound command summaries must not discard a `sed` stage that can edit files
in place.
## What changed
- Propagate `UnsupportedUntrustedApprovalPolicyError` from both app-server
configuration loads instead of replacing it with default configuration.
- Parse `sed` options through `--`, option arguments, combined short flags, and
backup suffixes so `-i`/`--in-place` commands remain unknown actions.
- Keep non-mutating `sed` operands after `--` from being mistaken for flags.
## Testing
Added parser coverage for in-place `sed` variants in compound commands and for
dash-prefixed operands after `--`.
GitOrigin-RevId: 112ead912e10fcb6c7dd0ede4bf84e390af82da8
## What changed
- Remove `untrusted` from the CLI, configuration schema, and MCP tool interface. Explicit `approval_policy = "untrusted"` settings now fail with an actionable error.
- Remove the known-safe command allowlist. Projects marked untrusted now request approval for every command unless an explicit exec policy rule allows it.
- Keep command parsing conservative by treating in-place `sed` forms as mutating and ignoring unrecognized commands when recording memory usage.
## Testing
- Cover rejection of the retired configuration value and approval requests for commands in untrusted projects.
GitOrigin-RevId: d6bf425edddfffbb325eee6acf383434af5fd33b
## What changed
- Remove `experimental_thread_config_endpoint` from the configuration model and schema.
- Stop app-server and the in-process client from constructing a remote thread config loader from local configuration.
- Keep the thread config loader supplied at app-server startup fixed for the lifetime of the config manager.
GitOrigin-RevId: e7907fee2d631e7ecf89ec6bac8f22bc2c221350
## What changed
- Track app-server turn lifecycle events for OpenAI API-key sessions when OTLP telemetry export is enabled.
- Query the turn-cost endpoint after completed or aborted turns and emit `codex.turn_cost` with the estimated USD cost, interruption state, model, speed, and reasoning effort.
- Preserve provider organization and project headers, wait for all observed responses to be priced, and retry pending or transiently failed queries with bounded tracking.
- Re-probe availability after authentication changes and shut the worker down with other app-server background tasks.
## Testing
- Cover late API-key login, transient probe failures, telemetry after thread removal, and turns with multiple responses.
- Verify turn-cost requests use API-key authentication and provider scope headers and deserialize priced response data.
GitOrigin-RevId: a303162a54798b554fcb2e9e2b372e1cf9f49f39
## What changed
- Treat workload identity environment markers as an explicit authentication selection, even when another process credential is present.
- Return initialization errors from `AuthManager` and propagate them through commands and services instead of continuing with an unusable authentication state.
- Make `codex login status` validate workload identity, keep the TUI on an embedded app server for local workload identity, and reject workload identity in `codex mcp-server`, where it is unsupported.
## Testing
- Cover workload identity precedence and partial configuration errors.
- Verify login status reports an unreadable identity assertion and app-server routing enforces the supported workload identity topology.
GitOrigin-RevId: efc6b6b4cd4d61652617de82aaa3d7ffc75d6618
## What changed
- Accept root `http://` and `https://` URLs in `--code-mode-host` and use the
shared gRPC session provider for those endpoints.
- Keep `ws://` and `wss://` URLs on the existing WebSocket transport.
- Reject paths, queries, fragments, and credentials where unsupported, without
exposing gRPC URL credentials in command-line validation errors.
## Testing
- Cover argument parsing and transport selection for both remote protocols.
- Exercise a gRPC host shared across app-server threads and verify credential
rejection does not disclose usernames or passwords.
GitOrigin-RevId: b6516a85cf76db5c4cea620f89ef866d8af30cf0
## What changed
- Add the under-development `psp` feature and expose it in the config schema.
- Use the feature to attach the PSP cookie to first-party ChatGPT clients.
- Remove the hidden `--psp` flag and its process-scoped configuration plumbing.
- Preserve configured ChatGPT cookies when creating the PSP client used for GET and POST requests.
## Testing
- Update the config manager service test to verify that enabling `features.psp` retains the setting in the effective config and configures the expected ChatGPT cookie.
GitOrigin-RevId: 53acb5495d2ff71e4ed25f674a0cff787aea474a
## Why
An account change can select different OpenTelemetry collector settings. The
long-running app server needs to stop exporting telemetry with the previous
account's configuration.
## What changed
- Rebuild and install the log, trace, and metrics exporters when authentication
changes, and shut down the previous provider without blocking the app server.
- Make cached global metrics clients and the tracing layer follow the replacement
provider so existing callers continue exporting through the current account's
configuration.
- Clear the cached cloud configuration loader after login and logout so telemetry
reloads from the new account context.
## Testing
- Add an app-server integration test that switches accounts and verifies logs,
traces, and metrics reach the new collector while trace context is preserved.
- Add a metrics test covering cached clients after provider replacement.
GitOrigin-RevId: a74359777a35edbee5bbe0b2baccc155074cb172
## Why
Authentication restrictions must apply before stored or environment-provided credentials can be used, including during bootstrap before cloud requirements are fetched.
## What changed
- Add local `requirements.toml` allowlists for login methods and ChatGPT workspaces. Ignore these fields in cloud-provided requirements.
- Combine managed workspace allowlists with existing workspace restrictions by intersection, and fail closed when the resulting policy permits no usable login method.
- Centralize policy checks in the authentication manager so CLI, TUI, app-server, external-auth, and credential-loading paths consistently reject disallowed authentication before token hydration or network requests.
## Testing
- Cover policy composition, workspace intersection, invalid stored and external credentials, bootstrap enforcement, and login endpoint restrictions.
GitOrigin-RevId: efef22b248f3c3333e9aa55423e539efa2d2dd48
## What changed
- Add a hidden global `--psp` runtime flag and propagate it through TUI, exec,
app-server, remote-control, and in-process startup paths.
- Attach the `oai-chat-psp=true` cookie to first-party ChatGPT requests when
enabled, using a cached cookie-aware client with sensitive request logging
disabled.
- Keep the routing selection out of persistent configuration layers while
preserving it across config refreshes and agent role changes.
## Testing
- Cover global flag parsing, app-server propagation, config-layer isolation,
and preservation across config rebuilds and role changes.
GitOrigin-RevId: 05cdc61ffd7162d8e48fc1e166f4732113e5a816
## What changed
- Replace the ordering enum and `include_disabled` boolean with named
`ConfigLayerStack` iterators for each precedence direction.
- Keep enabled-only iteration separate from `all_layers_*` iteration, which
includes disabled layers.
- Update config consumers to use the iterator matching their precedence and
disabled-layer requirements without allocating an intermediate `Vec`.
## Testing
- Add coverage that verifies ordering and disabled-layer filtering for all four
iterators.
GitOrigin-RevId: d14df3db4a2eae80ba97cdec246bff405e6c5f3d
## Why
Closing stdin could leave the app-server running when a remote-control client
was still connected.
## What changed
Track each connection's origin and shut down a stdio app-server when its stdio
connection closes, regardless of whether other connections remain. Report the
shutdown reason as `stdio_connection_closed`.
## Testing
Added a regression test that closes stdio while a remote-control connection is
active and verifies that the app-server exits and disconnects the remote client.
GitOrigin-RevId: 51ab14d45dfea7f40a0657a8bb167b54efaf0e48
## What changed
- Add `--code-mode-host ws://...` and `wss://...` support to `codex app-server`, gated by the `code_mode_host` feature. When omitted, app-server continues to start a local host.
- Share one remote WebSocket connection across the process's threads, using the configured HTTP client's proxy and TLS policy and preserving the existing framed host protocol.
- Reject invalid host URLs, bound WebSocket frame sizes, close connections cleanly, and return an error when a connection exceeds 1,024 pending delegate calls without disconnecting it.
## Testing
- Cover CLI validation, WebSocket protocol execution and shutdown, connection sharing across app-server threads, and delegate-call capacity recovery.
GitOrigin-RevId: 715e82d4d9db1e7e2f91b754a777dcab504e2ae4
## Why
The TUI must inspect the default execution environment before loading its final
configuration. Initializing the environment manager at that point can give
startup services the bootstrap HTTP policy instead of the effective policy after
managed requirements are applied.
## What changed
- Split environment discovery from manager construction so callers can inspect
the default environment without starting remote connections.
- Build the environment manager after final configuration loading and pass its
resolved `HttpClientFactory` through all construction paths.
- Add shared test support for managers that use the legacy default HTTP policy.
## Testing
- Cover connection-free environment discovery and explicit HTTP policy
propagation.
- Verify TUI startup services use the final managed `respect_system_proxy` value.
GitOrigin-RevId: 928fa31e6b4bcfbe1a121cade2f351427fdfa0f4
## Why
Codex and SQLite data can use separate home directories, but state consumers
could reconstruct database paths from the Codex home instead of consistently
using the resolved SQLite configuration.
## What changed
- Pass `SqliteConfig` through the core, rollout, state runtime, and thread store
instead of passing a directory and rebuilding the configuration downstream.
- Use that shared configuration for state, logs, memories, goals, and paginated
thread-history database access, including integrity checks and cleanup.
- Reject state database handles whose SQLite configuration does not match the
requesting store.
## Testing
Add coverage with separate Codex and SQLite homes that verifies startup
backfill, thread listing, and paginated history all use the configured SQLite
directory.
GitOrigin-RevId: 1de1cdd1d6ff1d70bbb6c360c8352e6543fb8ebf