A fresh boot.img mtime says nothing about which kernel is inside it
scope: generic · severity: trap · confidence: proven · subsystem: build
Two failure modes in the envkernel loop are invisible in timestamps, and
both produce a new boot.img wrapped around an old kernel:
pmbootstrap build --envkernelcan abort on a staleumount .output/Makefile(exit 32) after writing the.apkbut before refreshing APKINDEX.installthen resolves the kernel from a stale index and packs an old vmlinuz behind a freshboot.imgmtime. Soindexmust run chained, and the exit codes ofbuild/indexare deliberately ignored — they lie.indexmust run while the chroot frombuildis still mounted: pmbootstrap bind-mounts the abuild signing key only while the chroot is active, so a standalonepmbootstrap indexafter a shutdown fails with “can’t cd /mnt/pmbootstrap” / “No private key found”. Never split them.
Because neither is visible in file times, the build must verify contents:
tkbuild ends by comparing the DTB inside the exported boot.img against the
one make just produced, and refuses to report success if they differ.
Generalise: when a pipeline can produce a fresh-looking artefact around stale content, the only honest check compares content, not metadata.
Related: stale-dev-package-outranks-your-build, stacked-bind-mounts-break-pmbootstrap.
