packages/os/linux/variants/milady-tails/docs/update-architecture.md
This slice adds the production update foundation for app/runtime updates without adding a network downloader or ISO/IUK builder. It is a checked prototype: release keys, downloader UX, revocation service, and full rollback policy are still production work.
/opt/milady as the immutable factory runtime baked into the ISO./run/elizaos, not into user-writable
marker files.The verifier consumes this staged layout:
/home/amnesia/.eliza/updates/
channel # optional user preference, path-safe name
channels/
stable/
manifest.json
manifest.json.sig
runtime-2026.05.17/
bin/bun
bin/launcher
Resources/app/eliza-dist/entry.js
Resources/app/eliza-dist/node_modules/...
model-catalog.json
state/
... # legacy user hints are ignored for trust
/live/persistence/TailsData_unlocked/elizaos-system/
runtimes/<manifest-sha256>/ # root-owned materialized runtime store
update-state/
good/<manifest-sha256> # root-owned post-health marker
rejected/<manifest-sha256> # root-owned rollback marker
sequence-floor/<channel> # root-owned anti-rollback floor after good
The user-writable staging directory never establishes trust. The selected
manifest.json must pass signature verification and full inventory/hash
verification, then root copies the declared runtime into the root-owned
materialized store. Launcher state points at the materialized copy, not the
staged source tree.
/usr/local/lib/elizaos/update-manager verify is the root verifier. It fails
closed to /opt/milady unless all checks pass:
gpgv is available.$ELIZAOS_UPDATE_KEYRING/usr/share/keyrings/elizaos-update.gpg/etc/elizaos/update-keyring.gpg/usr/local/share/elizaos/update-keyring.gpgmanifest.json.sig verifies as a detached signature over manifest.json.runtime.filesComplete is true.runtime.files[].runtime.files[] hash matches.bun, launcher, and agent entrypoints exist and are included in
the hashed file list.kind: elizaos.modelCatalog.If any check fails, the verifier writes a fallback selector pointing at
/opt/milady.
Verified selector state is written to:
/run/elizaos/runtime.env
/run/elizaos/runtime-selection.json
runtime.env is shell-safe environment data intended for launcher scripts to
source through /usr/local/lib/elizaos/runtime-env. The helper refuses
non-root-owned or group/world-writable selector files and defaults to the baked
runtime when /run/elizaos/runtime.env is absent.
The app, agent, and renderer launchers source runtime-env and use
ELIZAOS_BUN, ELIZAOS_LAUNCHER, ELIZAOS_AGENT_ENTRY, and
ELIZAOS_NODE_PATH. The helper ignores caller-supplied runtime overrides by
default, refuses unsafe selector files, and falls back to /opt/milady.
The verifier labels a signed staged runtime as:
candidate when the manifest digest has not been marked good.active when update-manager mark-good has recorded the digest under
update-state/good/.update-state/rejected/ or verification
fails.The marker commands only operate on the current signed selection in
/run/elizaos/runtime-selection.json; they cannot mark an unsigned payload as
trusted. elizaos-update-health-check.service runs after the app supervisor
starts and calls:
/usr/local/lib/elizaos/update-manager mark-good
after the agent and renderer pass local readiness checks. It can call
mark-bad after timeout only when
ELIZAOS_UPDATE_HEALTH_MARK_BAD_ON_TIMEOUT=1; by default, timeout leaves the
candidate unpromoted instead of rejecting a potentially slow boot.
elizaos-update-verify.service is a oneshot root service:
/usr/local/lib/elizaos/update-manager verifytails-persistent-storage.service/run/elizaos and the root-owned elizaOS persistent runtime storeThe image hook enables the unit for multi-user.target.
Schemas live in:
schemas/update-manifest.schema.jsonschemas/model-catalog.schema.jsonThe manifest signs the runtime and pins the optional model catalog by hash. The model catalog describes model artifacts and capabilities, but model artifact fetching and model runtime loading remain separate future work.