Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ADR-0014: Declarative image builds — build backends + the building state

Status: proposed | Date: 2026-07-08

References: ADR-0005, ADR-0008, ADR-0011

Context

Four tiers of image production exist. Only CI-built and in-loop candidate builds are automated. Hand-built images (sandboxes, loop-openshell) use mutable tags and hand-plumbed digests. Version-knob choreography (VLLM_VERSION, REPO_SHA, WORLD_BASE) is synchronized by convention, not tooling.

Decision

One BuildBackend contract with two implementations: Cluster (detached rootless-buildah Job) and GithubActions (workflow_dispatch + poll). Named builds are declared in the domain manifest as [build.]. Digests are resolved by crucible itself via the registry. watch.paths defines when a build is needed. The template vocabulary is closed (no string injection). The controller blocks measurement on an explicit "building" state. crucible build provides a CLI for human-invoked builds.

Consequences

Positive: onboarding domain images becomes a manifest edit. Digests flow mechanically from the registry. Measurement rig can never run on a stale or half-built image because the controller blocks measurement on the explicit "building" state.

Negative: two build backends to maintain. The template vocabulary is deliberately closed, which limits extensibility. The "building" state adds a new controller lifecycle phase.

Alternatives Considered

One BuildBackend contract with Cluster and GithubActions implementations; named builds in manifest [build.]; digest resolved via registry; controller blocks measurement on building state (accepted)

Generate workflow files on the fly per domain (rejected)