Skip to content

Sessions

A session is Barista's durable unit of work: one long-lived workload whose useful memory and disk can outlive the sandbox currently running it.

Today that model has two handles:

  • Direct node: a client-chosen instance ULID, unique on that node.
  • Fleet: a stable human name, unique in the fleet bucket, whose lease points to the owning node and materialised instance id.

The product direction is name-as-the-handle everywhere. The current CLI keeps the distinction visible instead of pretending the direct Node Agent API already resolves fleet names.

Direct instance ids

Direct lifecycle commands use an instance id:

barista create \
  --instance-id 01ARZ3NDEKTSV4RRFFQ69G5FAV \
  --image ghcr.io/acme/agent:2026-08 \
  --digest sha256:9b2c0f… \
  -- /app/agent
barista start 01ARZ3NDEKTSV4RRFFQ69G5FAV
barista exec 01ARZ3NDEKTSV4RRFFQ69G5FAV -- ps

Omit --instance-id to let the CLI generate one. The operation result prints the id needed by later direct-node commands.

Fleet names

A fleet session is declared and resolved by name:

barista fleet apply checkout-agent \
  --image ghcr.io/acme/agent:2026-08 \
  --digest sha256:9b2c0f… \
  -- /app/agent
barista fleet resolve checkout-agent

Exactly one node owns a name at a time. Ownership is a conditional lease fenced by version and epoch. The lease also records the materialised instance id, so a superseded owner can stop the exact workload it no longer owns.

The planned gateway will make addressing a fleet name sufficient to wake and route application traffic. It is not implemented today; fleet resolve is coordination and discovery, not ingress.

Single writer

One mutating operation may be in flight per instance. A conflicting mutation is refused with CONCURRENT_OPERATION rather than interleaved.

Across a fleet, one owner lease exists per name. A node that loses its lease self-fences its local workload, including after an agent restart. These two rules keep in-memory state from diverging behind one handle.

One workload per instance

An instance runs one process tree from one OCI image. There is no pod shape, sidecar list, or init-container API.

Several processes launched by that workload share one memory image and pause atomically. Separate sessions do not. Choose that boundary deliberately.

The spec is immutable

InstanceSpec is fixed after create. Change it by destroying and recreating the instance, or by writing desired state under a new fleet name.

Snapshot compatibility depends on this. A mutable image, resource shape, or runtime bundle could make captured memory appear compatible with a different root filesystem.

What the API spec contains

Field Meaning
template OCI image label plus required digest identity.
resources vCPU, memory, and disk.
process Workload command, readiness command, environment, and working directory.
hooks Pre-snapshot and post-restore commands with timeouts.
ttl_seconds / ttl_action Idle deadline and PAUSE, STOP, or DESTROY action.
labels Values available to ListInstances selectors.
egress Optional mediated-egress request, capability-gated by the runtime.

The barista create convenience command exposes only image/digest, CPU, memory, TTL seconds, egress, hardware isolation, and the workload command. Use a generated Contract A client for the other fields.

Ready is not a state

RUNNING means the sandbox is up. Instance.ready is a separate boolean from ready_cmd and means the workload says it can serve.

Callers that configure ready_cmd should wait for ready, not merely RUNNING. The future request gateway follows the same rule.