User Story
As an operator running short-lived agent jobs, I want an ephemeral sandbox to be removed after its main process finishes and its terminal output has been delivered, so that completed jobs do not leave compute resources running.
Problem Statement
A sandbox created with --no-keep --detach receives the openshell.nvidia.com/retention: ephemeral annotation, but remains in Completed after its canonical process exits successfully. Its supervisor stays connected to retain the control-mode access plane, so the sandbox and its Docker containers remain present indefinitely until manually deleted.
Impact / Why This Matters
Unattended job launchers such as Gator can accumulate completed sandboxes and running supervisor/compute containers despite requesting self-deletion. The current workaround is to list and manually delete completed ephemeral sandboxes, which requires ongoing operator attention and does not prevent resource buildup between cleanups.
Acceptance Criteria
Reproduction Steps
- Start the local Docker gateway (
mise run gateway:docker).
- Run
openshell --gateway docker-dev sandbox create --name eph-check --no-keep --detach -- /bin/true.
- Run
openshell --gateway docker-dev sandbox get eph-check -o json and docker ps after the command exits.
- Observe
phase: Completed, exit_code: 0, and openshell.nvidia.com/retention: ephemeral. The sandbox and supervisor containers remain running. The supervisor logs Canonical process exited; retaining control-mode access plane.
- Manually delete the sandbox with
openshell --gateway docker-dev sandbox delete eph-check.
Environment
- OpenShell:
0.1.3-dev.28+g798500ccd
- OS: macOS 26.7, arm64
- Runtime: Docker Desktop engine 29.7.2; local
docker-dev gateway
- Reproduced on 2026-09-29 local time
Logs
$ openshell --gateway docker-dev sandbox list
NAME CREATED PHASE
eph-check 2026-09-30 06:20:08 Completed
supervisor: Canonical process exited; retaining control-mode access plane
Agent Investigation
The gateway schedules ephemeral deletion only in the supervisor-session disconnect path when terminal_delivery_finalized is true (crates/openshell-server/src/compute/mod.rs, around line 4456). The supervisor intentionally retains control-mode access after reporting and finalizing the process exit (crates/openshell-supervisor/src/lib.rs, around line 1293). The existing test ephemeral_cleanup_waits_for_terminal_finalization explicitly waits for a disconnect before expecting deletion (crates/openshell-server/src/compute/mod.rs, around line 9265). The finalize RPC records terminal delivery while the session is still connected (crates/openshell-server/src/supervisor_session.rs, around line 2055).
The shared Rust lifecycle e2e suite already tests attached --no-keep commands, but attached CLI cleanup can mask the gateway bug (e2e/rust/tests/sandbox_lifecycle.rs, around line 1345). Its detached canonical-process tests use persistent sandboxes (e2e/rust/tests/sandbox_lifecycle.rs, around line 760). Extend that shared suite with detached ephemeral cleanup and run it in each applicable driver lane; MXC has a separate Windows e2e runner.
User Story
As an operator running short-lived agent jobs, I want an ephemeral sandbox to be removed after its main process finishes and its terminal output has been delivered, so that completed jobs do not leave compute resources running.
Problem Statement
A sandbox created with
--no-keep --detachreceives theopenshell.nvidia.com/retention: ephemeralannotation, but remains inCompletedafter its canonical process exits successfully. Its supervisor stays connected to retain the control-mode access plane, so the sandbox and its Docker containers remain present indefinitely until manually deleted.Impact / Why This Matters
Unattended job launchers such as Gator can accumulate completed sandboxes and running supervisor/compute containers despite requesting self-deletion. The current workaround is to list and manually delete completed ephemeral sandboxes, which requires ongoing operator attention and does not prevent resource buildup between cleanups.
Acceptance Criteria
--no-keep --detachagainst the Docker, Podman, Kubernetes, and VM driver lanes, then verifies that the sandbox record and driver resources disappear without a CLI delete. Cover both successful and failed canonical-process exits. Add equivalent coverage to the separate MXC e2e lane where that driver supports this lifecycle.Reproduction Steps
mise run gateway:docker).openshell --gateway docker-dev sandbox create --name eph-check --no-keep --detach -- /bin/true.openshell --gateway docker-dev sandbox get eph-check -o jsonanddocker psafter the command exits.phase: Completed,exit_code: 0, andopenshell.nvidia.com/retention: ephemeral. The sandbox and supervisor containers remain running. The supervisor logsCanonical process exited; retaining control-mode access plane.openshell --gateway docker-dev sandbox delete eph-check.Environment
0.1.3-dev.28+g798500ccddocker-devgatewayLogs
Agent Investigation
The gateway schedules ephemeral deletion only in the supervisor-session disconnect path when
terminal_delivery_finalizedis true (crates/openshell-server/src/compute/mod.rs, around line 4456). The supervisor intentionally retains control-mode access after reporting and finalizing the process exit (crates/openshell-supervisor/src/lib.rs, around line 1293). The existing testephemeral_cleanup_waits_for_terminal_finalizationexplicitly waits for a disconnect before expecting deletion (crates/openshell-server/src/compute/mod.rs, around line 9265). The finalize RPC records terminal delivery while the session is still connected (crates/openshell-server/src/supervisor_session.rs, around line 2055).The shared Rust lifecycle e2e suite already tests attached
--no-keepcommands, but attached CLI cleanup can mask the gateway bug (e2e/rust/tests/sandbox_lifecycle.rs, around line 1345). Its detached canonical-process tests use persistent sandboxes (e2e/rust/tests/sandbox_lifecycle.rs, around line 760). Extend that shared suite with detached ephemeral cleanup and run it in each applicable driver lane; MXC has a separate Windows e2e runner.