Cross-host development#

A developer on one host can hand a branch to a worker on another host to build: develop on the thin box, build on the beefy one. Build outputs already cross hosts through the The build Store; this page covers the input side, the per-host ref channel that lets a development branch travel from one host to another over SSH (see ADR 0001, bare is the working repo).

The model#

Same-host, a developer and a worker share one Bare, so publishing a branch is just a commit and the worker builds it. Cross-host, the developer pushes the branch to the peer’s Bare over SSH, and the peer’s worker builds it from its own refs/heads/*. No build-flow change is needed, because prepare() already resolves a literal ref against the local Bare.

Refs (build inputs) cross by git; Store entries (build outputs) cross by nix copy. The two directions are independent: the peer remotes described here have no bearing on the Mirror or upstream remotes, nor on the Store catalog.

Peer remotes#

A peer is named by its SSH-host alias, the same alias the developer would type to ssh into the other host. Provisioning registers each alias as a remote on every Bare on this host, with the remote’s URL derived from the shared System workbench layout:

ssh://<peer>/<SYSTEM_DIR>/bare/<project>.git

and the refspec:

+refs/heads/*:refs/remotes/<peer>/*

The URL derivation assumes peers share this host’s SYSTEM_DIR path, which holds when the hosts share a home directory (for example one NFS-exported /home). The refspec maps the peer’s heads into a private refs/remotes/<peer>/* namespace, so a fetch from the peer never collides with local branches.

Provisioning only wires the remote; it does not fetch. Push is the workflow, and a peer may be empty or unreachable at provisioning time. If the remote already exists its URL is refreshed in place, so re-running is idempotent. List the other hosts as peers, never the host itself.

SSH prerequisite#

A peer alias resolves through ~/.ssh/config, and the transfer uses the same passwordless SSH the Store uses (the transfer devShell’s OpenSSH). Keep ~/.ssh/config at mode 0600.

Provisioning#

Run f/workbench/init (which drives f/workbench/fetch) with a peers list of the SSH-host aliases of the other hosts:

$ wmill flow run f/workbench/init --data '{"peers": ["hetzie"]}'

The peer wiring is implemented by the _ensure_peers helper in f/workbench/fetch.py: it adds (or refreshes) one <peer> remote per alias on each Bare and sets the +refs/heads/*:refs/remotes/<peer>/* refspec, printing each remote it touches.

Workflow#

The cross-host loop has three steps, given hosts A and B.

Provision peers on both hosts#

Provisioning is symmetric: on host A pass peers: ["B"], and on host B pass peers: ["A"]. Each Bare now carries a remote for the other host.

Publish a branch#

Push from a developer worktree on A. The worktree shares A’s Bare, so it inherits the <peer> remote:

$ git -C <worktree> push B HEAD:refs/heads/<branch>

The branch lands in B’s Bare as refs/heads/<branch>.

Build it on the peer#

Run B’s build flow with the branch as the ref:

$ wmill flow run f/kernel/build --data '{"worktree":{"git_ref":"<branch>"}}'

B’s prepare() resolves <branch> locally, because it is now a refs/heads/* entry in B’s Bare and needs no fetch. It lays B’s warm worker worktree under the fixed main group and builds. The build’s run layer can then travel back to A through the The build Store, closing the build-on-B, boot-on-A loop.

Fetch direction#

The +refs/heads/*:refs/remotes/<peer>/* refspec also lets a host fetch a peer’s development branches in the read direction:

$ git -C <bare> fetch <peer>

This is the symmetric counterpart to the push above. Push is the default developer flow; fetch is available when a host needs to pull a peer’s branches into its own refs/remotes/<peer>/* namespace.

The durable Bare#

These peer remotes live on the Bare, the durable working repo that holds development branches and worktrees (see Bare). The Bare is the ref channel between a developer and a worker, and the peer remotes extend that channel across hosts: the same per-host durable repository that anchors same-host collaboration becomes the cross-host endpoint, reached over SSH at a predictable ssh://<peer>/<SYSTEM_DIR>/bare/<project>.git address.