Rendered from docs/decisions/0091-the-runner-image-of-the-engine-release-build-is-written-in-the-workflow-because-it-sets-the-glibc-floor.md in the Headwater
corpus. Every document on this half of the site is typed by the taxonomy
the descriptor names: corpus.json.
The runner image of the engine release build is written in the workflow because it sets the glibc floor
Context
Before this record, the reason lived only in comments of .github/workflows/release.yml on 2026-09-27. They were the header (lines 44 to 53), the build matrix (lines 104 to 109) and the build step (lines 145 to 147). The build step of .github/workflows/release-taxonomy.yml (lines 89 to 91) cited the same reason for --locked.
.github/workflows/ci.yml reads its runner from the CI_RUNNER repository variable. That is correct for a verdict about a commit, because a move between the self-hosted runner and a hosted image then costs no commit. A person can change that variable with no commit and no review.
The glibc archive of an engine release needs the glibc version of the image that built it. README.md states that floor to an adopter as a fact about the download. The archive is built on ubuntu-24.04, so it needs glibc 2.39 or later.
Decision
Each row of the build matrix in release.yml names its runner image in the workflow file. No job of release.yml reads CI_RUNNER or any other variable for its runner. A change to an image is a diff in release.yml that a reviewer reads.
The release build runs cargo build --release with --locked. The binary that an adopter downloads resolves the committed engine/Cargo.lock, and not the dependency versions that resolve on the day of the build. The taxonomy release builds its engine with --locked for the same reason. Group 7 of tools/engine/build-declaration-fixtures.sh holds the flag. It reads every tracked file for a cargo build that names -p headwater-cli. So it reads the build step of both release workflows, and it names a copy with no --locked.
Consequences
The glibc floor of the archive moves only with a reviewed commit. A reviewer of that commit can then check the sentence in README.md that states the floor. No fixture compares the image with that sentence.
A move of CI between runners does not move the floor of the release archives.
The musl archive needs no C library, so its floor does not depend on the image. The smoke job for the musl archive runs it on debian:bullseye, which carries glibc 2.31, to show this.