From 63fafaf0f9e02171a02e7a20f41cd0c760b69262 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 6 Nov 2026 08:37:12 +0100 Subject: [PATCH] fix: read teknoparrot and simple64 from mirrors teknogods/TeknoParrotUI and simple64/simple64 answer 404 on the API and the web, and neither organisation lists them now. simple64's README at the pin archives the project for gopher64. Each profile declares upstream_gone and a fork that keeps its default branch at the analysed commit: thecrixux/TeknoParrotUI master is b75872ad, simple64-vault/simple64 main is d8c969c7. realign_prose reads a source declared gone through that mirror, which unblocks five teknoparrot notes citations that anchor unchanged. --- emulators/simple64.yml | 2 ++ emulators/teknoparrot.yml | 2 ++ scripts/profile_sync.py | 24 ++++++++++++++++++++---- tests/test_profile_sync.py | 28 ++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/emulators/simple64.yml b/emulators/simple64.yml index f09be5b1d..9df8dfdad 100644 --- a/emulators/simple64.yml +++ b/emulators/simple64.yml @@ -5,6 +5,8 @@ source: "https://github.com/simple64/simple64" upstream: "https://github.com/simple64/simple64" profiled_date: "2026-08-08" source_commit: "d8c969c7b932e3d76e6a25549d76348839dbaefd" +upstream_gone: "simple64/simple64 answers 404 on the API and the web, and the simple64 organisation lists no repository. The README at the pin archives the project in favour of gopher64. Observed 2026-11-06. simple64-vault/simple64 keeps main at the analysed commit." +source_mirror: "https://github.com/simple64-vault/simple64" core_version: "v2024.12.1-5-gd8c969c" version_basis: kind: tag diff --git a/emulators/teknoparrot.yml b/emulators/teknoparrot.yml index 59a2a4a5f..8b6ed2cf4 100644 --- a/emulators/teknoparrot.yml +++ b/emulators/teknoparrot.yml @@ -6,6 +6,8 @@ upstream: closed-source author: "TeknoGods" profiled_date: "2026-10-20" source_commit: "b75872addc1d5cce81a62f4c1468eab59e2d3cbe" +upstream_gone: "teknogods/TeknoParrotUI answers 404 on the API and the web, and the teknogods organisation no longer lists it. Observed 2026-11-06. thecrixux/TeknoParrotUI keeps master at the analysed commit." +source_mirror: "https://github.com/thecrixux/TeknoParrotUI" core_version: "TeknoParrotUI 7ffcdf1" version_basis: kind: unverified diff --git a/scripts/profile_sync.py b/scripts/profile_sync.py index 76bfdb95a..9c4471dfd 100644 --- a/scripts/profile_sync.py +++ b/scripts/profile_sync.py @@ -3914,7 +3914,8 @@ def _realign_part( def _writing_pairs( - document: dict, repos: list, revisions: list[tuple[str, dict]], intro_sha: str + document: dict, repos: list, revisions: list[tuple[str, dict]], intro_sha: str, + served: dict | None = None, ) -> tuple[list[list], list[str]]: """Every reading of where the text was written, and the ambiguities. @@ -3944,8 +3945,9 @@ def _writing_pairs( ambiguous.append(f"{pin_field}_commit {' -> '.join(written)}") # The current pin among the candidates reads as "no move" (None) for # that repository, which the other candidates must then agree with. + reader = (served or {}).get(repo, repo) options.append([ - (repo, pin, current) if pin != current else None for pin in written + (reader, pin, current) if pin != current else None for pin in written ]) readings = [ [pair for pair in combo if pair is not None] @@ -4026,8 +4028,20 @@ def realign_prose( ] if not repos: return [] + # A source declared gone is read through its mirror, which carries the + # same commits: teknoparrot's notes stayed blocked once + # teknogods/TeknoParrotUI answered 404, every reading of the old pin + # calling the files absent. + mirror = ( + upstream.parse_repo(str(document.get("source_mirror") or "")) + if document.get("upstream_gone") else None + ) + served = { + repo: mirror for field, _mode, repo in repos + if mirror is not None and field == "source" + } pinned = [ - (repo, pin) + (served.get(repo, repo), pin) for field, mode, repo in repos if (pin := _pin_of(document, f"{field}_commit", mode)) ] @@ -4107,7 +4121,9 @@ def realign_prose( if intro_sha is None: # The scalar is not committed yet: written now, under this pin. continue - readings, ambiguous = _writing_pairs(document, repos, revisions, intro_sha) + readings, ambiguous = _writing_pairs( + document, repos, revisions, intro_sha, served + ) if not any(readings): continue moves, blocked = _realign_citation( diff --git a/tests/test_profile_sync.py b/tests/test_profile_sync.py index 8bee4ba3d..9a0fb5241 100644 --- a/tests/test_profile_sync.py +++ b/tests/test_profile_sync.py @@ -4784,6 +4784,34 @@ class TestRealignProse(unittest.TestCase): self.assertTrue(flagged, messages) self.assertFalse([m for m in messages if "b.c:" in m], messages) + def test_a_source_declared_gone_is_read_through_its_mirror(self): + """teknogods/TeknoParrotUI answers 404. Read there, every citation + written under the old pin was absent and blocked the profile.""" + self._repo_with_advanced_pin() + self._commit( + PROSE_SAMPLE.replace( + 'source_commit: "pin"\n', + 'source_commit: "pin"\n' + 'upstream_gone: "o/n answers 404."\n' + 'source_mirror: "https://github.com/m/n"\n', + ), + "advance the pin, declare the forge gone", + ) + self.files[("oldpin", "a.c")] = ["x"] * 9 + ["subject"] + self.files[("pin", "a.c")] = ["x"] * 13 + ["subject"] + self.files[("oldpin", "b.c")] = list("pqrstuvwx") + self.files[("pin", "b.c")] = list("pqrstuvwx") + served = profile_sync.upstream.fetch_file + profile_sync.upstream.fetch_file = ( + lambda repo, sha, path, cache_dir, offline=False: ( + served(repo, sha, path, cache_dir, offline) + if repo.slug == "m/n" else None + ) + ) + messages = profile_sync.realign_prose(self.path, self.tmp.name, dry_run=True) + # b.c did not move between the two pins: nothing to read again. + self.assertFalse([m for m in messages if "b.c:" in m], messages) + def test_a_citation_in_an_unmoved_upstream_needs_no_reading(self): """nethersx2 cites AetherSX2 files that only its upstream carries, at an upstream pin that never moved. The port's pin did move under