When the region's file is absent, libretro.c (7fea57a5) finds no name and no matching sha1, then maps its built-in OpenBIOS (libretro.c:3425-3511). The region runs show it: each region's disc reaches its game with only the other regions' BIOS staged, under the oracle's reference frames (records 2026-10-27-55dd1e4943c4, 13be0e68b799, 33780d47efdf). scph5500.bin, scph5501.bin and scph5502.bin are required: false, hle_fallback stays true. Written through campaign_profiles.
Beetle PSX, Beetle PSX HW and SwanStation rerun under the oracle with the Japanese BIOS menu as an error screen: a Japanese BIOS under a US disc is now a BIOS error.
Without a BIOS, PCSX2 logs and shows 'PCSX2 requires a PlayStation 2 BIOS in order to run'. That line is now one of PCSX2's error patterns, for the next run's verdict: this record was judged without it.
Twelve runs on each of beetle_psx and beetle_saturn: each region's game with every regional BIOS, its own only, the others only and the region pack. One DuckStation check on the US disc with and without scph5501.bin.
Every reference block's run, judged again with the oracle as committed, boots in each repetition. Beetle Saturn's three BIOS lines are BIOS errors, the Japanese menu screens are error screens, and the PlayStation cores carry no error pattern.
Run output on a platform's Tested block is escaped for HTML, MDX and Markdown. inline_html links only http(s) and relative targets, quotes escaped. Pack probe runs stay off the emulator pages, shown on the platform's.
Every value a run produced (claim, method, statement, host, flags, variant labels, core, content and file names) is escaped with quotes and its braces made inert for MDX, never read as Markdown. A record link is written only for an http(s) or relative target. Reference runs fold with the tests from before the oracle.
Puzzle Bobble 2 (Japan) and Bust-A-Move 2 (Europe) on the PlayStation cores, and the three Saturn editions on Beetle Saturn, each frame reviewed on its PNG. Beetle Saturn's BIOS error lines, read from ss.c, are its error patterns.
The first runs showed it: beetle_psx reaches the game of the US disc on the Japanese and European BIOS, through a different licence screen, so its frames differ from the full run while the oracle says boots. The interim rule read those frames as a failure. A variant now boots on the same frames as the full run or by its oracle verdict, and otherwise has no answer.
The interpreter bind took each link's grandparent, so ~/.local/bin/python3 exposed all of ~/.local inside the sandbox. A tree is now bound only when it is a Python prefix (lib/pythonX.Y) or a venv (pyvenv.cfg), never / or the home folder or above it. Every other link is bound as a single file, and a path inside a bound tree is not bound again, since bwrap cannot mount over a link in a read-only tree.
The sandbox bound only /usr, /lib and /bin. On the CI runner setup-python puts Python under /opt/hostedtoolcache, so the worker could not start and every core_probe and campaign run crashed (7 tests, plus their replay without jsonschema). A venv, pyenv or uv do the same. The interpreter's prefix and every link on the way to it are now bound read-only, each at its own path. Reproduced with uv's Python 3.13 outside /usr, 92 tests pass under it and under the system Python.
Merging the card and platform branches left two SHORT_HASH definitions, 8 and 12. The later one silently won, so the platform rows showed 12 characters while their tests expected 8. One constant now, 12, the card anchor's length. The copy-button selector skips buttons that carry their own data-copy, and the tests follow the merged markup.
Each file is a details whose summary is the row: name, folder when it is not the bare name, status chip. The short hash sits on one copy button beside it, since a summary is itself a control. Opened, the evidence runs across the list. A list with no folder drops the column. Code spans in the evidence are plain text.
The lists split by the share of a page they render to (elements against 10,000, bytes against 600,000) instead of Markdown length. With its parts, Batocera goes from 12 pages, 18,854 elements and 1.21 MB to 10 pages, 13,671 and 1.11 MB. A part that folds back into its platform page redirects there, from the record in website/src/data/platform-parts.json.
Reference runs, then the full set, no BIOS and negative variants of Bust-A-Move 2 (USA) on Beetle PSX, Beetle PSX HW, SwanStation, PCSX-ReARMed and PCSX1, each judged by the boot oracle.
A finding line is written again when the records behind it change, so an open finding cites the oracle runs rather than a frame comparison. A contradicted validation shows the checks the runs prove, content and size, beside the profile's list.
MAME's card pages, GroovyMAME and yaps2 read 13,000 to 16,700 words of
cards. Each entry is now a table row (name, members, status, short
hash) that opens to its card in a details block, with the site's filter
box and row counter. Pages from 150 entries and every split part use it.
Visible words: mame-files-1 16,680 to 1,612, groovymame 14,396 to 1,876.
A row costs about five elements, so a part holds 180 cards: MAME goes
from 8 parts to 9, the largest at 567 KB and 8,989 elements.
Each wanted list (TOSEC, No-Intro, Redump) opens on its counts, then one
table folded under a filter box that opens it, in place of a block per
DAT. Only the names are searched: indexed descriptions and hashes put
the PlayStation page ahead of the PlayStation 2 one.
A filtered row stayed visible on a phone: a stacked row's display:block
outweighed the hidden attribute on every stacked table.
standalone_probe now holds the host probe lock for one run, its load check included, as core_probe does, and the docs no longer wrap region_check or standalone_probe in flock.
The install box's select had a rule of its own that dropped the arrow
and read as a text field. It now takes the shared select rule and
--rb-select-arrow in both themes.