Refresh resumed thread capability roots from executors (#39746)

## Why

Resumed threads can carry a persisted capability-root location that no longer
matches the location reported by the attached executor.

## What changed

- Refresh matching thread-owned capability roots from the live environment while
  preserving persisted roots when the executor reports none.
- Use the same merge behavior for capability-root inspection and per-step MCP
  resolution, without changing owner-configured root precedence.

## Testing

Extend the remote-environment resume test to cover both an executor-provided
replacement root and the persisted-root fallback.

GitOrigin-RevId: 0c66195b2406f431a2e156e00d5225a8d22d18b2
This commit is contained in:
sayan-oai authored and copyberry committed 2026-08-20 17:12:15 +00:00
1 parent c3db180493
commit 2e1f18e0db
3 files changed
+167 -47

No files matched your search

+13 -12
View File
@@ -1,5 +1,6 @@
use super::mcp_refresh::McpRefreshInvalidationGuard;
use super::*;
use crate::environment_selection::combine_selected_capability_roots;
use crate::tools::sandboxing::executor_windows_sandbox_level;
use codex_exec_server::ExecutorCapabilityDiscoveryCache;
use codex_exec_server::ExecutorCapabilityDiscoverySnapshot;
@@ -438,18 +439,18 @@ impl Session {
let mut root_locations_by_id = HashMap::new();
let mut selected_capability_roots = Vec::new();
let mut ready_environment_root_count = 0;
for (index, root) in self
.services
.selected_capability_roots
.iter()
.cloned()
.chain(
environments
.turn_environments()
.flat_map(|environment| environment.config().selected_capability_roots.clone()),
)
.enumerate()
{
let combined_roots = combine_selected_capability_roots(
&self.services.selected_capability_roots,
environments.turn_environments().map(|environment| {
(
environment.config_origin,
environment
.config_origin
.selected_capability_roots(&environment.environment, environment.config()),
)
}),
);
for (index, root) in combined_roots.into_iter().enumerate() {
if let Some(kept_location) = root_locations_by_id.get(&root.id) {
if kept_location != &root.location {
tracing::warn!(