Commit Graph
1755 Commits
Author SHA1 Message Date
Abdessamad Derraz 9c8dbcd99a chore: merge the automatic test campaign 2026-10-27 14:05:18 +01:00
Abdessamad Derraz 332c217155 feat: pass GITHUB_TOKEN to declared API steps
A step marked github_token: true receives the token. autorun accepts the key only on check_freshness.py, refresh_stale.py and python -m scripts.scraper.* tracked in this repository, refuses it on any other step and in the campaign job. The nightly steps declare it.
2026-10-27 13:41:40 +01:00
Abdessamad Derraz 57436839a8 fix: start each open finding with a capital
The statement of a finding follows a full stop on the Measurements page.
2026-10-27 13:07:33 +01:00
Abdessamad Derraz 5f3c836db9 chore: merge origin/main into the campaign work 2026-10-27 13:02:18 +01:00
Abdessamad Derraz 37d2c14e1d chore: keep campaign prose to the style rules
No clause semicolons in the campaign docstring and content list, and a help text for every option.
2026-10-27 13:02:15 +01:00
Abdessamad Derraz a67dc339bc chore: merge main into the audit 17 answers
# Conflicts:
#	install.ps1
#	install.sh
#	install/launchers/index.json
2026-10-27 12:48:04 +01:00
Abdessamad Derraz c138270edc refactor: keep commit rules in a tracked module
The rules lived only in the local commit-msg hook, which CI and other clones do not have, so autorun could only check a subject's shape there. scripts/commit_rules.py now holds them, the hook calls it, and autorun checks every job subject with it when the job list loads.
2026-10-27 12:41:06 +01:00
Abdessamad Derraz 31c574aab0 fix: line mode and screen share one decision
Answers code_audit_17 and tui_audit_10: the folder found after o, SHARE
drive roots, one same-choice command, a counted confirm step in line
mode, counts from the narrowed list, read-only advice without sudo,
systems recorded in packs, Ctrl-Z stopping the whole job, and the
wording, layout and docs items.
2026-10-27 12:24:26 +01:00
Abdessamad Derraz f5e98bfda6 refactor: fetch builds into bare mirrors
Host git only fetches into bare mirrors no sandbox ever sees, https only, with no user or system config and overrides emptying hooks, fsmonitor, ssh and proxy commands and every filter driver the mirror defines. Each build is a git archive of the commit and of each submodule commit from its own mirror. Old working-tree clones are deleted. The core copied out must be a regular file inside the build folder, opened without following links.
2026-10-27 12:19:55 +01:00
Abdessamad Derraz fdcf120a7d refactor: build cores from an exported tree
make runs on a git archive export of the commit and its submodules, the clone and its .git never bound into the sandbox. Host-side git runs with no user or system config, no hooks, no fsmonitor and the file and ext transports refused.
2026-10-27 12:07:16 +01:00
Abdessamad Derraz fd449fdae3 refactor: refuse unsandboxed campaign runs
Without a working bubblewrap the pass is refused and nothing third-party runs, probes require the sandbox and builds are refused, unless --allow-unsandboxed is given. A job report holding an alert raises an autorun alert.
2026-10-27 11:53:35 +01:00
Abdessamad Derraz e440073562 refactor: build the core sandbox as an allowlist
bwrap now binds only /usr, the /lib* and /bin links and the files of /etc the loader, fonts, TLS, the clock and user lookups read. Home, /tmp and /mnt are empty, the core, content and staged system directory read-only, the scratch folder the one writable path, every namespace unshared. --require-sandbox refuses to run without it. The worker imports nothing from the repository.
2026-10-27 11:53:35 +01:00
Abdessamad Derraz 960cc4a14e refactor: escape campaign values on the site
Values a run produced (core output, romfetch errors, profile names) are written as character references inside <code> or as plain text, so backticks, MDX braces and HTML stay text.
2026-10-27 11:48:22 +01:00
Abdessamad Derraz 95ca227bce refactor: run cores and builds in a sandbox
core_probe starts its worker with only the --env values, the worker clears its own environment before loading the core, and a working bubblewrap runs it with a read-only tree, no network and the user's credentials masked. The record names the isolation used. A timeout kills the whole process group. campaign.py starts core_probe, git, make and romfetch with the allowlist, make inside the same sandbox. --record refuses a folder that is not a checkout root.
2026-10-27 11:48:22 +01:00
Abdessamad Derraz e5cc1b5255 refactor: keep tokens out of autorun job steps
Every step, gate and recomputation runs with an allowlisted environment (PATH, HOME, LANG, LC_*, TZ, TMPDIR and the variables its env: key names). Names holding TOKEN, SECRET or PASS are dropped and refused in the registry. Only the push and the gh calls that read CI get GITHUB_TOKEN.
2026-10-27 11:48:22 +01:00
Abdessamad Derraz ee7319d838 feat: add the real-condition campaign runner
campaign.py takes buildbot nightlies (or a build of the pinned commit), the test content of tests/campaign/content.yml through romfetch, and runs core_probe for the files, boot, path, alias, variants and bench checks. A fixed rule table settles hle_fallback, required, path and aliases with the record ids as evidence, the rest goes to measurements/findings.jsonl. Resumable state, load, disk and budget guards, retries, content reference counting with an LRU cap, and an autorun job after the nightly.
2026-10-27 11:38:01 +01:00
Abdessamad Derraz faa79c5920 refactor: check job subjects with the repo hook
The runner carried its own copy of the refused vocabulary, which put those words in a tracked file. It now runs the commit-msg hook on each job's subject when the job list loads, and checks only the shape where no hook exists.
2026-10-27 11:08:19 +01:00
Abdessamad Derraz 07c34781e7 chore: merge the autorun runner and jobs 2026-10-27 10:41:53 +01:00
Abdessamad Derraz 343a4e8bd7 feat: add the autorun job runner
Runs the jobs of automation/jobs.yml under one host lock, with load and disk guards, one idle retry on a host misread, artifacts computed twice, explicit-path commits in .cache/autorun/worktree, an opt-in push (--push) and a CI circuit breaker. First jobs: nightly refresh chain, large-files asset dry run, disk cleanup and check, weekly bios integrity. install-timers writes systemd user units without enabling them.
2026-10-27 10:40:10 +01:00
Abdessamad Derraz 195a67e03b feat: add bios_integrity.py for bit flips
Rehashes every file database.json names. A confirmed mismatch on a committed file git sees as unmodified is restored from its HEAD blob after the blob is checked, then hashed again. Gitignored files are flagged only.
2026-10-27 10:40:06 +01:00
Abdessamad Derraz e5a43c0b04 feat: add sync_release_assets.py
Uploads the large-files assets check_release_assets reports out of date, only when the SHA-1 read twice equals database.json. Dry run by default, the release description is never edited.
2026-10-27 10:40:06 +01:00
Abdessamad Derraz 23cd012188 feat: add cleanup_disk.py with a disk alert
Tracked form of the private worktree and tmp cleanup: busy, recent and modified worktrees are kept, branches stay, tmp/acquire and bundles stay, and an entry holding a worktree is left to the worktree rule. Exit 1 under --alert-gb free.
2026-10-27 10:40:06 +01:00
Abdessamad Derraz 79c27b3798 feat: read saved findings in refresh_stale
--findings FILE takes a check_freshness.py --json report written earlier, kept to the --only areas, so one full check can drive a refresh of a few areas.
2026-10-27 10:40:05 +01:00
Abdessamad Derraz 0fbf920e45 chore: merge one-file measurement records 2026-10-27 10:24:41 +01:00
Abdessamad Derraz da68f19411 refactor: keep one full record per line
Each line of measurements/<emulator>.jsonl now holds the whole run:
every repetition, core logs, per-frame hashes and raw timings. The gzip
data files, the data schema and the split and join code are gone, and
core_probe --record appends one line. record_version moves to 3.

