The publish-snap verifier had never run against a real release and
encoded three stale expectations that the tag build's own validators do
not share:
- it required the app under usr/lib/iptvnator inside the snap, while
Electron Builder's snap target ships the app at the snap root
(/iptvnator.bin, /resources/**) — the layout the packaged smoke tests
exercise;
- it validated the source archive's runtime manifest with the raw
source-build validator, but the archive carries the STAGED manifest
(origin "vendored-lgpl" + sourceBuildOrigin) written by
stage-runtime.mjs; the staged envelope is now checked explicitly and
the remaining fields still go through the shared validator via an
origin projection;
- it deep-equaled the snap's bundled sourceRuntime against the archive
manifest, but the snap bundles the builder view (no staging
envelope); the binding now projects the envelope away first.
Verified end-to-end in a Linux container against the real v0.23.0
release assets: release-snap-assets.cjs verify now passes and emits the
sealed snapshot receipt. Regression tests cover the legacy usr/lib
layout and staged-envelope mismatches.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The "Build pinned Linux Embedded MPV runtime" job failed twice on 2026-08-11
because www.freedesktop.org answered GitHub runners with HTTP 418 for the
fontconfig tarball. The Linux builder curled a single pinned URL with no
fallback, so upstream rate-limiting reddened the build.
Route downloadArchive() through the shared downloadPinnedSource() helper the
macOS builder already uses, and pin a mirror for each single-host source:
fontconfig and libdisplay-info (freedesktop-hosted) plus freetype, which the
macOS builder already mirrors. Each mirror was downloaded and verified to hash
to the existing pin. The curl hardening flags and assertArchiveMatchesPin are
unchanged, and the helper verifies every candidate against the same SHA-256,
so a mirror serving different bytes is rejected rather than used.
Unlike macOS, the Linux manifest keeps sourceUrl at the canonical pinned value
even when a mirror served the bytes: notice generation and the Snap publication
boundary compare that field against the immutable pin. A used mirror is logged
instead.
build-linux-runtime.mjs now imports the downloader, so download-pinned-source.mjs
joins the released source-archive tooling set (otherwise the archive would ship
a build script it cannot run) and the Linux runtime cache key.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>