Restoring a rig on a fresh machine
A rig's durable state lives on git refs and branches β clone, bro work sync --pull, bd sync through a dolt remote, bro review drive install re-supervises open PRs.
A bro rig is designed so the machine is disposable. What dies with it is
processes β the daemon, act watchers, exec shells, dolt servers β
plus registrations β git worktree entries, the agent registry, loop
run records β and anything never pushed. Everything else already lives
on the remote: claims, molecules, and the ready
queue are bead state synced to refs/dolt/data; loop/* and snapshot
branches are ordinary git refs; the review-debt ledger and .agents/
state ride refs/bro/data.
Where each piece lives
| State | Location | Restored by |
|---|---|---|
Code, loop/* and fix/* branches, dirty-tree snapshot branches | refs/heads/* | git clone / git fetch |
bro artifacts β review-debt ledger, drill evidence, .agents/ state | refs/bro/data | bro work sync --pull |
| Beads store β issues, claims, drill frames, molecules | refs/dolt/data via a dolt remote (bd dolt remote list) | bd sync |
| Operator config β providers, agent templates, global skills | outside the repo (~/.config/bro, ~/.agents) | the operator's own backup β restore this first |
Running processes + machine-local state β daemon, watchers, shells, the bro/drive.json install marker, act watch markers (<git-common>/bro/watches/), agent logs, the agent registry (<git-common>/bro/agents.json), git worktree registrations, loop run records (<git-common>/bro/loop/), stack edges (<git-common>/bro/stack/) | nowhere | restarted below |
Sequence
git clone https://github.com/<org>/<repo>.git && cd <repo>
# repo bootstrap β for bro itself: npm ci && npm run build
bro work sync --pull # materializes refs/bro/data into the worktree, then runs bd sync;
# a remote with no data ref just prints "nothing to pull"
git fetch origin 'loop/*:loop/*' 'work/*:work/*' 'stack/*:stack/*'
# in-flight work as LOCAL refs β `bro review drive`
# enumerates open PRs from local branches, and a
# clone's are remote-tracking only until fetched
bro review drive install # re-arms the merge path and brings the supervisor up β the
# want-marker is machine-local, so a clone starts with nonebro review act rearm is deliberately absent: it resurrects watchers
from dead markers under <git-common>/bro/watches/ β machine-local
files a clone never carried β so on a fresh machine there is nothing to
rearm. The lost machine's open PRs get their supervision back from bro review drive instead, which discovers them from local branches, not
markers β hence the fetch step. A watch armed on a branch outside
work//loop//stack/ has no such enumeration: that promise died with
the machine β arm a fresh bro review act wait <PR> --merge if the PR
still needs one.
Stack edges ride the same loss: <git-common>/bro/stack/ maps each
stack/<name>/<n>-<slug> branch to the base it forked from, and a
clone carries none of it. bro flow stack list/sync falls back to an
open member PR's declared base, so members with a PR recover their
place in the chain β a member with no PR yet has no recorded base, so
sync reads it as already on the right base; rebase it by hand if its
parent merged in the meantime.
Then verify from the authoritative reads, not from process exits:
bd ready # the queue survived
bro fleet status # board, drill frame, fleet
git branch -r # in-flight work survives as branches (loop/*, work/*, fix/*) β
# `git worktree list` shows only this clone; registrations
# were machine-local state
bro fleet agents status # starts empty β agents.json is machine-localOrphaned claims
Beads restored as in_progress still carry the dead machine's assignee,
and every plane that could vouch for a worker β agent registry, run
records, session markers β was machine-local, so the claim reads as
foreign: bro work enter reports it refused and bro fleet agents up
rejects the step as claimed outside the registry. Release the claim,
materialize the surviving branch, then retake β the fetch above already
made it local:
bd list --status in_progress # the orphaned worklist
bd reopen <id> # release the dead machine's claim
bro work enter <id> --branch loop/<id> # resume a loop run's tree (work/<id> likewise)
bro fleet agents up <id> # respawn a registry worker β claims freshOr just reopen β an open bead is claimable again, so bro flow loop
retakes it on its own.
When bd sync cannot authenticate
Dolt's git client does not use the gh credential helper or
~/.git-credentials, so a git+https:// dolt remote is dead on machines
whose GitHub auth lives in gh. Route the store through a local mirror:
git clone --mirror https://github.com/<org>/<repo>.git /tmp/<repo>.git
bd dolt remote add file git+file:///tmp/<repo>.git
bd dolt pull --remote file # first pull
bd sync --remote file # pull+push thereafterA --mirror clone carries refs/dolt/data; refresh it before each sync
with git -C /tmp/<repo>.git fetch origin. After dolt pushes into the
mirror, publish with git -C /tmp/<repo>.git push origin refs/dolt/data.
Peer rigs keep their beads on their own refs/dolt/data (often a
dedicated *-beads repo) β repeat the mirror step per store.
Snapshot branches
Evacuations push dirty worktrees as snapshot branches (e.g. evac/*),
merge state included. None are needed for the rig to run β restore one
only when the work it captured matters:
git fetch origin '<prefix>/*:<prefix>/*' # e.g. 'evac/*:evac/*'
git worktree add ../<repo>-<name> <branch>