Running a host on cairn is forking a shell and pushing. An instance repo is a fork of one base variant plus the host-specific config: edit the Containerfile, point the base_image input at the variant you need, and push to main. CI builds and promotes that fork on its own and never reports back upstream, and the same shape carries a public example and a private host.

A fork rides a base tag the catalog has already promoted, so an instance does not boot-smoke itself: its promotion criterion is a green build against that tag.

Four lanes

cairn/example holds one forkable lane per posture, in one history. Three are rungs of a disk-encryption ladder. The fourth answers what can be shown about an image before it lands on disk, and composes with any rung.

FOUR FORKABLE LANES DISK-ENCRYPTION LADDER ORTHOGONAL PLAIN no encryption bootc + composefs ATTENDED passphrase LUKS a human at boot EDGE TPM-bound LUKS + recovery key EVIDENCE signed and attested composes with any rung BAKES nothing no LUKS at all BAKES nothing demote post-install BAKES tpm-rebind /usr/local/bin BAKES policy + key reject by default

A lane is named for the posture it demonstrates, and most of a posture is an install-day procedure: only edge and evidence carry anything for theirs in the image itself.

Pick a rung by who is present at boot. Nothing at rest worth protecting, rebuilt every pipeline: plain. A human types a passphrase: attended, whose posture is reached by demotion: add a passphrase, then retire every TPM keyslot. An unattended box that has to reboot on its own: edge, which swaps the install-time TPM slot for one bound to a signed-PCR11 policy over measured boot state, with the instrument baked in so the installed host has it at hand.

evidence is the lane that enforces at runtime. Its baked policy rejects any image outside its own repository and requires a valid signature inside it, so podman pull and bootc upgrade reach one verdict from one file. It is also the one lane that opts into signing at promotion, where the digest is signed and an SBOM and SLSA provenance are attached to it. The trust page carries the key and the verification story; the lane’s README carries the two settings a fork has to get right.

The contract is the same as any instance: fork it, keep the lane you want, edit its Containerfile, push.

whetstone, a real consumer

whetstone builds the golden image the estate’s own CI runners boot.

WHETSTONE: THE SELF-HOSTING LOOP BUILDS THE NEXT BASE IMAGE cairn/base pinned by digest LAYERS runner toolchain Containerfile layers DISK qcow2 install to-disk, ext4 EXECUTOR runner VM runs cairn's CI

The loop closes on itself: cairn's CI builds the operating system its own executors run, so the runner VM is one more instance of the thing it builds.

It layers the runner toolchain onto cairn/base as ordinary bootc Containerfile layers, so the executors and every other instance share one base and one supply chain. The qcow2 a runner boots comes from a standalone lane triggered by hand, because a multi-gigabyte disk build has no business running on every push. It runs bootc install to-disk --via-loopback, the same installer that puts an instance on metal, onto ext4 because sealed composefs needs fs-verity and xfs does not support it (D8). No user or SSH key is baked into the disk; provisioning happens after first boot, the same way every other instance gets its specifics. Install-day media and the walkthrough are on the install page.

Day two

A promoted base rings each instance’s doorbell. cairn/base posts one trigger per instance and never watches what it started, so each instance rebuilds in its own pipeline and owns its own verdict. The instance list lives in a protected group variable, so no public file names a consumer.

The cascade stops at a promoted image. No CI reaches a running host: an operator runs bootc upgrade and reboots on that host’s own timeline.

What a private host adds

A private host instance is the same fork-and-roll shape with real users, SSH keys, services and branding layered on top, and that layer is what stays private. Anyone can lift the build path from the public catalog; nobody can lift the deployment.

The seam holds at verification. A private host runs promoted digests, and anyone, including the host itself, can re-verify one against the cosign key on the anchors page, or ask the running host which certificate signed its source-built kernel modules with modinfo -F signer zfs. Trust comes from the fingerprint, reached out of band, not from access to the repo.