Workspaces
A mado workspace is one client’s checkout: a workspace name, a working-copy
commit @, an overlay of uncommitted mount edits, and (optionally) scratch
redirections. Against a shared server, a workspace can be paused on one
machine and resumed on another, so an agent’s environment is portable. This
page covers the lifecycle verbs (mado ws …) and the lease that keeps two
machines from fighting over one workspace.
Checkpoints
A checkpoint is an explicit, moment-in-time record that binds three things into one durable blob:
- the current jj operation (what
@and the view are), - the scratch manifest (the redirected build-dir state), and
- the presence of the workspace’s attribute table.
mado ws checkpoint # no scratch
mado ws checkpoint --scratch ~/scratch-alice --redirect target
mado ws checkpoint folds pending mount edits into @, snapshots the scratch
redirections into the blobstore, and writes the checkpoint record (in the
Derived domain), with .jj/working_copy/scratch-head pointing at it (atomic
write). This is the record pause / resume travel on. The daemon’s background
scratch snapshotter keeps the manifest fresh continuously, but only this
command (or pause) binds scratch state to an operation.
Auto-checkpoint
A mount against a remote records a remote-durable, resumable checkpoint on a
cadence — under the lease it already holds, without releasing it — so a
lost or crashed machine is resumable elsewhere up to the last checkpoint, with
no human running mado ws pause.
- Default cadence: 30 seconds (
mado mount --checkpoint-interval <secs>). This is the bounded off-box loss window: a crash loses at most this much cross-machine durability. Local crash-safety stays continuous via the overlay journal regardless. --no-auto-checkpoint(or--checkpoint-interval 0) relies solely on explicitmado ws pausefor off-box durability.- Auto-checkpoint never runs on a local (no-remote) workspace — there is no server to make anything durable to.
- It also never runs under
mado serve-virtiofs: that daemon holds no workspace lease of its own (the FUSE mount / resume path owns the lease), and auto-checkpoint commits only under the daemon’s own held lease. The virtiofs flags exist for CLI symmetry only.
Pause and resume
mado ws pause moves a workspace off the current machine so it can resume
elsewhere. It is one blocking sequence with a single commit point:
mado ws pause # no scratch
mado ws pause --scratch ~/scratch-alice --redirect target
Pause folds pending mount edits into @ (driving a running daemon over the
control socket, exactly like mado snapshot; with no daemon it folds directly),
snapshots the scratch redirections, uploads the attribute table, writes the
checkpoint record, and finally CAS-swaps the server-side wshead/<workspace>
scope to it. The order is load-bearing: every blob is remote-durable
before the record naming it, and the CAS is the commit point — a crash
anywhere earlier leaves the previous pause fully intact. Pause blocks until
everything is remote-durable.
mado ws resume adopts a paused workspace into a fresh checkout on another
machine:
mkdir ~/machine-b && cd ~/machine-b
export MADO_REMOTE_ADDR=http://server:50051
mado init --workspace alice --resume # same server, SAME workspace name, --resume
mado ws resume --scratch ~/scratch-alice # restore into a local scratch dir
The resume target must be a fresh mado init --workspace <name> --resume
against the same server under the same workspace name (the --resume flag
skips the name-collision probe, because the name is expected to be registered
— it is the paused workspace being adopted). Resume:
- fetches the workspace head (exactly one record; zero means never paused, several means concurrent pauses forked it — both are typed errors),
- restores the attribute table and the scratch redirections eagerly (lazy scratch hydration is future work), and
- positions
@at the checkpoint’s exact operation (no new operation is written).
Resume refuses a dirty workspace unless you pass --force. A resumed tree is
byte-identical — content, exec bits, and file mtimes are restored — so a
resumed build is incremental, not cold (see the measured F2 numbers in
Performance).
Leases
The lease is what makes concurrent multi-machine use safe. A workspace head is
single-writer per scope: while one machine holds the lease on
wshead/<workspace>, a second acquire on that scope is refused
(FailedPrecondition). The mount daemon renews its lease well within the TTL;
the default lease TTL is 300 seconds (server clock).
- Normal
mado ws resumetakes the lease only if it is free or expired, and never steals it from a live holder. mado ws resume --stealforces a takeover: the steal succeeds only once the lease has expired on the server clock, and it bumps the epoch so the old holder’s late writes are fenced off. Use it when the prior machine is gone but its lease still looks live.
Because the head is single-writer per scope, “N machines writing one workspace scope” is not physically realizable — the lease serializing each scope is itself the guarantee that concurrent checkpoints don’t storm the shared op-heads journal (measured: CAS retries stay at zero as concurrency rises — see Performance).