The seven records are rewritten once: each new line equals its old line
joined with its data file, and rebuilds the first-layout file its id
hashes.
2026-10-27 09:57:39 +01:00
Abdessamad Derraz 9cf0f9177d chore: merge installer tables from code
# Conflicts:
#	install.ps1
#	install.sh
#	install/launchers/index.json
#	scripts/measurement_records.py
#	tests/test_install_tui.py
#	wiki/installer.md
2026-10-27 09:48:44 +01:00
Abdessamad Derraz 47ed945b4a feat: write installer tables from install.py
scripts/generate_installer_doc.py rewrites the marked tables of
wiki/installer.md: options from build_parser(), events from EVENT_KEYS,
exit codes from the sys.exit calls, RETROBIOS_PAD values and the keys of
each route from TUI_ROUTES, the one table the bar, the help and the stop
line now read. Prose cells are kept, a row the code gains stops the
script until its text is written, and --check runs in the tests. The
site drops the markers.

The full screen falls back to the line questions where the terminal's
terminfo moves no cursor the ANSI way (vt52, glass terminals), and --tui
names why. The line mode draws no escape code with TERM unset, dumb or
such a terminal. Ctrl-Z typed on the screen stops the run as SIGTSTP
does, the terminal handed back and redrawn on fg. A window too small
names 40x12 and its own size.

