Boxes should self-update the platform binary via a channel subscription Idea open
Migrated from github.com/carlosframework/platform issue #333, opened 2026-08-28. GitHub issues are closed for this repo; see AGENTS.md, "Work is tracked on amadan, not GitHub".
Still outstanding: Boxes should self-update the platform binary via a channel subscription rather than an operator-run script.
---
Problem
Rolling a new platform binary today is an operator-side push: build (or fetch) the arm64 binary, upload it to each deployment's bootstrap/carlos bucket key, then run update-platform-binary.sh over SSM per box (install, re-stage embedded units, sysusers-before-tmpfiles, re-arm the adopt timer/path units, restart the edge). That has two structural costs:
- It makes every platform roll a vendor concern. Tito is a third-party deployment; a platform-dev session holding SSM access to a customer's boxes to push binaries is the wrong trust shape (Paul, 2026-08-27/28 — tito rolls are moving to a Tito-side operator agent as the near-term fix; runbook now lives in amadan.net/tito/carlos-infrastructure).
- It doesn't scale with boxes. 9 boxes today, per-box SSM invocations, ordering rules held in operator memory (home boxes before region edges, #300).
Idea
The platform already has exactly the machinery this needs — releases, channels, and a box-side adoption loop. Let the platform binary be a subscriber of its own releases:
- Platform builds are shipped as releases on a reserved channel (e.g.
platform/stable, withplatform/canarybelow it for staged rollouts). - Each box subscribes (a host.env or registry setting; per-box channel choice gives canary boxes for free).
- The adoption pass notices a new platform release, verifies signature + sha against the embedded release key, and installs: the same dance
update-platform-binary.shdoes today — binary swap,bootstrap -rootunit staging, sysusers applied before tmpfiles (the #104 group-resolution trap), tmpfiles, daemon-reload, re-armcarlos-adopt.timer/carlos-adopt.path/carlos-stage.path/carlos-restart.path, then a graceful edge restart. - Postconditions stay postconditions: a box that can't verify or whose units don't come back active must roll back to the previous binary and report, not stay half-updated.
What this retires
update-platform-binary.shand per-deployment roll runbooks (flagship, tito, dev).- The vendor needing box access on third-party deployments for routine updates.
Cares
- Self-update ordering across a fleet (home box first? staggered?) becomes a policy the platform owns instead of operator lore.
- The updater must never break the static-user tenants trap that
update-platform-binary.shexists to avoid (fullcarlos bootstrapre-chowns /data — that's why the script stages units into a temp root instead). - Interaction with
carlos update(#161's CLI self-update): same verification chain, different artifact/trigger — worth sharing the signature plumbing.