## Why
Failed image requests discarded the `x-codex-imagegen-request-id` header, leaving failure analytics without the request ID.
## What changed
Carry the request ID through `ImageRequestError` and backend errors for image generation and editing. Preserve it on failed image generation items for HTTP errors, response decoding errors, and responses with no image data.
## Testing
Extend the app-server failure test to verify that a request ID returned with an HTTP 500 response reaches `codex_image_generation_event` analytics.
GitOrigin-RevId: 57cddacc0221e5b58877ac375d5eca0afb99d853
## What changed
Reject authorization endpoints with schemes other than `http` or `https` before client registration or authorization URL return. Document this constraint for `mcpServer/oauth/login`.
## Testing
Make existing asynchronous tests wait for cleanup: wait for `ThreadIdle` before injecting user input in the guardian cached-score test, and poll for queue consumption before asserting that dispatched items are gone.
GitOrigin-RevId: e5f6b4c5556234c3cc2aa56910486e892c011116
## What changed
Mark `guardianv2.thread_context` as stable and enable it by default for synchronous and asynchronous Guardian reviews. Keep it independent of the Guardian v2 `enabled` toggle and preserve explicit configuration and profile overrides. Update the configuration schema documentation to match.
## Testing
Update coverage for default configuration and sender user messages, review prompt snapshots, history retention across compaction, and checkpoint provenance. Assert that later user input invalidates an in-flight review's authorization. Keep legacy transcript budgeting coverage by explicitly disabling thread context in that test.
GitOrigin-RevId: 19afd34d7bfc0ee36bbf878089c68b732a21bc6a
## Why
Posting to a new channel subscribed its author to replies on that post, but not to new discussion roots in the channel. The creator could therefore miss notifications for subsequent discussions.
## What changed
Subscribe the author to the channel in the same transaction that creates the channel and its first post. Document this behavior in the API and the `new_channel_name` tool parameter.
## Testing
Update coverage to verify that channel creators receive notifications without explicit targeting and that posting to an existing channel preserves an explicit unsubscribe. Adjust thread-deletion test expectations for the additional persisted subscription.
GitOrigin-RevId: 5553ebc9f9b51456ab48886e9871733e93370a2b
## Why
Posting to a discussion automatically subscribed its author, undoing an explicit unsubscribe and restoring unwanted reply notifications.
## What changed
Persist explicit opt-outs so posting follows a discussion by default but leaves unsubscribed agents opted out until explicitly subscribed again. Keep active subscriptions in the existing table for compatibility with older readers, and remove opt-outs when deleting a board. Update the API and tool descriptions to explain the behavior.
## Testing
Extend the local board test to cover reopening an older database, preserving opt-outs across reopen and subsequent posts, legacy subscription queries, explicit notifications without resubscribing, explicit resubscription, and board cleanup.
GitOrigin-RevId: 8b8f7f50cea5041541b8d93067c52db18cdde85c
## Why
Channel and thread subscriptions, or explicit `agents_to_notify`, could cause agents to receive notifications for their own posts.
## What changed
Exclude the author from notification recipients, even when explicitly targeted. Preserve the author's subscriptions so replies from other agents still reach them, and document this requirement in the board API.
## Testing
Update board tests to cover explicit self-targeting, subscribed authors, and delivery of other agents' replies. Update the model-context scenario and snapshot to verify posts remain searchable without a `CHANNEL_POST` self-notification.
GitOrigin-RevId: 0b2558e7df79122a6da06ad592f9735ba260cce1
## Why
Standalone web search selected a proxy route only for the initial endpoint. Redirect destinations can require a different system proxy route.
## What changed
- Add `RouteAwareClientPool` support to `ReqwestTransport` for both buffered and streaming requests, and use it for standalone web search.
- Preserve default Codex headers and Cloudflare cookie handling across routes, while retaining the default client behavior when route-aware handling is disabled or Codex is sandboxed.
- Share request construction so URL authentication and header precedence follow `reqwest` semantics, applying them once before redirects and TLS retries.
- Map route-aware failures to transport errors and remove request URLs from those errors.
## Testing
Add regression coverage for redirects through distinct proxies, preservation of POST bodies and default headers, URL authentication and header precedence, and transport error classification without URL leakage.
GitOrigin-RevId: 19a10a62118846db09dd95265dc277e54aac09ef
## Why
Classifier requests need to preserve their owning thread's workspace routing and account binding, including when reusing pooled connections or retrying after authentication changes.
## What changed
- Share the thread's `WorkspaceRoutingContext` with Guardian v2 and resolve routing before leasing HTTP or pooled WebSocket connections.
- Reuse WebSockets only when their connection key and authentication state still match. Cache HTTP transports by URL and redirect policy, rejecting redirects when routing requires it.
- Stop classification requests and retries when the account owner changes while allowing token refreshes for the same user and workspace.
## Testing
Add regression coverage for routing failures with prewarmed sockets, shared thread routing state, account switches during HTTP and WebSocket requests, same-account token refreshes, and HTTP redirect-policy cache changes.
GitOrigin-RevId: 7b3efcadb4797b6a2de2e28e7506b297b0728d69
## Why
Standalone web search used a default HTTP client, bypassing the configured system proxy route when `respect_system_proxy` was enabled.
## What changed
Pass the configured `HttpClientFactory` to the web search tool and create its client asynchronously for the provider's search URL using the API route policy. Export and reuse `SEARCH_ENDPOINT` so route selection and search requests use the same endpoint.
## Testing
Add an isolated regression test with environment proxies removed and a mock system proxy. Verify that standalone web search reaches the proxy and returns its result in the follow-up model request.
GitOrigin-RevId: 3b64803a777b9d1eb0ccf694e06658b0fd562129
## Why
Extension calls omitted environments whose working directories could not be converted to host-native paths, preventing extensions from receiving those environments.
## What changed
Store `ToolEnvironment.cwd` as `PathUri` and pass all turn environments to extension tools without requiring host-native path conversion. Keep image generation's existing path requirements by selecting the first environment with a convertible working directory when reading referenced images or saving generated images.
GitOrigin-RevId: b4320c6e07d27ef59885cd0013e5d1c535f69659
## What changed
- Add `auto_review.extra_policy` and the managed `guardian_extra_policy` requirement to supply policy text alongside the resolved tenant policy. Nonblank managed values take precedence; blank values are ignored.
- Render the additional text through `{{ extra_policy }}` in Guardian reviewer templates and append it to the tenant policy for Guardian v2 classification before truncation.
- Preserve placeholder-like text inside supplied policies literally.
## Testing
Add coverage for configuration precedence, blank values, template substitution, and classifier prompts, plus a scenario verifying that managed tenant and extra policies reach the Guardian reviewer together.
GitOrigin-RevId: 180d8d716c63fe96a92ec5bfbd22db4ddccd4f1f
## Why
Code Mode callbacks can retain skill tools after another turn becomes active. Looking up the active turn when a delayed skill invocation completes can lose access to the originating turn's metrics and metadata.
## What changed
- Capture and retain the originating `SkillTurnMetrics` when constructing skill analytics.
- Expose turn analytics metadata through the turn extension store and carry it into skill telemetry.
- Add optional turn metadata to `TrackEventsContext` and pass it from app, skill, and plugin usage call sites.
## Testing
Add a regression test that yields a Code Mode cell, starts another turn, and releases both skill reads through a shared barrier. Assert that each `skill_invocation` event retains its originating `turn_id`.
GitOrigin-RevId: aa629dd5f84563d558aa6a86bfbdfc356f1b98e4
## Why
Message board notifications exposed only post and thread IDs, requiring a read to see any post content.
## What changed
Deliver notifications as `agent_message` items with author and recipient attribution. Include a `CHANNEL_POST` payload with the sender, channel, message and thread IDs, and up to 150 characters of post text. Direct agents to `read_post` when the preview is truncated, and retain recognition of legacy user-role notices.
## Testing
Update the model-context scenario to assert the notification's author, recipient, and preview payload, and update the idle-agent scenario to check for the new notification format.
GitOrigin-RevId: e0e2794be82e38bba47f41fb4fc8128eb5e47619
## What changed
- Replace the built-in orchestrator skill provider with a host-supplied cloud provider, using `cloud` authority and `c` root aliases in skill tools and prompts.
- Add `cloud.skills.enabled`, defaulting to true but requiring a supplied provider. Keep `orchestrator.skills` accepted as a legacy no-op setting, and remove the app server's automatic orchestrator provider registration.
- Discover cloud skills once per turn during cancellable startup. Serve catalog snapshots to prompts and tools without triggering discovery or retries.
- Scope cached catalogs and resources to authentication state. Preserve them on refresh failures within the same scope, invalidate them when that scope changes, and reject late discovery or read results from replaced cache generations.
- Reuse executor discovery catalogs only when successful discovery inputs and bundled-skill settings match.
## Testing
Add coverage for per-turn refresh, skill removal, same-account failures and reconnects, authentication changes, and stale in-flight results. Update configuration and tool tests for cloud authority, provider gating, and resource reads without an executor.
GitOrigin-RevId: c57e38ec7dcc880c0d4c8a2995adfd3e28301079
## Why
When result metadata exceeds the output budget, message-board tools keep retrying identical reads after all limits reach one.
## What changed
Stop shrinking reads once every page and character limit reaches one, returning the existing metadata-budget error if the result still does not fit. Use the largest effective limit to keep retrying while either the page size or preview length can still shrink.
## Testing
Add regression assertions for all five read tools with an impossible output budget, checking the error and exact read counts. Cover unequal page and preview limits and limits that are not powers of two.
GitOrigin-RevId: f00ddbcf0372c8f9318fa178259868caae55e68b
Create `posts_roots_created` on `(board, channel, timestamp, seq)` for
posts where `id = root` in the local SQLite schema.
GitOrigin-RevId: 4c40e0d853deaa3ab6b6303525870e3b7bfc3b14
## Why
Listing threads issued two additional SQL queries per root to fetch its reply count and latest reply.
## What changed
Fetch roots, reply counts, and latest replies in a single query. Materialize the selected page before looking up reply summaries, preserving creation and activity ordering, pagination, and preview limits.
## Testing
Strengthen pagination assertions to check complete thread summaries for threads without replies, including Unicode preview truncation, reply counts, and last activity timestamps.
GitOrigin-RevId: cbbed36418a349a18daf0771f4ed27aa47de0bc1
## Why
Posting to the local agent message board fetched each subscriber row across SQLite's worker thread while holding a write transaction.
## What changed
Use `json_group_array(agent)` to fetch subscribers as a single JSON array, then deserialize it before collecting notification recipients.
## Testing
Extend the local board test to verify that posting to a channel with no subscribers succeeds without sending notifications.
GitOrigin-RevId: ad294e19c78ee501f1de2084f7c02fa96f53418d
## Why
Opening each local message-board handle created a separate SQLite pool for the same database.
## What changed
- Cache one shared pool per canonical database path within the process, using weak references so the last handle can release it.
- Serialize pool initialization with deletion and corruption recovery. Close and evict the cached pool before replacing a corrupt database, and block new handles until deletion tombstones are saved.
## Testing
Enable library unit tests and add coverage for concurrent handles sharing a pool, releasing it after the last handle drops, and creating a new pool on reopen.
GitOrigin-RevId: 4d4a5c9ea9f063733df85a2ac120d51099736520
## Why
A corrupt agent message-board database can block thread deletion even when the feature is disabled.
## What changed
When corruption prevents opening the database for board deletion, back it up and recreate it before recording deletion tombstones. Recovery resets all boards, retaining their previous storage in the backup. Other database open failures continue to return an error without deleting the thread or replacing storage.
## Testing
Add an app-server regression test with the feature disabled that verifies ordinary open failures preserve storage and the thread, while corruption recovery preserves the backup, deletes the requested thread, retains another thread, and records the board tombstone in the recreated database.
GitOrigin-RevId: 85f7d6303ae5c359782018cad4a78461d86c43db
## Why
Permanent thread deletion needs to remove persisted agent message board data even when the message board feature has been disabled.
## What changed
- Add a cleanup hook for single and batch thread deletion, invoked after reference and writer checks but before rollout removal so cleanup failures remain retryable.
- Remove the deleted roots' channels, posts, and subscriptions regardless of the current feature setting.
- Record board tombstones and check them within write transactions to prevent delayed writes from recreating deleted data.
## Testing
Add an app-server regression test that creates a board, archives its root thread, restarts with the feature disabled, and verifies that permanent deletion removes the persisted channels, posts, and subscriptions.
GitOrigin-RevId: 4ea71559a8df0814dffda23a056a9bbaf6e0a0cb
## Why
Message-board tools hardcoded the `collaboration` namespace and used a different namespace description from the multi-agent tools. This ignored custom namespace configuration and caused conflicts under strict tool collision checking.
## What changed
- Use `multi_agent_v2.tool_namespace` and the shared multi-agent namespace description for message-board tools, resolving the namespace at runtime startup.
- Support unnamespaced tool specifications when no namespace is supplied.
- Remove hardcoded `collaboration` prefixes from message-board notifications.
## Testing
Add app-server integration coverage for the default `collaboration` namespace and a configured `agents` namespace with strict collision checking enabled. Verify that both tool families are advertised together and that `get_channels` executes through the installed extension.
GitOrigin-RevId: fef7be51ea2a84bbdb6d3491606db442ed4e6ea3
## What changed
- Register the existing message-board tools with the app server through a lifecycle extension, gated on `agent_message_board`, multi-agent v2, and non-ephemeral sessions. The new feature flag is disabled by default.
- Bind tools to each agent's identity and share the SQLite-backed board across the agent tree and runtime resumes.
- Use the runtime clock for posts and deliver ID-only notifications to running agents, with tools to retrieve post contents. Skip inactive recipients without starting them or queuing notices.
- Emit a warning and leave board tools unavailable if initialization fails.
## Testing
Add runtime scenarios and a context snapshot covering feature gating without creating storage, posting and searching, active-only notifications, sharing with child agents, persistence across resume, and clock failure without channel creation.
GitOrigin-RevId: a81bd85cd372b0d122ba375ed1a1bfd3ba3a3b7c
## Why
Tool allowlists alone cannot express the reviewer's sandbox and shell restrictions, which previously depended on session identity. Threads need to supply these restrictions explicitly at startup.
## What changed
- Replace `AllowedTools` with `ToolPolicy`, combining an optional allowlist with managed-sandbox requirements, unified-exec requirements, and control over additional-permission arguments.
- Capture the policy once at startup and apply it during tool registration and construction, including hosted tool filtering. Later extension-state changes cannot relax it.
- Supply the reviewer policy explicitly while retaining the fallback for reviewer sessions without a supplied policy. Explicit policies take precedence over session identity; ordinary defaults preserve existing tool setup.
## Testing
Update tool-planning tests to use explicit policies and add startup coverage for additional-permission schemas, ordinary defaults, reviewer fallbacks, explicit-policy precedence, and policy capture despite later extension-state changes.
GitOrigin-RevId: 71e561d76ea24d961f5b29c7c619bdb1356c216a
## What changed
Add an integration test covering channel creation, case-insensitive channel search, channel and thread subscriptions, and notification recipients through the message board tools.
Verify that control-character-heavy posts produce valid JSON within the 8,000-byte output limit, mark truncated thread previews, preserve all threads across pagination in reverse creation order, and return the expected root and reply when reading a thread. Also cover rejection of subscription requests that specify both a channel and a thread.
Extract a shared `board_tool_call` helper for the tool tests.
GitOrigin-RevId: 05dc2f1f2ec883b030a8d354688c5e7fd65aec31
## What changed
Expose `message_board_tools` to create nine tools for channel creation and discovery, thread listing, post search and reading, subscriptions, and posting. Bind tools to the host-supplied caller identity and resolve agent references relative to the caller. The factory does not register or enable the extension.
Keep responses valid JSON within an 8,000-byte cap and the call's output budget. Reduce read limits and previews as needed while preserving backend pagination, and reject mutations when the budget is too small to acknowledge them. Derive post request IDs from turn and invocation metadata for direct and Code Mode calls.
## Testing
Add integration coverage for invalid arguments, mutation rejection without writes under insufficient budgets, duplicate post calls, distinct Code Mode invocations, relative notification recipients, author filtering, and bounded Unicode reads with continuation offsets.
GitOrigin-RevId: 2fbc58a4c7eb861055847c363061d73749bf573c
Add an index on `posts(board,channel,timestamp,seq)` to support the channel summary query that selects the latest message by `timestamp` and `seq`.
GitOrigin-RevId: 862b318fd70a039aa749240c389865f1c84f552c
## What changed
Implement `AgentMessageBoard` for `LocalAgentMessageBoard`, adding SQLite queries to list channels and threads, search posts, and read thread replies.
- Support Unicode case-insensitive substring search and post filters for channel, author, and `after_message_id`.
- Sort threads by creation time or latest activity, with reply counts and previews of the root post and latest reply.
- Bound pages to 50 results and post previews to a shared 20,000-character response budget. Use offset cursors for pagination; concurrent posts may shift results between pages.
- Add indexes for board and thread timestamp queries.
## Testing
Add integration tests covering pagination, page and preview caps, Unicode search and truncation, thread activity ordering, filtered search, and rejection of non-root thread IDs and unknown callers.
GitOrigin-RevId: c9c673768596efb6d33160e2db8dff62ee9b9cdb
## What changed
Add `LocalAgentMessageBoard` with persistent channels, posts, and subscriptions scoped by `SessionId`. Support channel creation, posting and replies, subscription changes, and bounded reads using Unicode character offsets.
Serialize mutations across independent handles with immediate transactions. Deduplicate retries by caller and request ID, reject changed requests that reuse an ID, and return existing post metadata without repeating notifications. Deliver deduplicated notifications after commit; notification failures leave committed posts successful and readable.
## Testing
Add integration tests covering concurrent retries across independent handles, reopening persisted boards, subscription routing, board isolation, Unicode reads, invalid recipients, inactive recipients, and notification failures.
GitOrigin-RevId: 0cdf621d19517bf57d527fd729290e08ac99f165
## What changed
Add `codex-agent-message-board-extension` to the Cargo workspace with a Bazel target. Define backend-independent contracts for discussions within a persistent agent tree:
- `AgentMessageBoard` covers channel creation, posting, thread listing, post search, bounded reads, and subscriptions, with documented membership and retry semantics.
- `MessageBoardHost` provides agent resolution, the caller's configured clock, and metadata notifications restricted to active turns.
- Shared request and response types represent channels, posts, threads, subscriptions, and cursor pagination, including derived page counts and continuation indicators.
The crate defines interfaces and records for local or remote backends; storage, tool adapters, and feature registration remain separate.
GitOrigin-RevId: d8734f0226bc0c0d521929e7dd30b414136dcb95
## Why
MCP requests requiring user input previously failed in subagents with guidance to ask the parent agent, blocking browser sign-in, form input, and interactive tool approval in the child thread.
## What changed
Remove the root-only MCP elicitation guard and `allow_user_interaction` plumbing so subagents can surface prompts and wait for responses under the existing approval policy and automatic review rules. Connector authentication can now return retry guidance after acceptance or preserve the original failure when declined.
Keep legacy tool approvals through `request_user_input` restricted to the root thread.
## Testing
Update unit and integration coverage for subagent prompt resolution, form responses, connector authentication acceptance and decline, automatic approval, strict review, and approval-policy updates on reused connections. Update the browser sign-in scenario snapshot to show the subagent continuing after an accepted response.
GitOrigin-RevId: c226fc6dfde724ed22b91dc04dd32bbc15245bee
## Why
The external queue lifecycle test waits through watcher and retry intervals,
including explicit 11-second sleeps.
## What changed
Run the test on Tokio's current-thread runtime and use `advance_queue_poll()`
to pause time, advance it by 11 seconds, and resume it at polling boundaries.
This skips interval waits while keeping the clock advancing during real I/O.
GitOrigin-RevId: 0d1c3f53cc8b79559d6a20b5c9e70b58216e4b4d
## Why
Subagents inherit applied instruction snapshots, so later provider updates do not reach running descendants. Hosts need an explicit way to share current thread instructions across an agent tree.
## What changed
- Add `ThreadInstructionsProvider::share_with_subagents()`, defaulting to `false`. Opted-in descendants refresh instructions at their next model-request boundary.
- Retain shared providers across root unloads and descendant reloads. Let a resumed root replace the provider for surviving descendants, or preserve their last shared instructions when it supplies a non-sharing provider.
- Keep providers scoped to their root tree and preserve snapshot-only instructions for root forks and isolated sessions, including Guardian reviews.
## Testing
Add coverage for child and grandchild instruction updates and clearing, provider replacement after root restart, lazy descendant reloads, default snapshot inheritance, and isolation between roots and Guardian sessions.
GitOrigin-RevId: 44c9fb7fe9ae1f96156bdf3c47ab6c4a81bd65e9
## What changed
- Support an optional cloud provider alongside executor plugins, refreshing its thread-scoped catalog at each regular turn when plugins are enabled.
- Use cloud connector metadata for app attribution without starting cloud-declared MCP servers.
- Scope cached catalogs to authentication and Apps availability. Retain the previous catalog on discovery failure within the same scope, clear stale catalogs on auth changes, and reject results completed under outdated credentials.
- Add a cancellable regular-task startup phase that reconciles MCP before discovery and reapplies contributor state afterward without invalidating resource caches.
## Testing
Add regression coverage for per-turn refresh, empty catalogs, discovery failures, plugin disabling, auth changes during discovery, MCP reconciliation and cancellation, and cloud app attribution alongside executor MCP tools.
GitOrigin-RevId: 8469eb109ea316e21cbc4122c52ad8000caeef03
## What changed
- Move catalog types and the `PluginProvider` listing interface into `codex-core-plugins`, with a concrete `PluginListQuery` carrying thread, turn, and MCP resource context.
- Remove root resolution from `PluginProvider`; keep executor package access in `ExecutorPluginProvider::resolve_bound`, which retains the filesystem used to resolve the package.
- Add shared provider result and error types, and re-export the listing API from `codex-mcp-extension`.
## Testing
Update executor and manifest tests to use `resolve_bound`, and assert that malformed manifest errors preserve the underlying `serde_json::Error` as their source.
GitOrigin-RevId: c6cd5a0269ed3b8ac9b93f306a70821e63e3671e
## What changed
- Rename the extension providers to `PluginMcpProvider` and `PluginAppProvider`, and use app terminology for plugin app declarations.
- Rename the MCP contributor to `PluginContributor` and its installation entry point to `install_plugins`; update the app-server call site and existing tests.
- Move the corresponding modules and tests to plugin-based names, change the contributor ID to `plugin`, and update tracing spans and log messages to match.
GitOrigin-RevId: 7106d2965675265f39e186e57cc334161bdb90d3
## Why
Providers need to serve Codex model metadata independently of their inference endpoint. A custom inference `base_url` alone should not opt API-key sessions into remote catalog discovery.
## What changed
- Add `model_catalog_url` to provider configuration and thread-config serialization. Fetch the full catalog URL with provider authentication, headers, query parameters, and `client_version`, while preserving inference routing.
- Require an explicit catalog URL for API-key discovery with a custom base URL. Keep default OpenAI discovery on the Codex backend, and apply `api_key_model_discovery` gating to provider API keys and cached catalogs.
- Include the catalog URL in cache identity so different catalogs do not share cached metadata.
- Limit explicitly configured catalog responses to 1 MiB, reject redirects, and suppress URL and response diagnostics that could expose credentials.
## Testing
Add coverage for catalog configuration round-trips, query encoding, authentication and header reuse, cache identity and discovery gating, oversized responses, and redirect rejection without credential forwarding. Add an integration test verifying that catalog model metadata and instructions reach conversation requests.
GitOrigin-RevId: 7f6ac5eec257278685e1867a6bcebae6514a365a
## What changed
- Add `PluginCatalog` types for discovery snapshots, warnings, plugin metadata, stable identities, and cloud or executor source locations. Keep MCP server declaration values out of debug output.
- Extend `PluginProvider` with a generic list query, asynchronous catalog listing, and shared error and future types. Provide empty defaults for listing and root resolution so providers can implement their supported operation.
- Add `PluginListQuery` in the MCP extension with thread and turn identifiers and an optional MCP resource client.
GitOrigin-RevId: 0bf2a1713c25d912c41daab788b88729d4871fcf
## What changed
Add an optional `onboardingSkill` summary to `plugin/read` responses and update the generated schemas, TypeScript types, and Python models.
- Resolve local declarations from `extensions["com.openai"].onboardingSkill`, accepting relative paths with or without `./`. Require the resolved path to stay within the plugin root and match a loaded skill.
- Match remote release metadata's `onboarding_skill_name` against the plugin's skills.
- Return the summary only when the plugin and matching visible skill are enabled; remote plugins must also be available. Otherwise, return `null`.
## Testing
Add parameterized local and remote `plugin/read` tests covering matching, missing, and unmatched declarations, disabled plugins and skills, and unavailable remote plugins.
GitOrigin-RevId: 88cabdfddbecba5efba756617da0cb1ff064bdf7
## What changed
Add `model_post_turn_compact_threshold_percent` to trigger compaction after a final response when context usage reaches the configured percentage of the usable window or an existing auto-compaction limit. Accept values from `0` to `100`; omitted or zero disables the feature.
Skip post-turn compaction when input is pending, the turn is cancelled, or token-budget mode is enabled. Disable it for approval reviewers to avoid delaying approval completion, and record a distinct `PostTurn` analytics phase.
Buffer local post-turn summaries until compaction succeeds and require a nonempty assistant summary before replacing history. Log compaction failures without failing the completed turn, while still propagating interruptions and turn aborts.
GitOrigin-RevId: b616994175829bd83b5d7974f95dabb042a39a89
## What changed
Add `ToolLifecycleContributor::on_command_start` with `CommandStartInput` carrying the resolved command, working directory, selected executor's filesystem, and lifecycle context. Await contributors after command hooks and environment resolution so they can prepare the filesystem before `exec_command` runs, including calls from code mode.
Reserve process IDs only after preparation completes so cancelled preparation does not consume an ID. Keep deterministic process IDs from being reused after removal.
## Testing
Add tests for direct and code-mode calls that verify callbacks receive hook-rewritten commands and the executor's working directory, filesystem preparation completes before execution, and interrupted preparation prevents execution without consuming a process ID. Add a regression test for deterministic process ID reuse after removal.
GitOrigin-RevId: d10bcafcc583a6e3e8b5924d004806727e3763bb
## Why
Timeout tests can avoid waiting for real deadlines by advancing Tokio's clock, but automatic advancement can expire requests before they reach the mock server.
## What changed
Pause Tokio time in the stalled-header sampling and model catalog deadline tests. Keep polling until the mock server receives each request, then explicitly advance past the relevant timeout. Add bounded wall-clock waits and fail if a request completes before reaching the server.
Preserve assertions for sampling retry exhaustion, connection permit recovery, and the catalog's `RequestTimeout` error.
GitOrigin-RevId: 252be25d75d73c713a4b8ccac1ff20ad820df556
## Why
Streaming `bio_policy` failures were classified as generic invalid requests, losing their policy-specific classification.
## What changed
- Add `BioPolicy` errors across the API and core protocol, recognizing streaming failures and HTTP 400 responses, including wrapped WebSocket errors.
- Preserve server messages and use a biological-risk fallback when the message is missing or blank.
- Treat bio policy errors as non-retryable in core and guardian handling, and classify them in diagnostics and telemetry.
- Map `BioPolicy` to `other` in the app-server v2 protocol.
## Testing
Add coverage for error classification, message preservation and fallbacks, HTTP and wrapped WebSocket responses, guardian retry decisions, and app-server conversion. Extend the core integration test to verify that bio policy failures emit a typed error and complete the turn after a single request.
GitOrigin-RevId: 78c2647e8fc8f80297cb8a23fff06ab141099632
## Why
`CodexThread` retained the full `SessionConfiguredEvent`, including initial replay messages, and cloned it even for callers that only needed thread or session IDs.
## What changed
Store `ThreadStartupMetadata` without replay history and expose it by reference through `startup_metadata()`. Update callers to read IDs from this metadata. When rejoining a running thread, rebuild the startup response using the supplied resume history for `initial_messages`.
## Testing
Extend the resume test to verify that rejoining reuses the loaded thread, preserves startup metadata, and still returns the original replay messages as a prefix.
GitOrigin-RevId: 9d656063088c28f091d29e5862e4b9d894b7642c
## What changed
Use `EnvironmentAccess` for skill discovery, environment skill loading, and plugin namespace resolution, replacing direct `ExecutorFileSystem` calls with explicit `None` sandbox arguments.
Wrap existing host and executor filesystems with `FileSystemEnvironmentAccessor::unrestricted` to preserve their current access behavior. Update discovery, loading, and namespace tests to use the same adapter.
GitOrigin-RevId: d68168cc0ee19dc303ef4ee726cf1de1a8db81e0
## Why
Asynchronous score publication updated the risk score, authorization, and tool-call coverage separately. Approval checks could therefore read inconsistent evidence when deciding whether to reuse a cached score.
## What changed
Keep Guardian's cached score and observation state under one lock, and use consistent snapshots for approval checks. Publish successful scores together with their authorization and classified tool-call index. Preserve timestamp ordering, fail-closed precedence on timestamp ties, and per-call oversized-action tracking.
## Testing
Add regression coverage for rejected delayed results and timestamp ties. Add a gated integration test showing that a delayed score becomes stale after intervening tool calls, while a sufficiently fresh score permits cached approval.
GitOrigin-RevId: 8df6fafd5e0ee59aa0f78f541eac562efce3d4d0
## Why
Filesystem reads previously required a sandbox whenever writes were restricted, even with full-disk read permission. This made permitted reads depend on sandbox availability.
## What changed
- Select sandboxing independently for reads and writes, allowing full-disk reads directly while keeping restricted operations sandboxed.
- Use the executor's path convention when evaluating full-disk access, including `:slash_tmp` denials.
- Apply read-specific checks to capability discovery and skill resource reads, allowing unrestricted reads on executors without sandboxed discovery support.
## Testing
Add regression tests for direct read APIs, restricted writes and reads, executor-specific permission rules, and capability discovery without sandbox support. Update Windows tests to verify sandbox enforcement through writes.
GitOrigin-RevId: a03844bd1f0ea583bb54326683cddbfdd050119f
## Why
Removing the selected working directory can prevent filesystem sandbox helpers from launching, even when the requested absolute paths remain accessible. Permission rules must stay anchored to the selected directory while those operations continue.
## What changed
- Require a policy `cwd` in `FileSystemSandboxContext` and launch filesystem helpers from the filesystem root while preserving the policy directory and workspace roots.
- Carry explicit `policyContext` in filesystem RPCs, preserving legacy wire fields and resolving omitted directories from older clients at executor ingress.
- Keep permission paths as executor file URIs and validate host compatibility where they are enforced.
- Bind Windows relative denial globs to the policy directory before changing the helper's launch directory, preserving home-relative patterns.
## Testing
Add regression coverage for `apply_patch` after working-directory removal, legacy RPC directory fallbacks, cross-platform permission URI transport, and Windows relative read denials. The patch regression verifies that an allowed file is updated while an explicitly denied file remains unreadable and unchanged.
GitOrigin-RevId: b0f4db722b27cb72ec129fc297c85732afac11f7
## Why
File images contributed zero to history and compaction token estimates and were dropped from Guardian context. This undercounted context usage and omitted image evidence from reviews.
## What changed
- Estimate file images using the fixed resized-image cost, or 10,000 patch tokens for `original` detail because file references do not expose dimensions.
- Charge file images against remote compaction and Guardian request budgets.
- Preserve file images from user messages and tool outputs through Guardian selection and delivery, and deduplicate review images by file ID.
- Apply transcript image count and byte limits to both reference types, counting file ID bytes rather than referenced file contents.
## Testing
Add coverage for file-image estimates, selection limits, delivery, and compaction retention. Extend Guardian tests to verify file-image evidence reaches reviews and uploaded original-detail images trigger reviewer-history compaction.
GitOrigin-RevId: ee024204dcbe16e277fea9347c6a4d7fc120e18d
## What changed
Stop emitting a warning when skill descriptions are shortened to fit the skills context budget. Continue warning when skills are omitted from the model-visible list.
Update the app-server warning test to set `skills.max_context_tokens` to `1_000` and expect the omitted-skills warning. Remove assertions and tests for the description-shortening warning.
GitOrigin-RevId: feac10b3d159d73648a786120d477b7fe4e082d7