Files
felixxia-oai 9c4879f3a5 Preserve complete actions in Guardian approval reviews (#44569)
## Why

Truncating action arguments can leave approval reviewers evaluating incomplete actions. Large actions need complete review input and explicit handling when they exceed the review budget.

## What changed

- Remove action truncation and the fixed synchronous action byte limit. Admit complete actions against the whole-request budget, splitting long text losslessly into bounded transport parts and accounting for their framing.
- Route actions exceeding the asynchronous action budget to synchronous review. Prevent cached scores from covering oversized calls, including expanded approval arguments, while allowing later small actions to recover score reuse.
- Request user approval when optional review exhausts its local input budget. Keep required review and compaction service failures closed to approval, and retire exhausted review sessions.

## Testing

Add coverage for complete large-action delivery, optional user fallback, required-review denial, subsequent review recovery, async overflow through MCP approval routing, and lossless text splitting with budget accounting.

GitOrigin-RevId: 08f06e68a94b2f779480dd6b6cf5bc30b241f6dd
2026-09-10 16:01:02 +00:00
..

User verification cancellation (experimental)

Local UI clients can cancel a native user-verification RPC by sending userVerification/cancel with {requestId} and the experimentalApi opt-in. The result is an empty acknowledgment ({}). This API does not enable desktop verification capability advertisement.

requestId is the original status, enroll, delete, or verify RPC's string or integer ID on the same connection, not the server elicitation ID. Use fresh IDs for each operation and a distinct ID for the cancel RPC. Unknown, finished, unrelated, and other-connection requests are no-ops.

The acknowledgment confirms the cancellation signal without waiting for the OS prompt to close. The original RPC completes independently, with cancelled/interrupted when cancellation prevents completion. Cancellation cannot roll back completed effects. It remains effective while a proof waits for outbound queue capacity, but cannot retract a response already enqueued.

Canceling or resolving an elicitation does not itself stop a separate userVerification/verify RPC. Clients must cancel that RPC separately and discard late proofs after the approval is canceled or resolved. Only one native worker runs per app-server; if an OS call remains active after cancellation or timeout, subsequent local operations return failed/providerError until that worker exits.

Hosted Codex Apps MCP protocol

The host-owned HTTP codex_apps server uses Legacy by default in app-server and standalone Codex. To discover the 2026-07-28 protocol, set codex_apps_mcp_2026_07_28 = true under [features], or send a true runtime override via experimentalFeature/enablement/set. Discovery falls back to Legacy when the server does not support it. Explicit config takes precedence. The dedicated setting does not apply to third-party HTTP or local codex_app stdio servers. The existing mcp_2026_07_28 flag still governs eligible other servers, regardless of whether their names or URLs resemble hosted Apps. App-server does not persist this selection.

Thread removal

thread/archive and thread/delete reject attempts to remove a live internal worker with JSON-RPC error -32600. The worker's owner controls its shutdown. For example, a Guardian reviewer remains available to its parent conversation after a client tries to archive or delete it.

After the owner releases the worker, its saved conversation can be archived or deleted normally. Ordinary client-controlled threads keep their existing behavior.

Amazon Bedrock authentication

If model_providers.amazon-bedrock.aws.credential_export is configured, Bedrock setup and Bedrock login return an error without changing configuration or saved credentials. Remove the exporter configuration before selecting another credential source. aws.credential_export and aws.profile cannot be configured together.

Stored thread attachments

  • thread/attachment/add — add a durable resource reference to a stored thread without loading it. Repeated writes with the same attachment type and identity key return the existing attachment.
  • thread/attachment/list — list attachments for one stored thread in a cursor-paginated request, including a thread that is not loaded.
  • thread/attachment/remove — remove an attachment by its thread, attachment type, and identity key; returns {}.
  • thread/attachment/updated — notification broadcast after an attachment is created or removed; contains the thread, attachment identity, attachment id, and operation.

Example: Manage stored thread attachments

Attachments record the resources currently associated with a thread, independently of conversation history. Clients can add, remove, and list attachments for one stored thread at a time without resuming those threads. Adding or removing an attachment does not create or delete the underlying resource or rewrite history. An attachment is idempotently identified by its thread, attachmentType, and identityKey. For pull requests, clients should reuse the canonical application identity JSON.stringify([canonicalHostname, lowercaseOwner, lowercaseRepository, pullRequestNumber]) so addition and removal agree across surfaces.

{ "method": "thread/attachment/add", "id": 20, "params": {
    "threadId": "thr_123",
    "attachmentType": "pull_request",
    "identityKey": "[\"github.com\",\"openai\",\"codex\",123]",
    "payload": { "url": "https://github.com/openai/codex/pull/123" }
} }
{ "id": 20, "result": {
    "outcome": "created",
    "attachment": {
        "id": "01984de2-8f74-7c91-a3b2-5c5e937cf318",
        "attachmentType": "pull_request",
        "identityKey": "[\"github.com\",\"openai\",\"codex\",123]",
        "payload": { "url": "https://github.com/openai/codex/pull/123" },
        "createdAt": 1750000000
    }
} }

{ "method": "thread/attachment/list", "id": 21, "params": {
    "threadId": "thr_123",
    "limit": 100
} }
{ "id": 21, "result": {
    "data": [{
        "id": "01984de2-8f74-7c91-a3b2-5c5e937cf318",
        "attachmentType": "pull_request",
        "identityKey": "[\"github.com\",\"openai\",\"codex\",123]",
        "payload": { "url": "https://github.com/openai/codex/pull/123" },
        "createdAt": 1750000000
    }],
    "nextCursor": null
} }

{ "method": "thread/attachment/remove", "id": 22, "params": {
    "threadId": "thr_123",
    "attachmentType": "pull_request",
    "identityKey": "[\"github.com\",\"openai\",\"codex\",123]"
} }
{ "id": 22, "result": {} }

{ "method": "thread/attachment/updated", "params": {
    "threadId": "thr_123",
    "attachmentType": "pull_request",
    "identityKey": "[\"github.com\",\"openai\",\"codex\",123]",
    "attachmentId": "01984de2-8f74-7c91-a3b2-5c5e937cf318",
    "operation": "deleted"
} }

thread/attachment/list accepts one threadId and returns at most 100 attachments per page, ordered by creation time and attachment id. Continue with nextCursor and the same threadId until the cursor is null. Each thread can retain up to 100 attachments. Removing an attachment frees a slot for a new attachment.

Attachment creation and deletion requests using the same thread ID are serialized across connections. The requesting client receives its response before the compact update is broadcast, and duplicate creates or absent deletes do not emit updates. Deleting the owning thread removes its attachments under the same lifecycle exclusion; queued attachment mutations then report that the thread was not found.