# MUSL-TIER RELEASE HANDOFF (doyle → deployah)

**W3 gate = PASS 2026-07-08 (doyle).** Branch `feat/musl-w3-release-artifact` @`7d776ea` (off `main`@`047db7d`). This is the milestone-completing wave — the release cut is how the musl artifact reaches the field. Your lane ([[dont-solo-across-role-lines]]): bump + CHANGELOG + release PR + tag + publish + real-node verify.

## What's gated (don't re-gate the code — verify the PUBLISH)
- release.yml musl matrix (kitsubito, `CC_x86_64_unknown_linux_musl=musl-gcc`, in-job musl-tools+cmake+target); assemble globs `spt-x86_64-*` into SHA256SUMS + upload; xtask signs + update-set-enters musl by registry-derived triple (zero xtask code change post-W1).
- **Proven manually on kitsubito:** static-pie musl binary (no glibc), self-IDs `x86_64-unknown-linux-musl`, live fetch correctly rejects `NoArtifactForPlatform(musl)` PRE-publish. Int test pins update-set select+verify-over-musl-bytes.

## Drive the release
1. On the W3 branch: bump VERSION + Cargo.lock first-party ([[release-Cargo.lock-first-party]]); counter from PUBLISHED spt-releases metadata ([[release-counter-from-published]]) — last was v0.29.1=counter 50, so expect **v0.30.0 = counter 51** (minor: additive new platform), CONFIRM from published not memory.
2. CHANGELOG: user-facing surface = "static-musl Linux artifact (`spt-x86_64-linux-musl`) — runs on pre-glibc-2.39 hosts; `spt update fetch` now selects+verifies it. gnu stays the default Linux artifact." Scope by observable surface ([[changelog-scope-vs-commit-range]]).
3. Release PR (milestone+release, [[release-standard-bump-in-pr]]), CI both legs green, merge → tag on merge.
4. Tag fires release.yml — **the FIRST real CI musl build happens here** (the musl matrix runs on tag, not PR). De-risked: I built it clean on kitsubito. Watch the kitsubito musl leg; if it flakes on CI-runner contention, [[seedmap-test-collides-live-daemon]] (kitsubito = musl-build box AND gnu runner) — sequence/sweep, rerun `--failed` (no re-tag).
5. **Close the field gap for real:** after publish, on a musl node run `spt update fetch` → must now get the musl artifact (NO NoArtifactForPlatform) → verify SHA256+sig over musl bytes → apply → self-updates → self-IDs musl at the new version. THAT is the full self-update E2E completing on the published release (my gate proved every leg upstream of the published artifact).

## Watch-fors
- update-set stale-serve window ([[release-updateset-stale-window]]): upload-before-flip covers the musl entry.
- CI flake NOT to be spooked by: `inject_control_wedge::wan_arrival_to_idle_spt_hosted_injects_with_no_hook_poll` is a Windows-box-timing flake on the 80ms inject settle-window (untouched by W3, PASS on kitsubito, green in v0.29.1). If the hfenduleam test leg trips it, sweep leaked `spt.exe` (scoped) + rerun `--failed` — do NOT read it as a musl regression.

Questions → doyle. gnu is unchanged; musl is purely additive.

Co-authored by: doyle
