From 9c500ff216a2415210be4e9727947a32540837b2 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Thu, 5 Nov 2026 12:18:51 +0100 Subject: [PATCH] docs: describe how a contested slot is decided --- tests/test_doc_pages.py | 21 +++++++++++++++++++++ wiki/architecture.md | 30 +++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/tests/test_doc_pages.py b/tests/test_doc_pages.py index 8cf8ed661..b442d79d4 100644 --- a/tests/test_doc_pages.py +++ b/tests/test_doc_pages.py @@ -1720,6 +1720,27 @@ class ReadmeKeepsItsPointers(unittest.TestCase): self.assertRegex(readme, r"more the collection does not hold and does not serve by name") +class ArchitectureStatesTheArbitration(unittest.TestCase): + """architecture.md said the profile takes precedence for pack generation, + while slots.arbitrate() keeps the platform's file where its frontend + checks the content: RetroBat's ATARIOSB.ROM.""" + + def test_the_page_says_what_arbitrate_decides(self): + import slots # noqa: PLC0415 + + page = (WIKI / "architecture.md").read_text(encoding="utf-8") + self.assertNotIn("the profile takes precedence for pack generation", page) + section = page[page.index("### When both layers claim one destination"):] + section = section[:section.index("\n## ")] + self.assertIn("`slots.arbitrate()`", section) + source = inspect.getsource(slots.arbitrate) + # The three outcomes the section describes. + for outcome in ("ADDRESSEE", "SERVES_BOTH", "FRONTEND_CHECKS_CONTENT"): + self.assertIn(outcome, source) + for said in ("--emulator", "`existence`", "the platform's file stays"): + self.assertIn(said, section) + + class ReportExcerptIsTheRun(unittest.TestCase): """reading-reports.md quoted 'From python scripts/verify.py --platform retrodeck' a run that said 0 required missing after the command had started diff --git a/wiki/architecture.md b/wiki/architecture.md index 590a68207..bd69cd264 100644 --- a/wiki/architecture.md +++ b/wiki/architecture.md @@ -169,11 +169,31 @@ The emulator's source code serves as ground truth for what files are needed, what names they use, and what validation the emulator performs. Platform YAML configs are scraped from upstream and record what each platform declares. A list kept by hand can lag behind an emulator release. The emulator profiles complement the -platform data by documenting what the code actually loads. When the two disagree, -the profile takes precedence for pack generation: files the code needs are included -even if the platform does not declare them. Files the platform declares but no -profile references are kept as well (flagged during cross-reference), since the -upstream may cover cases not yet profiled. +platform data by documenting what the code actually loads. Files the code needs +are included even if the platform does not declare them. Files the platform +declares but no profile references are kept as well (flagged during +cross-reference), since the upstream may cover cases not yet profiled. + +### When both layers claim one destination + +A platform and an emulator profile can each name a different file for the same +place in the BIOS folder: RetroBat puts its own `ATARIOSB.ROM` at +`bios/ATARIOSB.ROM`, where atari800 reads another dump. A claim counts only when +it rests on content or on the path. A file found by its name alone claims +nothing. The pack then answers to whoever asked for it: + +- A **platform pack** must leave the frontend's own check green, since a user + reading red concludes the pack is broken. Where the frontend only looks for + the name (`existence`), the emulator's file satisfies both, and the pack takes + it. Where the frontend checks an MD5 or SHA1, one path cannot hold both + answers: the platform's file stays, and the loss is reported. Only the + platform's own list can change what its frontend accepts there. +- A pack built with `--emulator` answers to that emulator, and takes its file. + +`scripts/slots.py` prints each contested destination and the reason for its +winner (`python scripts/slots.py --platform retrobat`). `generate_pack.py` and +`verify.py` both decide through `slots.arbitrate()`, so the pack and the report +agree. A platform YAML is regenerated by its scraper and never edited by hand: an edit would be lost at the next scrape, and the file would stop describing the