From cd8d56d487df2491fc9a6607f5000e6e59ec0bcb Mon Sep 17 00:00:00 2001 From: Wessel Verheij Date: Mon, 14 Sep 2026 17:15:09 +0200 Subject: [PATCH 1/2] docs(ops): the smoke test this page still describes was deleted before it was written MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "What the pipeline does" describes three platform builds, "each installing or extracting its bundle, launching it, asking its health endpoint, and comparing the reported versions before upload", and a publish step gated on all three. None of that is the pipeline. There are four platform builds — Android joined on 2026-08-17 — and publish declares five dependencies, the fifth being a self-host smoke job added on 2026-09-05. Neither change reached this page. The launch-and-probe is older than a drift. Per-platform smoke probes existed for one day: they went in on 2026-05-28 and came out the same day, because a hosted runner cannot start these bundles — the Linux runner has no display server, the Windows runner loses the silent-install to GUI-launch race, and macOS trips ad-hoc-signing friction on `open`. This page was written two months later, on 2026-07-27, and described the morning shape rather than the one that survived the afternoon. What the platform builds actually do is interrogate the artifact they produced: signing identity, forbidden contents, and the manifest written beside it. What is launched and probed is the self-host recipe, which is the one shape CI can run. The page already asks, on its own checklist, whether the ruleset's required checks still name the jobs that actually run (OPS-R18), on the grounds that a renamed job silently stops being required. Its own list of jobs had gone stale the same way. Verify-published is added to the list for the same reason: it is the step that re-reads the manifests and the checksum file off the release page and re-checks every signature, and the page's "verify the signed manifest by hand" item is easier to read next to it. This commit changes the description only. Whether OPS-R5 — "Every platform build MUST pass its smoke test before the publish step runs" — still says what it should, now that no platform build launches anything, is a question for the rule and not for this page. Signed-off-by: Wessel Verheij --- 70-operations/releasing.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/70-operations/releasing.md b/70-operations/releasing.md index 28171f2..a13e829 100644 --- a/70-operations/releasing.md +++ b/70-operations/releasing.md @@ -94,13 +94,21 @@ there is nothing to move by hand. ### What the pipeline does 1. **Quality gate**, fail-fast across the runtime matrix. -2. **Three platform builds in parallel**, each installing or extracting its - bundle, launching it, asking its health endpoint, and comparing the reported - versions before upload. -3. **Publish**, only if all three succeeded: generate the release notes from +2. **Four platform builds in parallel** — macOS, Windows, Linux and Android — + each interrogating the artifact it produced rather than trusting the build's + exit code: that it is signed by the identity expected, that it carries + nothing it must not, and that the update manifest written beside it names it. +3. **One self-host smoke test**, launching the shipped self-host recipe and + asking its health endpoint. A hosted runner cannot launch the other four — an + Electron bundle needs a session and a display, and the Android package needs + a device — so this is the one shape CI can start and probe end to end. +4. **Publish**, only if all five succeeded: generate the release notes from the commits since the previous tag, generate the update manifests with binary hashes, sign each manifest, and create the release with every binary and manifest attached — as a draft for stable, published for a preview. +5. **Verify what was published**, re-reading the manifests and the checksum file + back off the release page and re-checking every signature against the + publisher key, so that what the page serves is what the pipeline signed. ### After the tag @@ -113,8 +121,10 @@ there is nothing to move by hand. ## If something goes wrong -**A build fails.** Nothing is published — the publish step requires all three. -Fix and re-tag with a new patch version; do not move a tag. +**A build fails.** Nothing is published — the publish step requires all five, +the smoke test among them, so four green platform builds are not on their own a +reason for it to have run. Fix and re-tag with a new patch version; do not move +a tag. **A bad release is already published.** Publish a fixed version. A yanked manifest stops the updater offering it, but users who already installed it have From a8769c024a9322065ed2f29dbd3e07ee58b9843b Mon Sep 17 00:00:00 2001 From: Wessel Verheij Date: Mon, 14 Sep 2026 17:16:56 +0200 Subject: [PATCH 2/2] docs(quality): the same deleted smoke test, drawn as a diagram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `40-quality/ci-cd.md` carries an ASCII drawing of the release pipeline holding the same three errors as `70-operations/releasing.md`: three platform builds rather than four, a publish gated on "all three" rather than on five, and a per-platform smoke test — "install or extract, launch, ask the health endpoint, compare the reported versions" — that was removed on the day it was added, because a hosted runner cannot launch these bundles. A diagram is read more readily than the prose beside it and checked less often, so the same wrong shape survives longer here. Corrected to match: what each platform build checks is the artifact it produced, what gets launched and probed is the self-host recipe, and the verify-published step is drawn rather than left off the end. `40-quality/tooling.md` also says three platform runners, and is right to: it is describing desktop packaging, and the fourth build is mobile. Left alone. Signed-off-by: Wessel Verheij --- 40-quality/ci-cd.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/40-quality/ci-cd.md b/40-quality/ci-cd.md index 893c20b..4418fee 100644 --- a/40-quality/ci-cd.md +++ b/40-quality/ci-cd.md @@ -46,16 +46,25 @@ tag push │ (a broken build must not spend forty minutes producing │ installers it cannot publish) ▼ -2 three platform builds, in parallel - │ each: install → build → smoke-test → upload - │ smoke test = install or extract, launch, ask the health - │ endpoint, compare the reported versions +2 four platform builds, in parallel + │ each: install → build → interrogate the artifact → upload + │ the check is on what was produced, never the exit code: + │ signed by the identity expected, carrying nothing it must + │ not, named by the manifest written beside it + │ + │ one self-host smoke test, beside them + │ launch the shipped self-host recipe, ask its health + │ endpoint — a hosted runner cannot launch the other four ▼ -3 publish — only when all three succeeded +3 publish — only when all five succeeded generate the update manifests with binary hashes sign each manifest create the release with every binary and manifest attached stable → DRAFT · prerelease tag → published prerelease + ▼ +4 verify what was published + re-read the manifests and the checksum file off the page + re-check every signature against the publisher key ``` The asymmetric publish is