Browse docsDevelopers

Tasks

What a VM belongs to, who may touch it, and when it goes.

updated 2026-10-06

Two agent sessions of one user could step on each other's VMs: Rift's MCP is one request under a bearer token, and the token names the user, so every conversation looks the same at the door. What tells them apart is not a session — the transport has none — but ownership, and the task is the noun that carries it. A task says which VMs belong together, who may touch them right now, and when they should go.

The model

  • A task is the unit of work an agent claims VMs for. It has an id — task_…, short, for a person to read in a list — an owner, a name, and a status: open or closed.
  • Every claimed VM belongs to exactly one task; a task holds any number. rift_vm_new takes the task, and there is no VM outside one.
  • A task is held under a lease: one holder at a time, named by a secret the holder presents with every call. The handle the agent carries is task_<id>.<secret>. Rift keeps only the secret's hash, and the id alone buys nothing.
  • Attaching mints a new secret, so the previous handle stops working. Exclusivity is by possession, not by any idea of who is calling.
  • Closing destroys every VM in the task.

The agent session, then, is whoever holds a task's lease. Sub-agents of one conversation share its context and so share the handle — the grain is the task, not the process.

The holder

The holder a task shows is the label of the token that attached: mcp: plus the name the client declared, such as mcp:Claude. A list says which client has a task.

The clocks

  • Activity. Any call under a good handle is activity on the task; the clock moves at most once a minute.
  • A lease quiet for 30 minutes may be taken up without asking. rift_task_attach on a task held by a quiet handle succeeds; on one active lately it's refused unless takeover is set.
  • A task quiet for 4 hours closes itself, and its VMs are destroyed. A touch restarts the timer.

Refusals

Every refusal names the tool that mends it:

  • no handle → rift_task_new opens one
  • a task that isn't yours, or doesn't exist → says so
  • a closed task → its VMs are gone; rift_task_new opens another
  • a released task → rift_task_attach <id> takes it up
  • a handle that isn't the current lease → held by <holder> since <when>; rift_task_attach with takeover takes it over — tell the user

An accidental collision hits a wall with a clear message; a legitimate reconnect pushes through.

In the app

The app's Boxes page shows your open tasks with holder, last activity and VMs, and each VM with its task. The page does not change them. To put away VMs an agent left behind, ask your agent to call rift_task_close on the task, which destroys its VMs, or rift_vm_destroy on one VM. A task that is quiet for 4 hours closes itself.

The moves

Hand a task to another agent walks release, attach and takeover.