8.3 KiB
Phases 5 & 6 — Auto-launch elizaOS + wire the agent
Phase 5 makes the elizaOS app launch as the desktop. Phase 6 wires its agent / onboarding / local LLM. This doc is the integration design for the Tails-based elizaOS Live distro.
Paths: TAILS = packages/os/linux/tails.
Status as of 2026-05-19: Phase 5's OS-side launcher/supervisor overlay exists in source and passed the normal QEMU app-service path on a recent validated artifact. Phase 6 has the OS-side capability runner and launch env in place, but approval-gated package/network actions and production package boundaries are not release-complete.
Context established by research
- Tails uses GDM + a stock GNOME Wayland session. The
tails-greeteris a GDM greeter session; clicking "Start" auto-logs-in theamnesiauser (uid 1000) into GNOME./etc/gdm3/PostLogin/Defaultruns as root after login (locale, sudo, network unblock) — do not modify it. - Tails' GNOME honors
/etc/xdg/autostart/(proof:systemd-desktop-target.desktoplives there). For a production-feeling AI OS, autostart is only the session trigger; a root-owned systemd service is the supervisor that restarts elizaOS if it exits. No GDM patching. - Tails already ships
no-overview@fthx,disable-log-out,disable-user-switchingin its dconf — much of "GNOME shell defaults" is done; elizaOS Live only rebrands and confirms. - The removed root-level Linux prototype's session layer was not reusable here (sway + a custom shell, different user). elizaOS Live uses the GNOME session Tails already boots and starts the bundled app inside that session.
PHASE 5 — Auto-launch elizaOS on greeter exit
Mechanism: a root-owned systemd path watches for the live user's session
bus, then starts the elizaOS user services through a root-owned supervisor.
/usr/local/bin/elizaos uses a lock so restart paths cannot create duplicate
app instances. XDG autostart is intentionally not used; the app lifecycle is
owned by systemd.
Files to add (under TAILS/config/chroot_local-includes/):
etc/systemd/system/elizaos.path— enabled frommulti-user.target; startselizaos.servicewhen/run/user/1000/busappears.etc/systemd/system/elizaos.service— root-owned system service, starts the live-user services through/usr/local/lib/elizaos/elizaos-keeper. Normalamnesiacan close/minimize the window, but the service relaunches it and the user cannot delete/disable this system unit without root.usr/local/bin/elizaos— canonical wrapper; refuses root/non-amnesia, pinsELIZA_STATE_DIR=/home/amnesia/.elizaand XDG dirs, exports elizaOS mode/broker env, and holds a lock to prevent duplicate instances.etc/systemd/user/*.service— live-user agent, renderer, and app shell services enabled fordefault.target.etc/dconf/db/local.d/00_Tails_defaults— currently patched in place for elizaOS wallpaper/favorites while preserving Tails' existingenabled-extensions. If this is split later into a sibling00_elizaOS_defaults, keep the same rule: do not clobber Tails' extension list.- existing
20-dconf_updatechroot hook — compiles the local dconf database.
Window model: elizaOS should be a normal, movable GNOME window. It is not fullscreen, not a kiosk, and always-on because systemd supervises the process, not because the desktop is blocked. Users can still use Tor Browser, Files, Terminal, settings, and other Tails desktop tools.
Conflict callouts: Tails locks disable-log-out/disable-user-switching
(fine — elizaOS needs neither); usb-protection=lockscreen is fine (the
persistence USB is the boot device, already trusted). Don't touch
/etc/gdm3/PostLogin/Default.
PHASE 6 — Wire elizaOS onboarding + agent
App/runtime responsibilities
- Onboarding — the bundled app should run the v36-style first-run
flow and persist state under
~/.elizawhen Persistent Storage is unlocked. - Chat entry — first window open should be enough to start onboarding or the signed-in home surface; it must not require a private model download before the UI appears.
- Actions — BUILD_APP, OPEN_APP, persistence/status, provider sign-in, and local-model setup should be routed through app/runtime packages that are actually bundled in the image.
- Runtime — embedded Bun/agent startup must be self-contained in the live image, not dependent on workspace dev dependencies outside the ISO.
What's elizaOS Live-specific
This is real integration work, not a quick edit. The headline:
- Agent host model — recommended (A): the Electrobun elizaOS app
hosts the agent in-process. It runs inside the GNOME session and
inherits
WAYLAND_DISPLAY/XDG_RUNTIME_DIR/DBUS_SESSION_BUS_ADDRESS. This matches "the desktop IS the elizaOS app" and invalidates the "agent is detached under systemd, must rediscover the compositor" premise behind older sway socket-globbing approaches — so most of it simplifies rather than needing GNOME reimplementation. OPEN_APPGNOME delta —agent/src/runtime/actions/open-app.tshardcodesswaymsg exec. The one real code change: spawn the Chromium app-mode window directly (chromium --app=… --ozone-platform=wayland) or via Electrobun's native child-window API. TheswayEnv()sock-glob is dead under GNOME.- State dir — set
ELIZA_STATE_DIR=/home/amnesia/.elizain theelizaos.desktoplaunch env so onboarding/calibration/apps share one root Phase 7 can bind-mount. - Capability runner —
/usr/local/lib/elizaos/capability-runnerexists as a conservative first pass. It reports status/privacy/ persistence, opens Tails Persistent Storage, and allows exact sudo forroot-status; package install and network mutation intentionally refuse until approval-gated actions exist.
~/.eliza/ in amnesia vs persistent
- Amnesia:
/home/amnesiais already on Tails' tmpfs/overlay union.~/.eliza/is created on first write, lives in RAM, wiped on poweroff. No-op — just verify it materializes. - Persistent: Phase 7's
tpsElizaOSDataFeaturebind-mounts the LUKS-backed dir over/home/amnesia/.elizabefore the session starts. Phase 6's job: verify the agent tolerates~/.elizabeing a bind-mount (it does — all path resolution goes through$HOME).
Local LLM / GPU
Bake the GGUF to a elizaos path; the elizaos.desktop autostart sets
LOCAL_LARGE_MODEL — or the full elizaOS app uses @elizaos/plugin-local-inference
with its own Vulkan/CUDA profiles. Runtime package support should include
libvulkan1 + mesa-vulkan-drivers; bake the GPU-enabled
node-llama-cpp peer binary, not the CPU one.
Must verify in QEMU (Phase 6 success criteria)
- v36 3-question onboarding runs in chat after the greeter.
~/.eliza/works in amnesia (tmpfs) and persistent (LUKS bind-mount).- BUILD_APP — stub backend + Claude backend (v36 paste-code OAuth).
- OPEN_APP opens a Chromium app-mode window (the de-sway path — the one code-delta verification).
- Local LLM offloads to GPU on virtio-gpu + bare-metal NVIDIA/AMD.
Known conflicts (documented, not blockers)
- Privacy Mode routes through Tor → Anthropic/OpenAI often block Tor exit IPs; local LLM is the always-works path.
- Electrobun's CEF Chromium doesn't inherit the SOCKS proxy → leaks past
Tor in Privacy Mode (the known v1.0 gap —
docs/privacy-mode-v1-gap.md). - elizaOS must tolerate offline-first boot (it already does — "local-only mode" is a first-class elizaos deployment shape).
Ordered implementation checklist
Phase 5: confirm Phase 4's binary path → add root-owned elizaos.path/elizaos.service supervisor → add etc/xdg/autostart/elizaos.desktop backup → add /usr/local/bin/elizaos wrapper → add/extend dconf defaults and hook → just boot: greeter → Start → GNOME → elizaOS app window, normal desktop still usable, close/crash relaunches. The file overlay steps are done locally and the normal QEMU app-service path has passed on a validated artifact; exact release commits still need rebuild/revalidation if the branch moves.
Phase 6: apply the portability audit's must-fix categories → confirm the in-process agent host model → resolve the open-app.ts de-sway → bake the GGUF + GPU-enabled node-llama-cpp → QEMU verification matrix above.