## Why
Failed marketplace adds can leave temporary checkouts behind, and interrupted adds or upgrades can leave abandoned staging directories.
## What changed
- Share a staging guard across marketplace adds and upgrades so temporary checkouts are removed on completion or failure, including config-write rollback.
- Reclaim up to four abandoned directories per cleanup pass during add and upgrade operations. Use file locks to preserve active checkouts and operating-system-specific names to avoid reclaiming another platform's staging directories.
- Skip symlinks and unrelated entries, and report cleanup failures as warnings.
## Testing
Add regression coverage for failed adds, CLI and automatic-upgrade cleanup, cross-process ownership and abandonment, lock contention, bounded cleanup, and symlink handling.
GitOrigin-RevId: 20999da0eab861dfb8025aad5e9fba2bcaf818b8
## What changed
- Add an account IdP identity resolver that checks ID-token bindings against trusted issuer and client provenance before discovering the refresh-token endpoint. An expired ID token does not by itself invalidate the refresh grant.
- Generalize `EmaIdpIdentity` and token exchange requests to carry caller-owned credential leases. Invoke a `finish_idp` callback after the IdP exchange and before resource authorization server I/O so callers can release their refresh guards at that boundary.
- Reject empty expected OIDC issuers and client IDs, and expose an unverified issuer hint solely for explaining legacy login migration.
GitOrigin-RevId: 34473fed82a9a6e58997664cd5e6e67049b5ee7e
## Why
Queued prompts can resume before a pending permissions menu opens, and local
`/permissions` commands can bypass guards for outstanding permission changes.
Attaching to a different project can also retain model access information from
the launch directory.
## What changed
- Route `/permissions` through app permission guards and hold queued prompts
while the menu is pending. Settle the hold when opening is rejected, discovery
is invalidated, or a covering request is resolved.
- Apply the custom permission profile selection check beyond embedded servers.
- Refresh API-key model access when the first attached session changes the
working directory, including with an embedded server. Propagate the widget's
model catalog to the app and server even when the model response matches the
widget's already-updated catalog.
- Skip sessions reported as `thread not loaded` during name lookup for all
server types instead of falling back to unverified list metadata.
## Testing
Add regression coverage for permission guards, queued prompts across successive
permission menus, invalidated and covered menus, model catalog propagation,
project changes on initial attachment, and name lookup across server pages with
unreadable entries.
GitOrigin-RevId: eb49cb5268ce0ce1e40009b73a0180f23e61ed72
## Why
A persisted login replacement can leave the auth cache holding the previous login, even for the same account. Enterprise MCP authorization must detect that replacement before continuing to use enterprise credentials.
## What changed
- Check cached and persisted account login ownership before enterprise MCP connections and around token exchanges, revoking authorization when ownership changes.
- Recheck account ownership and login generation before committing enterprise sign-in credentials.
- Compare complete token data when checking whether an account OAuth grant is still current, and expose grant token access and credential comparison helpers.
## Testing
Add regression coverage for detecting a same-account login replacement without updating cached auth, rejecting enterprise MCP use after replacement, and keeping ordinary MCP usable while an enterprise account storage read is blocked.
GitOrigin-RevId: 6303f88a9cbcc84c99e453dc281b23d66930f518
## What changed
- Update Cargo and Bazel toolchain pins, CI and release workflows, and Windows setup from Rust `1.95.0` to `1.99.1`.
- Adapt Rust code to updated APIs and lint requirements, including `try_update` and `as_chunks`, and refresh the halfwidth sound marks snapshot.
- Update `webpki-root-certs` from `1.0.5` to `1.0.10` in the Cargo and Bazel lockfiles.
GitOrigin-RevId: e1aaed63b7e72bb8c8bbe25b32c6329c9a37b6c3
## Why
Agent Plugin manifests previously skipped app declarations, including service-generated declarations installed with remote curated plugins. This prevented those plugins from using app routing and suppressing matching direct MCP connections.
## What changed
- Recognize app declarations for Agent Plugins from `openai-curated-remote` across loading, capability summaries, plugin details, tool suggestions, and install authentication.
- Apply app routing to suppress same-name MCP servers when an app route is available. Keep unrelated MCP servers available and preserve direct MCP access in API-key mode.
- Keep app declarations inactive for Agent Plugins from other marketplaces.
## Testing
Add coverage for marketplace and authentication routing, service-generated app declarations during installation with both manifest formats, and app tools reaching turns. Verify that disabling Apps does not restore matching direct MCP connections.
GitOrigin-RevId: 791739569f0e01c898040bc2d028cf517f767e00
## Why
Decisions snapshot comparisons reject requests containing reasoning or compaction, while conversation comparisons already omit those items. A parent compaction also causes snapshot comparisons to be rejected.
## What changed
- Share filtering of reasoning, compaction, and context compaction across both comparison modes, and ignore parent compaction when building the Decisions request.
- Distinguish malformed request setup from unsupported input items. Record setup errors as failures and unsupported input items as skipped comparisons.
## Testing
Extend the HTTP contract test to cover both comparison modes with reasoning, compaction, context compaction, and parent compaction while preserving message content. Update assertions for the distinct setup and unsupported-input errors.
GitOrigin-RevId: e3ba0cce3b6457b3e3eab3589352b70288cbb1ef
## What changed
Add `MessageLifecycleContributor` hooks to capture extension state when local agent control publishes a message and notify contributors when the recipient commits it to history, before sampling.
Carry shared delivery state through submissions, input queues, and mailbox eviction with `PendingAgentMessage`. Notify consumption at most once per delivery, release captured state when consumed or abandoned, and drop pending mail outside queue locks. Preserve the serialized message format without republishing restored history.
## Testing
Extend the mailbox eviction test to verify that publication state survives eviction and retained messages are consumed before the first resumed model sample.
GitOrigin-RevId: 9a1f6832bd48ec646a3fd179485c095e8dcc72cc
## What changed
- Add `CodeModeCellTiming` notifications for yielded executions, terminal waits, and unavailable cells, with thread, call, and cell identifiers.
- Measure how long completed results remain buffered before retrieval and carry `result_buffered_for` through the runtime, stdio protocol, and gRPC response metadata. Immediate delivery reports zero; waits without a completed result report no buffering measurement.
- Default missing buffering data to zero for compatibility with older hosts.
## Testing
Extend runtime tests to verify buffering duration with a paused clock and retrieval through termination. Add gRPC conversion tests for nanosecond precision, optional metadata, and the distinction between immediate delivery and no completed result.
GitOrigin-RevId: 60c0c5a3affa69ac3779bf1812fca50f5748af76
## What changed
Collect compressed rollout paths and scan them in up to four concurrent batches, reusing compiled search patterns within each batch. Preserve match snippets, plain rollout path keys, and per-file error handling.
## Testing
Extend the regression test to verify matches across seven compressed rollouts while skipping a corrupt file, and retain coverage for oversized search patterns and missing files.
GitOrigin-RevId: 522403654ab8577499f8f8043ccc017590c4833e
## Why
An in-flight token refresh or auth reload can outlive a login change or logout. Its result must not overwrite credentials for a different login or restore stale cached auth.
## What changed
- Serialize in-process auth storage reads and writes that participate in credential updates.
- Verify the stored login before persisting refreshed tokens or agent identity records, while allowing older clients to drop login metadata when the refresh token still matches.
- Reject stale auth reload results using generation checks, and invalidate pending reads on logout even when the cache is already empty.
- Keep account grant reads strict when the keyring is unavailable, while preserving ordinary auth fallback behavior.
## Testing
Add regression coverage for stale reloads after logout, login replacement during refresh, legacy metadata loss, keyring recovery with rotated tokens, and refresh persistence failures.
GitOrigin-RevId: 01bce9ddbc3101de868adcda3370fcdc4eb70163
## Why
When unread events block notification delivery and the client request queue is full, shutdown can hang waiting to enqueue its shutdown message before reaching its timeouts.
## What changed
Drop the event receiver at the start of `InProcessClientHandle::shutdown` to unblock notification delivery before waiting for space in the request queue.
## Testing
Add a regression test that fills both queues with real requests and notifications, then verifies shutdown completes within the configured timeout budget.
GitOrigin-RevId: a2b01042fc81dd2df4affca1d6cf2ddfb64b39db
## Why
Input injected before `wait_agent` or `clock.sleep` begins must still interrupt the wait and reach the next model request.
## What changed
Track notifying response-item injections as pending steering activity. Reset that state when pending input is consumed or cleared so later passive context does not interrupt waits.
## Testing
Extend wait and sleep tests to cover injections queued before the wait and delivered while waiting, alongside user steering. Add queue coverage for pending injection detection and reset after consumption.
GitOrigin-RevId: 90f8d968336082c76271d1ca4f81b855bafc72c6
## What changed
Add `RuntimeAuthProvider` to resolve request authentication through the runtime auth manager. Support `dual_header` mode, which sends a bearer credential alongside `x-openai-agent-assertion`, and `assertion_only` mode, which uses `Authorization: AgentAssertion …`.
Replace stale authentication headers and sign a fresh assertion for each request attempt. Propagate registration failures without falling back to credential-only authentication, preserving policy errors and classifying transport failures, rate limits, and server errors as transient.
Add the disabled-by-default `features.runtime_agent_instances` configuration with independent `enabled` and `mode` settings, schema support, and structured override merging. Selecting a mode alone does not enable the feature.
## Testing
Add coverage for both modes with API key and ChatGPT credentials, stale header replacement, fresh assertions, credential refresh without runtime replacement, registration failures, and configuration parsing and merging.
GitOrigin-RevId: 9e93d25762600f0ff592c5248fe4c8c2c8182c8d
## Why
Guardian V2 previously skipped optional Decisions comparisons in conversation mode as unsupported evidence.
## What changed
- Start comparisons from the prepared conversation input, including retained history or rebuilt evidence after a history reset.
- Extract the classifier rubric and preserve evidence message roles, content order, and boundaries. Omit retained reasoning and compaction items while continuing to reject other unsupported evidence.
- Measure baseline sampling through the usable score, before history draining and commit, and report skipped comparisons when preparation fails or the request is superseded.
## Testing
Extend coverage to both classifier modes for comparison disagreements, failures, and disabled or uninitialized comparisons without changing baseline scores. Verify conversation evidence across history reuse and resets, malformed input rejection, and budget failures before either backend sends a request.
GitOrigin-RevId: ce32cf876d15d3b82e0b83ac02c33447e7724a51
## What changed
Classify messages from code-mode collaboration calls as `AgentMessage::Plaintext` so they receive the context wrapper for plaintext messages. Apply this to `spawn_agent`, `send_message`, and `followup_task`.
## Testing
Add a regression test that spawns an agent through `exec` and verifies that the child receives the task as plaintext with sender and recipient attribution.
GitOrigin-RevId: 495c70ea13fd2bb06989e5aacab60beed0c19a56
## What changed
- Add `--cloud-skills-snapshot PATH` to load a cloud skill catalog and resource contents from JSON once at app-server startup, without contacting a live skill service.
- Expose snapshot skills through the native `skills.list` and `skills.read` interface, preserving aliases and prompt visibility. Reads remain available after the snapshot file is removed.
- Validate package boundaries, required resources, duplicate packages, and size limits; fail startup for missing or invalid snapshots.
- Keep frozen cloud catalog and read caches independent of live MCP resource changes.
## Testing
Add provider, cache, app-server, and core scenario tests covering validation, exact resource contents, authority boundaries, startup failures, and listing and reading frozen skills alongside a named executor.
GitOrigin-RevId: d438a5d678121db3e17515fc5edcd00d4e20b900
## Why
Sibling rollout prefetching returns no paths when its candidate set omits the first ancestor. With more than 64 sibling rollouts, the candidate limit could exclude that ancestor and prevent prefetching.
## What changed
Pass the first ancestor ID into candidate collection and reserve the final slot for it until it is found, preserving the 64-candidate limit.
## Testing
Add a regression test that creates more siblings than the candidate limit and verifies that an otherwise omitted ancestor is included when prioritized.
GitOrigin-RevId: 130508dfb1a190af68ccf1911c7501617be79a00
## What changed
- Rename the snapshot comparison entry point to `start_snapshot_comparison` and extract request spawning into `spawn_request`.
- Accept a `ContentItem` rubric and an iterator of evidence in the request adapter.
- Read the Decisions comparison feature flag once per classification and simplify the budget rejection test setup.
GitOrigin-RevId: b4a294eeecb6069db0f80ff6e4f13f558cbd7815
## What changed
Extract the inline test modules for `bundled_bwrap`, `bwrap`, `exec_util`,
`launcher`, `proxy_routing`, and `seccomp` into sibling `*_tests.rs` files.
Keep them wired through `#[cfg(test)]` and explicit `#[path]` attributes,
with existing test coverage and runtime behavior unchanged.
GitOrigin-RevId: 79b70a092a19b10716939744542415bc1dcaf0b2
## What changed
- Update `rustls-webpki` from `0.103.15` to `0.103.16`.
- Update `webpki-roots` from `1.0.5` to `1.0.10`.
- Refresh the corresponding entries in `codex-rs/Cargo.lock` and `MODULE.bazel.lock`.
GitOrigin-RevId: c73d2afb6ce9f8bd8756d3cbe6f8114edc461262
## Why
Synchronous auth header construction could silently return no credentials when managed authentication became unavailable. Callers need an error to avoid sending requests with missing or partial authentication.
## What changed
- Make `AuthProvider::add_auth_headers`, `to_auth_headers`, and auth header telemetry fallible, and propagate failures through request and WebSocket setup.
- Return a transient error when managed authentication is unavailable, and preserve network policy denials through auth error conversion.
- Retry transient MCP authentication errors while treating build errors and policy denials as terminal.
- Cancel local MCP event streams before resolving authentication so cleanup still works when credentials become unavailable.
## Testing
Add regression coverage for rejected partial authentication, async header resolution, terminal auth errors without sending requests, managed account changes, MCP retry classification, and local stream cancellation after authentication becomes unavailable.
GitOrigin-RevId: 39d981e232cba1e302de502a2fa6239101114ed1
Move context prefixing and request extraction into `user_prompt`, and update
IDE context injection, thread routing, thread titles, transcript export, and
user message rendering to use the shared helpers. Preserve the request
delimiter, text element byte offsets, and input ordering.
Move the existing last-delimiter extraction test alongside the shared helpers.
GitOrigin-RevId: 3ee350506a536a6dba9575e8311188bc92fed584
## What changed
Prefer frequently selected entries in the TUI's `$` picker within exact, prefix, and fuzzy match tiers, keeping stronger match tiers ahead of usage preferences.
Track the last 50 confirmed selections and persist them in `mention_usage.json` under `CODEX_HOME` when history persistence is enabled. Preserve in-memory preferences across compatible chat widget replacements, including when history persistence is disabled. Serialize background writes, merge updates under a bounded file lock, and flush pending writes on shutdown.
## Testing
Add coverage for picker ordering, preference handoff and persistence, history-disabled widget replacement, selection expiry, malformed history, and lock contention.
GitOrigin-RevId: 7efa8c1c365e23000fcda10dbbc2a7e90f4e777c
Remove the exception that allowed clients without a package identity to connect
when the provisioning service had one. Keep the debug foreground-mode exception.
GitOrigin-RevId: def2d22a91575477d73e3d8c6ac14808a2ff3b2b
## What changed
Record `codex.guardian.turn.blocking_ms` when a turn completes or aborts, with an `outcome` label. Count overlapping approval waits once, exclude idle gaps, and split pending reviews across the active turns they span. Use each turn's telemetry so samples retain the servicing turn's model attribution.
## Testing
Add unit coverage for overlapping waits, idle gaps, late turn completion, and duplicate stops. Extend integration coverage to verify attribution across turns and model changes for yielded command reviews and MCP elicitation, including aborted turns.
GitOrigin-RevId: a3e6a0c32a06fe58ea93119ecd941076100fb82c
## What changed
Expose `PromptCacheKey` through `StartThreadOptions` with three policies: retain the default session-derived key, send a custom key, or omit `prompt_cache_key` from model requests. Keep session identity headers independent of this policy.
Propagate the policy to child agents, delegated sessions, and guardian review sessions. Hosts must reapply the policy when resuming a thread from storage.
## Testing
Add coverage for all three policies across turns, including unchanged session and thread headers. Extend subagent coverage to verify inheritance of the default and omitted-key policies.
GitOrigin-RevId: f9e8ab31fcf568636f9712726760e4e9a4672428
## Why
Polling a failed background compaction consumes the closed oneshot receiver.
Keeping that receiver in session state can cause a later await to panic instead
of falling back to foreground compaction.
## What changed
Remove the receiver from session state before polling it, restoring it only when
its result is still pending. Discard closed receivers so compaction can fall back
normally.
## Testing
Add a regression scenario where background compaction fails before the next
checkpoint and automatic compaction falls back successfully.
GitOrigin-RevId: 1461bb403f4b0b8b7e171d1b3cba41411f2014b4
## What changed
Default `features.multi_agent_v2.preserve_fork_prefix` to `true`, so full-history forks retain the parent's model-visible history and append child instructions. Keep `preserve_fork_prefix = false` as an explicit opt-out for instruction filtering, and update the configuration schema documentation.
## Testing
Update coverage to verify inherited prefixes across child and grandchild forks, child instruction ordering after compaction, and explicit filtering opt-outs.
GitOrigin-RevId: f14eae5b924cdeac555d112d0aba3fbbb063b0ea
`codex-secrets` pulls in unmaintained `basic-toml` 0.1.10 through the localization dependencies of `age` 0.12.1, and no patched release is available.
Add `RUSTSEC-2026-0374` to the `cargo audit` and `cargo deny` ignore lists. Document that the exception should be removed when the localization dependencies of `age` migrate off `basic-toml`.
GitOrigin-RevId: 92f31b687e91a73620e6f7f9a1b7c94790d9149d
## What changed
- Expose `AccountOAuthGrantLease` to prevent this auth manager's token refreshes from rotating account credentials during an identity-provider exchange. Releasing the lease returns an `AccountOAuthGrant` that callers can recheck before accepting asynchronous results.
- Validate grants against cached login ownership and persisted credentials, requiring OAuth provenance and complete account identity. Reject stale grants and propagate storage failures, including unavailable keyrings in `Auto` mode.
- Track `login_generation` separately from account ownership and use it to invalidate enterprise MCP authentication. Losing login metadata invalidates the login while preserving same-account network policy; a new login to the same account advances both generations.
## Testing
Extend auth refresh coverage to verify refresh blocking and wakeup on lease release, invalidation after token rotation or persisted login replacement, metadata loss and restoration, and logout while a lease is held.
GitOrigin-RevId: f51b3cd526d7ee94d5dffa16681f8ca332245ce3
## Why
Undecodable compressed rollouts need diagnostic details and their original bytes preserved for investigation.
## What changed
- Log compressed file size, first-frame content size, decoded byte count, and whether the open file changed when a compressed rollout read fails. Limit warnings to once per process per minute and exclude paths and contents.
- Allow diagnostic reports to attach the raw `.jsonl.zst` archive after a decoding failure when no preferred plain rollout exists. Retain attachment size limits and append `.zst` to filename overrides when needed.
## Testing
Add coverage for truncated streams, incomplete trailing frame headers, files truncated after opening, and diagnostic uploads that preserve undecodable archives with size limits and filename overrides.
GitOrigin-RevId: 76f7ee466f9bebdab5a91ce1894f4361749edc5b
## What changed
Split retained conversation scoring into `Reservation::prepare` and `PreparedConversation::run`, exposing the complete admitted input before model execution. Keep the history fork and capacity permit owned by the prepared conversation, and recheck authorization, score expiry, and backend generation before execution.
## Testing
Extend conversation tests to verify that preparation sends no model request, execution uses the prepared input, dropping a prepared conversation releases capacity, and stale prepared reviews cannot start model execution.
GitOrigin-RevId: c96cc6fac69179a78ecd7bcdb8e5a4b3087aa6e6
## Why
The maintenance-lock test relied on a 50 ms timeout to assume startup migration had encountered contention, and its completion timeout included the production retry delay.
## What changed
Add a per-store, test-only retry gate to observe lock contention and explicitly resume migration after releasing the maintenance lock. Verify that rollout metadata stays in `Legacy` mode while the lock is held and becomes `Paginated` after migration completes.
GitOrigin-RevId: 657fa6ec6f9494d9e66976560c8158fde8ffb495
## What changed
- Record executor handshake rejections and pending-validation resets in promptly completed diagnostic spans, with classified reasons and registry HTTP status when available. Normalize stream IDs as UUIDs and cap diagnostics at 100 per minute per relay connection, followed by a suppression marker.
- Add elapsed time and connection identifiers to harness handshake diagnostics, including initialization timeouts, and classify WebSocket read failures from typed errors.
- Forward valid stream UUIDs to harness key validation requests through the `x-codex-noise-stream-id` header.
## Testing
Extend tests to cover diagnostic rate limits, timeout correlation, prompt span export, typed WebSocket error classification, and optional stream ID headers. Verify that diagnostic output excludes authorization secrets, registry response text, reset reasons, and invalid stream IDs.
GitOrigin-RevId: 2c224e2d2828b300164868b10806add410e148b2
## What changed
Add `experimentalDisablePredictionMcp` to `thread/fork` and `disableMcp` to `thread/sample`. Disable MCP servers when requested and the inherited history contains incremental tools on Responses Lite. The fork option requires `experimentalPredictionMode: true`.
Apply disablement through a thread-local policy that excludes configured MCP servers and runtime contributions, including after MCP refresh. Preserve the inherited history prefix and append tool-removal instructions without changing the parent's tools.
## Testing
Add coverage for prediction forks with legacy and paginated history, flag validation, conditional disablement, MCP refresh, and sample/fork request parity. Add a request-history snapshot covering preserved history, tool removal across child turns, and unchanged parent tools.
GitOrigin-RevId: e31d602480e6550ed130d8152f538b8668280fa0
## What changed
Read `RequirementsPath` from the 64-bit registry view of `HKLM\SOFTWARE\Policies\OpenAI\Codex` to select the system requirements file on Windows. Require an absolute path and return an error for relative values. If the registry key or value cannot be read, retain the default `OpenAI\Codex\requirements.toml` location under ProgramData.
## Testing
Expand absolute-path validation tests to cover empty, drive-relative, and root-relative paths. Update the Windows default-directory test to remain independent of registry overrides.
GitOrigin-RevId: c31045d749e32cf266b389245ae4db2440156e8e
## Why
A fixed feature allowlist excluded other boolean feature overrides from daemon use. Feature mismatches could also silently fall back to embedded mode, while automatic startup could persist enabled overrides without confirmation.
## What changed
- Allow boolean feature overrides without a fixed allowlist and compare explicit overrides with the daemon's reported settings. Ignore removed features, treat unreported features as disabled, and include only mismatches in restart settings.
- Preserve saved daemon settings during automatic startup. Prompt on feature mismatches even when embedded fallback is allowed, letting users run without the daemon, confirm a managed-daemon restart, or cancel.
- Detect managed daemons during recovery, mark available restarts as recommended, and limit the displayed feature list to three entries plus a remaining count.
## Testing
Update compatibility tests for mixed overrides, removed and unreported features, unreachable daemons, and required versus optional attachment. Update recovery snapshots and the TUI integration test to exercise explicit embedded-mode selection.
GitOrigin-RevId: 9204620f168ff80aaef312c88e681b754908a431
## What changed
Add the experimental `thread/sample/cancel` request with a `requestId` identifying a `thread/sample` request on the same connection. Cancellation returns an empty response, stops the matching sample with `sample canceled`, and cleans up its ephemeral fork. Repeated cancellation and unknown request IDs are harmless no-ops; other request types are unaffected.
## Testing
Add coverage for connection and request ID isolation, request type filtering, and repeated cancellation. Extend the sample integration test to verify cancellation keeps the parent responsive and reclaims the child thread.
GitOrigin-RevId: 92d12e5c0190e1d3b06cb482543615a3ec77bdc8
## What changed
Add `RuntimeAuthManager` to share one registered runtime per credential source and return request-scoped `RuntimeAuth` values that pair the runtime with its credentials and HTTP client factory.
- Preserve registration keys and idempotency IDs across retryable failures and refreshes that retain the credential source.
- Replace the runtime when the credential source changes, preserve existing request snapshots, and reject late registration responses for a previous source.
- Use bounded credential recovery for registration `401` responses and cache `403` denials until the credential source changes.
- Expose authenticated actor and agent host information on `RuntimeAgentInstance`.
## Testing
Add tests for concurrent registration sharing, retry identity preservation, network policy recovery, credential refresh and replacement, bounded recovery, cached denials, and credential changes during registration.
GitOrigin-RevId: ea1e6e10a5939e8c3f7c0c317ccf8a83522c635f
## What changed
Render async question titles with the Markdown renderer so emphasis, fenced code blocks, and labeled links display with their intended formatting. Remove blanket bold styling and wrap overwide tokens while preserving hyperlink destinations and accurate row counts.
## Testing
Update rendering snapshots and extend the question rendering test to cover Markdown formatting, link destinations, selective bold styling, and equivalent LF and CRLF rendering at narrow and wide widths.
GitOrigin-RevId: b3e8a94a04433c2d9e5d11e66f83cbd16959d8ed
## Why
A new OAuth login can belong to the same account as an earlier session, while token refreshes can change credentials within one session. Auth consumers need to distinguish these cases when deciding whether a runtime can be reused.
## What changed
- Add `source_generation` to `AuthChangeState` and expose `AuthManager::auth_change_state_for` to check whether selected credentials still match the manager's current source.
- Preserve source continuity across OAuth refreshes only when session, issuer, and identity claims match. Advance the source revision for new sessions, credential replacements, and logout.
- Keep agent identity persistence from replacing cached credentials with credentials read from disk; credential publication remains managed by `AuthManager`.
## Testing
Add tests for refresh continuity, new logins, identity and workspace changes, sessionless tokens, API key replacement, logout, and identity persistence followed by an explicit credential reload.
GitOrigin-RevId: 56eddb7edb9c5f8854b18fd50ce917c0b27e75d6
## Why
A remote server can refuse the initial `thread/start` while shutting down. An explicit refusal establishes that no thread was created, allowing the TUI to retry without risking duplicate startup submissions.
## What changed
- Wait for the draining connection to close, reconnect within a shared two-minute deadline, and retry startup once.
- Preserve the initial prompt, confirmed draft, model, and reasoning effort across recovery. Keep drafts editable and allow cancellation of a pending submission.
- Restore input without submitting if recovery fails or startup is refused again. Continue treating a lost startup reply as uncertain and avoid automatic resubmission.
## Testing
Add regression coverage for successful reconnection with exactly one prompt submission, repeated refusal, disconnect event ordering, and draft cancellation, editing, and paste provenance during recovery.
GitOrigin-RevId: 85b756e14f29c239c4774af2b32215fe251530ac
## Why
Saving an API key does not validate it. Login and status messages should make clear that authentication is checked when a request is sent.
## What changed
Report `API key saved` after API key login and `API key configured` in `login status`. Both messages now explain when authentication is checked.
## Testing
Update the API key login integration test with snapshots for login and status output, while retaining assertions that the key is saved to `auth.json`.
GitOrigin-RevId: 2f36ebb270a48771be25060a596cf9731e8d0325
## Why
The handshake readiness channel only signals success, so a dropped sender does not explain why the handshake failed.
## What changed
Emit structured `codex.exec_server.noise_handshake_failed` warnings before harness handshake failures drop the readiness sender, including a failure reason and environment, executor registration, and stream identifiers. Emit the same event on handshake timeout with `timeout_ms`.
Preserve the current tracing span when the `noise_relay.stream` debug span is disabled so the relay task retains its trace context.
GitOrigin-RevId: 0b1314d5237b7c77a854c2c0a966391bf856e75d
## What changed
Extend `codex-runtime-agent-instance` with a registration client and an in-memory assertion signer. Pending registrations retain their signing key and idempotency key across caller-driven retries; registered runtimes generate fresh versioned assertions with a timestamp and unique ID.
Bound registration requests and responses, reject unsafe endpoints, disable redirects and request logging, and preserve network policy errors. Report server rejections using only the status and recognized error codes.
## Testing
Add HTTP-backed tests for retry stability, assertion signatures and freshness, policy revocation, endpoint and response validation, redirect refusal, and error redaction.
GitOrigin-RevId: a6dab0900459dfb75f72652a0a2ee1e4b65ca322
## Why
A temporary exec-server transport loss could emit a thread environment disconnect notification while the session was still recovering.
## What changed
- Add `EnvironmentConnectionState::Recovering` for interrupted transports and pending session recovery.
- Suppress thread lifecycle notifications during recovery, emit a connected notification after successful recovery, and report disconnection when recovery fails.
- Ignore recovery callbacks from retired clients so they cannot overwrite the connection state during refresh.
## Testing
Add coverage for fast and near-deadline recovery, recovery timeout, rejected session resume, and retired-client callbacks. Extend app-server coverage to verify one lifecycle notification per selected thread and usable `environment/info` after recovery.
GitOrigin-RevId: d6dce5cc5264af29b6f993daa209b93102122e40
## What changed
Add `codex-runtime-agent-instance` with serializable registration requests and deserializable responses. Requests support OAuth, personal access tokens, and platform API keys, along with an installation ID, public key, harness metadata, and runtime role. Responses include runtime and host IDs plus ChatGPT or platform actor context.
Use `RedactedString` for credentials to keep secrets out of debug output.
## Testing
Add tests covering request serialization for all three credential types, debug redaction, response decoding for both actor types, and rejection of responses missing required fields.
GitOrigin-RevId: f33bae734fdd1402144dee407e5b868f5eef1d37
## Why
Token refresh needs the issuer and client ID used at login. Unverified token claims cannot establish that authority, and OAuth error bodies may echo credentials.
## What changed
- Save `oauth_provenance` and a new `login_owner_id` on browser and device-code login. Preserve the login identifier through token rotation.
- Refresh using the recorded issuer and client ID, retaining the existing endpoint override and fallback behavior for legacy records. Clear provenance when an override changes the endpoint or when a response without token rotation encounters a concurrently replaced refresh token.
- Keep both metadata fields optional for older records without inferring provenance from token claims.
- Remove backend token error details from structured logs and refresh error messages.
- Box large futures in token refresh, MCP initialization, and embedded app-server test startup to reduce surrounding async frame sizes.
## Testing
Add coverage for legacy record compatibility and metadata round trips, browser and device-code login persistence, refresh using recorded OAuth settings, metadata preservation through rotation, and provenance clearing for a superseded refresh token.
GitOrigin-RevId: b6b5d2fcbe2a284a171a242c1a17128af55f1024
## Why
Resolving a history page's rollout lineage performs a separate filesystem lookup for each ancestor. Ancestors stored alongside the current rollout can share a lookup traversal.
## What changed
- Prefetch paths for up to 64 sibling rollout IDs belonging to the same thread when listing history turns or items.
- Resolve candidates in the normal lookup order to preserve first-match selection for duplicate rollout IDs.
- Validate prefetched paths before use and fall back to normal lookup for missing or stale paths. Treat prefetch failures as optional and continue with normal resolution.
## Testing
Add a regression test verifying that sibling prefetch selects the same first match for a duplicate rollout ID as normal lookup.
GitOrigin-RevId: 5d86c9643562a82a53af78b20f70322c1506c6e1