The three release layers
Three publishing layers exist and must stay distinct. Conflating them breaks releases.
1. Compilers package
ghcr.io/workbooks-sh/compilers:{latest,<sha>} — the in-sandbox WASM compiler
toolchain (clang / mrustc+libstd / zig / go-yaegi / quickjs-ng) plus the JS npm
lane. Its own ghcr package. Published manually from a provisioned machine —
CI cannot build it. The staging allowlist (runtime/scripts/stage-tools.sh)
decides what ships; add a take line for any new compiler asset.
2. Runtime image
ghcr.io/workbooks-sh/runtime:{latest,<sha>} — the BEAM runtime + wasmtime +
litestream + the release, containing runtime/host/**. Built by CI on push to
main; it COPY --from's the compilers package (layer 1). Runtime code change →
push → CI rebuilds. Compilers change → publish layer 1 first, then CI rebuilds the
runtime on top.
3. wb deploy (Deploy Kit) — users only
The tool for consumers with the CLI to deploy the runtime image for their own
use — locally (krunvm/podman/docker) or cloud (Fly), to their registry. Never
wire platform-release ops into wb deploy.
Rule of thumb: compilers ship as their own ghcr package, published manually; the
runtime ships via CI; wb deploy is the user's tool to run the runtime.
See Deploy locally and Deploy to the cloud for the user path.