11. Versions: CalVer tags for released images, the gbook version in uname -r
Status
Accepted 2026-11-04 (owner: “all a” to the open questions 2, 3, 4, 6 and 8 of milestones-versioning.md, section 5). Question 5 (patch status lines) is an update to ADR 0007.
Context
- Several things change at different rates: the repo (every commit), the boot image (every
package-image.sh), the kernel base (a re-pin), the local patches, and the boots themselves. Each boot has an attempt IDYYYY-MM-DD-Ninattempts.tsv. The repo has no tags. An image is identified only by its kernel banner (release plus UTS#N). - SemVer requires a declared public API (semver.org 2.0.0, item 1), and gbook has none. CalVer suits projects whose releases are driven by external changes (calver.org, “When to use CalVer?”). Here those changes are the mainline base and the milestones.
- Annotated git tags “are meant for release” (
git-tag(1)), andgit describereads only annotated tags by default. scripts/setlocalversionat the pin appends the contents oflocalversion*files in the object and source dirs to the release.init/Kconfigcaps the release at 64 characters.- The pin
a804c57is a 7.4 merge-window commit, 1703 commits afterv7.3and beforev7.4-rc1(GitHub compare API, research note section 2).
Decision
-
A release is a base image with 3 clean cold boots. A base image has no debug command-line or DT extras (
scripts/attempt.sh stickreadsbase image). The 3 boots of one image hash are counted byscripts/attempt.sh tally, and the image is one the owner would hand on. Every other image is an experiment, named only by its attempt IDs. -
A release gets an annotated tag
vYYYY.0M.0D[.MICRO](CalVer, e.g.v2026.11.20;.1for a second release the same day). The tag goes on the gbook commit that built the image, after its 3 boots. The image must have been built from a clean tree (no+in itsuname -r). No SemVer. -
The tag message is the release note until a tagged image first leaves the build host. From then on,
CHANGELOG.mdin Keep a Changelog 1.1.0 form is the release note. The message contains:- the milestone;
- the kernel base (
a804c57, “v7.3 + 1703, 7.4 merge window”) and the kernel release fromuname -r; - each local patch with its status line;
- the image sha256 as
scripts/attempt.sh stickprints it; - the attempt IDs and the
tallyline that proved it; - what changed since the last tag.
-
uname -rnames the gbook state.scripts/build-kernel.shwriteslocalversion-gbookinto the build directory (theO=dir, never the source tree). Itsgbook_localversion()gives the exact rules, and check 35 tests them:-gbook-plusgit describeagainst the nearest annotatedv[0-9]*tag, without thev(-gbook-2026.11.20-3-g1a2b3c4);-gbook-g<hash>before the first tag;- a trailing
+when the tree differs from the commit (changed tracked files, or untracked ones that are not ignored).
Today that reads
7.3.0-gbook-g6934235-ga804c5742bff-dirty. The kernel tree’s own-dirty(the applied patches, ADR 0007) stays. A released image keeps the-gbook-g<hash>it was built with, because the tag comes after its boots. The tag message maps that hash to the version, and a rebuild at the tag would be a new, unproven image. Thekernelcolumn ofattempts.tsvalready records the release, so each attempt names its gbook commit, and no new column is needed. -
Upstream series use the kernel’s scheme only. That means
[PATCH RFC], then[PATCH vN], with the per-version changelog below---andgit format-patch --base(submitting-patches.rstat the pin). A gbook version never appears in a patch subject. -
The pin moves onto a mainline release tag. The next re-pin is onto
v7.4(or the release current then), after M3 and before M5 in any case (ADR 0010). After that, the pin moves at most once per mainline release. Each re-pin re-checks every local patch (check 20) and the DTS, and the first base image on the new pin needs its own 3 clean cold boots before it can be released.
Consequences
- No tag exists on 2026-11-04. The image on the stick is a test image (
gbook.suspend=1 no_console_suspend), and no base image with patches 0008 and 0009 has 3 clean cold boots yet. - Every gbook commit changes the kernel release, so a rebuild relinks the version objects. The UTS
#Nkeeps counting builds as before. - The release grows by about 20 to 33 characters (worst case
-gbook-2026.11.04.1-12-g1234567+), which stays under the 64-character cap. - A tool to cut a release (check the tally, compose the tag message) is not needed until M3. It is left for then.
- Verified on 2026-11-04: build
#25(kernelImage52734464 bytes) reads7.3.0-gbook-g8493ab4+-ga804c5742bff-dirtyininclude/config/kernel.release, andscripts/image_uts.shreads the same release from theImagebanner. The+was an uncommitted log edit at build time. - The
v7.4re-pin replaces patches 0002 to 0007. Their series has a v2 (2026-10-30) that drops 0003 and adds four patches, and torvalds master’scf27afc3bd6e(“drm/msm: default separate_gpu_kms to auto selection”) conflicts with 0002, 0003 and 0005 to 0007 (patch-status lookup, 2026-11-04). The status lines of ADR 0007’s update record both.
Update 2026-11-04 (2:03 PM ET): a release names the rootfs too
Owner, M3 round (“yes” to question 10 of m3-rootfs.md). From M3 on, a release is two
artifacts: the KERN-A image and the rootfs image (ADR 0012). The tag message adds
the rootfs image’s sha256, its snapshot.debian.org timestamp and the hash of its lock list, next to the KERN-A image
hash that scripts/attempt.sh stick prints.
Update 2026-11-04 (8:39 PM EST): the first release, v2026.11.04
Tagged by the owner from scripts/release-draft.sh M3 '^2026-11-04-2[123]$' at commit 506159b: kernel
7.3.0-gbook-g82c43ed-ga804c5742bff-dirty (patches 0001 to 0009), KERN-A image 9673d6d782ef4cdb, rootfs
4b0e2e027c0b2d74… from snapshot 20261104T000000Z (lock 12f96fa08768262e…, 321 packages), 3 clean cold boots.
Two things the first real run taught the tool: the Attempts line must come from attempts.tsv (tally lists every
id on one line), and git log -n 40 rather than | head, which ended the script by SIGPIPE under pipefail before the
owner’s tag line. The tag also records the rootfs read back from the stick (attempt.sh root-verify, retro-9/01):
release-draft.sh refuses a stick whose ROOT is not the manifest’s rootfs.
Update 2026-11-05 (9:54 AM EST): the second release, v2026.11.05
Tagged by the owner from scripts/release-draft.sh M3 '^2026-11-05-5$' at commit 69edd54: kernel
7.3.0-gbook-2026.11.04-35-g7c6a1aa-ga804c5742bff-dirty (patches 0001 to 0011; the two new ones, 0010 and 0011, keep the four
speakers through the SoundWire masters’ runtime PM wakes), KERN-A image bc62c69ecf560525 (the sound node in the board DTS, no
extras), a rootfs from the same snapshot and lock as v2026.11.04‘s (20261104T000000Z, lock 12f96fa08768262e…, 321 packages),
rebuilt 2026-11-05 as 6fea12f2… (the audio group, the m3-swrm capture; the udev rule tried that night never shipped), 3 clean cold boots (attempt 2026-11-05-5), the four spoken channel names heard on each boot and the
microphones’ capture heard played back. The AP console was absent for the three boots (the SuzyQ was unplugged on the build host’s side);
the bar’s evidence is the netlog, which attempt.sh tally reads. The draft ran once before the final docs commit and again on it,
so the tag file names the tagged commit: run it last.