Upgrading
hermetic upgrade --hermeticd <ver> # fleet-wide only: no name, no --all; rewrites the fleet manifest pointerhermetic upgrade --hermes <ver> [<name>|--all] [--now]--hermeticd is fleet-wide by definition — it takes no <name> and no --all, and there’s no RPC to any box; it only rewrites the fleet manifest’s version pointer. Each agent’s own nightly update tick — a minute in the 03:00–03:59 UTC window picked from a hash of its name, so the fleet doesn’t hit S3 in the same minute — notices the rollout by comparing the sha256 of its installed binary against the manifest’s, not by comparing version labels; a digest mismatch downloads the new binary first, then the stages, then restarts hermeticd.service last, while a stage-only change skips the restart. hermeticd update --check on the box reports without writing anything. --hermes bumps the pinned version in the render and re-uploads the agent manifest — one agent, or --all for the whole fleet, upgraded one at a time. On its own that is all it does: the box keeps running the Hermes it has, and the pin takes effect on the agent’s next recreate, same as any other config change (the agent reads as config-drifted until then, and hermetic plan rollout --agent <name> applies it too). Add --now to apply it in place: hermetic writes the same converge request a rollout does and waits — up to ten minutes per agent — for the box to report the new config. On the box, hermeticd stops the Hermes gateway and dashboard, checks out the pinned ref, reinstalls the venv and restarts them; the instance, its disks and its tailnet address stay, but a turn in flight is interrupted. A box that is not ready, degraded or error keeps the pin and is reported skipped, and one that does not answer in time is reported unconverged rather than failed — hermetic agent history <name> shows what its apply did. The app’s Lifecycle card offers both: Upgrade now is --now, Pin for next recreate is the pin alone. --now cannot be combined with --hermeticd. Hermes memory and skills survive either kind of upgrade because they live on /data, never the root volume. hermeticd itself has exactly one version, the laptop package’s own version compiled in at build time — there’s no separate hand-maintained agent-daemon version to keep in sync.
Knowing when to bump Hermes. hermetic never bumps Hermes for you — the pin is per agent, and which agent goes first is your call. What it does do is tell you there is something to decide: hermetic foundation status prints a hermes line, and the app’s Settings → Foundation card shows the same thing with a badge, comparing the tag this build pins (hermes_ref, e.g. v2026.9.24) against the tag on upstream’s latest GitHub release. The check is advisory and best effort — unauthenticated (GitHub allows 60 requests an hour per IP), five-second ceiling, cached for six hours, and nothing polls it on a timer. When it cannot answer it says “could not check” and why; it never reports “up to date” for a check that did not happen, and it never blocks or fails the command it rides on. Acting on it is one agent at a time:
hermetic foundation status # ... hermes pinned 0.21.1 (v2026.9.14) · latest 2026.9.18 · update available# then, in this repo: set BUILD_VERSIONS.hermes (the semver upstream's pyproject reports)# and BUILD_VERSIONS.hermes_ref (the tag — v2026.9.4 in this example output; the ref# this build actually pins is v2026.9.24) together, and rebuild.hermetic artifacts push # mirrors the new ref into the fleet buckethermetic upgrade atlas --hermes <new semver> --now # one agent first, reinstalled in place# or pin it and let the next rebuild install it:hermetic upgrade atlas --hermes <new semver>hermetic agent recreate atlas --yesThe two-step is not ceremony, and --now does not shorten it: an agent row has no ref of its own, every render pins this build’s BUILD_VERSIONS.hermes_ref, so an in-place upgrade — like a recreate from this checkout — can only reach the ref this build pins. Upstream’s tags are dates and its pyproject version is a semver, and neither derives from the other — so the ref the box checks out lives in BUILD_VERSIONS.hermes_ref and no flag moves it, while --hermes pins what hermes --version must then report. Bumping only the flag gives you a box that checks out the old ref and fails its own version assertion, which is the apply refusing to ship a version nobody asked for.
A bump also has to reach the fleet bucket, because a box does not clone github.com when the manifest offers it something better. hermetic artifacts push — and init, and upgrade --hermes — builds hermes/<ref>.bundle from a bare mirror it keeps on the laptop at $HERMETIC_HOME/mirror/hermes-agent.git, uploads it, and records its digest and size in the fleet manifest’s hermes block (§3.6). Only tags are mirrored: a hermes_ref naming a branch is skipped with a warning rather than pinned to a moving target. The step fails soft — a laptop that cannot reach GitHub reports a mirror_warning on artifacts push and leaves the manifest’s hermes block as it was, and any box whose ref has no bundle falls back to the direct clone it always used. The fleet must be on foundation v7 for boxes to read the bundle at all (the agent role’s hermes/* S3 grant): run hermetic foundation update on a fleet created before it, or every agent quietly takes the fallback path.