Rendered from docs/explanations/how-a-headwater-release-reaches-an-adopter.md in the Headwater
corpus. Every document on this half of the site is typed by the taxonomy
the descriptor names: corpus.json.
How a Headwater release reaches an adopter
Scope
This page states what an adopter gets from a Headwater release, and how the adopter can trust it. It is for a person who installs the engine, or who pins a version of the headwater/standard taxonomy in a corpus. It states no new rule. Each fact comes from one of the decisions that it draws on, or from the install section of README.md. Where this page and a release workflow disagree, the workflow is correct and this page is stale.
How a maintainer cuts a release is out of scope. Cut a release and the process decisions that start at HW-PD-0009 hold that account. This page also does not rule whether the kinds of this corpus follow the four modes of Diátaxis (HW-OBL-0097).
How it works
Headwater has two release lines. Each line has its own tags, and each line gives a different thing to an adopter.
- The engine line. A tag that matches
v*starts the engine release. It attaches theheadwaterbinary in archives for Linux and macOS (HW-DR-0088). - The taxonomy line. A tag that matches
taxonomy/headwater-standard/v*starts the taxonomy release. It attaches one zip of theheadwater/standardpackage (HW-DR-0088). - One field links the two lines. A tag cannot match both patterns, so no release waits on the other. The package states the oldest engine that it needs in
requires_engine. When a package raises that value, the engine release that satisfies it comes first (HW-DR-0088). - The taxonomy zip comes from the source at the tag. The taxonomy release builds the engine at the tagged commit, and it runs
headwater taxonomy publishontaxonomy-source/headwater-standardat that commit. It never attaches the copy of the package that the repository keeps under.headwater/packages/(HW-DR-0089). - The release notes state the digest to pin. Each release of either line prints the
release.digestofheadwater/standardin its notes. The taxonomy release prints the digest that its ownpublishrun printed. The engine release prints the digest in the release record of the tree at its tag (HW-DR-0090). - The adopter pins that digest. The adopter writes the digest into
.headwater/taxonomy.yml, or gives it toheadwater taxonomy vendor --expect.vendorcomputes the digest again from the files, and it refuses a package that does not match the pin (HW-DR-0022). - The runner image sets the C library floor. Each build row of the engine release names its runner image in the workflow file, and no variable changes it. The glibc archive needs the glibc version of that image. The build uses
--locked, so the binary uses the dependency versions in the committedengine/Cargo.lock(HW-DR-0091). - The APT repository is signed only when the signing secret is set. The engine release also builds one
amd64Debian package. The package holds no taxonomy, so the adopter runsheadwater taxonomy vendorafter the install. When theAPT_SIGNING_KEYsecret is set, a subkey signs the metadata of the APT repository onheadwater.tools. When the secret is not set, the release carries the Debian package and no metadata. Each deploy of the site then stops, so the site keeps the APT repository of the last signed release. CI holds that subkey, and the owner holds the primary key offline. Rotate or revoke the APT signing subkey says what an adopter does when that key changes (HW-DR-0094).
The table shows what each route gives an adopter, and what the adopter checks.
| what the adopter gets | from | what the adopter checks |
|---|---|---|
the headwater binary in an archive |
an engine release, tag v* |
the checksum file beside the archive, with sha256sum -c |
the headwater binary in a Debian package |
the APT repository on headwater.tools |
apt checks the signature of the repository metadata, which the release signs only when the APT_SIGNING_KEY secret is set. Without the secret, this route does not exist for that release. |
the headwater/standard package as a zip |
a taxonomy release, tag taxonomy/headwater-standard/v* |
headwater taxonomy vendor --expect <digest>, with the digest from the release notes |
README.md gives the commands for each route, and the current version of each line.
Why it is this way
Each record below holds the reasons for one part of the design. This page does not repeat them.
- The two lines have tags that cannot collide, and
requires_engineis the only link (HW-DR-0088). - The zip and the tag make one claim, because the zip comes from the source at the tag (HW-DR-0089).
- The adopter pins the digest from the release that the adopter downloaded (HW-DR-0090).
- The runner image is in the workflow, because it sets the glibc floor that an adopter reads (HW-DR-0091).
- When the APT repository exists, a key that CI holds signs it, and the owner's offline key certifies that key (HW-DR-0094).
- A digest is a check against a pin that a person committed, and it is not a signature (HW-DR-0022). Whether a pin can also prove who published the package is an open question (HW-OBL-0115).
When one of these records is superseded or withdrawn, headwater check reports this page through its draws_on edge, and this page must change with it.