feat: record the pin a prose reread confirmed

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.
This commit is contained in:
Abdessamad Derraz committed 2026-10-18 02:49:24 +02:00
1 parent a5f41511cc
commit 8a9d6919d9
7 files changed
+52 -1

No files matched your search

+1
View File
@@ -6,6 +6,7 @@ upstream: "https://github.com/PCSX2/pcsx2"
author: "Oleksandr (sashkinbro)"
profiled_date: "2026-10-04"
source_commit: "9884c9f9a0c5d5df2f0c0c064ec41029a4528d72"
prose_written_at: "9884c9f9a0c5d5df2f0c0c064ec41029a4528d72"
upstream_commit: "c10a5c9ad951c517dc48b722b5b84eb9bf7fdb42"
core_version: "0.4.7"
display_name: "Sony - PlayStation 2 (EmuCoreX)"
+1
View File
@@ -5,6 +5,7 @@ source: "https://github.com/libretro/fixNES"
upstream: "https://github.com/FIX94/fixNES"
profiled_date: "2026-03-23"
source_commit: "72af6c6fd9d3b6c23d334ba7385b6a09225f2276"
prose_written_at: "72af6c6fd9d3b6c23d334ba7385b6a09225f2276"
core_version: "Alpha v1.3.1"
display_name: "Nintendo - NES / Famicom (fixNES)"
cores:
+1
View File
@@ -4,6 +4,7 @@ core_classification: other
source: "https://github.com/chernandezba/zesarux"
upstream: "https://github.com/chernandezba/zesarux"
source_commit: "8e1e8f3fcb5a8e677984df7aeaff30667682ab56"
prose_written_at: "8e1e8f3fcb5a8e677984df7aeaff30667682ab56"
profiled_date: "2026-09-17"
core_version: "13.1-SN"
display_name: "Sinclair - ZX Spectrum and clones (ZEsarUX)"
+5
View File
@@ -800,6 +800,11 @@
"type": "string",
"description": "Branch the port was read from, when it is not the default one."
},
"prose_written_at": {
"type": "string",
"pattern": "^[0-9a-f]{40}$",
"description": "The pin a reader confirmed every prose citation against. When the profile's history shows several pins under one text, profile_sync takes this one as the revision the text describes; it never overrides a single candidate."
},
"pin_frozen": {
"type": "string",
"description": "Why source_commit is held on purpose rather than followed. The profile is then judged against its own revision, like one pinned to a superseded tag: comparing it to HEAD says nothing and recaling would repoint its refs at code the build it documents never had."
+10 -1
View File
@@ -3016,14 +3016,23 @@ def _writing_pairs(
Each reading lists (repo, writing pin, current pin) per declared
repository. A repository whose text lived under several pins gives one
reading per pin; the caller settles them when they all agree.
`prose_written_at` names the pin a reader confirmed the prose against.
Among several candidate pins it is the answer: fixnes's doOpenFDSBIOS
citation lived under four pins, exact at the last, and with nothing to
record that reading the bump stayed refused for good. It never
overrides a history with a single candidate.
"""
options: list[list] = []
ambiguous: list[str] = []
attested = str(document.get("prose_written_at") or "")
for pin_field, mode, repo in repos:
current = _pin_of(document, f"{pin_field}_commit", mode)
if not current:
continue
written = _writing_pins(revisions, intro_sha, f"{pin_field}_commit", mode)
if attested in written:
written = [attested]
if len(written) > 1:
ambiguous.append(f"{pin_field}_commit {' -> '.join(written)}")
# The current pin among the candidates reads as "no move" (None) for
@@ -3336,7 +3345,7 @@ def _stale_prose_blocks(name: str, path: Path, args: argparse.Namespace) -> bool
if stale:
print(
f"{name}: {len(stale)} prose citation(s) written under an older pin; "
"run --realign-prose or read them before the pin moves",
"run --realign-prose, or read them and set prose_written_at to the pin they match",
file=sys.stderr,
)
return bool(stale)
+33
View File
@@ -2379,6 +2379,39 @@ class TestWriteDryRun(unittest.TestCase):
self.assertEqual(readings, [[(repo, "pin1", "pin2")], []])
self.assertTrue(ambiguous)
def test_a_confirmed_pin_settles_the_readings(self):
"""fixnes: doOpenFDSBIOS lived under four pins and was exact at the
last; with nothing to record that reading, the bump was refused for
good. prose_written_at names the pin and the readings collapse."""
revisions = [
("c2", {"source_commit": "pin2", "notes": "x"}),
("c1", {"source_commit": "pin1", "notes": "x"}),
]
repo = object()
readings, _ambiguous = profile_sync._writing_pairs(
{"source_commit": "pin2", "prose_written_at": "pin2"},
[("source", "", repo)], revisions, "c1",
)
self.assertEqual(readings, [[]])
later, _ = profile_sync._writing_pairs(
{"source_commit": "pin3", "prose_written_at": "pin2"},
[("source", "", repo)], revisions, "c1",
)
self.assertEqual(later, [[(repo, "pin2", "pin3")]])
def test_a_confirmed_pin_outside_the_history_changes_nothing(self):
revisions = [
("c2", {"source_commit": "pin2", "notes": "x"}),
("c1", {"source_commit": "pin1", "notes": "x"}),
]
repo = object()
readings, ambiguous = profile_sync._writing_pairs(
{"source_commit": "pin2", "prose_written_at": "elsewhere"},
[("source", "", repo)], revisions, "c1",
)
self.assertEqual(readings, [[(repo, "pin1", "pin2")], []])
self.assertTrue(ambiguous)
def test_a_pin_keyed_by_build_mode_is_read_for_its_mode(self):
"""eka2l1 pins a dict per build: read as a string, it gave no
repository and its prose was never judged."""
+1
View File
@@ -355,6 +355,7 @@ which CI validates every profile against.
| `known_hash_adler32` | expected Adler-32 hash (Dolphin's DSP ROMs); pair with `adler32_byteswap` when the code hashes 16-bit byte-swapped data |
| `adler32_pairs_with`, `adler32_pairs` | the file hashed together with this one and the combinations the code accepts, this file's value first, in table order: Dolphin warns on a DSP ROM pair outside its `known_roms` even when each file passes alone |
| `pin_frozen` | why `source_commit` is held on purpose rather than followed. The profile is then judged against its own revision, like one pinned to a superseded tag |
| `prose_written_at` | the pin a reader confirmed the prose citations against. When the profile's history shows a text living under several pins, profile_sync takes this one as the revision the text describes, so a bump is no longer refused for a citation already reread. It never overrides a history with a single candidate |
| `upstream_gone` | why the declared upstream can no longer be reached, when that is settled rather than transient. Records the death instead of leaving the profile failing every pass; profile_sync reports it as declared, and reports the contradiction if the forge answers again |
| `source_mirror` | a repository carrying the same tree, consulted after `source` and `upstream`. What keeps a profile checkable once its own forge stops answering |
| `validation` | checks the code performs: `size`, `crc32`, `md5`, `sha1`, `adler32`, `signature`, `crypto`. Can be a list or dict `{core: [...], upstream: [...]}` for divergent checks |