Browse docsDevelopers

Boxes

A box's life from provisioning to done, every status you'll see, and every published deadline.

updated 2026-10-14

A box is a machine built for a repository at a commit: Rift's base system, your checkout, and whatever your fixed-labs.rift expression asks for. It's built once, warmed in a pool, claimed by an agent, and destroyed when the work is done. This page is the reference for that life: the statuses, what moves a box between them, and how long each step may take.

The life

  1. Provisioning. A watched ref wants a box at its head. Rift creates a volume and a machine from the bootstrap image, with the repository, ref and commit in its environment.
  2. Warming. The box's agent clones the repository at the commit onto the volume — a full clone, on a real branch — and builds the system the expression at that commit describes, or the base system alone if there's none. It reports ready.
  3. Parked. Rift suspends the box: the process tree intact, the memory snapshotted. A box keeps no secret, so its snapshot holds none either.
  4. Running. An agent's rift_vm_new claims it. The box resumes and is the agent's. It still keeps no secret: the owner's GitHub token and the repository's secrets go only to a verb run, which fetches its credential when it starts and drops it when it ends. A cold start, when the pool has nothing parked, goes provisioning → warming → running directly, and the claim waits.
  5. Destroying → done. rift_vm_destroy, rift_task_close, a task that expired, or a drain: the machine goes, then the volume.

A box never changes after it is built. A push to its ref or a new expression reaches the next box, and the way to get one is to destroy this one and claim again. Credentials are the exception: a verb asks for your GitHub token, or for a repository secret, each time it runs, so a running box's next verb run gets the current value.

Ids and names

Each VM has an id: b- and 24 hexadecimal characters. Rift makes the id from the repository, the ref and the number of the VM in its pool, so no two VMs get the same id. The id is the name of the VM's machine and of its volume, and the agent tools take it as vm.

Each VM also has a name for a person to read: the short name of the repository, the ref and the number, for example app-main-3. Two repositories with the same short name, or two refs such as feat/a and feat-a, can give the same name to two different VMs. A tool takes a name only when one VM of the task has it, and refuses a name that two or more VMs of the task have. A VM made before Rift gave ids keeps its name as its id.

Statuses

rift_vm_ls and the app's Boxes page show where a box is:

  • provisioning — the machine is being created.
  • warming — cloning and building; the long one.
  • parking / parked — suspending; suspended, warm, waiting to be claimed.
  • resuming — a claim is bringing a parked box back.
  • running — an agent's. Commands run here, and only here.
  • destroying / done — going; gone.

There is no failed status. A box whose step ran out of time, whose build broke or whose provider said no goes straight to destroying with the reason recorded on it, and rift_repos shows that reason against the head it happened at. A tool called on a box that isn't running is refused with the status it's in.

Published deadlines

Rift never leaves a box hanging in a step. Each in-flight status has a deadline, and a box past it is torn down with a timeout as its reason:

  • Provisioning — 5 minutes. The machine has to exist.
  • Warming — 30 minutes. The clone and the build, including a Nix build from the public cache.
  • Parking — 5 minutes. The suspend has to land.
  • Resuming — 5 minutes. A claimed box has to report running.
  • Destroying — 10 minutes. Then the box is done regardless.

A claim itself waits 30 seconds for the box to run before answering with whatever status it's at, and the agent polls from there. Every tool call on a box answers in under a minute. rift_bash and rift_output wait at most block_for seconds (45 at most); the command itself runs until it ends or its timeout passes, and rift_output reads the rest of its output.

What a box is made of

The machine boots Rift's bootstrap image: the boot recipe, the box's agent, and a minimal baked system. Nothing per repository is baked in; the warm step builds your system on the box, from your expression, and sets it as the volume's profile. When Rift ships a new image, parked boxes built on the old one are drained and rewarmed on the new, and a claimed box keeps its image until it's destroyed. See Inside a box for what the agent finds once it's in.