0.2.3's manifest pinned the sha256 of one Android build's focal64
(16.82.0, the build the dev phone runs). Fairphone re-signs the trustlet
every release, so that pin matched exactly one of the six builds seen,
and two of two field reports had no sensor: one user on 16.100.0 edited
the manifest by hand, another ended up with a file QTEE refuses.
The manifest now carries '-' instead of a hash and depends on
fp6-vendor-blobs 1-r3, which tries the active slot first and verifies the
image's structure; QTEE's signature check is the gate it always was (one
flipped byte -> ERROR_ELF_SIGNATURE_ERROR, measured 2026-09-03 and again
today).
post-install reassembles the trustlet right away, so 'apk add' no longer
needs a boot for it. post-upgrade re-derives it from the active slot,
which replaces a hand-placed or wrongly pinned file, and then restarts
the daemon -- a plain restart, so a daemon that exited on a refused
trustlet comes back up on the re-derived one.
loadFromBuffer failures name the loader's verdict. The field's first
report was a bare result=12; it now reads ERROR_ELF_SIGNATURE_ERROR with
what to do about it. Probed on the phone with this build: a one-byte
tampered image and 100000 random bytes both print it, the pristine image
loads, and the suites pass 8/8.
fp6-vendor-blobs learned the mbn directive in 1-r2. The extractor before it
exits on an unknown directive, so a fresh flash with 1-r1 and our
20-focal64.manifest processes the audio fragment and then fails the blobs unit
on ours: a red unit, no trustlet, and nothing in the daemon's own logs to say
why. Saying >=1-r2 makes apk refuse a combination that cannot work instead of
installing one that fails at first boot. Existing installs never saw this --
the old fast path only checks file lines and exits before the dispatcher.
apk also swaps the binary on disk and leaves the running daemon alone, which is
how 0.2.2's FingerMatched signal first presented: a clean MATCH in the journal
and nothing downstream, because the boot's 0.1.3 was still answering. A
post-upgrade try-restart closes that. A daemon that is not running stays not
running, and a build chroot without systemd is left alone.
0.2.3, so the package CI publishes it.