0043. Releases reach servers through the autopilot: gated, staged, reversible
Status: accepted, 2026-10-30. Refines 0010: home plans the platform's
updates and xvii-node carries them out, its own included.
Context
Releases are tagged by hand and installed from an SSH session or home's Update button; home's automatic updates
(October 2026) install in a nightly window and trust only xvii-node's health check. appsd names the store's
newest xvii-node in every node's desired state, so an upload reaches every agent at once, with no canary, pin or
way back but the agent's own probation; the control plane's xvii-node is updated by hand. When a release
migrated its database, xvii-node's rollback runs the old binary on the new schema, and no release says whether
that works. Nothing says when the platform may change, and while it changes people get 502s.
Decision
- Patch releases cut themselves. A scheduled CI job tags vX.Y.Z+1 when the default branch has only fixes,
performance and dependency changes since the last release, its pipeline is green and its head is two hours
old: at most once a day per repository, and only where the repository turns it on. Minors and majors are
people's. Only commits on the default branch are signed.
- Every release says how far back it can go. CI writes a
release block into the signed manifest: the
previous release, the changes, and a rollback floor — the oldest version whose binary runs on what this release
leaves behind — from contract migrations (marked, and linted), a start of the previous release on the new
schema, and a tag mark for changes outside the database.
- home's autopilot plans, xvii-node installs, gates decide. Inside maintenance windows and in rings — the
control plane's xvii-node; notify and batch services; standard services; id and ai; the other servers'
xvii-node through apps; home — each install bakes behind readiness and restarts (node), panics and new issues
(errors), error rate and latency (analytics), monitors and journeys (status) and SLO burn. A failure rolls that
service back by binary and halts the run; two halted runs pause the autopilot until a person resumes it.
- Nothing automatic is irreversible. A release whose floor is above the running version never installs by
itself, and data is restored only by a person.
- xvii-node rolls out in rings. The control plane's own updates from home through its socket and goes back to
its previous binary by itself (probation in the process, and a systemd unit that runs the previous binary when
the new one can't start). The other servers' follow a rollout in apps — a canary node, a bake, then the rest —
which reverts a failing node to the binary it ran before and halts. No desired state names a version a rollout
didn't put there, and none goes back.
- Maintenance windows and maintenance mode are home's. Windows say when the platform may change. Maintenance
mode, at most a day, answers the affected panels and APIs with a page and
503 maintenance (in Caddy, rendered
by xvii-node, which also ends it on time), silences their pages in notify, may announce itself in status, and
holds the autopilot.
Consequences
- A fix reaches the instance in the next window without anyone at a laptop; a regression is rolled back before a
person reads about it.
- Every service declares its class and gates in its manifest; errors, analytics and status serve gate endpoints;
notify accepts silences from home.
- Contract migrations carry a header, released migrations never change, and a release that changes a data format
marks its tag; conventions/git.md and go.md say so.
- The forge needs a bot token that may create tags and merge requests, scoped to the release jobs.
- The agent protocol gains the agent's update state, a revert request and release mirrors; appsd stops reading
the store's newest xvii-node. Uploading a release no longer means it reaches any server.
- Design:
superpowers/specs/2026-10-30-autopilot-and-thin-control-plane-design.md in this repository.