diff --git a/docs/plans/0009-debian-publication-through-apt-publisher.md b/docs/plans/0009-debian-publication-through-apt-publisher.md index a4d2350..33d02ce 100644 --- a/docs/plans/0009-debian-publication-through-apt-publisher.md +++ b/docs/plans/0009-debian-publication-through-apt-publisher.md @@ -8,9 +8,14 @@ and [ADR-0056](../adr/0056-rebuild-images-after-apt-publication.md); replaces This plan moves every Frostyard Debian producer and consumer from the frozen legacy `stable` suite to explicit codenames at `https://repository.frostyard.org/debian/`, published by -[`frostyard/apt-publisher`](https://github.com/frostyard/apt-publisher). The -writer and the seeded `trixie` suite exist. What remains is producers, -caching, Snosi, and `forky`. NBC and omarchy-apps retirement stay with +[`frostyard/apt-publisher`](https://github.com/frostyard/apt-publisher). + +- **Done:** the writer, the seeded `trixie` suite, CDN caching, every + producer whose packages Snosi installs, and Snosi itself (Phases 1–5). +- **What remains:** validating `forky` (Phase 6) and steady state + (Phase 7). + +NBC and omarchy-apps retirement stay with [Plan 0008](0008-post-nbc-bootc-only-transition.md) and [ADR-0049](../adr/0049-retire-omarchy-apps-without-breaking-snosi.md). @@ -56,7 +61,7 @@ caching, Snosi, and `forky`. NBC and omarchy-apps retirement stay with - a missing file was `BYPASS` both times; - `InRelease` was `DYNAMIC`. -## Phase 4 — Move producers +## Phase 4 — Move producers (done for Snosi's producers 2026-10-04) For each producer: @@ -68,39 +73,77 @@ For each producer: 3. Give it an `APT_PUBLISH_TOKEN`. 4. Remove its production signing and R2 secrets. +Step 4 was done for every producer at once on 2026-10-03. The organization's +R2 and Repogen signing secrets are now limited to Snosi, for sysext +publication. Until then, producers pinned to `publish-to-r2` commits that +predate its `.deb` refusal could still write signed `stable`: + +- incus at `v0.4.1` did on 2026-09-16; +- firn at `6648671` did on 2026-10-01. + +See the +[drift alarm's baseline provenance](../design/stable-repository-drift-alarm.md). + Producers are ordered by what Snosi installs from the repository (scan of Snosi `dd0def7`, 2026-10-02): -- [ ] **updex.** Ships `frostyard-updex`, which every image installs. +- [x] **updex.** Ships `frostyard-updex`, which every image installs. - Attested, static Go: `trixie` and `forky`, notify `frostyard/snosi`. - - Its `release_workflow_contract_test.go` pins the direct Snosi dispatch - and changes with ADR-0056. -- [ ] **bootc-debian.** Ships `bootc` and `libostree-1-1`, which every OCI + - Its release workflow and `release_workflow_contract_test.go` now pin + the `publish-deb` request (frostyard/updex#432). + - v2.0.2 was published on 2026-10-02 by + [publish run 37058743496](https://github.com/frostyard/apt-publisher/actions/runs/37058743496). + It was `forky`'s first publication. +- [x] **bootc-debian.** Ships `bootc` and `libostree-1-1`, which every OCI profile installs. - - The repository is private, so the writer needs read access to its - releases. - - Its releases are manual (`workflow_dispatch`), and it is not attested: - register it `attested=no` until it adds provenance. - - It links distribution libraries, so it needs per-codename builds - (`~deb13`, `~deb14`). Debian `forky` already ships libostree 2026.4-1, - which is newer than Frostyard's 2026.3. -- [ ] **chairlift.** Ships `frostyard-chairlift` (snow, snowfield and sundog) + - Made public on 2026-10-04, so the writer reads its releases with its + workflow token. + - A manual Build run on `main` publishes a GitHub release of exactly those + two `.deb` files, then requests `trixie` (frostyard/bootc-debian#8). + - Versions end in `~deb13`; GitHub lists the assets with `.` in place of + `~`. + - Registered `trixie` only and `attested=no`, because its provenance names + `refs/heads/main` (frostyard/apt-publisher#10). + - `bootc-1.16.8-ostree-2026.3-202610040153` was published on 2026-10-04 + by [publish run 37170106018](https://github.com/frostyard/apt-publisher/actions/runs/37170106018). +- [x] **chairlift.** Ships `frostyard-chairlift` (snow, snowfield and sundog) and `frostyard-chairlift-system-integration`. - - Not attested. - - puregotk loads GTK4 and libadwaita at runtime, and the package declares no - `Depends`. Verify it on `forky` before registering `forky`. -- [ ] **intuneme.** Ships `frostyard-intuneme` (snow and sundog). Attested, - static. -- [ ] **first-setup.** Ships `snow-first-setup`, architecture `all` (snow and - snowfield). Attested. Its Repogen step is pinned to `@main`. -- [ ] **firn.** Ships `frostyard-firn`, which the firn-installer ISO pins to - 0.6.0. Not attested, static. -- [ ] **incus.** Ships `incus`, `incus-base`, `incus-client`, `incus-extra` and + - Attested from tag runs since frostyard/chairlift#239. + - `trixie` only, amd64 and arm64. puregotk loads GTK4 and libadwaita at + runtime and the package declares no `Depends`, so `forky` waits for a + smoke test. + - Its dead `build` dispatch to the archived `frostyard/snow` was removed. + - v0.11.2 was published on 2026-10-04 by + [publish run 37170541501](https://github.com/frostyard/apt-publisher/actions/runs/37170541501). +- [x] **intuneme.** Ships `frostyard-intuneme` (snow and sundog). Attested, + static, `trixie` and `forky` (frostyard/intuneme#204). v0.20.3 was + published on 2026-10-04 by [publish run 37163711657](https://github.com/frostyard/apt-publisher/actions/runs/37163711657). +- [x] **first-setup.** Ships `snow-first-setup`, architecture `all` (snow and + snowfield). + - Attested, `trixie` only (frostyard/first-setup#30). + - The release asset is now versioned, and the tag must match + `debian/changelog`. + - v0.4.1 was published on 2026-10-04 by + [publish run 37163781456](https://github.com/frostyard/apt-publisher/actions/runs/37163781456). +- [x] **firn.** Ships `frostyard-firn`, which the firn-installer ISO pins to + 0.6.0. + - Attested since frostyard/firn#104, static, `trixie` and `forky`, + amd64 and arm64. + - v0.6.1 was published on 2026-10-04 by + [publish run 37163739499](https://github.com/frostyard/apt-publisher/actions/runs/37163739499). +- [x] **incus.** Ships `incus`, `incus-base`, `incus-client`, `incus-extra` and `incus-ui-canonical` (the incus sysext). - - It publishes from the `stable` branch, and is not attested. - - It links distribution libraries, and its versions carry `-debian13-`, - which is not a codename marker. Register it for `trixie` only until its - versions carry `~deb13` or `~deb14`. + - Each push to the protected `stable` branch builds Debian 13 amd64, then + publishes a GitHub release holding exactly those five `.deb` files, then + requests `trixie` (frostyard/incus#6). The release job is generated by + `sync-docker-build.py`. + - Registered by exact package names, `trixie` only, `attested=no`. + - Its versions carry `-debian13-`, which is not a codename marker. + - Its attestations name `refs/heads/stable`, not the release tag the + writer checks. + - Incus 7.5.1 (frostyard/incus#7) was published on 2026-10-03 by + [publish run 37153494023](https://github.com/frostyard/apt-publisher/actions/runs/37153494023) + as `1:7.5.1-debian13-202610032056`. - Its epoch makes apt prefer it over Debian's incus, and `incus-ui-canonical` exists only here. - [ ] **omarchy-apps.** Not migrated @@ -110,40 +153,70 @@ Snosi `dd0def7`, 2026-10-02): Producers whose packages Snosi does not install from the repository: -- [ ] **pilothouse.** Snosi downloads `frostyard-pilothouse` from its GitHub +Not ported, by decision on 2026-10-04. Their Repogen `.deb` steps fail for +lack of credentials, so nothing writes legacy `stable`. Port them if they +ever need APT publication. + +- **pilothouse.** Snosi downloads `frostyard-pilothouse` from its GitHub release instead. - Its daemon is built with CGO on `ubuntu-latest`. Build it in `debian:trixie` before publishing to APT. - Not attested. -- [ ] **snowcat-cockpit.** Ships `frostyard-snowcat-cockpit`. Attested, static. -- [ ] **gchlog.** Ships `frostyard-gchlog`, which is not in the legacy suite. +- **snowcat-cockpit.** Ships `frostyard-snowcat-cockpit`. Attested, static. +- **gchlog.** Ships `frostyard-gchlog`, which is not in the legacy suite. The repository has been dormant since February 2026. - No producer to migrate: - igloo (archived); - nbc (archived; [ADR-0052](../adr/0052-remove-nbc-artifact-retention-gates.md)); - `kapsule` and `kapsule-gnome` (their `Homepage`, `github.com/frostyard/kapsule`, does not exist). -- **Done when:** every producer above publishes its next release through - apt-publisher, and no producer workflow calls Repogen's `publish-to-r2` - with `package-type: deb`. +- **Done when:** every producer whose packages Snosi installs publishes its + next release through apt-publisher, and none of their workflows calls + Repogen's `publish-to-r2` with `package-type: deb`. + - This held on 2026-10-04 for updex, incus, intuneme, firn, first-setup, + bootc-debian and chairlift. omarchy-apps is retired. + - Each first release was checked from outside: routing, signature, index + contents, apt canary, attestation where registered, and legacy `stable` + unchanged. -## Phase 5 — Move Snosi to `/debian/` `trixie` +## Phase 5 — Move Snosi to `/debian/` `trixie` (done 2026-10-03) -- [ ] Change `mkosi.sandbox/etc/apt/sources.list.d/frostyard.sources` to +- [x] `mkosi.sandbox/etc/apt/sources.list.d/frostyard.sources` reads `URIs: https://repository.frostyard.org/debian/` and `Suites: trixie`, - keeping `frostyard.gpg`. Try it in a test build first. -- [ ] Confirm that Snosi's sysext publication, through Repogen's - `package-type: sysext` path, writes nothing under `dists/` or `debian/`. + keeping `frostyard.gpg` (frostyard/snosi#1042). + - Before the change, a sandboxed apt comparison resolved every Frostyard + package Snosi installs to the same version from both sources, except + `frostyard-updex` (2.0.1 to 2.0.2). + - The PR's image builds fetched updex 2.0.2 from `/debian/` `trixie`. +- [x] Snosi's sysext publication, through Repogen's `package-type: sysext` + path, writes nothing under `dists/` or `debian/`. After the post-merge + sysext publication on 2026-10-03, `stable`, `trixie` and `forky` kept their + earlier `InRelease` dates. - Requires Phase 3. - **Done when:** Snosi's default builds install Frostyard packages from `/debian/` `trixie`, and the [stable repository drift alarm](../design/stable-repository-drift-alarm.md) - still reports `stable` unchanged. + still reports `stable` unchanged. Both held on 2026-10-03: + - the post-merge sysext, image and installer-ISO builds passed; + - the alarm passed on its re-baselined record (frostyard/core#153, + [run 37151554483](https://github.com/frostyard/core/actions/runs/37151554483)). ## Phase 6 — Build and validate `forky` +On 2026-10-04 Snosi's secure image builds were failing on Debian's +half-published trixie-backports kernel. `linux-signed-amd64` 7.2.6 was +waiting in `backports-new`, leaving every 6.18+ backports kernel +uninstallable. frostyard/snosi#1043 takes their kernel from `forky` (7.2.8) +until that queue is processed. + - [ ] Producers that register `forky` publish to it: unmarked static builds directly, and distribution-linked packages as `~deb14` builds. + - Done for updex, intuneme and firn. + - chairlift and first-setup wait for a smoke test on a `forky` image. + - bootc-debian needs a `debian:forky` build with `~deb14` versions and + per-codename `Depends`. Its ostree must be at least 2026.4, because + `forky` ships libostree 2026.4-1 (frostyard/bootc-debian#5). + - incus needs a Debian 14 build carrying `~deb14`. - [ ] Prove clean install, update and rollback on `forky`, without changing `trixie` or `stable`. - [ ] Rebase or replace Snosi PR #924 once packages and products validate. @@ -158,6 +231,16 @@ Producers whose packages Snosi does not install from the repository: - **Done when:** the nightly audit passes, and the retention windows are recorded in this plan. +## Later / ideas + +- **Refuse non-canonical asset names.** Refuse any `.deb` whose release asset + name isn't `__.deb`, with the epoch dropped and + GitHub's `~`→`.` rename accepted. aptly keeps asset names for pool files, + and first-setup's unversioned legacy asset showed the collision risk. +- **Check which workflow signed an attestation,** not only the tag + (`--signer-workflow` or a tag pattern). firn's and updex's release + workflows run on any tag, while their tag rulesets protect only `v*`. + ## Open questions - **What Repogen becomes,** whether it keeps only sysexts or is replaced by a