Skip to content

An envkernel _p snapshot blocks every install, and nothing reports it until a build refuses twelve minutes in

scope: generic · severity: finding · confidence: proven · subsystem: build

The state. apk sorts _p<timestamp> ABOVE -rNN, so an envkernel dev snapshot left in the local repo wins against the release the world file asks for, and pmbootstrap install resolves to it. _ph_assert_no_devpkgs refuses the build when that happens — correctly, and only once the build has started.

The defect is not the refusal. It is that nothing asks the question early. On 2026-09-08 seven snapshots had been sitting in the repo since 2026-08-31. porthole doctor was clean. porthole next was clean. The build preview listed every rung as runnable. The only surface that knew was a shell function that runs after the work begins, and a porthole flash --yes on that host had already failed for an unrelated reason without ever reaching it.

So “can this host do a from-scratch install today” had no answer anywhere, and the honest answer was no.

Purging the repo is not sufficient, and this is the half that gets missed. _ph_assert_no_devpkgs has a second check: a _p kernel already INSTALLED in the rootfs chroot outranks every release, so apk add -U -u will not replace it — an upgrade request cannot downgrade -r28 from _p20260820013151-r0. Measured 2026-08-20: the repo was clean, tkpurge-devpkgs reported zero, and pmbootstrap export still shipped a kernel from an 01:31 envkernel build with every config symbol added that morning missing. apk info -W /boot/vmlinuz is what catches it. Timestamps do not.

What to do. Both questions belong in preflight, before a rung is chosen:

ls "$PMB/packages/edge/$ARCH"/*_p*.apk # the repo
pmbootstrap chroot -r -- apk info -W /boot/vmlinuz # the chroot, precise

A check that only reads the repo reports clean on exactly the case that cost a session.

The chroot question has a fast method too, and preflight has to use it. apk info -W /boot/vmlinuz shells out to pmbootstrap chroot, which costs seconds – fine for a one-off diagnosis, wrong for a check that runs on every preview. The chroot’s own status db answers the cheaper half of the same question directly, with no subprocess:

$PMB/chroot_rootfs_<codename>/lib/apk/db/installed

A flat text file: each installed package is a P:<name> line followed by others including V:<version>, blocks separated by a blank line. Scanning it for the kernel package’s V: and checking the version for _p<timestamp>-rNN measured 22ms on the reference host, against seconds for apk info -W. Verified against each other 2026-09-08: both agreed – linux-postmarketos-qcom-msm8998-7.2 at 7.2.2-r31, a release.

The two methods ask slightly different questions, and where they could diverge apk info -W is the one to trust: it asks what package OWNS the running /boot/vmlinuz, while the db scan asks only whether a _p build of the kernel package is installed at all (e.g. after a partial upgrade, the two could name different packages). For a preflight check running before anything else, the db scan’s answer is the one that is affordable to ask every time; apk info -W stays the precise fallback for a real diagnosis. Related: the-lock-says-who-not-what.