checkpoint: into wallentx/termux-target from release/0.143.0 @ cb2e3d1b74e5 - #295
Merged
unemployabot[bot] merged 32 commits intoJul 8, 2026
Conversation
[Codex Thread 019edd6d-6f14-74e2-853c-345d1803d4a6](https://codex-thread-link.openai.chatgpt-team.site/thread/019edd6d-6f14-74e2-853c-345d1803d4a6) ## Stack Review and merge in order. Every layer is independently correct and documents its safe stopping point. 1. [openai#30292](openai#30292) — aggregate File/Secrets store locking 2. [openai#30293](openai#30293) — resolve and lifecycle-pin the exact OAuth store 3. [openai#30416](openai#30416) — serialized authoritative refresh transaction 4. [openai#30294](openai#30294) — Codex-owned transport refresh and one-shot 401 recovery 5. [openai#30295](openai#30295) — login/logout transaction serialization 6. [openai#30296](openai#30296) — diagnostic-only Auto store drift reporting **This PR is layer 1.** ## Why MCP OAuth credentials stored in File or Secrets share one aggregate map. Concurrent read-modify-write operations for different MCP servers can both read the same snapshot and let the later write discard the earlier update. That is a correctness problem independent of refresh-token rotation. ## What this PR does - Adds a bounded cross-process lock around aggregate File and Secrets loads, saves, and deletes. - Distinguishes aggregate-lock failures from Secrets backend unavailability, so Auto can fall back only for the latter and cannot bypass serialization by reading or writing File. - Keeps Direct keyring operations outside this lock because they are already per credential. - Releases the Secrets aggregate lock before legacy File cleanup so cross-store cleanup cannot create nested aggregate-lock ordering. - Tests actual contention by waiting for an observed `WouldBlock`, rather than assuming a sleeping worker reached the lock. - Tests load and save with only the Secrets lock path broken while fallback File remains readable and writable. ## Decisions and non-goals - This lock protects aggregate-store read-modify-write integrity only. It does not choose a credential authority or serialize an OAuth refresh transaction. - The lock is scoped to the active `CODEX_HOME`, matching the aggregate files it protects. - Lock waits are bounded, and coordination failures are surfaced rather than treated as evidence that Secrets is unavailable. ## Safe stopping point This PR can merge alone. It prevents lost updates and partial aggregate reads. Auto can still resolve again during a client lifecycle until layer 2, and concurrent refreshes remain possible until layer 3. ## Validation - `just test -p codex-rmcp-client` (96 passed; expected environment skips) - Focused aggregate File/Secrets lock contention and Auto fallback tests
## Why Users can see that usage-limit reset credits are available, but not which credits they have, when each one expires, or which credit will be consumed. The TUI should use the supported rate-limit RPC for that information without maintaining a second reset-credit request path. ## What changed - load reset-credit details through the existing `account/rateLimits/read` refresh when the user opens **Redeem usage limit reset** - show available credits sorted by expiry, using the backend title when present and a scope-based fallback otherwise - consume the exact selected credit and preserve its idempotency key across retries - fall back to the existing generic reset action when the RPC returns a positive count without detail rows - remove the dedicated list-RPC event, request, response-combining, and TUI state plumbing - handle a selected credit becoming unavailable without incorrectly caching the user's total count as zero - handle forward-compatible unknown reset types with the existing scope-based fallback label ## TUI preview Rendered from the final standard-width and narrow `insta` snapshots in this PR. <img width="1280" height="570" alt="pr30488-reset-picker-preview" src="https://github.com/user-attachments/assets/8b84cd33-cb35-4a37-aaed-dbd6b62bff51" /> ## Validation - `just test -p codex-tui chatwidget::tests::usage` (32 passed) - `just fix -p codex-tui` - no pending `insta` snapshots Uses the reset-credit details added by openai#30395. Fixes openai#29618.
This PR depends on [openai#31296](openai#31296) for the canonical-to-legacy event mappings. ## Description This PR makes command execution emit canonical `TurnItem::CommandExecution` lifecycle from both the shell tool path and user `/shell` commands. App-server v2 consumes the canonical command items directly and ignores the mapped `ExecCommandBegin` / `ExecCommandEnd` compatibility events, so clients still receive one command item lifecycle. `UnifiedExecInteraction` stays on the legacy path because `TerminalInteraction` is still the v2 surface for stdin and poll events. Emitting a command item there would render the same wait twice. ## Why This is the first live producer migration after the compatibility mappings in openai#31296. Keeping command execution separate makes the unified exec exception reviewable without mixing in dynamic tools or multi-agent behavior. ## What changed - Emit canonical command execution items from shell tool events and user shell commands. - Preserve the existing unified exec interaction carveout. - Move app-server command deduplication and completion bookkeeping onto canonical item events. - Update unified exec coverage to assert the completed command item.
This PR depends on [openai#31296](openai#31296) for the canonical-to-legacy event mappings. ## Description This PR makes dynamic tools emit canonical `TurnItem::DynamicToolCall` lifecycle instead of `DynamicToolCallRequest` / `DynamicToolCallResponse` directly. App-server v2 now sends the client `DynamicToolCall` request from the canonical item start. It ignores the mapped legacy request/response events, so clients receive one item start and one tool request. ## Why Dynamic tools are a separate migration boundary because their start event also drives a client request. Keeping that routing change isolated makes it easier to verify that the request still happens exactly once. ## What changed - Emit in-progress and completed/failed dynamic tool items from the dynamic tool handler. - Move app-server client request dispatch onto canonical dynamic item starts. - Add focused app-server coverage for the canonical start notification and client request.
## Why Before changing plugin namespace loading performance, lock down the existing behavior so the same cases can be validated before and after the optimization. ## What - cover mixed plain and nested plugin skills under one scan root - cover inherited, nested, and invalid-manifest namespace precedence - cover symlinked plugin skill directories, symlinked plain directories, and scan-root ancestor symlinks ## Validation - just test -p codex-core-skills namespace on unmodified main: 12 passed
## Why Intel macOS release binaries crash on the first Code Mode tool call while V8 creates its code range. The x86_64 V8 allocator later makes a non-`MAP_JIT` reservation executable, which Hardened Runtime rejects when the signature contains only `com.apple.security.cs.allow-jit`. Tracks [SE-8006](https://linear.app/openai/issue/SE-8006/intel-macos-codex-cli-crashes-in-v8-startup-on-gpt-56-sol-tool-calls). Fixes openai#28390. ## What - add an expanded entitlement profile only for x86_64 `codex` and `codex-app-server`, the release binaries that link V8 - keep arm64 and `codex-responses-api-proxy` on the existing narrower profile - share one fail-closed target/binary selector between signing and final verification - verify the expected Mach-O architecture and exact entitlement dictionary for the signed binary, tar.gz, zstd, package, and DMG copies ## Verification - `just test-github-scripts` (34 tests) - `UV_CACHE_DIR=/private/tmp/codex-uv-cache just fmt-check` - `bash -n .github/scripts/macos-signing/select_codex_entitlements.sh` - `plutil -lint` on both entitlement profiles - parsed `rust-release.yml` as YAML - `git diff --check` - ad-hoc Hardened Runtime signing smoke on an x86_64 Mach-O slice: strict `codesign` verification passed; the Codex profile contained exactly both keys and the proxy profile retained exactly `allow-jit` ## Release validation Run a native Intel smoke of the final Developer ID-signed x86_64 Codex binary through V8 isolate creation before shipping. PR openai#30849 is diagnostic scaffolding, but its non-sandbox release job currently fails in the harness before V8 starts, so it is not counted as coverage here.
## Summary - refactor `ExternalAuth` to return `CodexAuth` directly - remove the parallel `ExternalAuthTokens` wrapper - preserve existing external bearer and app-server refresh behavior This is a mechanical precursor refactor; it does not add auth capabilities or change recovery behavior. ## Testing - `cargo fmt --all` - `cargo test -q -p codex-login --lib` - `cargo test -q -p codex-app-server --test all external_auth_refreshes_on_unauthorized`
## Why Windows Bazel test shards currently cap local test actions at 4. Controlled forced-test-execution measurements in openai#31339 found that 8 local jobs reduced Bazel elapsed time on every shard by 19–29%, including the slow shard from 835.5s to 609.3s, while 12 jobs regressed. ## What Set `common:ci-windows-cross --local_test_jobs=8` in `.bazelrc`. ## Manual validation - `git diff --check` - `just fmt` - [8-job CI experiment](https://github.com/openai/codex/actions/runs/28838387129)
## Summary - Adds `writes` to `AppToolApproval` and exposes it through config and app-server schemas, including `[apps._default].default_tools_approval_mode`. - In `writes`, tools with `readOnlyHint = true` skip approval; all other tools prompt, including non-destructive writes and tools without annotations. - Prevents session or persistent approval choices in this mode so later writes still prompt. ## Why `auto` only prompts for risk-hinted actions, while `prompt` also interrupts reads. Apps need a middle mode that gates writes without prompting for declared read-only actions. ## Validation - `just write-config-schema` - `just write-app-server-schema` - `just fmt` - `just test -p codex-core mcp_turn_metadata` (4 passed) - `just test -p codex-core writes_mode` (2 passed) - `just test -p codex-app-server config_read_includes_apps` (1 passed) - `just test -p codex-app-server-protocol` (251 passed) - `just test -p codex-config` (200 passed) - `just test -p codex-cli` (300 passed) - `just fix -p codex-core -p codex-config -p codex-app-server-protocol -p codex-app-server -p codex-cli`
## Summary - Treat streamed Responses `bio_policy` failures as terminal invalid requests instead of retryable stream errors. - Recognize the new biology policy code and message in the TUI while preserving the legacy `invalid_prompt` contract. - Keep the existing dedicated biology safety notice and add regression/snapshot coverage for all supported error shapes. ## Why [openai/openai#1068559](openai/openai#1068559) gates a Responses API contract change from `invalid_prompt` and the legacy message to `bio_policy` and new biology copy. Without this compatibility change, streamed blocks are retried as transient failures and the OSS TUI falls back to a generic/raw error instead of the dedicated safety notice. ## Validation - `just test -p codex-api` — 137 passed - `just test -p codex-tui app_server_safety_access_errors_render_dedicated_notice` — passed - `just fix -p codex-api` - `just fix -p codex-tui` - `just fmt` - `just test -p codex-tui` — 2,957 passed; two reproducible failures remain in untouched Guardian feature-flag persistence tests: - `update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default` - `update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history`
## Summary - measure successful legacy `app/list` latency with `codex.apps.installed.duration_ms`, segmented by `path=legacy` and `reload` - measure successful host-owned `codex_apps` startup and explicit refresh latency with `codex.apps.refresh.duration_ms` - add the refresh trigger to successful `codex.mcp.tools.fetch_uncached.duration_ms` samples for `codex_apps` without changing other MCP-server samples ## Why This establishes a small latency baseline for the current connector path before `ConnectorRuntimeManager`, `app/installed`, and `app/read` land. Error-rate and broader runtime-state instrumentation are intentionally deferred. This is telemetry-only and does not change connector behavior. ## Validation - `just test -p codex-mcp` (94 passed) - `just test -p codex-app-server list_apps` (13 passed) - `just fix -p codex-mcp` - `just fix -p codex-app-server` - `just fmt` - `git diff --check`
## Why Approval guidance is currently assembled entirely by the client. Model Messages V2 needs model catalogs to provide model-specific `on_request` guidance for both user-reviewed and auto-reviewed approval flows while retaining the existing generated prompt as a compatibility fallback. ## What changed - add nullable `on_request` and `on_request_auto_review` catalog messages - select the message matching the active approvals reviewer for `on_request` policies - replace the complete legacy approval section when the selected catalog value exists, including support for an empty string that suppresses the section - retain legacy rendering when the object or selected key is absent, and for non-`on_request` policies - preserve approval messages when base-instruction or personality overrides clear instruction templates - refresh permissions instructions when the active model changes - pass catalog messages through initial and incremental permissions construction ## Relationship to reviewer persistence PR openai#31309 independently persists the approvals reviewer in turn context and refreshes permissions when that reviewer changes. This PR is based directly on `main` and does not duplicate that rollout migration; once both land, reviewer switches will also select and append the new catalog variant. ## Testing - `just test -p codex-protocol` - `just test -p codex-prompts` - `just test -p codex-models-manager` - `just test -p codex-core permissions_messages`
## Why Remote-executor integration tests need one host-agnostic exec-server fixture target instead of a Windows-only wrapper. ## What - rename the testing binary target to exec-server - make the fixture source and target host-agnostic - update Windows remote-executor test wiring to use the shared target ## Validation - bazel build //codex-rs/exec-server/testing:exec-server - bazel cquery --config=ci-windows-cross 'set(//codex-rs/exec-server/testing:exec-server //codex-rs/core/tests/remote_env_windows:smoke-test)' ## Stack 1. [openai#31422 test: generalize exec-server fixture](openai#31422) 2. [openai#31425 test: add TestAppServer builder](openai#31425) 3. [openai#31427 test: add delayed exec-server transport](openai#31427) 4. [openai#31295 bench: add cold skill load macrobenchmark](openai#31295) 5. [openai#31428 bench: add e2e benchmark entrypoints](openai#31428) 6. [openai#31429 ci: smoke Bazel e2e benchmarks](openai#31429)
## Summary - enable `auth_elicitation` by default - promote the feature to `Stable`, as default-enabled features must be stable - update the feature regression test to cover the new lifecycle state and default ## Impact Auth elicitation is now available without requiring users or clients to opt in through configuration. ## Testing - `just test -p codex-features` (52 passed)
## What Adds an optional hosted login-success redirect path for app-server login requests. - Keeps the existing localhost success page as the default. - Lets app-server callers opt into a hosted success page with an optional protocol field. - Persists credentials before redirecting to the hosted success page. - Keeps org setup and existing CLI/device-code login flows on the local success page. - Accepts an optional typed `appBrand` value and forwards it to the hosted page as `app_brand` so web can select the correct asset. - Generates the app-server protocol schema updates for the new optional fields. ## Why This supports the hosted Codex login success page rollout without changing existing login behavior by default. The Codex Apps frontend can gate the opt-in with Statsig after the hosted web page. ## Rollout safety - Old callers omit the new field and continue using localhost. - New callers talking to old app-server builds remain safe because the Codex Apps side treats the field as optional and defaults the flag off. - Missing brand values default to Codex. - The hosted redirect always uses the app-login source so the hosted page can reopen Codex; the existing streamlined-login visual flag remains separate. ## Validation - `just fmt` - `just fix -p codex-login -p codex-app-server-protocol -p codex-app-server -p codex-app-server-test-client -p codex-tui` - `just test -p codex-login` - `just test -p codex-app-server-protocol` - `just write-app-server-schema` - `git diff HEAD --check` The focused login and protocol run passed all 380 tests. I also started the broader `just test -p codex-app-server`; it compiled successfully, then many tests failed on this machine because spawned test servers tried to use the ambient `/Users/rafaelj/.codex/sqlite` state DB, which is read-only in this sandbox. I stopped that run after confirming the failures shared that environment issue.
## Why This PR is a behavior-preserving refactor only. It does not add a fallback, change which model is used for compaction, or otherwise change compaction behavior. The behavioral change is implemented in the stacked follow-up, openai#30319. Pre-sampling compaction deliberately uses the previous turn's context when the compaction compatibility hash changes or when switching to a model with a smaller context window. That preserves the model settings that produced the history being compacted, but the previous context is not always usable. For example, a resumed thread can still reference a model slug that has since been retired, causing compaction to fail before the currently selected model can sample. openai#30319 addresses that failure mode by retrying compaction with the current turn's selected model when the backend rejects the previous-model attempt. This PR performs only that preparatory refactor. ## What changed - Extracted one legacy `/responses/compact` request attempt into `compact_remote_request.rs`. - Extracted one Responses-based remote compaction request attempt into `compact_remote_v2_attempt.rs`. - Kept hooks, lifecycle events, analytics, window advancement, history processing and installation, and error behavior unchanged in the existing orchestration paths. - Preserved standalone Responses-based compaction's owned client-session lifetime through lifecycle completion. ## Testing - `just test -p codex-core -E 'test(remote_compact)'` (22 tests)
This PR depends on [openai#31296](openai#31296) for the canonical-to-legacy event mappings. ## Description This PR makes the MultiAgentV2 spawn, message/follow-up, and interrupt paths emit completed canonical `TurnItem::SubAgentActivity` items instead of `SubAgentActivityEvent` directly. App-server v2 now applies interrupted-agent thread-watch cleanup from the canonical completed item and ignores the mapped legacy activity event. ## Why Sub-agent activity is separate from the v1 collab tool begin/end lifecycle. Keeping it separate makes the v2 watcher side effect reviewable without mixing in the larger collab tool-call migration. ## What changed - Emit canonical sub-agent activity items from v2 spawn, message/follow-up, and interrupt paths. - Move missing-thread watcher cleanup onto canonical completed activity items. - Update focused app-server coverage to exercise canonical interrupted activity.
## Why The backend config-bundle contract now exposes managed configuration in `managed_layers`, split into `baseline` and `system_overlay`. The Rust transport models need to match that contract before any runtime behavior changes. ## What changed - add the generated `DeliveredManagedLayers` model - model `baseline` and `system_overlay` as required arrays - expose optional/null `managed_layers` on delivered config and requirements documents - retain `enterprise_managed` for transport compatibility This PR changes transport types only; cloud-config runtime behavior is unchanged. ## Stack 1 of 4. Next: openai#31286. ## Validation - `just test -p codex-backend-openapi-models -p codex-backend-client` - `just test -p codex-cloud-config` - revalidated against the current generated backend schema
This PR depends on [openai#31296](openai#31296) for the canonical-to-legacy event mappings. ## Description This PR makes the non-wait v1 collaboration tools—spawn, send input, resume, and close—emit canonical `TurnItem::CollabAgentToolCall` lifecycle instead of their legacy begin/end events directly. App-server v2 consumes the canonical collab items directly, ignores the mapped legacy events, and applies close-agent thread-watch cleanup from the completed item. ## Why These four tools share the same single-target lifecycle shape. Wait stays separate because it carries multi-target status snapshots and has its own status-shaping cleanup. ## What changed - Add shared helpers for emitting canonical collab tool-call lifecycle. - Migrate spawn, send input, resume, and close handlers. - Move close-agent watcher cleanup onto canonical completed collab items.
This PR depends on [openai#31296](openai#31296) for the canonical-to-legacy event mappings. ## Description This PR makes the v1 and v2 wait paths emit canonical `TurnItem::CollabAgentToolCall` lifecycle instead of `CollabWaitingBegin` / `CollabWaitingEnd` directly. Both paths already used the same legacy waiting events before this PR. The v1 item carries receiver metadata and final agent statuses for its target agents; v2 waits for mailbox activity rather than specific agents, so it keeps those fields empty, matching the existing v2 legacy payload. App-server v2 consumes the canonical item directly and ignores the mapped legacy wait events. ## Why Wait is separate from the other collab tools because it is multi-target and has distinct timeout/status behavior. Keeping it last also lets this PR remove the old helper that only existed to shape legacy wait status entries in core. ## What changed - Emit canonical collab wait items from both v1 and v2 wait handlers. - Preserve receiver metadata and agent status snapshots on completed wait items. - Remove the old core helper for building legacy wait status entries. ## Follow-up The next stack PR, [openai#30188](openai#30188), writes canonical `TurnItem` values to paginated rollout files.
…enai#30319) ## Why Pre-sampling compaction intentionally uses the previous turn's model when the compaction compatibility hash changes or when switching to a model with a smaller context window. This keeps compaction aligned with the settings that produced the history, but it can block the next turn when a resumed ChatGPT thread still references a model slug that has since been retired. The Codex backend rejects that compaction request before the user's currently selected model gets a chance to sample. This PR lets those threads recover without changing previous-model compaction behavior for API-key authentication or custom providers. It is stacked on openai#31316, which is a behavior-preserving extraction of the individual remote compaction attempts; this PR contains the fallback behavior. ## What changed - For automatic previous-model compaction, capture the selected model's request context when using ChatGPT authentication with the OpenAI provider and the selected model differs from the previous model. - If the previous-model attempt returns an `InvalidRequest`, retry compaction once with the selected model for both `/responses/compact` and Responses Compaction V2. - Complete history processing, lifecycle events, and token accounting with the context of the model that successfully compacted the thread. - If the fallback also fails, return the original previous-model error so the retry does not change the user-visible failure. - Record fallback attempts with reason, implementation, and outcome telemetry. - Leave API-key authentication, custom providers, same-model turns, and non-`InvalidRequest` failures on their existing paths. ## Testing - `just test -p codex-core -E 'test(pre_sampling_compact) | test(model_unavailable_error)'` (10 tests) - Added integration coverage for a resumed thread whose model was renamed, a model downshift using Responses Compaction V2, and API-key authentication with a custom provider.
## Summary
- recognize embedded HTTP(S) URL prefixes case-insensitively in Windows
dangerous-command detection
- add regression coverage for uppercase and mixed-case schemes inside
`Start-Process` invocations
## Why
PowerShell and URL parsing treat schemes case-insensitively, but the
pre-parser only searched for lowercase `http://` and `https://`. When a
URL appeared in the same shlex token as surrounding PowerShell syntax,
such as `Start-Process('HTTPS://example.com');`, the prefix was not
stripped and the command was incorrectly classified as not dangerous.
Validated with the scoped `codex-shell-command` suite (138 tests) and a
direct classifier reproduction that failed before the change and passed
afterward.
## Summary Autocomplete completion previously inserted a new space even when a separator was already present, which could leave redundant whitespace around neighboring text. Popup dismissal also tracked only the query string, so dismissing one token could suppress a different occurrence with the same text. This gives completions one horizontal-separator policy across files, images, skills, and mentions. Existing separators are reused when possible, ordinary suffix text remains separated, and line breaks stay intact. Dismissal now identifies the complete whitespace-delimited token occurrence, so offset-only edits preserve dismissal while later identical tokens remain independent. Newly completed values beginning with `$` or `@` can also remain closed when the next PR's affinity rule recognizes the token to the left of the cursor. ## Examples The examples below use `|` to represent the cursor. ### Reuse existing separators Starting with an existing two-space gap: ```text @ma| next ``` After accepting `src/main.rs` and typing `foo`, completion previously added a third separator and left both original spaces before `next`: ```text src/main.rs foo| next ``` After this PR, completion reuses the first existing separator as the insertion point and preserves the second between the new text and `next`: ```text src/main.rs foo| next ``` ### Keep a completed sigil-prefixed value closed Starting before a line break: ```text @ma| next ``` and accepting a path whose result is itself prefixed with `@` produces: ```text @scope/main.rs | next ``` Without this PR's completion dismissal, the affinity rule in openai#30463 rediscovers the completed token to the left of the cursor and reopens its popup: ```text @scope/main.rs | ^^^^^^^^^^^^^^^ popup reopens next ``` With this PR, the inserted occurrence is dismissed and the popup remains closed: ```text @scope/main.rs | ^^^^^^^^^^^^^^^ popup remains closed next ``` ### Do not dismiss an identical later occurrence Given two identical tokens: ```text @scope/main.rs| @scope/main.rs ``` after dismissing the first popup with Escape and moving to the second token, query-only dismissal previously suppressed the second popup too: ```text @scope/main.rs @scope/main.rs| ^^^^^^^^^^^^^ popup remains closed ``` After this PR, dismissal also matches the token's ordinal among complete tokens, so the second occurrence opens normally: ```text @scope/main.rs @scope/main.rs| ^^^^^^^^^^^^^ popup opens ``` ### Keep dismissal across offset-only edits After dismissing `@ma`, moving to its start, and pasting an email-like token: ```text email@ma.com @ma| ``` the `@ma` bytes embedded in `email@ma.com` do not count as another autocomplete token. The original `@ma` keeps its dismissal even though its byte range moved. ## Stack This is PR 2 of 3, stacked on openai#31190. It relies on the explicit replacement ranges introduced there and provides the completion lifecycle used by the targeting fix in openai#30463.
## Why Test callers need one composable way to create app-server fixtures instead of a growing family of overlapping constructor implementations. ## What - add a feature-complete TestAppServer::builder() - make the default builder own a temporary CODEX_HOME and select the automatic test environment - expose builder knobs for no automatic environment, explicit CODEX_HOME, program, arguments, plugin startup tasks, environment overrides, managed config, and JSON logging - keep the existing public constructor surface, but route every constructor through the builder so the new path is exercised immediately - remove the redundant private constructor ladders; caller migration and public constructor removal live in the optional cleanup stack ## Validation - just test -p codex-app-server (940/941 before updating the expected builder error wording) - just test -p codex-app-server auto_env_rejects_explicit_environment_config - just fix -p codex-app-server - just fmt ## Follow-up stacks Cleanup, optional for the benchmark work: 1. [openai#31451 test: migrate TestAppServer callers to builder](openai#31451) 2. [openai#31452 test: remove TestAppServer constructors](openai#31452) Benchmark infrastructure: 1. [openai#31427 test: add delayed exec-server transport](openai#31427) 2. [openai#31295 bench: add cold skill load macrobenchmark](openai#31295) 3. [openai#31428 bench: add e2e benchmark entrypoints](openai#31428) 4. [openai#31429 ci: smoke Bazel e2e benchmarks](openai#31429)
## Why openai#31335 lets HTTP callers obtain proxy-aware clients from `HttpClientFactory`, but a non-HTTP transport such as WebSockets also needs two pieces of policy owned by `codex-http-client`: a concrete route decision for its destination and the same custom-CA-aware rustls trust configuration used by HTTPS. Keeping these prerequisites in the shared abstraction means the dependent Responses WebSocket change (openai#31441) cannot independently reinterpret `features.respect_system_proxy`, PAC results, or enterprise CA settings. ## What changed - Add a redaction-safe `OutboundProxyRoute` with explicit transport-default, direct, and concrete-proxy outcomes. - Add `HttpClientFactory::resolve_proxy_route()` so transports can resolve a destination through the already-selected outbound proxy policy. - Resolve `ws://` and `wss://` URLs through their HTTP equivalents so system and PAC rules apply consistently. - Add an always-returned rustls config builder that starts from native roots and layers in any configured Codex custom CA bundle. The existing optional builder remains available to callers that can delegate the default configuration to their transport. - Continue redacting proxy URLs from `Debug` output because they may contain credentials. ## Review guide 1. `http-client/src/outbound_proxy.rs` defines the transport-neutral route result and WebSocket URL normalization. 2. `http-client/src/custom_ca.rs` factors the native-root/custom-CA construction so callers that perform TLS themselves can always obtain a config. 3. `http-client/src/outbound_proxy_tests.rs` verifies WebSocket normalization and legacy transport-default behavior. ## Test plan - `just test -p codex-http-client outbound_proxy` - `just test -p codex-http-client custom_ca` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/31342). * openai#31431 * openai#31363 * openai#31362 * openai#31361 * openai#31442 * openai#31441 * __->__ openai#31342
## Why Loading skills from a remote executor can add a lot to thread start time when there are many skills. Previous changes added some concurrency for the file reads themselves, but we're still bottlenecked on the initial root path discovery. Using the benchmark from [openai#31295](openai#31295), this change reduces the measured mean of loading 66 skills about 71%. Behavioral coverage lands separately in [openai#31369](openai#31369). ## What - resolve the scanned root's inherited namespace once - resolve discovered nested plugin roots once, retaining nearest-valid-ancestor behavior - pass an explicit resolved Plain / Plugin namespace into skill parsing instead of probing per skill - preserve explicitly provided plugin namespaces as the highest-priority source - reuse the same resolver for environment skills, deleting its duplicate root-probe and ancestor-selection path ## Validation - just test -p codex-core-skills namespace: 12 passed on both the parent and optimized branches
# Conflicts: # .github/actions/macos-code-sign/codex-app-server.entitlements.plist # .github/actions/macos-code-sign/codex-code-mode-host.entitlements.plist # .github/actions/macos-code-sign/codex-responses-api-proxy.entitlements.plist
Termux rust-v0.143.0-alpha.39
…nt/wallentx_termux-target_from_release_0.143.0_cb2e3d1b74e5
unemployabot
Bot
deleted the
checkpoint/wallentx_termux-target_from_release_0.143.0_cb2e3d1b74e5
branch
July 8, 2026 03:15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Termux release checkpoint
release/0.143.0cb2e3d1b74e5af8cbe99d80dd6f22b4a23c56e0cwallentx/termux-targetThis PR carries release-train conflict fixes and follow-up changes back into the reusable Termux patch branch.
Release-only workflow files and metadata under
.githubwere restored to the destination branch versions before opening this PR.