Skip to content

chore: post-release tail for 2026.8.17.1 — pin, report, and two things the self-review found - #449

Merged
Sunrisepeak merged 10 commits into
mainfrom
chore/post-release-2026.8.17.1
Aug 16, 2026
Merged

chore: post-release tail for 2026.8.17.1 — pin, report, and two things the self-review found#449
Sunrisepeak merged 10 commits into
mainfrom
chore/post-release-2026.8.17.1

Conversation

@Sunrisepeak

@Sunrisepeak Sunrisepeak commented Aug 16, 2026

Copy link
Copy Markdown
Member

Post-release tail for 2026.8.17.1 (#448). Four things, and the title changed once because the last two were not planned.

1. The bootstrap pin

Moves only now, in the order the checklist requires:

step evidence
released v2026.8.17.1 — four platforms + versionless aliases + SHA256SUMS
mirrored all assets mirrored + verified on 2 host(s) in 488s, then independently re-checked with a real GET (not curl -I, which lies on gitcode) — all four archives byte-size-identical to upstream
indexed openxlings/xim-pkgindex#643, merged
installable xlings install mcpp@2026.8.17.1 in a fresh sandboxed SubOS, then new → build → run → test → pack, and a Windows PE packed from that Linux sandbox

A pin ahead of what the index has fails every job's bootstrap with package 'mcpp@X' not found, which is why this is separate from the bump.

2. The round's report

What shipped, what was deliberately not done and why (cross-architecture ELF packing, the manifest SDK key, mcpp pack on macOS still executing the artifact), and the findings that were not in the plan.

3. e2e 241 — the ucrt@ identity reaches a real build

The unit tests pin the hash function; they cannot see whether the value is ever filled in on a real Windows build, and a green Windows CI does not distinguish "the identity is there" from "the code path ran and produced nothing" — an empty string flows through every one of those jobs silently. So this reads resolution.json and asserts the value, the participation (non-empty contract hash), and that it was not projected into libc.

It pins msvc@system explicitly: Windows' default toolchain is clang-targeting-MSVC, where clang finds its own SDK and mcpp honestly has nothing to declare — a test on the default would assert an empty identity and pass for the wrong reason.

4. A crash, found by re-reading merged and green code

identify() is documented as never throwing and, for one input, terminated the process:

if (b.substr(*lfanew, 4) == "PE\0\0")   // *lfanew comes straight out of the file

string_view::substr throws std::out_of_range when pos > size(). A file starting with MZ and garbage at 0x3C is ordinary malformed input — and mcpp pack calls this on every artifact it packages. Measured, not argued: string_view{256 bytes}.substr(0xFFFFFFFF, 4) throws under libc++.

Every other read in that module goes through a bounds-checked accessor; these two comparisons were the exceptions. The existing truncation test missed it because it only ever produced an e_lfanew exactly at the end, where substr is well-defined.

The pin moves only now, in the order the release checklist requires:
released → mirrored (GitHub + GitCode, both GET-verified byte-for-byte) →
in the index (openxlings/xim-pkgindex#643, merged). A pin ahead of what the
index actually has fails every CI job's bootstrap with "package not found".

The report records what shipped, what was deliberately not done and why, and
the three things this round ran into that were not in the plan — including a
clang crash on two targets at once, and a page of the docs that contradicted
itself about a key that does not exist.
Not the local build and not this machine: `xlings install mcpp@2026.8.17.1`
from the index, into a SubOS created for it, every command through
`--sandbox`. Including the one that matters most — a Windows zip packed from
inside that Linux sandbox, verified by Python's own zipfile reader.

Also records that the local-`gtc` gitcode fill was not needed this time: the
mirror leg passed on its own and was re-checked with a real GET.
`mcpp new` + `mcpp add compat.gtest@1.15.2` does not build: the scaffolded
test carries its own main() and the dependency links gtest_main.o into every
test target. Found while verifying the ecosystem, and reproduced on the
PREVIOUS release (2026.8.16.3) in the same sandbox — so it is recorded as
pre-existing, not as something this round did.
The unit tests pin the hash function — two SDK versions produce two hashes.
What they cannot see is whether the value ever gets there on a real Windows
build, and a green Windows CI does not distinguish "the identity is filled
in" from "the code path ran and produced nothing": an empty string flows
through every one of those jobs without a complaint.

So this reads resolution.json and asserts the VALUE — `runtime_id` starts
with `ucrt@`, the contract hash is non-empty (an identity that participates
in nothing is decoration), and it was NOT projected into `libc`, which names
a private libc PAYLOAD that has no ucrt equivalent.

It pins `msvc@system` explicitly. Windows' default toolchain is clang
targeting the MSVC ABI, where clang finds its own SDK and mcpp honestly has
nothing to declare — a test that took the default would assert an empty
identity and pass for the wrong reason.
…ointer

The report described the unit tests and e2e 240 but not the assertion added
after it was written — the one that says the ucrt identity reaches a real
Windows build rather than merely being computable. A report that omits the
test which closes an acceptance criterion is a report that overstates the
other evidence.

The design doc now points forward to it, so a reader who starts at the plan
finds what actually happened.
`identify()` is documented as never throwing and, for one input, terminated
the process. `std::string_view::substr` throws `std::out_of_range` when
`pos > size()`, and the position came straight out of the file:

    if (b.substr(*lfanew, 4) == "PE\0\0")

A file that starts with "MZ" and has garbage at 0x3C is ordinary malformed
input — a truncated download, a DOS stub, a text file named `.exe` — and
`mcpp pack` calls this on every artifact it packages. Measured rather than
argued: `std::string_view{256 bytes}.substr(0xFFFFFFFF, 4)` throws
`string_view::substr` under libc++.

Every other read in the module goes through a bounds-checked accessor; these
two comparisons were the exceptions, which is exactly how a module whose
stated contract is "total over nonsense" stopped being one. `has_at()` now
does the same job with the same check as the rest.

Found by re-reading the file after it was already merged and green — the
existing truncation test never produced an `e_lfanew` PAST the end, only one
exactly AT it, where `substr` is well-defined and returns empty.
The fourth is the one the report would most have been improved by hiding: a
crash in code written this round, found by re-reading it AFTER it was merged
and green. Recorded with what the existing test missed and why.
@Sunrisepeak Sunrisepeak changed the title ci: bootstrap pin -> 2026.8.17.1, and the round's report chore: post-release tail for 2026.8.17.1 — pin, report, and two things the self-review found Aug 16, 2026
The examples I reached for — a half-downloaded file, a DOS stub, a text file
named .exe — are inputs mcpp is never handed: `identify()` receives a LINK
OUTPUT, so the realistic path is a truncated or killed link, not arbitrary
user input. The finding stands on what it is (a function documented as never
throwing did), not on a frequency it does not have.
It says what it produces, and since #448 that is a .zip for a Windows target.
`--format tar` selects "an archive rather than a plain directory"; WHICH
archive follows the artifact, because a .tar.gz full of DLLs is a package most
Windows users cannot open without installing something first.

Found by smoke-testing the RELEASED binary — the behaviour shipped and its
help did not follow.
Checking the four published archives against the file whose name promises to
cover them: only `linux-x86_64` is in it — the aarch64, macOS and Windows
archives are absent, and have been for at least v2026.8.16.3 and v2026.8.15.1
too, so this is not something this round did.

The mechanism is structural rather than flaky: `build-release` (linux
x86_64) runs first and writes the file; the other three platforms upload
their own `.sha256` sidecars and nothing appends. Verification IS possible —
the sidecars are there — but not through the file that says SHA256SUMS.

Recorded as outstanding, not fixed: it is the release pipeline, not one of
the three axes, and this PR is already the post-release tail.
@Sunrisepeak
Sunrisepeak merged commit 204d606 into main Aug 16, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants