Skip to main content
Every node offers three directories, and the one a recipe mounts declares the data’s lifetime. rm reads the space, not the recipe: convention with teeth.
Screens verified by walkthroughs/test_spaces.py.

The three spaces

dabs never reads tmp to decide anything — it is the box’s scratch and nobody else’s business.

Name them in a recipe

$NODE_* variables name the box’s own spaces; $PARENT_* name the spaces of the place the box stands on (your project, a worktree). They substitute in source paths only — they are not environment variables inside the box.
After the box writes into each, dabs ls shows a dot per space that holds files:
dabs info <node> says the same thing one node at a time, in words (holds files / empty) — and names the recipe that mounted each space.

What rm does with each

The preview spells out every space’s fate before you consent:
rm -y then stops the box, takes held (that is what -y consented to), clears tmp — and keeps the volume, telling you how to take it when you mean it:
A box whose volume still holds files stays listed (STATE gone) so the data has an owner. rm <box> -y --volume finishes the job.

$PARENT_VOLUME: what comes back next time

A box’s own volume dies with its node; the parent place persists. So a box that wants data back on the next box writes it to $PARENT_VOLUME. Write keep-me there, reap the box (--volume and all), boot a fresh one:
The parent’s volume reloaded; the old box’s own cache is gone. This is exactly how a Claude box keeps its session transcripts across re-ups.
$NODE_EPHEMERAL / $PARENT_EPHEMERAL are permanent aliases of $NODE_HELD / $PARENT_HELD (the held space’s former name) — old recipes keep working.