Commit a401945
authored
* feat: date-based version scheme + xlings pin single source of truth (2026.7.27.1)
Two things that had to ship together: mcpp's version format moves to the
date form YYYY.M.D.N, and that format broke a comparison that had to be
fixed first.
Version scheme
--------------
`YYYY.M.D.N`, month/day unpadded, matching the xlings ecosystem (xlings
migrated from 0.4.70 to 2026.7.27.x the same day). The fourth segment:
`.0` is reserved for formal / stable releases; routine iterations start
at `.1`.
Ordering across the change is monotonic — 0.0.109 < 2026.7.27.1.
Fix: four-segment versions were silently truncated
-------------------------------------------------
`version_req::Version` was strictly three segments, so
parse_version("2026.7.27.1") produced {2026, 7, 27} and dropped the fourth
without an error — every release of a given day compared EQUAL.
That lands on pm/index_contract.cppm: an index declaring
min_mcpp = "2026.7.27.5" against a running 2026.7.27.1 compares equal,
`have >= need` holds, and the E0006 floor lets a too-old mcpp through —
the single thing that check exists to prevent.
Version now carries a fourth component plus `components` (how many segments
the source wrote). Two constraints:
- ordering compares only the four numbers; if `components` took part,
"1.2" would stop equalling "1.2.0".
- str() must render the fourth segment, because pm/resolver.cppm returns
it as the RESOLVED dependency version, which flows into the lock file
and the xlings wire address. A version ending in ".0" collapsed to three
segments would address an index key that does not exist.
Existing three-segment resolution is byte-identical: the fourth component
is 0 on both sides, so ^ / ~ / = are unchanged (regression cases added).
xlings pins: one source of truth, machine-checked
-------------------------------------------------
All pins move to 2026.7.27.2, and `pinned::kXlingsVersion` becomes the
single source of truth that .github/tools/check_version_pins.sh enforces
across all 16 pin sites in 7 files — plus mcpp's own version across its 4
locations.
This replaces a comment that said to keep three named files in lock-step by
hand. That list was ALREADY incomplete: it omitted both composite actions,
which is how CI's sandbox sat on 0.4.30 for weeks unnoticed. Building the
check surfaced three more pin sites nobody had recorded (release.yml's
hardcoded aarch64 xlings tarball literals, which are not interpolated from
XLINGS_VERSION) and three stale bootstraps (ci-fresh-install.yml on v0.4.38
twice and v0.4.51).
install_pinned_mcpp.sh's version regex matched three segments only, which
does not fail on a date version — it truncates both sides identically, so
the pin check would silently accept any release of that day.
Verified: v2026.7.27.2 exists on both openxlings/xlings and d2learn/xlings
with all four platform assets, same naming as 0.4.69, direct GET 200. The
aarch64 bundling step is guarded by `if curl`, so a missing asset would
degrade silently rather than fail.
* fix: stop poisoning the run target's LD_LIBRARY_PATH with the private glibc (#291)
Also corrects the pin invariant this branch's own guard got wrong, which is
what turned every CI job red.
#291 — private glibc payload on LD_LIBRARY_PATH
-----------------------------------------------
LD_LIBRARY_PATH is inherited by the entire process subtree. When the run
target is something that shells out — a course provider calling
popen("mcpp test ...") — /bin/sh is a HOST binary: its PT_INTERP is baked
in, so it loads the HOST ld.so, while this variable hands it the PAYLOAD
libc.so.6. glibc's libc and ld.so are version-locked through GLIBC_PRIVATE
(verified: the payload libc.so.6 carries a GLIBC_PRIVATE dependency on
ld-linux-x86-64.so.2), so on any host whose glibc differs from the
payload's the shell dies of SIGSEGV inside the dynamic linker, before main,
with empty stdout and no diagnostic.
This is NOT "compiled on a different build machine, ABI-incompatible" as
originally reported — it is plain version mismatch, and it hits every user
whose host glibc differs. It survived this long precisely because it does
not reproduce when the two happen to match.
The payload dir is the one entry on LD_LIBRARY_PATH that is not also in the
executable's RUNPATH — flags.cppm excludes it deliberately to keep static
and musl links clean. Its only purpose is letting a dlopen()'d library,
whose own DT_NEEDED closure never consults the executable's RUNPATH,
resolve the same libc. So emit it only when the build actually has such a
library (depRuntimeLibraryDirs non-empty). The real host-GL passthrough
case reaches mcpp through compat.glx-runtime's `[runtime] library_dirs`,
which populates exactly that vector, so it is unaffected; a
zero-dependency binary no longer gets it.
process.cppm's strip_private_glibc already protects mcpp's own children. It
cannot reach one hop further out — mcpp sets the variable for the target on
purpose, and what the target spawns is beyond its control. Not emitting it
when unnecessary is within its control.
e2e 166 pins both directions: a zero-dependency project must NOT receive
it, a project with `[runtime] library_dirs` MUST. It asserts on the emitted
environment rather than on whether a shell crashes — a crash-based test
passes for the wrong reason wherever host and payload glibc match, which is
how this went unnoticed.
e2e 65 dropped its glibc-payload assertion: its fixture has no
dependencies, so it never modelled the dlopen case its own header
describes.
Pin guard: the bootstrap pin is SUPPOSED to lag
-----------------------------------------------
The guard added earlier in this branch asserted that all four version
locations are equal. That is wrong, and CI proved it — every job failed
with `package 'mcpp@2026.7.27.1' not found`.
.xlings.json and MCPP_PIN name a mcpp that is already published, so they
must agree with each other but must NOT track the version being built; they
are bumped in a separate commit after the release lands in xim-pkgindex
(as ci-fresh-install.yml's own comment says). Both are back to 0.0.109.
The guard now checks three invariants instead: mcpp.toml == MCPP_VERSION;
the two bootstrap sites agree; and the bootstrap pin is never NEWER than
the version being built — a four-key numeric sort, so the date scheme
orders correctly. That last check reproduces the exact CI failure locally
in under a second.
1 parent ca9825e commit a401945
23 files changed
Lines changed: 969 additions & 70 deletions
File tree
- .agents
- docs
- skills/mcpp-release
- .github
- actions
- bootstrap-mcpp
- setup-macos-llvm
- tools
- workflows
- src
- build
- toolchain
- tests
- e2e
- unit
Lines changed: 242 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
Lines changed: 135 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
0 commit comments