Pty tests check the modes, the cursor and the main screen after Ctrl-C,
Ctrl-D, SIGTERM, SIGHUP and Ctrl-Z then fg. Tests from a mutmut run over
the device filter, the card bounds and the WSL paths raise its score
from 62/71 to 71/71. The parser lists its options in the page's order,
with NAME, PATH, NAMES and N as arguments.
2026-10-27 09:47:44 +01:00
Abdessamad Derraz fb15ca68bb docs: name the sync_measurements path options
The option audit test failed on --clone and --pin, and two docstrings in
measurement_records.py joined clauses with a semicolon.
2026-10-27 09:47:36 +01:00
Abdessamad Derraz 9c34e8891f chore: merge origin/main 2026-10-27 09:11:43 +01:00
Abdessamad Derraz 571e50f2a8 refactor: read measurements from the local tree
The site compiles the index and the SQLite files from measurements/
instead of a pinned clone. The pin, the sync script, the CI clone steps,
the freshness area and its refresh handler are gone. core_probe --record
writes into measurements/ of the checkout by default, and a test fails
when a line or data file HEAD holds changed or vanished.
2026-10-27 09:11:12 +01:00
Abdessamad Derraz 7fa8d2d019 docs: document measurement sync clone and pin 2026-10-27 09:02:28 +01:00
Abdessamad Derraz 087e5b4d73 feat: show measurements on the site
Each emulator with records gets a Tested block: claim, result, method, computer, core build and the permalink of its record at the pin. A Measurements page filters every test in the browser from the compact index, and the Data page lists measurements.sqlite with its tables. One SQLite file per emulator is linked from its page. wiki/measurements.md says how a test runs, held to the Start here budgets.

Both workflows fetch the pinned commit alone with git before the build, and the deploy fails without it.
2026-10-27 08:30:16 +01:00
Abdessamad Derraz effa9e332f feat: read measurements at a pinned commit
measurements-pin.json names the measurements repository and the commit read. sync_measurements.py reads the clone in .cache/measurements at that commit, checks every line against its id and sidecar, and writes the site index and the SQLite databases. --fetch refuses a remote that changed or removed a line the pin holds, --bump moves the pin. validate_schemas checks every line and sidecar against their schemas, check_freshness flags a pin behind the remote head.
2026-10-27 08:30:11 +01:00
Abdessamad Derraz 6109d7abd5 feat: split probe records into line and sidecar
A record is now one line of records/<emulator>.jsonl in the measurements repository, under 20 KB, and a gzip sidecar holding every repetition, the core logs and the raw timings, its sha256 in the line. record_version 2, core-probe-data.schema.json for the sidecar. core_probe --record appends to a measurements clone and refuses a directory inside this repository's tracked tree.

