Commit Graph
191 Commits
Author SHA1 Message Date
Nick Steele af0d68a236 Restrict enterprise MCP auth and fail closed on config refresh (#49260)
## Why

Configuration reloads must honor current managed restrictions without granting new enterprise MCP authority to existing sessions or overwriting newer configuration with stale snapshots.

## What changed

- Allow enterprise managed authentication only for configured MCP servers. Remove plugin `ema_auth` overlays from the schema and disable servers that still use them.
- Refresh ordinary MCP settings while preserving session settings and initially admitted enterprise registrations. Disable enterprise MCP when its registration changes, policy revokes access, or configuration loading or resolution fails; require a new session to restore enterprise authority.
- Publish refreshes only when their captured configuration is still current, with bounded retries in app-server reloads. Preserve updated managed restrictions even when a refresh is rejected.
- Finish processing other thread refreshes before `config/mcpServer/reload` reports a rejection, and document that an error can accompany partially applied changes.

## Testing

Add regression coverage for stale refreshes, bounded retries, managed-policy revocation, persistent enterprise disablement, ordinary MCP transport changes, and rejection of plugin enterprise authentication. Verify that denied enterprise servers receive no requests.

GitOrigin-RevId: 34429cd339c1ec152a2ee8697cb29f0cff5d9e5f
2026-09-29 13:08:37 +00:00
vkg-oai 3f4668da20 Add history-aware prewarming for idle threads (#48812)
## What changed

- Add `CodexThread::prewarm_with_history()` to prepare a WebSocket response with existing conversation history and executed-tool metadata using `generate: false`. The next turn can reuse the prepared response when its prompt extends that history and request settings match.
- Keep startup prewarming and `prewarm()` on the existing empty-input path, and skip preparation when the cached WebSocket is ready.
- Label prewarm telemetry by input mode and WebSocket continuation metrics with `after_prewarm`.
- Rename `persistent_mode_enabled` to `persistent_execution_enabled` without changing its behavior.

## Testing

Extend WebSocket coverage to check history preservation during reconnect prewarming, reuse of the prepared response on the next turn, and omission of `previous_response_id` for a non-prefix prompt.

GitOrigin-RevId: c7731541b11b2e6668027a47f37f696213268c66
2026-09-27 23:21:25 +00:00
victor-openai ea64727556 Add single-server MCP status discovery with thread connection reuse (#48783)
## Why

Inspecting one MCP server should not require full-inventory discovery or a separate connection when a thread already has one.

## What changed

- Add optional `serverName` to `mcpServerStatus/list` and update generated schemas and bindings.
- With `threadId`, apply any pending runtime refresh and reuse the thread's current connection and tool catalog, waiting only for the selected server during discovery.
- Without `threadId`, create a discovery connection for only the selected server. Unknown names return an empty page; omitting `serverName` preserves full-inventory discovery.

## Testing

Add a regression test covering both status detail modes, checking that tool metadata is preserved and that status reads do not repeat `initialize` or `tools/list` requests.

GitOrigin-RevId: 1b361b67a993ab45cae493e88c146f50cfaf753a
2026-09-27 21:07:54 +00:00
Ankush Gupta 88235f881d Retain confirmed Code Mode messages for Guardian reviews (#48725)
## Why

Guardian needs the assistant's delivered question to interpret a user's reply. Messages sent through nested Code Mode tools must remain available as review context, and approvals based on earlier context must become stale when a new delivery is confirmed. Assistant messages do not themselves grant authorization.

## What changed

- Capture successful hosted User Messaging sends after input rewriting and before result callbacks or post-tool hooks.
- Retain bounded delivery text in acceptance order, persist it through cancellation and shutdown, and preserve it across compaction and resume with an older-client-compatible rollout encoding.
- Track assistant review context separately from user authorization, invalidating pending and cached approvals for both local and worker reviews when that context changes.
- Associate retained deliveries with the correct instruction or communication boundary during rollback.

## Testing

Add coverage for nested messaging review context, fast replies and communication ordering, shutdown persistence, stale local and worker approvals, rollout compatibility, and rollback retention.

GitOrigin-RevId: 1bc1ec9e8947560b99f4b39a42ddb9f2099f519b
2026-09-27 15:03:38 +00:00
sayan-oai 97da50c1aa Expose current environment selections for a running turn (#47970)
## Why

`active_turn_environment_selections()` returns the selections captured at turn start, so it does not reflect later environment settings updates.

## What changed

Add `CodexThread::current_turn_environment_selections(expected_turn_id)` to read the running turn's current selections, including environments that are still starting or have failed. Return `None` when the requested turn is no longer active or has been cancelled.

## Testing

Add a regression test covering selection updates, mismatched turn IDs, and completed turns, while verifying that the initial selection snapshot remains unchanged.

GitOrigin-RevId: bb526a686d549209142150ffde99ad1444add205
2026-09-25 00:07:35 +00:00
sayan-oai fbd0c0d96c Add direct replies for thread settings updates (#47937)
## Why

Callers need to await acceptance or rejection of thread settings without consuming the thread event stream. Acceptance must precede event delivery because the caller may hold a lock needed by the event consumer.

## What changed

- Add `CodexThread::update_thread_settings` and re-export `ThreadSettingsOverrides` from `core-api`.
- Add an optional reply channel to `Op::ThreadSettings`. Return validation failures as `InvalidRequest` through that channel, retaining error events for callers without a reply channel.
- Reply to successful updates before emitting `ThreadSettingsApplied`, while holding the settings persistence lock through notification.

## Testing

Extend settings constraint coverage to direct replies, including rejection without an error event and successful notification. Verify that acceptance and continuation invalidation precede blocked event delivery, while checkpointing waits for notification.

GitOrigin-RevId: e09b0d3cc4b6750709c173371632f19619e5c250
2026-09-24 20:59:51 +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
felixxia-oai 1cd253c987 Preserve explicit user goal updates in Guardian authorization (#47811)
## Why

Explicit user goal edits can restrict permitted actions, such as “Inspect only; do not publish.” Guardian needs these edits as authorization evidence even though they are recorded as contextual messages.

## What changed

- Add `UserGoalUpdate` and a recording API for objective, status, and clear updates without scheduling a model response.
- Use host annotations to retain goal updates in Guardian review history and root authorization evidence, and invalidate cached authorization when updates are recorded.
- Omit oversized objectives whole and mark their evidence incomplete so truncation cannot turn a restriction into a grant.
- Keep item injection from updating shared model and multi-agent metadata.

## Testing

Extend authorization, retained-context, and review snapshot tests to cover goal-edit cache invalidation, root goal visibility from child threads, and restrictive goals reaching Guardian alongside managed policies.

GitOrigin-RevId: 17b99d9fa8c1620840d6f408d79b405a78a778f8
2026-09-24 10:46:46 +00:00
vkg-oai d838c2346d Allow idle threads to prewarm and repair WebSocket connections (#47701)
## Why

A previously used WebSocket can close while a thread is idle. Hosts need a way to prepare the connection before the next turn without repeating warmup on a healthy connection.

## What changed

- Expose `CodexThread::prewarm()` using the existing startup warmup and next-turn handoff.
- Reuse healthy connections and pending warmups, retry failed warmups, and repair closed connections. Treat a finished WebSocket reader task as a closed connection.
- Skip scheduling during an active turn or shutdown, and stop warmup admission before shutdown takes the pending task.
- Expose `active_turn_environment_selections()` so hosts can inspect the environments captured by the active turn, including those still starting or failed, when authorizing steering.

## Testing

Add regression coverage for repeated idle prewarm calls, healthy connection reuse with preserved response continuation, reconnection with `generate: false`, and warmup rejection after shutdown. Update delayed MCP discovery coverage to verify prewarm repairs an eagerly closed socket and the first turn reuses it.

GitOrigin-RevId: aa164b91a399de2375eda3bf28397725439fce93
2026-09-24 00:37:56 +00:00
felixxia-oai 1d516d8b3d Remove legacy Guardian authorization evidence paths (#47688)
## What changed

Use retained root context for subagent authorization reviews, removing the separate legacy history path. Remove the runtime `request_user_input` answer buffer and its response counter; authorization versions now track the user-message revision and retained-context completeness.

## Testing

Update authorization and input-handler tests to exercise retained context, and add coverage for the `user_messaging` connector in subagent reviews.

GitOrigin-RevId: 00ad151cf71b843af0e82ae90cbcf559d0c65f89
2026-09-23 22:50:23 +00:00
jif 27969c0ae9 Route session agent operations through AgentControl (#47520)
## What changed

- Store `Arc<dyn AgentControl>` in session services and route agent tools, turn admission, usage accounting, completion notifications, and shared settings through the trait.
- Add `AgentControlInit` so delegated and guardian sessions inherit the parent's controller and local runtime.
- Move local registry and context helpers to `LocalAgentRuntime`, keep resume, close, inspection, and status subscriptions on the local controller, and simplify synchronous and infallible trait methods.

GitOrigin-RevId: ad3f213eb483ac524bde56d769f20a78f20989a0
2026-09-23 09:39:30 +00:00
sayan-oai 370cd7cba8 Allow environment selection updates during an active turn (#47435)
## What changed

- Add `environments` to `TurnSettingsUpdate` to replace the selection for subsequent steps without changing future turns.
- Capture model settings and environments together so combined updates apply or reject atomically, while existing steps retain their captured selection.
- Validate environment IDs, working directories, configuration ownership, and permission requirements against the running turn's selections.
- Preserve executor startup behavior when switching environments and use the step's local working directory for tool hooks.

## Testing

Add coverage for workspace switching and restoration on the next turn, atomic model and environment updates, permission validation, executor connection waits, and replacement of pending environment selections.

GitOrigin-RevId: 02b5c57a78fd594b2aed84fc09d9e99eb97be28c
2026-09-23 03:12:33 +00:00
jif acc20df49f Prevent V2 agent eviction from racing with queued messages (#47240)
## Why

Accepted inter-agent messages can still be waiting in the submission queue when a worker appears idle. Evicting that worker can lose the queued work, while cancelling an eviction caller can leave shutdown unfinished and allow delivery to a closing runtime.

## What changed

- Pin V2 recipients until queued submissions are handled or dropped, and verify that delivery targets the registered runtime.
- Move `Submission` into core so it can carry the residency guard through queue handoffs.
- Give eviction exclusive access to each runtime and keep it counted against capacity until removal. Run teardown in a separate task so it completes even if its caller is cancelled, and remove registry and residency entries together.

## Testing

Add a regression test covering queued follow-up delivery, eviction refusal while mail is pending, cancelled eviction completing teardown, rejection of late delivery, and capacity reuse after removal.

GitOrigin-RevId: d6de3d68cb6b911942e9ddfc05c65b3741b796b2
2026-09-22 09:50:48 +00:00
dermanyang-oai b781733f95 Separate thread preparation from execution persistence (#47199)
## Why

Injecting context before the first turn currently forces a full flush. Stores need a preparation checkpoint that can leave disposable context in memory, while local storage must keep prepared context durable before the first user input.

## What changed

- Add `PersistContext::ThreadPreparation` and `CodexThread::checkpoint_preparation()`, and use the checkpoint in `inject_response_items()`.
- Allow stores to defer rollout-derived metadata writes through `record_thread_metadata()`, including during preparation and execution checkpoints. Keep standard metadata updates synchronous.
- Flush local storage at preparation checkpoints so injected context survives restart.

## Testing

Add tests showing that preparation and first sampling can proceed without waiting for durable metadata. Cover prepared context in first and follow-up requests, plus durability before first input and restoration after restart, in both legacy and paginated history modes.

GitOrigin-RevId: 74f6bb1a5f8d47192364b8bba6afd703a3b7d688
2026-09-22 05:53:29 +00:00
sayan-oai cd2f9ca692 Fix active-turn environment selection lookup (#46557)
Read `initial_environments` in `active_turn_environment_selections` to
return the environment selections captured at turn start.

GitOrigin-RevId: 445b52508733ef971eb6d2d7eea2b2f019542d5f
2026-09-19 01:27:48 +00:00
sayan-oai c7828dd010 Keep step settings and approval environments consistent (#46556)
## Why

Background processes can outlive their launching turn. Their approval reviews need the originating environment's filesystem restrictions, even when the active turn uses a different environment. Remote restrictions must also be resolved using executor paths rather than the local filesystem.

## What changed

- Capture settings and environment selections together in `StepInputs`. Preserve the captured selection during active model updates while allowing environment startup to finish.
- Carry environment IDs into Guardian network and `execve` requests, and use the owning process's environment with current review settings. Refresh environment readiness for network requests that fall back to the active turn.
- Resolve remote denied paths and globs using the executor's policy context. Decline automatic approval when the request's environment is unavailable or an explicitly denied temporary directory cannot be resolved.

## Testing

Add regression coverage for active model updates retaining their environment while the next turn adopts a new selection, background approvals using their owning environment, newly ready network environments, and remote denied paths and globs, including Windows paths and missing temporary-directory metadata.

GitOrigin-RevId: b620d4b030c597a4f430fe0500864fa5469db3d4
2026-09-19 01:27:26 +00:00
viyatb-oai 328feb0c29 Track executor registrations across connection refresh and recovery (#46555)
## Why

An executor can renew its registration while retaining its Noise identity. Connection refresh must distinguish registrations even when their keys match, and a stale registry lookup must not retire a session that recovery has already renewed.

## What changed

- Track the installed session's registration and expose it through `Environment::cached_executor_registration_id()` without connecting. Publish registration changes only when the new connection is installed.
- Require both registration and executor key to match before refresh reuses a session. Retry stale lookups and prevent recovery from installing a connection after retirement.
- Pin session recovery to the original Noise key while allowing registration renewal to preserve the session and running processes.
- Expose `CodexThread::active_turn_environment_selections()` so hosts can authorize steering against the active turn's selections, including starting and failed environments, independently of later settings updates.

## Testing

Add regression coverage for registration replacement, renewal with a running process, stale refresh lookups, missing sessions, and rejection of changed Noise keys. Extend active-turn tests to check selection snapshots across settings updates, deferred startup, and turn completion.

GitOrigin-RevId: 4395bc6c57f137691887e6585f52dcc5b958101c
2026-09-19 01:27:02 +00:00
jif c026e7a622 Expose a backend-independent agent control contract (#46547)
## What changed

Add a public, object-safe `AgentControl` trait and request/response types for coordinating an agent tree independently of where its threads run. Define contracts for lifecycle operations, message delivery, status observation, execution admission, usage accounting, shared configuration, and guardian evidence.

Move shared agent types out of the local controller and export them from `codex-core`. Let `AgentExecutionGuard` own a backend-provided reservation while preserving the local limiter's release-on-drop behavior. Include `root_thread_id` in `GuardianRootSnapshot` to identify the source of authorization evidence.

## Testing

Add tests for reservation release when a guard is dropped or a turn is cancelled, and extend the guardian authorization test to assert the root thread identity. Check trait object safety at compile time.

GitOrigin-RevId: 9385c9fbfd189f08429539fd89061ef8c9efe0d9
2026-09-19 01:03:55 +00:00
Henry Levy 7e0463b568 Skip skill discovery when injecting items into initialized threads (#46546)
## Why

Recording response items in an initialized thread builds a turn context without starting a turn. Running host skill discovery for that context is unnecessary.

## What changed

Use a dedicated context build mode that skips host skill discovery for history injection. Preserve full discovery for initial context creation, startup prewarming, and execution. If compaction clears the reference context during preparation, rebuild a full context before initializing history.

## Testing

Add a regression test verifying that initial injection discovers skills, subsequent injection records items without discovery, and a real turn still discovers skills and sends the selected skill body and both injected messages to the model.

GitOrigin-RevId: 4a64e04eb0f21698f9b47160bfcfe5b6d6a68554
2026-09-19 01:03:32 +00:00
sayan-oai c775dd3c33 Defer environment selection changes until the next turn (#46310)
## Why

Updating environment selections while a turn is running must not redirect its tools or prevent its pending environment setup from completing.

## What changed

- Store future environment selections separately from active environments, and activate them when preparing new work with no task running.
- Keep turn contexts and MCP workspace roots tied to the active environment snapshot. Report saved selections through thread settings and `environment_selections()`.
- Route environment configuration and failure callbacks to matching active or future selections so each can finish setup independently.
- Stop the running task before manual compaction adopts the saved environments.

## Testing

Add regression tests that preserve a running task's working directory and workspace roots, then adopt the saved selection for the next task. Add remote environment coverage showing that future setup can complete while the active turn waits, with each turn receiving its own capability roots.

GitOrigin-RevId: 09a6b90131d2ab2441ce2fe9b0368a3668889f31
2026-09-17 21:47:23 +00:00
Charlie Marsh 17baabd01b Separate thread startup metadata from replay history (#46294)
## 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
2026-09-17 19:55:20 +00:00
Sean Huang 83dc7d11e8 Preserve executor path URIs in permission profile workspace roots (#45863)
## Why

Executor profile roots can use path conventions that are not native to the current host. Converting them to host paths during configuration or turn reconstruction can reject or drop those roots, while case-insensitive comparison can hide Windows path spelling changes.

## What changed

- Store profile roots as URI-backed `ProfileWorkspaceRoot` values throughout permission snapshots and thread settings, preserving spelling in equality and deduplication.
- Keep effective workspace roots as `PathUri` values for permission materialization and status summaries. Convert Windows sandbox root hints to native paths only at native Windows sandbox boundaries, rejecting incompatible roots.
- Omit the legacy rollout `workspace_roots` field when profile roots cannot be represented as host paths, retaining the compiled permission profile.

## Testing

Add regression coverage for Windows and UNC root spelling changes, settings restoration and turn recording with foreign roots, executor-root status display, and backend-specific Windows root conversion.

GitOrigin-RevId: 903c068fd74959bdd10e7cb1141aa42b953a59a4
2026-09-16 04:23:46 +00:00
Eric Traut f2b5b81f39 Continue interrupted work after managed daemon restarts (#45820)
## Why

Daemon recovery reloads threads but leaves interrupted work unfinished. Resume eligible work automatically from the saved conversation, even without a connected client.

## What changed

- Attempt one new continuation turn immediately after restoration, including in Plan mode. Mark the old turn interrupted and supply recovery context without creating a user message or granting new authorization.
- Require an idle thread, matching permissions, and the same single local environment configured by the thread. Skip completed, aborted, or superseded work and snapshots without environment identity.
- Add `continue_turn_if_idle` with an atomic previous-turn check so newer tasks or standalone settings changes invalidate pending continuation.
- Preserve the output schema, service tier, and root turn ID, and emit a “Resuming interrupted work” warning when continuation starts.

## Testing

Add daemon restart coverage for continuation without a client, Plan mode, permission and environment mismatches, and legacy snapshots. Add core coverage for preserved continuation metadata, absence of user-message events, rejection of superseded continuations, and exclusion of remote execution from recovery snapshots.

GitOrigin-RevId: 2b290b75d9399fc58258bcda2e85c74e9b5b3b09
2026-09-16 00:54:58 +00:00
Eric Traut 4d2807023a Record interrupted turns in managed daemon recovery snapshots (#45807)
## Why

Managed daemon recovery snapshots previously saved only loaded thread IDs, without identifying active turns or preserving their turn-specific options.

## What changed

- Capture regular, uncanceled turns after their input is recorded, saving the turn ID, output schema, service tier, and cyber access program alongside persisted thread IDs.
- Store interruption metadata atomically in the existing candidate array format so older servers can still read thread candidates.
- Begin snapshotting once admitted operations drain, while turns may still be running. Run snapshot collection and thread listener attachment independently of the event loop to keep forced shutdown responsive.

## Testing

Add coverage for running, completed, canceled, and compacting turns; recovery readiness for automatic and user turns; admitted resumes during shutdown; forced shutdown with a blocked rollout writer and child listener attachment; and legacy candidate-array compatibility.

GitOrigin-RevId: ed46342c3a5c71b09c48fa9acece2f15ae748e2f
2026-09-15 23:31:44 +00:00
jif 18d7ace221 Move Guardian reviewer lifecycle into the extension (#45537)
## Why

Guardian reviews must stop when their parent shuts down or their history is reset. Shutdown must also finish reviewer cleanup before closing the parent's persistent history, including when a review is waiting to retry after a rate limit.

## What changed

- Let the Guardian extension own reviewer startup, prewarming, and shutdown through `ThreadManager`, tracking and joining outstanding work during teardown.
- Cancel reviews on history reset or parent shutdown and reject decisions returned after cancellation, including cached extension decisions.
- Keep background prewarm previews from overwriting the active turn's model metadata.

## Testing

Extend regression coverage to verify reviewer cleanup after parent shutdown, prompt shutdown during a 60-second Guardian retry with the network request denied, and preservation of active model review requirements during prewarming.

GitOrigin-RevId: 05efc369b9a1642a10365eac8a09da77f3f6e28c
2026-09-14 22:58:51 +00:00
Matthew Zeng c62d191c4c Expose disabled plugin settings in the app-server API (#44905)
## What changed

- Accept `disabledPluginIds` in `thread/settings/update` and `turn/start`. A supplied list replaces the saved selection; omission or `null` preserves it, and `[]` clears it.
- Return the selection in thread start, resume, and fork responses and `thread/settings/updated` notifications. Update generated schemas and client types.
- Restore disabled plugin IDs from the history retained at the requested fork boundary, preserving explicit overrides.

The selection persists across resume but does not yet filter plugin capabilities.

## Testing

Add coverage for replacing, preserving, and clearing selections without inference; turn-start notifications; resume; and fork boundaries across legacy and paginated history, with loaded and restarted parents. Add a core regression test for history restoration and explicit clearing.

GitOrigin-RevId: 654a8c2a0527228d422c0dd4919228447e2663db
2026-09-11 20:27:37 +00:00
priyanshusingh-de 60825b4988 Honor thread analytics opt-outs when using shared clients (#44646)
## Why

An enabled shared analytics client could override a thread's explicit opt-out.
Delegated threads also emitted initialization events through the parent's client,
bypassing the child's analytics setting.

## What changed

- Use a disabled analytics client when `config.analytics_enabled` is `Some(false)`,
  without disabling analytics for sibling threads or overriding a disabled host client.
- Emit delegated thread initialization events through the child's analytics client.
- Expose the effective analytics state through `CodexThread::analytics_enabled()`.

## Testing

Add regression tests for explicit and unset thread settings with enabled, disabled,
and absent shared clients, plus delegated child opt-outs with an enabled parent.
Update compaction and rollout-budget rollback tests to wait for thread idle after
turn completion and fail immediately on rollback errors.

GitOrigin-RevId: 547852909af1a6822b95c0bcd2336b0d6bc7aad1
2026-09-10 21:30:56 +00:00
Matthew Zeng b5544d5732 Persist disabled plugin IDs in thread settings (#44332)
## What changed

- Add `disabled_plugin_ids` to thread startup options, settings overrides, snapshots, and persisted turn contexts. Omitted overrides preserve the current list; an empty list clears it.
- Restore the selection on resume and capture it before truncating history for a fork. Prefer the owning thread's latest settings snapshot, falling back only to the latest turn context so stale history cannot resurrect an older selection.
- Freeze the selection at turn admission and retain compatibility with histories that lack the new fields.

## Testing

Add coverage for owned settings, explicit clears, latest-turn fallback, and legacy snapshots. Extend settings tests to cover plugin selection during runtime restoration and compaction, and verify initial turn persistence without extra settings checkpoints in both history modes.

GitOrigin-RevId: 75ffbff5763cd93cc5ac69d73b08b237f59bc009
2026-09-09 23:23:59 +00:00
jif 2617ed2e1c Move synchronous Guardian orchestration into the reviewer extension (#44252)
## What changed

Move the synchronous review loop, outcome mapping, deadline helpers, and session pool into `codex-guardian-reviewer`. Core supplies adapters for evidence capture, authorization checks, session creation, and event publication through the new host interfaces.

Have `guardian-v2` initialize the reviewer pool and host separately, with the pool managing prewarming, session reuse, concurrent forks, invalidation, and shutdown.

## Testing

Extend the app-server reviewer lifecycle test to cover interrupted concurrent reviews as well as completed reviews, including resuming a reviewer after parent shutdown. Adapt core reviewer tests to use the pool and factory interfaces.

GitOrigin-RevId: 2d69bd20c169b20534764b98cbdb63f38564a530
2026-09-09 17:59:10 +00:00
Steve Coffey 78932f4493 Expose the queued event count on CodexThread (#43918)
Add `CodexThread::queued_event_count()` to support a finite event drain
before transferring the receiver. Callers must remain the sole event reader
until they consume the snapshot count, leaving later events for the next reader.

GitOrigin-RevId: 55f9dd1cf8ebd396fdb60a1dc3d1428ed28cc2d2
2026-09-08 21:26:22 +00:00
rhan-oai 6515a72db7 Preserve runtime workspace roots across thread resume (#43848)
## Why

Resuming a thread should retain its selected workspace folders, including additional roots and explicit empty selections. Resume overrides also need to survive a subsequent resume when no turn has run.

## What changed

- Persist `runtime_workspace_roots` in startup metadata and thread settings snapshots, separately from explicit environment selections and permission-profile roots.
- Restore roots from the latest snapshot owned by the resumed thread, falling back to owned startup metadata only when no snapshot exists. Honor explicit `runtimeWorkspaceRoots` overrides, retarget the old `cwd` root when `cwd` changes, deduplicate roots, and validate restored paths for the current host.
- Checkpoint effective settings on resume and restored settings after revert. Reload resume configuration if saved workspace roots change during loading.
- Normalize Windows rollout path spellings when matching thread search results, preserving selection of the correct rollout after revert, including compressed rollouts.

## Testing

Add regression coverage for workspace restoration, empty and explicit overrides, foreign paths, compaction and revert, resume checkpoints without recency changes, concurrent settings persistence, and rollout search path matching.

GitOrigin-RevId: d98d9d34dd63934d441120916c61c12b69e7f062
2026-09-08 16:24:38 +00:00
jif 98a5cb46b1 Manage synchronous Guardian reviewers through the thread manager (#43570)
## What changed

- Store the shared `GuardianReviewSessionManager` in thread extension data and let the Guardian extension spawn and fork reviewers through `ThreadManager`, independently of async scorer startup.
- Preserve reviewer reuse, concurrent forks, cancellation, inherited environments, and user instructions. Gate managed reviewer startup on parent registration and remove terminated reviewers from the manager.
- Retain the `guardian` subagent identity in saved conversations. Reject resume of live Guardian reviewers and reject client archive or delete of live owner-managed workers with JSON-RPC error `-32600`; allow normal access after the owner releases them.
- Keep standalone reviewer support for inline delegates and remove duplicated extension prompt and configuration code.

## Testing

Add app-server tests covering reviewer reuse and concurrent forks, inherited instructions and prompt cache keys, live resume and removal rejection, saved reviewer discovery and resume after parent shutdown, and strict Guardian assessment inside an inline review.

GitOrigin-RevId: 4f9893c1ade151eacb4c11ffeae3d9e9ec019187
2026-09-07 19:43:10 +00:00
Alex Daley 32351a7b1a Keep refreshed MCP tool catalogs with their clients (#43031)
## Why

Refreshed Apps catalogs need to survive connection reuse. Catalog revisions scoped to the connection set can lose refreshed tools during reconciliation and invalidate prepared calls for unrelated servers.

## What changed

- Store tools, revisions, and refresh coordination on each MCP client, and key cached bindings by client identity and revision.
- Preserve existing binding snapshots while rejecting stale calls before preparation. Wait for active calls to finish before publishing a refreshed catalog.
- Add `CodexThread::refresh_codex_apps_tools` to reconcile the runtime and return the refreshed client's raw Apps inventory alongside tool names eligible under that runtime's generic MCP policy. Keep hidden and disabled tools in the inventory for callers to apply app-specific policy.

## Testing

Add regression coverage for refreshed catalogs surviving client reuse, unrelated calls remaining valid, binding cache invalidation, and refresh snapshots retaining the client's own inventory when another client wins the shared-cache race. Update stale-call and preparation tests to use client-owned catalogs.

GitOrigin-RevId: f2308c81f7474eb31f3380c091c977030123cda2
2026-09-05 15:04:46 +00:00
felixxia-oai 87628df77a Preserve root authorization context in Guardian reviews (#42832)
## Why

Guardian reviews for delegated workers need the current root instructions and verified answers even after the parent context is compacted. Approvals must also become stale when that root authorization changes.

## What changed

- Build bounded root review evidence from retained context, preserving source order and answer scope while prioritizing user instructions over optional assistant context.
- Recover retained instructions from Guardian history after compaction and mark authorization incomplete when required instructions or answers are unavailable.
- Version root authorization in synchronous and reusable review sessions so an allow result is cancelled when its evidence changes.
- Strip parent-only Guardian approvals when forking worker history in retained-context mode.

## Testing

- Cover retained and legacy context modes, oversized evidence, message limits, parent compaction, and authorization changes during review.

GitOrigin-RevId: 658219b7cee08f2752adcea9966268fd21727976
2026-09-04 19:19:04 +00:00
felixxia-oai ad8ee16a5f Require Guardian review for incompatible compaction checkpoints (#42588)
## Why

Guardian can reuse an opaque parent compaction only when the checkpoint's
recorded producer hash matches the scoring model. Missing or incompatible
provenance must not allow an asynchronous score or cached approval to omit
compacted context.

## What changed

- Record the producing model's compatibility hash on compaction history items
  and expose the latest checkpoint hash through conversation snapshots.
- In thread-owned context mode, fail closed and require synchronous review when
  checkpoint reuse is enabled but the latest checkpoint is incompatible or has
  unknown provenance.
- Reject incompatible checkpoints in the sampler while preserving the legacy
  context behavior.

## Testing

Add coverage for local, remote, resumed, compacted, and rolled-back histories,
including matching, mismatched, missing, and empty compatibility hashes.

GitOrigin-RevId: 1ce959cb276edc602fd7dfa442133c7fe5e53857
2026-09-03 17:48:15 +00:00
felixxia-oai 1d74c3ba1e Persist verified user answers in Guardian thread context (#42579)
## Why

Guardian authorization reviews need host-verified `request_user_input` answers to
remain aligned with thread history across compaction, resume, and rollback.

## What changed

- Record verified question-and-answer pairs in retained thread context when
  `GuardianThreadContext` is enabled, and source both local and delegated Guardian
  review evidence from that context.
- Preserve complete answer records within the evidence budget. Mark authorization
  context incomplete when records are unavailable or oversized, and defer cached
  fast approvals in that case.
- Keep the existing runtime-only answer path for threads that do not enable the
  thread-owned context.

## Testing

- Cover answer retention through compaction and resume, removal after rollback,
  source-call eviction, oversized answers, delegated review evidence, and legacy
  behavior.

GitOrigin-RevId: 01f6f4541515434a0d00fdde318ff59f2f8bd2eb
2026-09-03 16:41:11 +00:00
jif a0dcfe2ada Skip Guardian scoring in User approval mode (#42256)
## What changed

- Skip Guardian prewarming and asynchronous scoring when `approvalsReviewer` is
  `"user"`, including when the reviewer changes during an active turn.
- Automatically accept ordinary `node_repl.js` execution confirmations in this
  mode while continuing to surface sensitive-action checks and requests for user
  input.
- Cover transitions between User approval, automatic review, and Full Access in
  the app-server integration tests.

GitOrigin-RevId: 599c8ebb672728b9bf3d64c34377ddec230325f8
2026-09-02 10:32:22 +00:00
jif e576993911 Skip Guardian reviews in Full Access (#42147)
## Why

Full Access already combines `approvalPolicy: "never"` with unrestricted
permissions, so confirmation-only actions do not require a model review.

## What changed

- Detect Full Access consistently across the thread and every selected
  environment. Pending, failed, or restricted environments are not treated as
  Full Access.
- Approve confirmation-only Guardian and MCP requests without synchronous
  review, sampler prewarming, or background scoring. Cancellation, explicit
  denials, and forms that require user input keep their existing behavior.
- Re-evaluate the active permission state on each turn so an existing thread
  can enter or leave Full Access safely.

## Testing

Added coverage for switching approval modes, strict sensitive MCP
confirmations, failed and pending environments, and suppression of Guardian
requests and background-scoring connections.

GitOrigin-RevId: 089ab4296dde473b8e33ab8324be79c5446c46f6
2026-09-01 22:16:54 +00:00
felixxia-oai 2350823caa Unify Guardian context section collection (#42076)
## What changed

- Add typed context sections for root-conversation evidence, trusted user answers, and conversation transcripts to `codex-guardian-context`.
- Use the shared section registry when building core Guardian prompts and asynchronous Guardian V2 scoring context.
- Preserve source-role labeling while delivering authorization evidence as user-role context, and fail closed when context collection fails.

## Testing

- Cover shared section ordering and role preservation for synchronous and asynchronous targets.
- Verify trusted user answers appear exactly once as user-role input in Guardian V2 approval flows.

GitOrigin-RevId: 1d5d793ffbf166077411a66e85e039596907fb7e
2026-09-01 15:22:21 +00:00
Owen Lin 5f79a92e39 Persist response token usage in rollout history (#41912)
## Why

Resumed threads need to continue per-turn and per-thread token totals without scanning arbitrarily far beyond the latest compaction checkpoint.

## What changed

- Add durable `TokenUsageRecord` rollout items with response, turn, thread, session, and root-turn attribution.
- Restore accumulated usage on resume and snapshot the latest record plus the compaction response ID in compaction checkpoints.
- Preserve root-turn lineage in persisted turn context, while ensuring forked child threads start with their own usage totals.

## Testing

- Cover usage accumulation across multiple responses and resumed turns.
- Cover local and remote compaction checkpoints, invalid remote compaction output, rollout reconstruction, and fork isolation.

GitOrigin-RevId: ef9e0c4a9102a08a2c382be4cdac68c84353c90a
2026-08-31 21:15:38 +00:00
jif 0a12b855a0 Preserve Guardian authorization across history compaction (#41660)
## Why

Compaction and host-injected context can rewrite the model-visible conversation
without changing what the user authorized. Treating those updates as authorization
changes prevents Guardian from reusing an otherwise valid review.

## What changed

- Track a host-owned user-message revision separately from the conversation history
  generation.
- Advance the revision for genuine user messages and history resets, while preserving
  it across compaction and internal context injection.
- Use message content-kind metadata to distinguish host context from user input,
  conservatively treating unknown or incomplete metadata as user authorization.

## Testing

Added coverage that cached Guardian authorization survives compaction and internal
context, but is invalidated by user input and rollback.

GitOrigin-RevId: c7960fa182d1686042c23764d2abc58acbc4b882
2026-08-30 11:56:24 +00:00
Eric Traut 4210c08def Preserve turn lineage across goal continuations (#41562)
## Why

Automatic goal continuations should remain attributable to the turn that created the goal. External input, hook context, or goal edits can make that attribution ambiguous and must not leave stale lineage metadata behind.

## What changed

- Carry the trusted root and previous parent turn through successive automatic goal continuations.
- Invalidate stored lineage when external context reaches an active turn or when a goal is edited or cleared.
- Preserve lineage for async hook results only when they belong to the receiving turn.

## Testing

- Cover goal continuations across intervening user turns and external objective edits.
- Cover active, buffered, and externally injected hook or response context.

GitOrigin-RevId: 22ccc07961cd0ed8f4b17912b7efa416b342bf50
2026-08-29 18:51:11 +00:00
rka-oai 035295b46e Improve sandboxing, MCP errors, and cached approvals (#41196)
Expand Windows deny-read globs robustly across protected directories while preserving filesystem enforcement. Preserve structured MCP tool and resource errors through app-server responses. Bind cached Guardian classifications to current local and root authorization state so stale scores cannot approve actions.

Add regression coverage for the sandbox resolver, structured protocol errors, and authorization changes.

GitOrigin-RevId: 4b80ed724d869afeca79204222d8465fa99d3a24
2026-08-27 20:05:08 +00:00
felixxia-oai 694edc23b2 Propagate trusted root skills to delegated workers (#41118)
## Why

Guardian reviews for delegated workers need to recognize skills explicitly
invoked by the user on the root turn.

## What changed

- Record verified user-owned skill paths as bounded, turn-matched Guardian
  evidence.
- Include trusted paths from the current worker and its root snapshot when
  building review context.
- Exclude skill trust from later root turns so stale authorization is not
  inherited.

## Testing

- Add an app-server lifecycle test covering inheritance of a root-invoked
  skill by a delegated worker and its removal on the next root turn.

GitOrigin-RevId: aa28f485edb7a447e51d51de8dc89b959fd63d40
2026-08-27 11:31:40 +00:00
rka-oai b9c4b9a0cf Support standalone function outputs in turn routing (#40991)
## What changed

- Allow `start_or_steer_turn` to accept named `function_call_output` items without a `call_id`, starting a turn when idle or steering the active turn.
- Preserve standalone outputs as pending input, assign response item IDs, and record them in conversation history without treating them as user prompts.

## Testing

- Cover starting a turn with a standalone output and steering an active turn with one.
- Verify passive response items do not signal pending steering activity.

GitOrigin-RevId: e32b292106b3c5a5f03577b8ebf67d2d7dee4e5d
2026-08-26 22:48:37 +00:00
faizan-oai 94967e03e5 Add per-turn cyber access program selection (#40687)
## What changed

- Add the experimental `turn/start.cyberAccessProgram` option with `standard`,
  `daybreakBlue`, and `daybreakRed` values.
- Forward the selection as `access_programs.cyber` on Responses, WebSocket,
  and remote-compaction requests made with ChatGPT authentication, while
  omitting it for API-key and custom-provider requests.
- Preserve the per-turn selection across recovery, compaction, and child-agent
  turns without making it a persistent thread setting.

## Testing

- Cover app-server forwarding, authentication boundaries, WebSocket reuse,
  turn recovery, compaction, and child-agent inheritance.

GitOrigin-RevId: d2eb468f365b2214c5099bc21741cf30f8bd2eb5
2026-08-25 19:54:52 +00:00
joeflorencio-openai ba6cf9c692 Make automatic turn admission atomic with settings updates (#40648)
## Why

Turn settings can change after an input request previews its overrides. Automatic idle work could therefore make a Plan-mode admission decision from stale settings or apply a sparse override built from an outdated collaboration mode.

## What changed

- Evaluate automatic turn admission against both the current and proposed configuration under the settings publication lock.
- Reject automatic work that would enter or leave Plan mode without committing settings or triggering runtime configuration effects.
- Keep model and reasoning-effort overrides sparse until they are merged with the configuration being committed.
- Continue allowing explicit user and recovery turns to make valid mode transitions.

## Testing

Add coverage for concurrent settings changes, sparse model and effort updates, commit-time constraint validation, atomic Plan-mode rejection, and subsequent explicit user submission.

GitOrigin-RevId: 234f06de116bdce7c3a3fb5cac3d15583304a253
2026-08-25 17:30:45 +00:00
joeflorencio-openai 1d64085e67 Validate step settings against proposed permissions (#40647)
## Why

Model requirements must be evaluated against the permissions that will apply
after a settings update. Validating against the current profile can reject a
valid model-and-permission update or allow a later permission-only update to
invalidate the selected model.

## What changed

- Group model, reasoning, service-tier, personality, and approval inputs into
  `StepSettings`, with a single apply-and-validate path.
- Apply permission and environment changes before validating step settings, so
  auto-review requirements use the proposed effective permissions.
- Revalidate existing step settings when permission or environment changes alter
  their constraints, and commit the update only when the complete candidate is
  valid.

## Testing

Added unit and integration coverage for atomic model/permission updates,
permission-only revalidation, environment-derived constraints, and both
standalone and turn-start settings operations.

GitOrigin-RevId: f50dfbd300484a09acc51ee4607278f300ca1cd9
2026-08-25 17:27:04 +00:00
joeflorencio-openai 4e883ce36e Keep settings operations bound to their committed snapshot (#40645)
## Why

Post-commit work can overlap with another settings write. Reading the session
again afterward could make a settings operation report or use the later state
instead of the state that it committed.

## What changed

- Return the committed configuration and `ThreadSettingsSnapshot` from session
  settings updates.
- Use that commit result when creating a turn and emitting
  `ThreadSettingsApplied`, while retaining current-state snapshots for
  synthesized fork history.
- Route turn-start updates through the shared settings update path.

## Testing

Add coverage for standalone and turn-start updates that pause after committing,
restore different settings concurrently, and verify that each operation keeps
its original configuration and notification snapshot.

GitOrigin-RevId: cee5be9536d2840170893e6eb0c64cd039fb0a96
2026-08-25 17:20:37 +00:00
jif 4b81410a80 Treat user input answers as Guardian authorization changes (#40623)
## Why

Answers collected by `request_user_input` can change what the user authorizes, but post-tool hooks may replace or reject the tool output that Guardian normally sees.

## What changed

- Record bounded, host-observed answers before post-tool hooks run and provide them as trusted evidence to synchronous and asynchronous Guardian reviews.
- Include root-thread answers in worker review context.
- Count successful answers as authorization changes so earlier review evidence becomes stale, while ignoring empty or unrelated answers.

## Testing

Add coverage for allowed and denied stale reviews, empty and oversized answers, hook-modified output, and root-to-worker propagation.

GitOrigin-RevId: 970c52e40338ecd057c7cd2a69d04b06e97cd068
2026-08-25 15:03:46 +00:00