The documented example looked up a test fixture hash, printed NOT FOUND
and exited 0. The docs now use a hash the database holds and say which
line forms a hash file accepts.
A count of assets misses a failed upload beside a stray file and a part
re-uploaded from an older build. check_release.py holds each asset's
GitHub sha256 against SHA256SUMS.txt and release.json, and the release
process publishes the draft only on its clean exit.
The documented command, discover tests, makes tests/ the top level,
so tests/__init__.py never ran and the variable it sets to keep tests
offline was missing from every local run. Every documented and CI
run now passes -s tests -t ., and a test requires it.
verify accepted --verbose beside --json and dropped it in every
mode, so the output was the same with or without it. The JSON now
lists every entry with its ground truth under --verbose.
A prose citation whose text lived under several pins stayed in
read again until the text changed, so fixnes, zesarux and emucorex,
exact at their pins, would have refused every later bump.
prose_written_at names the pin a reader confirmed; it settles the
readings and never overrides a history with one candidate.
Dolphin and its forks hash dsp_rom.bin and dsp_coef.bin together and
warn on any combination outside known_roms. The profiles now carry the
accepted pairs, and the resolver keeps both files inside the first pair
the collection holds whole: MMJR and Ishiiruka were served the free ROM
beside the official coefficients.
Both run on Linux but inherited RetroArch's case folding, so a core
file differing from a platform name only by case left their packs:
MesenCE's bios.col and np2kai's lowercase 2608_*.wav, which those
cores open with that exact case. They are now case-sensitive, the
shared groups fold only where the platform does, and Lakka gets its
own pack instead of sharing RetroArch's.
Recalbox ships libretro/mame built at 0.258 and at 0.278, and no
profile described either release. mame_hash_scraper gains --release,
which reads the BIOS root sets at one mamedev tag and writes a profile
pinned to it; mame0258 and mame0278 are generated from it, every
source_ref anchored at its tag.
Step 2 refreshed the data directories, then the pack build and the
manifest build refreshed them again, so a tree tracking a moving
branch could differ between the pack and the manifest. generate_pack
gains --no-refresh-data, which packs the cached trees and still
fetches release assets; the online pipeline passes it to both builds.
nethersx2-turnip-classic documents the shim rules of the revision it
pins, and says so in prose: the classic build is that revision. Compared
to HEAD it reported the same two changes every pass, and recaling would
have repointed its refs at rules this build never had.
pin_frozen says the freeze is deliberate, and the profile is then judged
against its own revision, exactly as one pinned to a superseded tag
already was. Recale and bump are refused for it, which is what makes the
declaration safe to trust.
Recaling refs while the pin stays put produces exactly the state the
all-or-nothing rule exists to prevent: a profile whose refs describe one
revision and whose source_commit names another. The tool manufactured it
on mariani, where three prose runs it could not rewrite kept
bump_commit refusing while eleven refs had already moved.
Asking for both writes is now atomic. The work happens on a copy, which
is promoted only when the pin follows, and a rebase is refused outright
when something visible beforehand will hold the pin: an annotated ref,
one under a mode key, or a prose run whose tokens cannot be located well
enough to rewrite. Where the block only appears after the write, the
copy is discarded and the profile is named on stderr rather than left
half moved.
mariani is back on its pin and stays at four refs to read, which is
honest: three of them have to be rewritten by hand before anything can
advance.
An empty file list is the one assertion here that ages unwatched. Nothing
can go missing and no ref can drift, so nothing notices when a core that
embedded everything grows a path. virtualjaguar said "No external BIOS
files are required or loaded by this core" while its source had grown
eleven filenames read from the system directory, and only a reading
found it.
fileless_audit looks for the request itself, the system directory ask, in
the sources each profile already cites. Over the 151 fileless profiles it
named eleven, of which two were covered by data_directories, six carried
an exclusion_note, and three had nothing written down at all: craft
writes its world database in that directory, dice stores the answer in a
variable no other file in the tree names, lutro hands it to the Lua game.
Each now says so.
The check settles: declared files, a declared directory, or a written
answer all end it, so what it reports is the set nobody has read yet. A
test holds the corpus at zero.
profile_sync follows content, so a ref that drifted still anchors where
the cited text went. That is drift detection working, and it cannot
answer the only question a MAME romset ref asks: does this line declare
this set. It flagged five refs in one driver file where nineteen were
stale, the fourteen others having been relocatable somewhere plausible.
mame_ref_audit asks the stronger question and found ninety-two across
the four profiles whose upstream still moves: mame 66, mamearcade 18,
mamemess 6, groovymame 2. Each had exactly one declaration to point at.
The frozen generations, mame2009 through mame2016, come out clean, which
is the check saying it finds drift only where drift can happen.
The set name is argument 1 of the machine macro. Matching it anywhere on
the line matches every clone naming it as parent, which is most of a
driver, and comments are stripped first because a declaration can sit
behind one. A set no machine declares is reported as not judgeable, not
wrong: device archives take their DEFINE_DEVICE_TYPE shortname.