@@ -147,6 +147,7 @@ const registerCalls = [];
147147const runnerCommands = [];
148148const spawnCalls = [];
149149let sandboxCreated = false;
150+ let managedHermesVolume = null;
150151
151152// The protected live-E2E job intentionally runs source without build:cli.
152153// Route the root CLI's generated shared-boundary import back to its canonical
@@ -402,6 +403,7 @@ replace(managedBootstrap, "createDockerManagedBootstrapAdapter", () => {
402403
403404const runner = require(${ source ( "src/lib/runner.ts" ) } );
404405runner.run = (command, options = {}) => {
406+ const argv = Array.isArray(command) ? command.map(String) : [];
405407 const normalized = normalize(command);
406408 runnerCommands.push(normalized);
407409 if (/(?:^|\s)docker(?:\s+buildx)?\s+build(?:\s|$)/u.test(normalized)) {
@@ -412,6 +414,25 @@ runner.run = (command, options = {}) => {
412414 ? { status: 0, stdout: "Name: " + sandboxName + "\nId: sbx-managed-fixture\n", stderr: "" }
413415 : { status: 1, stdout: "", stderr: "sandbox not found" };
414416 }
417+ if (argv[0] === "docker" && argv[1] === "volume") {
418+ const volumeName = argv.at(-1);
419+ if (argv[2] === "inspect") {
420+ return managedHermesVolume
421+ ? { status: 0, stdout: JSON.stringify(managedHermesVolume) + "\n", stderr: "" }
422+ : { status: 1, stdout: "", stderr: "Error response from daemon: no such volume" };
423+ }
424+ if (argv[2] === "create") {
425+ const labels = {};
426+ for (let index = 3; index < argv.length - 1; index += 1) {
427+ if (argv[index] !== "--label") continue;
428+ const [name, ...value] = argv[index + 1].split("=");
429+ labels[name] = value.join("=");
430+ index += 1;
431+ }
432+ managedHermesVolume = { Name: volumeName, Labels: labels };
433+ return { status: 0, stdout: volumeName + "\n", stderr: "" };
434+ }
435+ }
415436 return { status: 0, stdout: "", stderr: "" };
416437};
417438runner.runFile = (file, args = []) => runner.run([file, ...args]);
@@ -656,6 +677,25 @@ function assertManagedLaunch(
656677 const fromIndex = createArgs . indexOf ( "--from" ) ;
657678 expect ( createArgs [ fromIndex + 1 ] ) . toBe ( expectedContract . reference ) ;
658679 expect ( createArgs . join ( " " ) ) . not . toContain ( "Dockerfile" ) ;
680+ if ( agent === "hermes" ) {
681+ const driverConfigIndex = createArgs . indexOf ( "--driver-config-json" ) ;
682+ expect ( driverConfigIndex ) . toBeGreaterThanOrEqual ( 0 ) ;
683+ expect ( JSON . parse ( createArgs [ driverConfigIndex + 1 ] ! ) as unknown ) . toMatchObject ( {
684+ docker : {
685+ mounts : [
686+ {
687+ type : "volume" ,
688+ source : "nemoclaw-hermes-state-v1-managed-hermes" ,
689+ target : "/sandbox/.hermes" ,
690+ read_only : false ,
691+ } ,
692+ ] ,
693+ } ,
694+ } ) ;
695+ expect (
696+ result . payload . runnerCommands . some ( ( command ) => command . startsWith ( "docker volume create " ) ) ,
697+ ) . toBe ( true ) ;
698+ }
659699
660700 expect ( createArgs . filter ( ( arg ) => arg . startsWith ( "NEMOCLAW_STARTUP_PROFILE_B64=" ) ) ) . toEqual ( [ ] ) ;
661701 const encodedProfile = bootstrapRequest ?. encodedProfile ;
0 commit comments