Signed channel pointers carry no manifest digest: an old pointer plus a reused, pruned version name installs bytes nobody promoted open
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 5b793570 · claude-code/2.1.288 · DOCS-T1
Found by Astra while reviewing the instance update settings spec (branch design-zero-downtime-deploys, docs/superpowers/specs/CODEX-FINDINGS-SETTINGS-S3.md finding 1). It predates that spec and is independent of it.
The chain today
ChannelPointer (internal/release/release.go) signs the account, app, channel and version name, with history. It carries no manifest or artifact digest.
Manifests and artifacts are unsigned. Staging checks the artifact's sha256 against the manifest (adopt.go's staging), so the manifest is what binds the bytes.
A version name can be shipped again with different content once it has been pruned (release.go, around line 632).
Boxes can write the deployment bucket (infra/modules/region-host/main.tf, around line 166).
The gap
Someone who can write the store does this: save a valid signed pointer that names V. After V leaves history and is pruned, upload new bytes and a matching manifest under V, then write the saved pointer back. Root verifies the pointer's signature, fetches the manifest, finds the bytes match it, and installs them. Nobody promoted those bytes.
Possible fixes
Put the manifest digest in the signed pointer, for the head and for each history entry.
Or refuse to reuse a version name once it has been promoted.
The instance-settings spec (rev 5) adds a digest-bound signed promotion record per version and requires it for every install that spec adds. Ordinary head adoption still relies on the pointer, so this gap remains there.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 5b793570 · claude-code/2.1.288 · DOCS-T1
Specced and accepted (Astra S7: accept with fixes, the fix applied). See §4.6 of docs/superpowers/specs/2026-10-07-instance-update-settings-design.md on branch design-zero-downtime-deploys (rev 10, 3a9658c6).
Pointers carry digest and history_digests. These are additive; old binaries ignore them.
A digest comes either from the newly promoted version, computed at promotion, or verbatim from the signed predecessor. Nothing is backfilled.
FastTrack keeps digests verbatim.
A rollback onto a history entry with no digest needs carlos channels resign first.
Every reader checks the manifest against the digest before staging. That covers root adoption and static-site extraction on the edge.
A per-box ratchet and the CARLOS_REQUIRE_POINTER_DIGEST fleet flag close the replay of old pointers.
Rollout order is writers before readers, behind a root-signed marker.
It will be implemented as its own task group in the settings plan, at Paul's request (2026-10-07).
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 5b793570 · claude-code/2.1.288 · DOCS-T1
#253 is merged into main as 8d33cef (squash of settings-1-pointer-digests, CI green, Astra ACCEPT on the final merge).
Pointers carry digest and history_digests under the provenance rule.
Root staging and edge static extraction check the manifest against the digest, composed with plan 4's pin-set restage refusal.
A per-box ratchet persists marks and fails closed.
CARLOS_REQUIRE_POINTER_DIGEST is the fleet switch.
carlos channels digests on|off sets the signed emission marker; carlos channels resign is marker-gated.
The console reports stragglers.
Dormant until the marker is set. Rollout order (writers before readers) is in the roll notes. Copy was approved by Paul.