Test selected capabilities across availability and resume (#30157)

## Why

This stack crosses World State, executor skills, selected plugin
metadata, MCP processes, connectors, dynamic environments, and resume.
This PR adds two end-to-end scenarios that validate those pieces
together.

Both tests enable `deferred_executor`, so they exercise the real
delayed-environment path.

## Scenario 1: availability across turns and resume

```text
1. Start a thread with one selected plugin root bound to E1.
2. E1 is unavailable.
   - executor skill is absent
   - selected MCP is absent
   - connector has no selected-plugin attribution
3. Start E1 and register the same stable environment ID.
4. Start a new turn.
   - the executor skill appears through World State
   - its body beats a colliding host skill
   - the selected MCP tool is advertised and executes inside E1
   - the connector is attributed to the selected plugin
5. Start another turn without changing E1.
   - the MCP PID stays the same, proving runtime reuse
6. Restart app-server and resume the thread.
   - durable selected-root intent is restored
   - skills, MCP, and connector attribution are restored
   - a new MCP PID proves ephemeral process state was rebuilt
```

## Scenario 2: availability changes inside one turn

```text
1. Start a turn while E1 is unavailable.
2. The first model sample sees no executor skill, MCP, or selected connector.
3. The turn pauses on request_user_input.
4. Start E1 and register it while that same turn is still active.
5. Continue the turn.
6. The very next model sample sees:
   - the executor skill catalog
   - the selected MCP tool
   - selected-plugin connector attribution
7. The model calls the MCP, and its output proves execution happened inside E1.
```

This second scenario specifically protects the aeon-style behavior:
capability state is captured again for every sampling step, not only at
the next user turn.

## Scope

These are integration tests only. They do not add a combinatorial matrix
for unsupported plugin-file mutation, environment generations, transport
disconnects, or delayed `required = true` executor MCPs.
This commit is contained in:
jif
2026-06-26 03:11:55 +01:00
committed by GitHub
Unverified
parent 0d4351c1b8
commit 25f50de6ed
5 changed files with 735 additions and 6 deletions
+15 -2
View File
@@ -29,6 +29,7 @@ use crate::protocol::FsWalkParams;
use crate::protocol::FsWriteFileParams;
const INVALID_REQUEST_ERROR_CODE: i64 = -32600;
const METHOD_NOT_FOUND_ERROR_CODE: i64 = -32601;
const NOT_FOUND_ERROR_CODE: i64 = -32004;
#[path = "remote_file_stream.rs"]
@@ -194,14 +195,26 @@ impl RemoteFileSystem {
) -> FileSystemResult<WalkOutcome> {
trace!("remote fs walk");
let client = self.client.get().await.map_err(map_remote_error)?;
let response = client
let response = match client
.fs_walk(FsWalkParams {
path: path.clone(),
options,
sandbox: remote_sandbox_context(sandbox),
})
.await
.map_err(map_remote_error)?;
{
Ok(response) => response,
Err(ExecServerError::Server {
code: METHOD_NOT_FOUND_ERROR_CODE,
..
}) => {
return <Self as ExecutorFileSystem>::walk_via_directory_reads(
self, path, options, sandbox,
)
.await;
}
Err(error) => return Err(map_remote_error(error)),
};
Ok(response)
}