Lifecycle and Storage

Agent Sandbox separates the desired operating mode, observed status, scheduled expiration, and persistent data model. Clients must treat these as distinct contracts.

Running and Suspended Modes

Set spec.operatingMode on the core Sandbox:

  • Running requests an active workload.
  • Suspended requests that the workload stop while the Sandbox object and its declarative configuration remain.

Example patches:

kubectl patch sandbox python-sandbox \
  -n "$BUSINESS_NAMESPACE" \
  --type=merge \
  -p '{"spec":{"operatingMode":"Suspended"}}'

kubectl patch sandbox python-sandbox \
  -n "$BUSINESS_NAMESPACE" \
  --type=merge \
  -p '{"spec":{"operatingMode":"Running"}}'

Suspending a Sandbox terminates the active workload Pod. Returning to Running causes the controller to prepare the workload again.

Status Conditions

Read Sandbox conditions as typed boolean status records. Do not infer state from condition presence alone.

In v0.5.4, the Suspended condition remains present after initial reconciliation:

  • Suspended=True means the Sandbox is suspended.
  • Suspended=False means it is not suspended.
  • The termination reason PodTerminating replaces the older PodNotTerminated reason.

Inspect conditions with:

kubectl get sandbox python-sandbox \
  -n "$BUSINESS_NAMESPACE" \
  -o jsonpath='{range .status.conditions[*]}{.type}{"="}{.status}{" reason="}{.reason}{"\n"}{end}'

Wait for the specific boolean state required by the operation:

kubectl wait --for=condition=Ready=True sandbox/python-sandbox \
  -n "$BUSINESS_NAMESPACE" \
  --timeout=180s

kubectl wait --for=condition=Suspended=True sandbox/python-sandbox \
  -n "$BUSINESS_NAMESPACE" \
  --timeout=180s

Scheduled Shutdown

shutdownTime is an absolute RFC3339 timestamp. For example:

spec:
  shutdownTime: "2026-08-11T12:30:00Z"

It is not a relative duration. It is not automatically extended by commands, network traffic, CPU usage, or heartbeats.

A client SDK can offer a relative helper such as “30 minutes from now,” but that helper ultimately writes a fixed absolute shutdownTime to the Kubernetes resource. Extending the lifecycle requires an explicit update by the client or another authorized component.

Shutdown Policies

For a core Sandbox, shutdownPolicy supports:

PolicySandbox object after expirationPod and Service after expiration
DeleteDeletedDeleted
RetainRetained with expired statusDeleted

The default policy is Retain. Underlying workload resources are deleted on expiration even when the Sandbox object is retained.

A SandboxClaim has its own extension lifecycle policies: Delete, DeleteForeground, and Retain. DeleteForeground keeps the claim in terminating state until the underlying Sandbox and Pod have terminated, allowing external systems to observe shutdown progress.

Persistent Data

Use spec.volumeClaimTemplates when the Sandbox requires Kubernetes-managed persistent storage. The controller creates PersistentVolumeClaims from these templates.

Persistent storage preserves data written to the mounted volume. It does not preserve:

  • Packages installed only in the container writable layer.
  • Operating-system changes outside the mounted volume.
  • In-memory process state.
  • An entire executable environment snapshot.

Build repeatable environments into a trusted image, and store business data on an appropriate persistent volume or external service.

Immutable Volume Claim Templates

Sandbox.spec.volumeClaimTemplates is immutable after creation. The API rejects updates that add, remove, or modify a template.

When the template must change:

  1. Prepare the replacement storage and Sandbox definition.
  2. Stop application writes or use an application-specific consistency mechanism.
  3. Migrate or restore data through the storage system's supported workflow.
  4. Create a replacement Sandbox.
  5. Validate the replacement before deleting the original resource.

A controller rollback does not make an in-place template update valid.

Idle Shutdown Boundary

Native idle shutdown is not provided in this release. Agent Sandbox does not infer idleness from API requests, shell activity, network traffic, CPU, I/O, or heartbeats.

Do not describe shutdownTime as idle shutdown. A productized idle mechanism would require a trusted activity signal and an authorized component that deliberately renews or expires the Sandbox lifecycle.