sources: list places things into the box at a path. Exactly one
of four kinds names each source’s origin — and the kind decides whether the
box’s writes ever reach your disk.
Screens verified by
walkthroughs/test_sources.py.
Add
ro: true to any mount to make it read-only inside the box.
Copy vs mount, demonstrated
This recipe hands the box a snapshot of the project and a read-only reference directory:What a copy leaves behind
Acopy: . source snapshots your cwd into a workdir node (its bytes live
in that node’s held space), and the boot says so:
dabs rm <workdir-id> -y.
mkmount: provisioning on first boot
mkmount: is mount: that creates its host origin if missing — say it where
you mean “provision this”. The canonical use: a login/config dir a harness
fills on first run, shared by every later box that names it:
mount: whose origin is missing is treated as a typo and refused:
A per-box destination: $NODE_ID
A source’s path: (and the recipe’s workdir:) may name $NODE_ID — the id of
the box being provisioned. It is the one variable a box path may name; the
space variables name host origins only.
It earns its keep when a tool keys state off its own working directory. A recipe
that mounts . → /work gives every box the identical cwd, so every agent
session inside derives the same transcript slug and they collide across boxes.
Namespacing the destination gives each box its own:
/
and no ..: $NODE_ID cannot move a mount out of the path that names it.
Where a snapshot lands: at:
For worktree: and copy: sources, at: says where the bytes land in the
new node’s own spaces — e.g. at: $NODE_HELD/worktree (the default), so rm
asks before reaping the checkout. See Spaces.