The pack integrity tests failed whenever another run was writing
dist/, reporting a corrupt archive when the only fact established was
that somebody else was building. Which test went red depended on how
far along that build was. They skip now, the way validate_schemas
already does.
The README said 14 files were 'not in the collection yet', which
implies somebody could still put them there. Nine of them cannot be:
WHDLoad.key is a per-user signed registration, Custom.dat and key.txt
are slots the emulator expects the user to fill, gpib.rom and
dragonfly-2.3.rom have never been dumped, CARTS.CRC belongs to a dead
code path. The profiles already record why, so the two are now counted
apart: five still to be found, nine that cannot be.
install.py fetches a file from its repo_path or from a release asset.
Resolution can land on a file the database does not index, and the
entry then shipped with neither: a line in the download list that can
only ever fail. Those are recorded as omitted instead, which is what
the installer already knows how to report, and a test holds the
committed manifests to it.
validate_schemas read dist/ while a build was writing it and reported
a half-written pack as 'File is not a zip file'. It takes the shared
lock --verify-packs uses, and says so when a build holds it.
A required-only build is narrower than the platform declares by
design, like the source-restricted variants already handled, so the
full expectation must not be applied to it. --region is also refused
alongside --manifest-targets, which carries no region dimension.
Links to this site get shared on Discord, Reddit and forums, where a
page with no Open Graph tags renders as a grey rectangle. The pages
already carry a per-page title and description, so a theme override
fills the tags from those; mkdocs-material would otherwise only emit
them through its social plugin, which pulls in Pillow and CairoSVG to
render a preview image these pages do not need.
Decorated site pages carry the generation stamp twice: once as the
markdown footer and once as a rendered element. write_if_changed knew
only the first, so every page was rewritten on every run for the clock
alone.
The comparison is what makes the deploy-site freshness guard a real
staleness check rather than a guaranteed failure, and it had no tests.
generate_emulator_page carried a 228-line loop body rendering one file
row from thirty-odd optional fields, which put its complexity at 141,
more than twice the next function in the repository. The row renderer
and its badge strip are now their own functions and the page function
sits at 68.
_forge_sources went from 18 to 32 when it learned to pair each
repository with its own revision; the pairing is now its own function
and the caller is back under the threshold.
Verified by regenerating the site and diffing: all 505 pages are
identical apart from their generation timestamps.
The job carried if: false, which blocks workflow_dispatch as well as
push, so there was no way to cut a release through CI at all and the
comment described a temporary state that had become permanent.
Releasing is deliberate: the push trigger is gone and the job runs when
someone dispatches it. The seven-day rate limit stays as the guard
against dispatching twice, and concurrency no longer cancels a run that
may be midway through uploading assets.
The cached hashes were rebuilt by iterating a set, so their order in
each database entry followed set hashing rather than a declared one. A
run with a warm cache rewrote all 7,850 entries with no content change.
The order is now the one compute_hashes returns, and a test holds a
warm-cache run byte-identical to a --force rehash.