Size
L
Area
tooling
Depends on
none
Summary
Parked on purpose — do not pick this up without a product call. The appliance side of auto-update is built as far as it can go without infrastructure that does not exist. The box can verify, parse, decide and cache a signed release manifest, and it polls hourly (#395, #397). It will never act, because no build has a signing key, so every manifest is refused and the poll does not even start. That is the deliberate safe state, not a bug.
Hosted is the focus. This issue exists so the appliance remainder is written down somewhere rather than carried in someone's head. It is deliberately not in NEXT.md: that doc is a design backlog, and most of what follows is decided-but-unbuilt.
If we never do this, appliance boxes simply do not auto-update. Users still install and run them; they just do not get a new brain or UI on their own. That is an acceptable state for now.
Spec / source of truth
docs/specs/RELEASE_MANIFEST.md (whole doc); docs/specs/UPDATES.md # 3
Do
Four things, in order, none of them mostly code:
- A signing keypair, and the custody rules around it. minisign / Ed25519. The private key stays off every server and out of CI (
RELEASE_MANIFEST.md # Signing). Still undesigned: where it physically lives, who can use it, and the rotation runbook — the spec defers all three until there is a release to sign. The box side is already built for rotation: the verifier takes a list of keys, so the standard "ship a build accepting {old, new}, dual-sign, drop the old" sequence needs no box change.
- A place to publish.
releases.malmo.network serving stable.json + stable.json.minisig, from a small git repo per # Where it lives. Neither the name nor the repo exists.
- The publishing step. A release cuts the images and knows their digests; something has to write the manifest, sign it offline, and land it. Today nothing does.
- Digests in the manifest. The schema names versions, and the box pulls by digest, so the manifest should carry the digests the release build already knows — the same call being made for the hosted target (the sender resolves, the box never trusts a movable tag). This is a
manifest_version schema change and should ship with the first real manifest, not after it.
Then the appliance source plugs into the update-target seam (#399) and everything above it — the prompt, the apply path, the failure state — is already there.
Touch
docs/specs/RELEASE_MANIFEST.md, internal/hostagent/relmanifest/, release infrastructure outside this repo
Done when
A real signed stable.json is served at a real URL, a box with the matching key baked in polls it, verifies it, and offers the update it names. Until then this stays parked.
Size
L
Area
tooling
Depends on
none
Summary
Parked on purpose — do not pick this up without a product call. The appliance side of auto-update is built as far as it can go without infrastructure that does not exist. The box can verify, parse, decide and cache a signed release manifest, and it polls hourly (#395, #397). It will never act, because no build has a signing key, so every manifest is refused and the poll does not even start. That is the deliberate safe state, not a bug.
Hosted is the focus. This issue exists so the appliance remainder is written down somewhere rather than carried in someone's head. It is deliberately not in
NEXT.md: that doc is a design backlog, and most of what follows is decided-but-unbuilt.If we never do this, appliance boxes simply do not auto-update. Users still install and run them; they just do not get a new brain or UI on their own. That is an acceptable state for now.
Spec / source of truth
docs/specs/RELEASE_MANIFEST.md(whole doc);docs/specs/UPDATES.md# 3Do
Four things, in order, none of them mostly code:
RELEASE_MANIFEST.md# Signing). Still undesigned: where it physically lives, who can use it, and the rotation runbook — the spec defers all three until there is a release to sign. The box side is already built for rotation: the verifier takes a list of keys, so the standard "ship a build accepting {old, new}, dual-sign, drop the old" sequence needs no box change.releases.malmo.networkservingstable.json+stable.json.minisig, from a small git repo per # Where it lives. Neither the name nor the repo exists.manifest_versionschema change and should ship with the first real manifest, not after it.Then the appliance source plugs into the update-target seam (#399) and everything above it — the prompt, the apply path, the failure state — is already there.
Touch
docs/specs/RELEASE_MANIFEST.md,internal/hostagent/relmanifest/, release infrastructure outside this repoDone when
A real signed
stable.jsonis served at a real URL, a box with the matching key baked in polls it, verifies it, and offers the update it names. Until then this stays parked.