## Why
Global deny globs such as `/**/.env` unnecessarily block directory renames and removals on macOS. Moving an ancestor does not let a matching basename escape these rules.
## What changed
Skip ancestor unlink restrictions for root-anchored recursive globs with a literal basename. Keep matching files protected and extend the deny to descendants of matching directories. Preserve ancestor protection for scoped, multi-component, and nonliteral patterns.
## Testing
Add Seatbelt tests covering directory moves and removals, continued protection after moves, symlink access, matching directory descendants, and files created after policy generation. Verify that scoped and nonliteral deny patterns still block ancestor moves.
GitOrigin-RevId: 4e8ea601e8ea98c4da5e3a3fe0d8ce2c63013bc5
## Why
Expanded recursive deny lists can exceed the Windows command-line limit, preventing sandbox wrappers and setup helpers from launching.
## What changed
- Use chunked environment transport for wrapper and non-elevating setup payloads above 24,000 UTF-16 code units, preserving the existing argument protocol for smaller requests.
- Share the transport with the MXC launcher, supporting payloads up to 16 MiB with Unicode-safe chunking and validation.
- Keep transport variables out of the workload environment and remove inherited chunks before launching setup helpers.
## Testing
Add coverage for transport boundaries, Unicode round trips, malformed payload rejection, environment cleanup, and large payloads crossing Windows process creation. Extend the elevated sandbox integration test with 1,000 nested denied files to verify read restrictions and `AGENTS.md` discovery with a payload exceeding the command-line limit.
GitOrigin-RevId: 8ef92fdc7d534143f0eac76036a2173a6f585d08
Accept `service_name` and the expected originator as test parameters, passing
`service_name` through `ThreadStartParams`. Retain the existing case that
expects `TEST_ORIGINATOR` when no service name is provided.
GitOrigin-RevId: 71097dcfe45496216cf3e765999ed0abd0a0cd71
## Why
Agent messages arriving during a response can interrupt sampling at reasoning or commentary boundaries, cutting off remaining tool calls.
## What changed
Add the disabled-by-default `defer_mailbox_preemption` feature flag. When enabled, sampling continues past these boundaries and queued agent messages reach the next model request alongside completed tool results.
## Testing
Add streaming scenarios and snapshots for reasoning and commentary boundaries with deferral enabled and disabled. Verify that deferral preserves the planned tool call and that both queued messages arrive in order in the next request.
GitOrigin-RevId: d6846dd73b3afb47e7293f3b1aa2abcd04e37853
## Why
Thread startup can prewarm the Responses WebSocket before the creating client is registered with the thread, leaving the handshake unable to request attestation from that client.
## What changed
Reserve a thread ID and register the creating connection before starting the thread, including for ephemeral threads. Remove the thread state if startup fails.
## Testing
Extend the attestation round-trip test to cover persistent and ephemeral threads. Handle attestation requests while awaiting `thread/start` and `turn/start` responses, and verify the WebSocket handshake includes the expected `x-oai-attestation` header.
GitOrigin-RevId: 1bdb38bac641253eed58a2431658ab54d93819c5
## What changed
Add `tui.prompt_suggestions`, defaulting to `false`, along with suggestion request state, a generation prompt, and strict parsing of single-line suggestions up to 240 characters. Suggestion generation is not connected yet.
Keep suggestions outside the draft and render them dimly in an empty, focused composer. `Tab` accepts a suggestion for editing, a separate `Enter` submits, and `Escape` cancels pending suggestions. Respect active key bindings, popups, attachments, paste bursts, and interactive transcript footers; ignore stale results and cancel suggestions when a task starts.
## Testing
Add parser tests, composer interaction tests, and snapshots covering acceptance, dismissal, stale results, input precedence, wrapping, and transcript search layout.
GitOrigin-RevId: 868001a0fc3e6fd8c11ef1650aabc477fa36e03d
Normalize the legacy setting so existing `tui.whimsy` values control the
starfield effect. If both keys appear in the same config layer, the explicit
`tui.effects.starfield` value takes precedence.
GitOrigin-RevId: 2884dbd643690d500ed8d1493ce47950d93d6ab3
## What changed
Represent legacy and canonical config keys as full paths, allowing aliases to target nested tables within the legacy key's containing table. Create missing destination tables, preserve existing canonical values, and skip insertion when an intermediate value is not a table.
Keep the existing `memories` and `agents` alias mappings unchanged.
GitOrigin-RevId: 9ef17e9d1b6adf6299777ed0051cb301fd245073
## Why
Sparse config edits must preserve aliases in unrelated base tables so the returned config version remains consistent with the file on disk.
## What changed
Normalize the full overlay before merging and normalize base aliases only in tables reached by the overlay. Reuse the root-level normalization helper when reporting config origins.
## Testing
Add a regression test showing that an `agents` overlay normalizes `max_threads` while leaving the unrelated `memories` alias untouched.
GitOrigin-RevId: 25cc95b0969979c49c43b766824fa0bd019465a4
## Why
Recursive config merging clones overlay tables at each nesting level, repeatedly copying their descendants.
## What changed
Clone the overlay at the `merge_toml_values` entry point and pass owned values through recursive merges. Normalize overlay tables in place, preserving the public API and existing merge semantics.
GitOrigin-RevId: 05e66648e37d571566b3d119bd3aab3924fb0c74
## What changed
- Add `StorageTelemetry` to record operation counts, durations, secure-store outcomes, and file fallback reasons using bounded labels. Emit fallback warnings without credential payloads or error text.
- Add task-local client attribution with explicit propagation across task boundaries.
- Preserve typed keyring error causes through `std::io::Error` and the local secrets backend, classifying supported native failures without parsing error messages.
- Remove service names, account names, value lengths, and error text from keyring trace logs.
## Testing
Add tests for buffered metric emission, fallback outcomes, exclusion of sensitive error contents, client attribution isolation, and typed native error classification.
GitOrigin-RevId: 18e7201566a3b09061a6014fd6bd90eae96e3fc2
## What changed
- Make `LocalThreadStore` default to paginated history while retaining explicit legacy mode.
- Explicitly use paginated history for Guardian review sessions and allow in-memory stores to create paginated threads.
- Rename full-history resume, fork, and subagent helpers to identify them as legacy APIs, and document the paginated alternatives.
- Reject `thread/revert` for ephemeral threads and prevent the TUI from replaying or attaching to ephemeral agent threads.
## Testing
Add coverage for preserving the default and explicitly selected history modes and conversation context across restart, and for retaining context after rejected ephemeral reverts. Extend Guardian checkpoint coverage across both history modes and verify that saved reviews use paginated history.
GitOrigin-RevId: 870239eb3757018159ee4f230a009c97d38ac5b7
## Why
The `attribution_error` status does not explain why MCP attribution is incomplete. Preserve a diagnostic reason so callers can distinguish history and recorder errors from request serialization failures.
## What changed
- Add optional `error_reason` diagnostics to `McpAttribution`, retaining the first recorder error through checkpoints, compaction, resume, and fork.
- Identify missing or invalid checkpoints, conflicting sources, invalid sources, and poisoned recorder state. Use `restored_error_unknown` for older error checkpoints without a reason.
- Distinguish `payload_too_large` from `serialization_failed` in request metadata fallbacks.
- Tolerate missing, unknown, or malformed diagnostic reasons when reading history, without letting diagnostics determine attribution status.
## Testing
Add coverage for reason preservation, recorder poisoning, backward-compatible checkpoint decoding, resume and cold-fork restoration, and request metadata serialization, including oversized payloads.
GitOrigin-RevId: 389b9446fae119f793978f3e7e4a926677e84d8c
## Why
Treating an omitted `allow_local_binding` setting as `false` prevents environment policies from inheriting local-binding permissions.
## What changed
Keep `allow_local_binding` optional when composing controller and environment policies. Preserve explicit denials from either policy and resolve executor defaults after composition. Without a controller, default to denying local binding unless the environment explicitly allows it.
## Testing
Add coverage for omitted, allowed, and denied settings, managed constraints, executor defaults, and remote launch rejection when local-binding restrictions cannot be enforced. Extend remote network approval tests with loopback requests to verify controller and environment policy composition.
GitOrigin-RevId: aa0d15e8be87a2741255cd3a5a2cabffa03214ac
## Why
Transcript selections were copied as plain text, losing the formatting of rendered Markdown when pasted.
## What changed
- Retain semantic Markdown annotations through rendering, wrapping, and streaming, then serialize selected text with balanced markup.
- Preserve inline formatting, web links, headings, lists, blockquotes, and hard breaks in Markdown clipboard payloads.
- Keep code-only and other literal-only selections as plain text. In mixed selections, escape user prose and fence code, tables, and tool output to preserve their literal content.
## Testing
Add unit tests and Markdown/HTML snapshots covering partial selections, nested containers, escaping, links, resize stability, and streaming boundaries.
GitOrigin-RevId: f0476334a6bf8ad0fb57626627bd258443540852
## Why
TUI test helpers used `TempDir::keep()`, leaving temporary Codex homes on disk after fixtures were dropped.
## What changed
Retain `TempDir` ownership in widget and app fixtures so their homes are removed on drop. Transfer ownership to app fixtures to keep the home alive across widget replacement, and retain directory guards in tests that use configs directly.
## Testing
Add regression tests for recursive cleanup, isolation between widget homes, and app home survival across widget replacement followed by cleanup on app drop.
GitOrigin-RevId: fe80f982cc467ede4c3e1edbac8012ec3066dfb3
## Why
MCP OAuth configuration supported a pre-registered client ID but could not supply a client secret for token exchange or refresh.
## What changed
- Add `oauth.client_secret` and `codex mcp add --oauth-client-secret`, requiring a nonempty secret and client ID. Persist the secret in server configuration and accept `clientSecret` in plugin configuration.
- Pass configured credentials through CLI, app-server, and plugin login flows and token refresh. Require a new login when a configured confidential client's ID differs from stored credentials.
- Redact secrets in debug output and keep them out of authorization URLs and persisted OAuth token records.
- Invalidate cached OAuth connections when the configured client ID or secret changes.
## Testing
Add coverage for configuration validation and round trips, CLI argument redaction and subsequent login, app-server login, connection invalidation, and refresh with `client_secret_basic` and `client_secret_post` in both refresh modes. Verify secret exclusion from token records and reject mismatched client IDs before contacting the provider.
GitOrigin-RevId: 85bb0e410e9e68e6cd68eb6359badfc7eac78147
## Why
Diagnostic uploads through the app server do not include the TUI client's diagnostic buffer. Attach those diagnostics when users consent to uploading logs.
## What changed
- Stage the most recent 1 MiB of client logs as `client-logs.txt` on the app-server host and append it to `extra_log_files`.
- Skip staging without log consent and list the optional attachment in the consent dialog.
- Continue uploading the report if staging fails, noting the omitted logs in the report reason. Attempt to remove the staging directory after both successful and failed uploads.
- Make app-server filesystem helpers usable by background requests.
## Testing
Extend submission tests to cover log truncation, preservation of existing attachments, consent gating, staging failures, cleanup after upload failure, and error display. Update consent dialog snapshots to include the client log attachment.
GitOrigin-RevId: 9790834d52772c08a147ee7c176cbbc2aa029d5f
## 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
## Why
Paste input classification and asynchronous flush deadlines need to share a clock, including when Tokio time is paused in tests.
## What changed
Use Tokio's clock for chat composer paste timing and startup draft newline tracking, converting to `std::time::Instant` where existing composer helpers require it.
## Testing
Run the existing startup draft multiline paste test with `start_paused = true`. It checks that non-bracketed pastes preserve newlines without submitting the draft.
GitOrigin-RevId: 73bac963204473d85e7395781e0df966ecc92801
## Why
Local `apply_patch` permission checks can treat a macOS system alias and its canonical spelling as different locations, sending writes covered by temporary-directory grants for unnecessary approval.
## What changed
- Normalize trusted top-level aliases in local policy roots and patch targets, reusing a prepared matcher for permission requests and patch safety checks.
- Share alias normalization with Seatbelt and the macOS executor sandbox while preserving mutable symlinks and missing descendants.
- Preserve read-only and deny precedence, protected metadata restrictions, and remote URI matching. Propagate normalization failures from fallible permission checks.
## Testing
Add macOS regressions for multi-file patches with missing parent directories through both direct `apply_patch` calls and shell interception, asserting automatic approval and file contents. Add unit coverage for alias restriction precedence, mutable symlink preservation, missing descendants, and remote permission isolation.
GitOrigin-RevId: 0822ff951eaab728cb1ad91281745fa1b8809f15
## What changed
Record `codex.thread.tools.namespaces_total` and `codex.thread.tools.fragment_bytes` histograms through session telemetry. Tag samples by `stage` (`before` or `after` the 4 KiB cap) and `kind` (`snapshot` or `delta`). Measure bytes after description normalization and XML escaping, including the `<tools>` wrapper, with explicit fragment-size buckets.
Delta counts include only changed entries, and unchanged state emits no samples.
## Testing
Extend rendering tests to verify snapshot and delta metrics, omission counts, byte sizes with Unicode and XML escaping, and no samples for unchanged state.
GitOrigin-RevId: 26543585e2bea54bff6d63263faa9a6ca5dca379
## Why
The PID reservation test could race with the backend's read on Windows by deleting the PID file from its cleanup task. The guardian heartbeat snapshot and environment normalization also needed to match the current permission-context wording.
## What changed
- Release the reservation lock and let `stop()` remove the stale PID file, then assert that the file is gone.
- Update the guardian heartbeat snapshot and normalization pattern to use `The active permission profile for environment`.
GitOrigin-RevId: d9cadae0e5d36cb2e1ab0517e2d7121cf2d0715d
## What changed
Add `otel.log_guardian_assessments`, disabled by default and requiring an OTLP HTTP or gRPC log exporter. Emit `codex.guardian_assessment` when a synchronous Guardian review finishes, including review identifiers, status, risk level, user authorization, and rationale. Include `allow` or `deny` outcomes only for completed model assessments, not review errors, timeouts, or cancellations.
Cap exported rationales at 64 KiB on a UTF-8 character boundary and record their original byte length and truncation status. Use the log-only route to exclude assessment payloads from trace export, local state logs, and bug-report log buffers. Cached V2 approvals are not included.
## Testing
Add coverage for configuration gating, enabled and disabled denial logging, terminal statuses and outcomes, UTF-8 rationale truncation, export routing, and bug-report log buffer exclusion.
GitOrigin-RevId: dcbb5b429c8726a5a5c80ff82f9d625e81796ede
## What changed
- Resolve remote sandbox modes, writable roots, and denied read paths/globs using the executor's filesystem context, displaying paths in its native format. Preserve local filesystem resolution for local environments.
- Resolve remote read denials individually so missing executor facts omit only the unresolved entries.
- Apply a shared 32 KiB budget to displayed permission paths/globs, omitting whole entries and warning that all restrictions still apply, including omitted read denials.
## Testing
Add coverage for remote Windows writable roots and read denials, missing executor path facts, and whole-entry omission with multibyte paths under the shared budget.
GitOrigin-RevId: c61e7ddc8fa569dbc25e9990d90357c42315188f
## Why
`render_ref` already holds a read lock on `sign_in_state`. Acquiring another read lock in `render_continue_in_browser` can deadlock when a writer is waiting.
## What changed
Pass the borrowed `ContinueInBrowserState` from `render_ref` into the browser sign-in renderer instead of reading the lock again.
## Testing
Update the existing narrow-width browser sign-in test to exercise `render_ref`, retaining checks for the full OSC 8 authentication link, device-code guidance, and cancellation footer.
GitOrigin-RevId: ba83e212d510627be9dfd068c8d7318da32a1749
## Why
Checking installed plugin roots performs filesystem work while holding the loaded plugins cache mutex, blocking lookups for other cache keys.
## What changed
Store cache entries in `Arc`s and release the mutex before validating installation paths. After reacquiring the lock, check the cache generation and entry identity to reject entries invalidated or replaced during validation. Preserve stale-entry eviction and most-recently-used ordering.
GitOrigin-RevId: cb5a5f7ec52cba852e6bb9da03a8e214cc19727d
## Why
Image and audio estimate cache misses computed values while holding the cache mutex, blocking access to unrelated keys during initialization.
## What changed
Add `BlockingLruCache::get_or_init` using `Arc<OnceLock<V>>` and migrate the image and audio estimate caches to it. Initialization and same-key waits run in a Tokio blocking region after releasing the cache mutex. Callers share initialization while an entry remains cached; eviction can allow another initialization, so factories must be deterministic.
## Testing
Add a concurrency test covering access to other keys during initialization, eviction of an in-flight entry, and successful completion of both the evicted initializer and its replacement.
GitOrigin-RevId: 079226a58828b854eddc2b501079527bcbe5e603
## Why
Platform proxy resolution holds the system proxy cache mutex, so checking the cache could block a Tokio worker while another lookup was in progress.
## What changed
Use `try_lock` for cache reads, treating contention as a cache miss so async callers on Windows and macOS wait through the existing asynchronous resolver path.
## Testing
Add a Windows/macOS regression test that verifies resolution yields while the cache is locked and completes after release. Adapt the cached-route test to tolerate concurrent cache writers, and isolate the unavailable-decision cache test from shared cache contention.
GitOrigin-RevId: d61da8d37f81b84637e51bf30e4b26091d5fde24
## Why
Unchanged scheduled heartbeat instructions should not become fresh authorization evidence that supersedes a later human override or floods Guardian review context.
## What changed
- Capture heartbeat provenance per input, including when steering an active turn, and persist it in history and retained context.
- Coalesce unchanged instructions for each automation at their original acceptance order. Preserve changed instruction versions and ordinary human messages.
- Represent repeated heartbeats as references to earlier instructions in Guardian transcripts, while tracking the latest input turn separately for trusted skill selection.
- Limit coalescing to recognized, bounded heartbeat envelopes with host-provided provenance.
## Testing
Add regression coverage for human overrides across repeated and steered heartbeats, instruction changes, checkpoint restoration, transcript references, envelope parsing, and latest-turn trusted skills in delegated reviews.
GitOrigin-RevId: 31e444ddb685a1a618be26d3cc32fb562296946b
## Why
Native clipboard setup and writes can block, preventing the TUI from processing input or closing overlays while a copy is in progress.
## What changed
- Route clipboard copies through one session worker that retains native clipboard ownership. Keep terminal escape output on the UI thread.
- Show pending and busy status messages, reject additional copies without queuing them, and ask users to retry image paste after an active copy finishes.
- Abandon setup after five seconds and prevent late delivery. Keep the worker busy until the blocked call returns, and bound shutdown waiting for clipboard handoff.
- Match completions to their originating requests so stale results cannot clear newer selections or unexpectedly resume transcript following. Retain selections on automatic copies, failures, and unconfirmed delivery.
## Testing
Add regression tests for blocked backends, overlay exit, copy and paste ordering, setup expiry, bounded shutdown, completion status messages, and preservation of replaced or moved selections.
GitOrigin-RevId: 4ba1f8da258b9d0700b0edec9ac0ba699f536785
## Why
Cold Rosetta translation and cache invalidation from hard-linked executables can interfere with timed CLI tests. Sampling the clock twice also makes local retry telemetry report a delay shorter than the selected backoff.
## What changed
- Warm CLI fixtures with `--version` on macOS x86_64 before timed checks, and use copies or Unix symlinks to avoid invalidating the shared executable's Rosetta cache.
- Use one clock sample to calculate the response retry deadline and recorded delay.
- Include the retry telemetry event in delay-range assertion failures for the headerless rate-limit stream test.
GitOrigin-RevId: fc573bfff912e999cf74b94a1c6e7ae1be07974b
## Why
Asynchronous Guardian scoring omitted the target environment's denied-read restrictions, and cached score authorization did not include that permission context. A score from one environment could therefore be reused for an action in another environment with different restrictions.
## What changed
- Share permission resolution between synchronous review and asynchronous scoring, including resolving `write_stdin` targets from the owning terminal session.
- Include environment identity and denied-read paths/globs in async scoring context and cached score authorization.
- Fall back to synchronous review when permission evidence cannot be resolved or exceeds the async limit of 3,000 bytes, rather than omitting restrictions.
## Testing
Add regression coverage for rejecting cached scores with different environments or denied paths, passing the target environment's restrictions to the classifier, and rejecting oversized async permission evidence.
GitOrigin-RevId: 14b6f3454bbea458be037560eb1da47d22874df1
## Why
Login clears the recommendation cache after its RPC response, allowing thread startup to race with cache invalidation in the external login tests.
## What changed
Wait for `account/login/completed` and assert a successful notification before starting the thread. This keeps thread startup and the background refresh on the same cache generation in both variants of the recommended plugin test, with `tool_suggest` enabled and disabled.
GitOrigin-RevId: 7be46dacd947b30a28c83176dc2e3b5f730005f1
Raise `max_concurrent_threads_per_session` from 3 to 4 in the test
configuration so the root, worker, grandchild, and sibling can all remain
resident until explicit shutdown.
GitOrigin-RevId: 564fd7bd64d2a91c160437f7346c7e17a30a5f2a
## What changed
Add a `TestCodexBuilder::with_thread_manager` hook for configuring the thread manager before test threads start, and register an integration suite using a test `AgentControl` implementation.
The tests verify:
- Controller factory calls for new roots, forks, and cold resumes, with reuse for warm resumes and shared session identity for internal sessions.
- Child session identity, persisted parent lineage, message-board authorship, and routing of child reloads through the host controller.
- Preservation of the controller's service tier when child threads start or root starts are rejected.
- Dispatch of `spawn_agent`, `send_message`, and `list_agents` to the host controller, including propagation of its errors to tool results.
GitOrigin-RevId: bc6a6c6dbcde9ecc3ce15456aaf7a0610a14eceb
## Why
New user input during a Guardian review invalidated an in-flight approval and aborted the pending action, even when the input was only a status inquiry. Review the action again against the latest authorization evidence so it can proceed or be denied based on the updated instructions.
## What changed
- Treat stale authorization as a retryable review error within the existing attempt budget and shared deadline.
- Refresh authorization evidence for each attempt while keeping the pending action fixed, and record evidence from the completed attempt.
- Preserve cancellation and history-reset aborts, and deny approval if stale authorization exhausts the retry budget.
## Testing
Add and update coverage for parent status updates, authorization revocation, repeated updates, cancellation, history resets, and retry deadlines. Verify that refreshed reviews see the latest input and that the pending action executes exactly once only after approval.
GitOrigin-RevId: c683e2efb6f07840b99d0d34acf0d38c9ddfe9bd
Wait for an assistant item to start before resuming a running paginated
thread, ensuring the user message has reached live history. Emit the initial
response events before the gate and keep completion gated during resume.
Increase the memory dual-write test's consolidation timeout from 10 to 60
seconds to allow Git workspace and agent process startup under contention
on Windows CI runners.
GitOrigin-RevId: 4d74d04955c88a9c208a809f639fe14fdb2ebf37
Use `notify_one()` instead of `notify_waiters()` in
`terminating_initial_exec_command_rechecks_initial_response_state` to retain
the release notification if the termination waiter has not registered yet.
This prevents the test from timing out due to a missed notification.
GitOrigin-RevId: d233ffc50e016eb75752fd360a4d846de0063683
## Why
The list-voices barrier can consume the sleep completion event that `any_new_input_interrupts_sleep` needs to observe.
## What changed
Enqueue agent mail directly in the test so the subsequent wait can observe sleep completion. Keep the `TestCodex` fixture alive for the duration of the test by cloning its `codex` handle instead of moving it out.
GitOrigin-RevId: 957165c2f20cc4d76df763cd41fd99816b477be3
## Why
Explicit user goal edits can restrict permitted actions, such as “Inspect only; do not publish.” Guardian needs these edits as authorization evidence even though they are recorded as contextual messages.
## What changed
- Add `UserGoalUpdate` and a recording API for objective, status, and clear updates without scheduling a model response.
- Use host annotations to retain goal updates in Guardian review history and root authorization evidence, and invalidate cached authorization when updates are recorded.
- Omit oversized objectives whole and mark their evidence incomplete so truncation cannot turn a restriction into a grant.
- Keep item injection from updating shared model and multi-agent metadata.
## Testing
Extend authorization, retained-context, and review snapshot tests to cover goal-edit cache invalidation, root goal visibility from child threads, and restrictive goals reaching Guardian alongside managed policies.
GitOrigin-RevId: 17b99d9fa8c1620840d6f408d79b405a78a778f8
## What changed
- Add `ThreadManager::with_agent_control_factory` to select a host-owned controller asynchronously using the final thread ID for new and cold-resumed threads. Keep local control as the default, reuse live controllers on warm resume, and preserve parent controllers for internal sessions.
- Fail startup on factory errors or when a provided controller's identity does not match the session identity.
- Defer root service-tier updates to host controllers until thread registration succeeds, preventing failed starts from changing settings on a shared controller.
GitOrigin-RevId: 095afbecfee5d47329038d2a97d0cc0081f181df
## What changed
Promote `write_stdin_approval` to stable and enable it by default.
## Testing
Update the stdin approval suite to rely on the default feature setting. Adjust the background network approval test to account for terminal input review before network access and explicitly wait for the network assessment.
GitOrigin-RevId: 1bb449f6d9ecf4ee451e84f95f839a6744877e8b
## Why
Passing extra descriptors to a PTY previously selected behavior intended for inherited escalation sockets: no EOF on stdin close, different signal exit statuses, and no default `SHELL`. Launch attachments need ordinary PTY behavior and must survive execution even when marked `FD_CLOEXEC`.
## What changed
- Add `ChildFds::Attached` alongside `ChildFds::Inherited` to distinguish launch attachments from legacy inherited descriptors.
- Preserve ordinary EOF, default `SHELL`, and signal exit status behavior for PTY attachments.
- Allow explicitly supplied close-on-exec descriptors through pipe and PTY launches without changing the parent's descriptor flags, using child-side flag updates and macOS spawn inheritance actions.
- Update existing callers to use `ChildFds::Inherited`.
## Testing
Add Unix coverage for attachment accessibility, unchanged parent descriptor flags, default `SHELL`, and signal exit statuses. Extend the PTY stdin-draining test to cover attachments and EOF delivery.
GitOrigin-RevId: 864aedc6c5717d8b43c9d71057c9f54409834509
## What changed
Use the model catalog's `send_user_message_async.parameters` override for the `request_user_input_async` tool schema. Fall back to the bundled schema when the override is absent or invalid, logging a warning for invalid overrides while preserving the catalog description.
## Testing
Extend integration coverage for catalog schemas, empty and invalid overrides, and schema updates during mid-turn model changes. Update the asynchronous question-and-answer scenario to verify that requests carry the catalog schema while work continues and the user's answer arrives.
GitOrigin-RevId: c51a90d3266daaba1e7001aa4026964f84dfb206
## Why
The 32 KiB per-result cap and 128 KiB aggregate budget discard tool metadata even when the outgoing request has room to retain it.
## What changed
- Remove the per-result capture cap and raise the aggregate executed-tool metadata budget to 2 MiB.
- Apply a 15 MiB soft budget to serialized HTTP requests and WebSocket messages, using the actual WebSocket delta. Trim optional result metadata on the wire copy while preserving ordinary content and logical history.
- Prioritize `openai/resource_access` metadata during trimming, and include `overage_bytes` in omission markers.
- Record bytes removed by metadata budgets in `codex.tool_metadata.shed_bytes`, tagged by stage.
## Testing
Add coverage for HTTP and WebSocket message boundaries, resource preservation, residual marker removal, unchanged history, and shedding metrics. Update direct-tool and code-mode tests to verify metadata survives beyond the previous limits.
GitOrigin-RevId: ed00996b77945300f60db1e52eff22b4de2707c1
## What changed
Use `KNOWN_PRODUCT_SKUS` in `SessionTelemetry::with_product_sku`, preserving the existing mapping: `codex` stays `codex`, missing or empty values omit the label, and all other values become `other`.
Remove the registry test `dispatch_uses_the_invoking_turn_product_sku` and its unused imports.
GitOrigin-RevId: b4ad6cbc6205aa35fb2866d72f7205814f5b3566
## What changed
Share response decoding and typed error mapping across in-process and remote clients and request handles. Route enum wrappers through `request`, and drop the completed transport future before invoking caller-provided deserialization.
## Testing
Add coverage for dropping typed requests while waiting to send or receive a reply. Exercise the remote typed round trip through `AppServerClient::Remote`.
GitOrigin-RevId: 573c6c45859a96cab69888c3a90c29caa93368b1
## Why
RPC sending and waiting do not depend on request or response types, and Markdown layout does not depend on the parser iterator. Share these implementations across typed calls and parser variants.
## What changed
- Extract `RpcClient::send_request_and_wait` into a non-generic async method, preserving registration before serialization and disconnected-client error precedence.
- Remove the iterator type parameter from `Writer` and pass iterators to event traversal methods, retaining static dispatch and dropping the parser before rendering state, including on unwind.
- Update streaming rendering and existing rendering tests to use the separate parser.
GitOrigin-RevId: 4cc07223111b7c08211028948d13fe04598f8fc7