From 74193cd6859e09e4d2f2d4053471a0b084f5c765 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Thu, 6 Aug 2026 16:30:56 +0800 Subject: [PATCH 1/2] fix(xpkg): 0.0.52 and 0.0.53 were only in the linux section Both bumps added the entry to `xpm.linux` and nothing else, so macosx and windows stopped at 0.0.51. Linux CI passed and macOS/Windows failed with `mcpplibs.xpkg@0.0.53 not found` -- against a file that literally contains `["0.0.53"]`, just not in their platform's block. The tarball is platform-independent (it is the libxpkg source archive, identical GLOBAL/CN bytes, one sha256), so the entries are identical to linux's. There was never a reason for them to differ; there was only a reason they were missing, which is that I edited one section and checked the file. Verified by parsing and enumerating per platform, not by grepping: linux ok (0.0.53, 0.0.52, 0.0.51) macosx ok (0.0.53, 0.0.52, 0.0.51) windows ok (0.0.53, 0.0.52, 0.0.51) and asserting each new entry's sha256 and that its CN url names its own version. A whole-file grep for `["0.0.53"]` passes on the broken file -- which is exactly what my CI assertion did, so it did not catch this either. --- pkgs/x/xpkg.lua | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pkgs/x/xpkg.lua b/pkgs/x/xpkg.lua index 7fdf042..5e1a42c 100644 --- a/pkgs/x/xpkg.lua +++ b/pkgs/x/xpkg.lua @@ -112,6 +112,20 @@ package = { }, }, macosx = { + ["0.0.53"] = { + url = { + GLOBAL = "https://github.com/openxlings/libxpkg/archive/refs/tags/0.0.53.tar.gz", + CN = "https://gitcode.com/mcpp-res/xpkg/releases/download/0.0.53/xpkg-0.0.53.tar.gz", + }, + sha256 = "158da808846c09cb8758322828a6175a636d74f570f4ac47575c844f93c20cf8", + }, + ["0.0.52"] = { + url = { + GLOBAL = "https://github.com/openxlings/libxpkg/archive/refs/tags/0.0.52.tar.gz", + CN = "https://gitcode.com/mcpp-res/xpkg/releases/download/0.0.52/xpkg-0.0.52.tar.gz", + }, + sha256 = "5cfa70af911b31a3c142a0a8e7faee9c56b1655baa5963d3153b1721e1f9c60c", + }, ["0.0.51"] = { url = { GLOBAL = "https://github.com/openxlings/libxpkg/archive/refs/tags/0.0.51.tar.gz", @@ -198,6 +212,20 @@ package = { }, }, windows = { + ["0.0.53"] = { + url = { + GLOBAL = "https://github.com/openxlings/libxpkg/archive/refs/tags/0.0.53.tar.gz", + CN = "https://gitcode.com/mcpp-res/xpkg/releases/download/0.0.53/xpkg-0.0.53.tar.gz", + }, + sha256 = "158da808846c09cb8758322828a6175a636d74f570f4ac47575c844f93c20cf8", + }, + ["0.0.52"] = { + url = { + GLOBAL = "https://github.com/openxlings/libxpkg/archive/refs/tags/0.0.52.tar.gz", + CN = "https://gitcode.com/mcpp-res/xpkg/releases/download/0.0.52/xpkg-0.0.52.tar.gz", + }, + sha256 = "5cfa70af911b31a3c142a0a8e7faee9c56b1655baa5963d3153b1721e1f9c60c", + }, ["0.0.51"] = { url = { GLOBAL = "https://github.com/openxlings/libxpkg/archive/refs/tags/0.0.51.tar.gz", From efa7c86d8ddf6db4f2eaa37524babb7a8837eb31 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Thu, 6 Aug 2026 16:35:59 +0800 Subject: [PATCH 2/2] test: a version bump must land in every platform section The rule, enforced rather than remembered: Within one descriptor, every platform section that carries any version entry must carry the same set of version entries. A bump is a one-line-looking edit that has to land in N places. Editing `xpm.linux` and reading the file back gives a file that CONTAINS the new version, so the author -- and any whole-file grep -- sees success. The other platforms are simply left behind, and the failure surfaces somewhere else: `mcpplibs.xpkg@0.0.53 not found` on macOS, against a file that literally contains `["0.0.53"]`. That is what happened here twice in a row (0.0.52, then 0.0.53). Linux CI went green both times. The cause was then diagnosed eight times from the outside -- index commit, published artifact, rolling pointer, releases/latest, publish lag, the client version pin, install-vs-use, the lockfile hash -- and every one of those checks was CORRECT, because each asked "is 0.0.53 in the index?" rather than "is it in THIS PLATFORM's section?". Packages that genuinely diverge opt out with `platform_versions_diverge = true` plus a reason. The opt-out is a claim someone made on purpose, which is the difference between a divergence and an omission. Falsified before landing: against the pre-fix xpkg.lua it names `xpm.macosx is missing 0.0.52, 0.0.53` and the same for windows; against the fixed file and all 80 descriptors in the repo it passes. Zero existing divergences, so the rule costs nothing today and only fires on a partial bump. --- .github/workflows/validate.yml | 16 +++ tests/check_platform_version_parity.lua | 124 ++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 tests/check_platform_version_parity.lua diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index fe75617..abeffcd 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -200,6 +200,22 @@ jobs: # because it needs the full set of declared identities. - name: Lint cross-package references run: lua5.4 tests/check_cross_package_refs.lua pkgs/*/*.lua + # ── Partial version bumps ──────────────────────────────────────── + # A bump is a one-line-looking edit that has to land in N platform + # sections. Editing `xpm.linux` and reading the file back gives a file + # that CONTAINS the new version, so the author -- and any whole-file + # grep -- sees success, while the other platforms are left behind. The + # failure then surfaces as `@ not found` on a platform, + # against a file that literally contains that version string. + # + # Measured 2026-08-06: xpkg 0.0.52 and 0.0.53 were both added to + # `xpm.linux` alone; linux CI went green twice while macOS and Windows + # failed, and eight checks made from the outside all came back correct + # because each asked "is it in the index?" instead of "is it in THIS + # platform's section?". Whole-repo, because a partial bump is only + # visible by comparing sections against each other. + - name: Lint platform version parity + run: lua5.4 tests/check_platform_version_parity.lua pkgs/*/*.lua # ── Single-source-of-truth grammar check ───────────────────────── # `mcpp xpkg parse` uses EXACTLY the resolver's parser, so what # passes here is what builds for users of the pinned MCPP_VERSION. diff --git a/tests/check_platform_version_parity.lua b/tests/check_platform_version_parity.lua new file mode 100644 index 0000000..9c18fa7 --- /dev/null +++ b/tests/check_platform_version_parity.lua @@ -0,0 +1,124 @@ +-- Every platform section of a package must carry the same set of versions. +-- +-- WHY THIS EXISTS +-- +-- A version bump is a one-line-looking edit that has to land in N places. +-- Editing `xpm.linux` and reading the file back gives a file that contains +-- the new version -- so the author, and any whole-file grep, sees success. +-- The other platforms are simply left behind, and the failure surfaces +-- somewhere else entirely: `mcpplibs.xpkg@0.0.53 not found` on macOS, +-- against a file that literally contains `["0.0.53"]`. +-- +-- Measured 2026-08-06: xpkg 0.0.52 and 0.0.53 were both added to `xpm.linux` +-- alone. Linux CI went green twice. macOS and Windows failed, and the cause +-- was diagnosed eight times from the outside -- index commit, published +-- artifact, rolling pointer, releases/latest, publish lag, the client version +-- pin, install-vs-use, the lockfile hash -- each of which was correct, +-- because each asked "is 0.0.53 in the index?" rather than "is it in THIS +-- PLATFORM's section?". +-- +-- THE RULE +-- +-- Within one descriptor, every platform section that carries any version +-- entry must carry the same set of version entries. +-- +-- Packages that genuinely diverge (a platform that stopped at an older +-- release, or ships versions the others never had) opt out explicitly: +-- +-- package = { +-- ... +-- -- +-- platform_versions_diverge = true, +-- } +-- +-- The opt-out is a claim someone made on purpose, which is the difference +-- between a divergence and an omission. Surveyed at the time this was +-- written: 80 descriptors, 0 divergences -- so the rule costs nothing today +-- and only fires on a partial bump. +-- +-- Usage: lua5.4 tests/check_platform_version_parity.lua [...] +-- Exits non-zero, with ::error lines, listing what each platform is missing. + +function import(...) + return setmetatable({}, {__index = function() return function() end end}) +end + +local fail = 0 + +local function err(file, msg) + io.stderr:write(string.format("::error file=%s::%s\n", file, msg)) + fail = 1 +end + +local function version_keys(tbl) + local set, n = {}, 0 + for k in pairs(tbl) do + -- A version key, not `latest` / `deps` / `exports` / ... + if type(k) == "string" and k:match("^%d[%d%.]*$") then + set[k] = true + n = n + 1 + end + end + return set, n +end + +local function sorted(set) + local out = {} + for k in pairs(set) do table.insert(out, k) end + table.sort(out) + return out +end + +local function check(file) + package = nil + local chunk = loadfile(file, "t") + if not chunk then return end -- parse errors: other checks + if not pcall(chunk) then return end + local p = package + if type(p) ~= "table" or type(p.xpm) ~= "table" then return end + if p.platform_versions_diverge then return end + + -- Only platforms that carry versions at all. A section that is purely + -- `inherits` or `deps` is not an omission. + local plats, sets = {}, {} + for plat, pt in pairs(p.xpm) do + if type(pt) == "table" then + local s, n = version_keys(pt) + if n > 0 then + table.insert(plats, plat) + sets[plat] = s + end + end + end + if #plats < 2 then return end + table.sort(plats) + + local union = {} + for _, plat in ipairs(plats) do + for v in pairs(sets[plat]) do union[v] = true end + end + + for _, plat in ipairs(plats) do + local missing = {} + for _, v in ipairs(sorted(union)) do + if not sets[plat][v] then table.insert(missing, v) end + end + if #missing > 0 then + err(file, string.format( + "xpm.%s is missing %s -- present in another platform's section. " + .. "A version bump has to land in every platform block; editing " + .. "one leaves a file that still contains the version, so the " + .. "omission reads as 'not found' on the platforms that lack it. " + .. "If the platforms genuinely differ, set " + .. "`platform_versions_diverge = true` and say why.", + plat, table.concat(missing, ", "))) + end + end +end + +if #arg == 0 then + io.stderr:write("usage: check_platform_version_parity.lua [...]\n") + os.exit(2) +end +for _, file in ipairs(arg) do check(file) end +os.exit(fail)