diff --git a/docs/workstream-b-signing-runbook.md b/docs/workstream-b-signing-runbook.md index 29c4ee00..c32b9747 100644 --- a/docs/workstream-b-signing-runbook.md +++ b/docs/workstream-b-signing-runbook.md @@ -1,12 +1,28 @@ # Workstream B — Signed app-catalog: completion runbook -**Status (2026-06-28):** The registry-distributed manifest pipeline is live — nodes fetch +**Status: ✅ COMPLETE** (runbook retained for re-running the ceremony — key +rotation, a new publisher, or a fresh release root). + +The ceremony described below has been performed. Verified 2026-08-08: + +- The anchor is **pinned** — `trust::anchor::RELEASE_ROOT_PUBKEY_HEX` is a + `Some(...)`, not `None`. +- `releases/app-catalog.json` carries a `signature` and a `signed_by` did:key. + +Everything below therefore describes how to *do* the ceremony, not work that is +outstanding. The one-way-door warning in "Why this is gated on you" still +applies in full to any re-run: once a binary pins an anchor, a catalog signed by +a different key is hard-rejected fleet-wide. + +--- + +**Original status (2026-06-28):** The registry-distributed manifest pipeline is live — nodes fetch `releases/app-catalog.json` from the OTA mirror and embed manifests (origin-wins, disk fallback). What remains for Workstream B is **authenticity**: pin the release-root anchor and ship a *signed* catalog so nodes can cryptographically verify the publisher. Today the catalog is **accepted unsigned** ("migration window") and the anchor is **unpinned** -(`core/archipelago/src/trust/anchor.rs:21` → `RELEASE_ROOT_PUBKEY_HEX = None`). Completing B is +(`core/archipelago/src/trust/anchor.rs` → `RELEASE_ROOT_PUBKEY_HEX = None`). Completing B is a coordinated ceremony that **only the publisher can run** — it needs the offline `RELEASE_MASTER_MNEMONIC`, which is not (and must not be) stored on any node or build host.