The seven records of issue 85 moved to Abdess/retrobios-measurements: each line plus its sidecar rebuilds the first file, and keeps its first id.
2026-10-27 08:30:07 +01:00
Abdessamad Derraz cb5bb738cb fix: core probe through run_cli, documented
The probe skipped run_cli, accepted option prefixes in its shared options, left three options undocumented and was missing from the published schemas. The worker runs under -I, so the script directory is put back on sys.path before importing common.
2026-10-27 07:11:45 +01:00
Abdessamad Derraz e627f0cf49 chore: merge the core probe and issue 85 runs 2026-10-27 07:02:05 +01:00
Abdessamad Derraz 22ece6998d docs: describe every core_probe option 2026-10-27 06:58:38 +01:00
Abdessamad Derraz fecc6d9d32 chore: merge round 5 search fixes 2026-10-27 06:54:51 +01:00
Abdessamad Derraz 07f785cfd7 fix: rank a console first for its own name
The PlayStation 2 page holds every word of "playstation bios" and pagefind ignores the words a page has that the query lacks, so its own body matches put it first. A console whose every word another system page's consoles also hold is now written again in an `exact` field (weight 20). File names reach the `files` field as their parts: whole names let "ds" reach twelve dsi_* names on the DSi page. `consoles` weighs 100 so an emulator named after its console (Saturn.emu) comes second, and `aliases` 10 so the Nintendo page keeps "gba bios". The gate runs both directions of the PlayStation, Game Boy, DS and Wii pairs and Saturn.
2026-10-27 06:54:08 +01:00
Abdessamad Derraz 4522f3ba01 fix: keep the paths of a tree no folder lists
A repository that answers 404 (TeknoParrotUI) was listed folder by folder,
every listing failed, and the tree read as holding nothing: a fetch without
its cached tree dropped its recorded paths. It is now unread, so the record
keeps what it held.
2026-10-27 05:55:10 +01:00
Abdessamad Derraz 8b12685c16 feat: settle a probe check per observable
A check is inconclusive when the compared observable differs between repetitions, a run fails to load or a file changes during it. A disagreement on another observable stays flagged without voiding the comparison. Core log lines name the staged directories instead of the host paths.
2026-10-27 05:53:52 +01:00
Abdessamad Derraz 68f42bf8e2 fix: judge each build's refs in its own tree
A profile keyed by build mode compared a part in every repository and kept
the best outcome: xenia-edge's libretro tree carries emulator.cc offset,
and its lines vouched for standalone refs that had moved 4 lines. A part
of an entry with a mode is read in that build's repository, and a part
naming none in the first build declared, as _realign_part decides.
2026-10-27 05:41:27 +01:00
Abdessamad Derraz 9b2cddfbe5 fix: structured data names releases, not pins
The home page is the site: named RetroBIOS, part of nothing. A source repository states the core_version of its build when it names a release, never a commit id or a pin, and no placeholder description.
2026-10-27 05:40:03 +01:00
Abdessamad Derraz 15f7c72077 feat: setup tab, letter crumbs, console words
get/ pages join the tab of the setup pages of the same name, so no page is excluded from every tab and the tabs keep their names. Groups filing emulators by first letter are no crumb. A console page carries "<name> BIOS" in its terms field. The search gate runs the console, checker, schema, license and iOS queries.
2026-10-27 05:39:59 +01:00
Abdessamad Derraz 9690579f34 feat: record env files by name and sha256
A path given to --env is a detail of the host that ran the probe. The record keeps the file name and its sha256, which is what the run depended on.
2026-10-27 05:34:31 +01:00
Abdessamad Derraz d0de6dde30 fix: rebuild source paths from the written pins
load_emulator_profiles caches by directory, and the run had loaded the
profiles before writing them, so the record rebuilt after a write kept the
pins just replaced: linapple, then ten profiles in one advance. The cache
is cleared first. The record is rebuilt for those ten.
2026-10-27 05:24:04 +01:00
Abdessamad Derraz 00b034612f feat: add headless libretro core probe
core_probe.py loads a libretro core with no window, runs it for a
number of frames and reports the files it opened (strace), its log
lines, frame, audio and save-state hashes and its speed. bench repeats
a run after warm-up and gives median, mean, deviation and range; check
swaps one system file between runs and compares one observable.

--record writes a JSON record with the core build, frontend commit,
host and every input by hash, validated against
core-probe-record.schema.json. A busy host is refused, and a
repetition that disagrees with the first is flagged.
2026-10-27 05:18:10 +01:00
Abdessamad Derraz 951bd070bf feat: advance profiles that cite no source
_needs_review held every skipped report, so a profile with no source_ref
never moved: anarch sat behind a CI-only commit through every bulk advance.
Its source pin now moves; its upstream pin does not, since nothing was
compared there.
2026-10-27 04:26:28 +01:00
Abdessamad Derraz 4b11a43a86 feat: version check reads tags and numbers
A project that tags without releases (eightyone, higan) was never compared,
and a core_version naming no tag (parallel-launcher 9.0.5 beside v9.0-6)
silenced the passed-release warning. The newest tag stands in when it is a
version number, and an untagged core_version is compared by number within
one scheme. --emulator is repeatable: a stored value kept only the last.
2026-10-27 04:16:31 +01:00
Abdessamad Derraz 44378ae5c9 feat: name a release newer than the pinned tag
A profile pinned on its release tag read as clean forever: armsx1, armsx2
and x1-box sat on old tags while newer releases were out. --check-version
now names the latest release when it follows both the declared tag and
the pin, unless pin_frozen holds the pin on purpose.
2026-10-26 23:25:51 +01:00