Commit Graph
11378 Commits
Author SHA1 Message Date
Vivian Fang 339e981ba7 Make MCP and Code Mode input schema budgets configurable (#47936)
## Why

Fixed schema budgets can strip parameter descriptions from large MCP tools or render their Code Mode input types as `unknown`. Allow larger budgets to preserve that guidance.

## What changed

- Add `mcp_servers.<name>.tool_input_schema_max_bytes` to configure the UTF-8 byte threshold for best-effort input schema compaction, retaining the 5,000-byte default.
- Add `features.code_mode.tool_input_schema_max_bytes` for rendered input types. Use the largest of the 16,000-byte default, the Code Mode setting, and the ordinary MCP server's explicit setting.
- Apply rendering budgets to prompt declarations and the runtime tool catalog, and avoid reusing cached declarations after the Code Mode budget changes.

## Testing

Add coverage for UTF-8 compaction thresholds, budget precedence, configuration round trips, and preservation of parameter guidance in both the Code Mode prompt and `ALL_TOOLS`.

GitOrigin-RevId: 0ef2823a614d4794e636f518b09c0b03a5239b45
2026-09-24 20:39:37 +00:00
Henry Levy b62fcd3c4b Allow cached catalogs to satisfy MCP startup readiness (#47935)
## Why

Required MCP servers can block startup while establishing a live connection even when a usable tool catalog is already cached.

## What changed

- Add per-server `startup_readiness = "catalog"` to expose cached tools while the connection starts, retaining `"connection"` as the default.
- Allow an eligible cached catalog to satisfy required-server startup validation and model binding capture. Explicit server or plugin requirements still wait for a live connection, and tool execution still requires the current connection.
- Check tool filters and model visibility when accepting cached catalogs, and preserve cached catalog revisions for binding reuse.
- Serialize the new setting, expose it in the configuration schema, and trace startup readiness at validation and model binding gates.

GitOrigin-RevId: a1cbdf1757ebb5824cffe2cc56408be49711c422
2026-09-24 20:38:50 +00:00
Henry Levy af09e926d6 Apply the unchanged-model compaction shortcut to all session sources (#47934)
Remove the basic-session restriction from the early return in
`maybe_run_previous_model_inline_compact`. When the model is unchanged and
no compaction compatibility hash change is detected, all session sources now
skip rebuilding the previous model's turn context and checking its limits.

GitOrigin-RevId: 75044856609603859b12e6668c7bae488ce0f7f5
2026-09-24 20:38:26 +00:00
andrewgu-oai 694d8d45bd Remove GPT-5.4 from bundled catalogs and preserve migration prompts (#47932)
## Why

Saved model selections can outlive their catalog entries. Removing GPT-5.4 needs to preserve a migration path without applying it to other providers that may still support the same model slug.

## What changed

- Remove `gpt-5.4` from the bundled catalog and `openai.gpt-5.4` from the Bedrock catalogs, including GovCloud.
- Add fallback migration prompts to GPT-6 Sol for saved GPT-5.4 selections on OpenAI and Amazon Bedrock. Scope fallback migrations, including the existing GPT-5.4 Mini migration, to their owning providers while honoring catalog metadata.
- Update tests that depend on bundled GPT-5.4 metadata to use GPT-5.5 or explicit model overrides.

## Testing

Extend migration tests to cover catalog metadata precedence, acknowledged targets, missing or hidden replacements, and preserving the provider while saving the replacement model and its default reasoning effort. Update Bedrock catalog assertions and picker snapshots.

GitOrigin-RevId: f739795da423b9622db2a416be6c52b01b8e7a71
2026-09-24 20:28:31 +00:00
Eric Traut e154f7b807 Generate TUI prompt suggestions after successful turns (#47929)
## What changed

Connect the existing composer suggestion UI to generation when `tui.prompt_suggestions` is enabled. Request suggestions after successful live turns with known reasoning-summary settings, skipping replayed or duplicate completions and turns with queued follow-ups.

Generate suggestions in hidden, ephemeral forks of the completed turn, preserving conversation context and exposed live settings. Keep fork events out of the visible conversation and reject requests for user interaction. Cancel generation after 30 seconds, interrupt unsuccessful requests, and unsubscribe temporary threads.

Clear suggestions on new submissions, thread changes, reconnects, and feature disablement. Let Escape dismiss suggestions before entering backtrack mode.

## Testing

Add tests for live-turn eligibility and deduplication, preserved request prefixes and settings, hidden fork behavior, startup cancellation, and timeout cleanup.

GitOrigin-RevId: 92ddf3b06448adcc6f4330914cbd8102bff98046
2026-09-24 20:01:59 +00:00
willwang-openai 4b97832cfb Use 127.0.0.1 for local login redirects (#47927)
## What changed

Use `127.0.0.1` instead of `localhost` in the OAuth callback URI and local login success URL.

## Testing

Update login and app-server tests to check the callback address, verify that the success redirect shares the callback origin, and assert that the token exchange uses the same `redirect_uri` as the authorization request.

GitOrigin-RevId: a27dd63dca34b9de81fb937da47c753d5dd1ac90
2026-09-24 19:53:34 +00:00
mtsui-oai 0037b39cc1 Retry file blob uploads on HTTP 502 and 504 (#47926)
## Why

File blob uploads previously failed immediately on HTTP 502 and 504 responses, even though these transient gateway errors can recover on retry.

## What changed

Treat HTTP 502 and 504 as retryable alongside 503, using the existing attempt limit, upload deadline, and server-provided retry delays.

## Testing

Expand upload retry tests to cover recovery from 502 and 504, mixed transient responses, exhausted attempts, and retry delays exceeding the remaining budget. Verify that 403, 409, and 500 responses are not retried, including responses without an Azure error code.

GitOrigin-RevId: a8e2f6bcf69338fb6d24f4c2d1ee333fb77bdbc0
2026-09-24 19:52:26 +00:00
Sean Huang 1866e51677 Make project trust lookup paths explicit and defer root resolution (#47924)
## What changed

- Export `ProjectTrustPath` and make `ProjectTrustLookup::from_paths` accept an explicit working directory and optional repository root instead of an arbitrary sequence of path pairs.
- Defer repository-root canonicalization until neither working-directory key matches, avoiding unnecessary filesystem access while preserving lookup precedence.

## Testing

Extend the active-project regression test to cover repository-root fallback and ensure a working-directory entry without a trust level takes precedence over a trusted root. Adapt the existing POSIX and Windows lookup tests to the new API.

GitOrigin-RevId: ba5dc0df1ef9d5109933df00c055eef04434601f
2026-09-24 19:44:50 +00:00
zm-oai 731d4a5ca8 Allow full-access Windows setup to provision through registered Core (#47922)
## Why

Elevated Windows sandbox setup rejected `danger-full-access` as an incompatible permission profile before registered Core could reach the provisioning service.

## What changed

Allow `PermissionProfile::Disabled` to reach service provisioning when registered Core is requested. Keep legacy full-access setup on the shared setup path and retain permission validation before provisioning for restricted profiles.

## Testing

Add Windows-only regression cases covering full-access and supported restricted profiles reaching the service, unsupported restricted permissions failing before provisioning, and legacy full-access setup skipping the service. Each case checks the completion error and verifies that the configuration file remains unchanged.

GitOrigin-RevId: 5ba190da6f8b1c6ef665015acdb9428718a724dc
2026-09-24 19:29:53 +00:00
chess c19dcd975d Allow directory moves under global Seatbelt basename denies (#47920)
## 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
2026-09-24 19:22:06 +00:00
malsamiri-oai c8c1ee5da8 Transport large Windows sandbox launch payloads through the environment (#47919)
## 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
2026-09-24 19:15:17 +00:00
Ahmed Ibrahim 3e27195f2d Parameterize the turn-start originator header test (#47918)
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
2026-09-24 19:06:17 +00:00
Ahmed Ibrahim edd0df9084 Reuse verified V8 checksum manifests from the artifact cache (#47915)
## Why

V8 artifact fetching always downloaded the checksum manifest, requiring network access even when all cached files were valid.

## What changed

Reuse a cached manifest when it is not a symlink and matches the checkout's trusted SHA-256 pin. Continue verifying both the archive and bindings against that manifest, downloading replacements when needed.

Refresh missing, invalid, or symlinked manifests. Preserve existing cache contents if the refresh is interrupted, and reject downloaded manifests that do not match the current pin.

## Testing

Add regression coverage for network-free cache reuse, manifest refresh, corrupt artifact repair, changed pins, symlink replacement, interrupted downloads, and source or paired artifact overrides. All 12 tests in `scripts/codex_package/test_v8.py` pass.

GitOrigin-RevId: d3bdb1ae5f6bc48dd6d081df33dec8db9d3257a8
2026-09-24 18:46:57 +00:00
jif 766d2377a8 Add an opt-in flag to defer mailbox preemption (#47913)
## 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
2026-09-24 18:38:58 +00:00
Charlie Marsh a8a4f14087 Fix attestation routing during thread startup (#47912)
## 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
2026-09-24 18:38:00 +00:00
Eric Traut 6743672ad7 Add TUI composer support for prompt suggestions (#47911)
## 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
2026-09-24 18:37:33 +00:00
Ian MacLeod 5c8fc15cc9 Alias tui.whimsy to tui.effects.starfield (#47908)
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
2026-09-24 18:23:11 +00:00
Ian MacLeod f0f38b68f7 Support nested canonical paths in config key aliases (#47904)
## 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
2026-09-24 18:09:47 +00:00
Ian MacLeod 0b78ddb035 Move config key alias normalization ahead of merging (#47903)
## 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
2026-09-24 18:09:23 +00:00
Ian MacLeod 975d30c043 Avoid repeated table clones during config merging (#47902)
## 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
2026-09-24 18:08:57 +00:00
Celia Chen 2347a61d0d Add bounded credential-storage telemetry helpers (#47901)
## 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
2026-09-24 18:08:31 +00:00
Owen Lin 12cb14f7b7 Default local threads to paginated history (#47900)
## 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
2026-09-24 18:07:37 +00:00
peilin-openai 62197a65e5 Add diagnostic reasons to MCP attribution errors (#47899)
## 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
2026-09-24 18:06:07 +00:00
Sean Huang 2457571e4c Preserve local-binding inheritance in environment network policies (#47898)
## 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
2026-09-24 18:05:40 +00:00
Felipe Coury a33fb9751c Preserve Markdown formatting when copying transcript selections (#47896)
## 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
2026-09-24 17:55:29 +00:00
Felipe Coury f6fd7f17ed Clean up temporary Codex homes after TUI tests (#47894)
## 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
2026-09-24 17:43:15 +00:00
willwang-openai 83b56bc5ad Support client secrets for pre-registered MCP OAuth clients (#47891)
## 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
2026-09-24 17:26:18 +00:00
Eric Traut b3ea9fa632 Include TUI client logs in diagnostic uploads (#47889)
## 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
2026-09-24 17:21:45 +00:00
Dmitriy Kovalenko 3d6428510f Warn users when SQLite diagnostic log writes fail (#47887)
## 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
2026-09-24 17:04:50 +00:00
Dmitriy Kovalenko a285066737 Preserve diagnostic logs when SQLite logging fails (#47886)
## 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
2026-09-24 17:04:24 +00:00
Charlie Marsh 90b67c96ca Use Tokio's clock for TUI paste timing (#47881)
## 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
2026-09-24 16:48:22 +00:00
felixxia-oai 6f51c65958 Fix macOS system-alias matching in patch permission checks (#47879)
## 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
2026-09-24 16:36:57 +00:00
Matthew Zeng 4021746a15 Measure deferred tool namespace fragments before and after truncation (#47873)
## 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
2026-09-24 16:14:45 +00:00
jif 42266240fd Fix PID reservation test race and update guardian heartbeat snapshot (#47871)
## 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
2026-09-24 16:07:15 +00:00
jif 30758e5c77 Add opt-in OTLP logging for Guardian assessments (#47870)
## 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
2026-09-24 16:06:07 +00:00
iceweasel-oai 2deb542491 Render remote permission paths using executor context (#47867)
## 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
2026-09-24 15:57:42 +00:00
jif 3e9d1d2937 Avoid nested read locking when rendering browser sign-in (#47861)
## 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
2026-09-24 15:21:29 +00:00
jif 58838dfa5b Validate loaded plugins outside the cache lock (#47858)
## 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
2026-09-24 14:58:31 +00:00
jif df06bb054c Initialize media estimates outside the global cache lock (#47856)
## 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
2026-09-24 14:58:04 +00:00
jif 421082e79d Avoid blocking async proxy resolution on the system proxy cache (#47852)
## 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
2026-09-24 14:50:27 +00:00
felixxia-oai e7f119819a Preserve human overrides across repeated heartbeat instructions (#47851)
## 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
2026-09-24 14:48:41 +00:00
Felipe Coury 12fd929f72 Keep the TUI responsive during clipboard copies (#47847)
## 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
2026-09-24 14:15:42 +00:00
jif 282cd7b019 Stabilize Rosetta test timing and retry delay telemetry (#47832)
## 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
2026-09-24 13:09:49 +00:00
jif 61e23bc6a1 Bind Guardian async scores to target environment permissions (#47830)
## 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
2026-09-24 12:34:04 +00:00
felixxia-oai b15718acfc Wait for login completion in recommended plugin tests (#47828)
## 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
2026-09-24 12:26:05 +00:00
felixxia-oai 4083a68f88 Allow four concurrent threads in the multi-agent resume test (#47824)
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
2026-09-24 12:15:57 +00:00
jif b19cebecc0 Add integration coverage for host agent controllers (#47820)
## 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
2026-09-24 11:20:59 +00:00
teddywyly-oai 49862b62be Retry Guardian reviews when authorization changes (#47819)
## 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
2026-09-24 11:19:16 +00:00
jif 16b20547f6 Stabilize thread resume and memory dual-write tests (#47817)
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
2026-09-24 11:10:14 +00:00
felixxia-oai 869b5527cd Fix a lost wakeup in the unified exec termination test (#47814)
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
2026-09-24 10:56:24 +00:00