#!/usr/bin/env bash # CPU-light static checks for the elizaOS Live overlay. set -euo pipefail # This gate is a long `set -e` assertion chain of silent test/grep commands, so # an unannotated failure exits with no output at all — that silence hid a red # nightly for over a week. Name the dying assertion on the way out. trap 'echo "static-smoke: FAILED at ${BASH_SOURCE[0]}:${LINENO}: ${BASH_COMMAND}" >&2' ERR ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" REPO_ROOT="$(cd "${ROOT}/../../.." && pwd)" SOURCE_ONLY="${ELIZAOS_STATIC_SOURCE_ONLY:-0}" cd "${ROOT}" if ! command -v rg >/dev/null 2>&1; then echo "ripgrep (rg) is required for elizaOS Live static smoke checks." >&2 exit 1 fi stat_mode() { local path="$1" local index_mode index_mode="$( git -C "${ROOT}" ls-files -s -- "${path}" 2>/dev/null | awk 'NR == 1 { print $1 }' )" case "${index_mode}" in 100755) printf '755\n' return 0 ;; 100644) printf '644\n' return 0 ;; esac stat -c %a "${path}" 2>/dev/null || stat -f %Mp%Lp "${path}" | sed 's/^0//' } echo "==> shell syntax" test -f tails/data/debootstrap/scripts/debian-common.patch test -f tails/data/splash.png test -x tails/data/wrappers/apt-get test -f docs/riscv64-gui-support.md test -f tails/config/chroot_local-packageslists/elizaos-riscv64-gui.list grep -Fq "virtio-gpu-pci" docs/riscv64-gui-support.md grep -qx "linux-image-riscv64" tails/config/chroot_local-packageslists/elizaos-riscv64-gui.list grep -qx "gnome-shell" tails/config/chroot_local-packageslists/elizaos-riscv64-gui.list grep -qx "nodejs" tails/config/chroot_local-packageslists/elizaos-riscv64-gui.list for tails_build_input in \ tails/config/chroot_local-includes/usr/share/tails/build/customize-ublock-assets \ tails/config/chroot_local-includes/usr/share/tails/build/group \ tails/config/chroot_local-includes/usr/share/tails/build/mksquashfs-excludes \ tails/config/chroot_local-includes/usr/share/tails/build/passwd \ tails/config/chroot_local-includes/usr/share/tails/build/plymouth-theme.diff do test -f "${tails_build_input}" done for custom_tails_package in \ apparmor \ apparmor-profiles \ evince \ evince-common \ flatpak \ haveged \ libapparmor1 \ libevdocument3-4t64 \ libevview3-3t64 \ libgcrypt20 \ libhavege2 \ libyelp0 \ yelp do grep -qx "${custom_tails_package}" tails/config/chroot_local-hooks/99-custom-packages-check done bash -n build.sh build-iso.sh tails/auto/build \ scripts/build-cache-contract.test.sh \ scripts/dev-sign-update-manifest.sh \ scripts/usb-write.sh \ scripts/generate-elizaos-brand-assets.sh \ scripts/run-cool-build.sh \ scripts/submodule-checkout.sh \ scripts/security-smoke.sh grep -Fq 'if [ -f "${SRC}/binary.iso" ]' build-iso.sh grep -Fq 'find "${SRC}" -maxdepth 1 -name' build-iso.sh grep -Fq "sort -nr" build-iso.sh bash scripts/build-cache-contract.test.sh bash -n scripts/sync-runtime-to-chroot.sh sh -n \ tails/auto/config \ tails/config/chroot_local-hooks/9100-install-elizaos \ tails/config/chroot_local-hooks/9150-brand-inherited-strings \ tails/config/chroot_local-hooks/99-zzzzzz_permissions \ tails/config/chroot_local-includes/usr/sbin/swapon.tails \ tails/config/chroot_local-includes/usr/local/bin/elizaos \ tails/config/chroot_local-includes/usr/lib/live/config/0001-elizaos-privacy-mode \ tails/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/00-firewall.sh \ tails/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/00-resolv-over-clearnet \ tails/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/10-tor.sh \ tails/config/chroot_local-includes/usr/local/lib/elizaos/capability-runner \ tails/config/chroot_local-includes/usr/local/lib/elizaos/create-persistent-storage-session \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-keeper \ tails/config/chroot_local-includes/usr/local/lib/elizaos/persistence-maintenance \ tails/config/chroot_local-includes/usr/local/lib/elizaos/runtime-env \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-browser-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-pill-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-renderer-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-health-check \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-manager \ tails/config/chroot_local-includes/usr/local/bin/tails-backup \ tails/config/chroot_local-includes/usr/local/lib/tails-report-disk-ioerrors \ tails/config/chroot_local-includes/usr/local/lib/thunderbird \ tails/config/chroot_local-includes/usr/local/lib/persistent-storage/on-activated-hooks/ElizaOSData/10-clean-runtime-state \ tails/config/chroot_local-includes/usr/local/lib/persistent-storage/on-activated-hooks/ElizaOSData/20-restart-elizaos \ tails/config/chroot_local-includes/usr/local/lib/persistent-storage/on-deactivated-hooks/ElizaOSData/20-restart-elizaos node --check scripts/prepare-elizaos-app-overlay.mjs node --check scripts/generate-release-evidence.mjs node --check scripts/validate-model-catalog.mjs node --check scripts/validate-runtime-overlay.mjs node --check tails/config/chroot_local-includes/usr/local/lib/elizaos/renderer-server.mjs grep -q 'ELIZAOS_APP_ARTIFACT' Justfile grep -q 'ensure_plugin_runtime_dist "plugins/plugin-health" package-js' Justfile grep -q 'ensure_plugin_runtime_dist "plugins/plugin-calendly" tsup-index' Justfile python3 -m json.tool schemas/update-manifest.schema.json >/dev/null python3 -m json.tool schemas/model-catalog.schema.json >/dev/null python3 - \ tails/config/chroot_local-includes/usr/local/bin/tails-documentation \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell \ tails/config/chroot_local-includes/usr/local/bin/electrum \ tails/config/chroot_local-includes/usr/local/bin/tails-about \ tails/config/chroot_local-includes/usr/local/bin/tails-upgrade-frontend-wrapper \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tailsgreeter/ui/main_window.py \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tca/ui/main_window.py \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tails_installer/gui.py \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tps/device.py \ tails/config/chroot_local-includes/usr/local/lib/tails-low-ram-notify-user \ tails/config/chroot_local-includes/usr/local/lib/tails-uefi-ca-notify-user \ tails/config/chroot_local-includes/usr/local/lib/tails-virt-notify-user \ tails/config/chroot_local-includes/usr/local/lib/additional-software/asp-handle-package-changes \ tails/config/chroot_local-includes/usr/local/lib/additional-software/asp-install \ tails/config/chroot_local-includes/usr/local/lib/additional-software/asp-update-config <<'PY' import py_compile import sys import tempfile from pathlib import Path with tempfile.TemporaryDirectory(prefix="elizaos-pycompile-") as tmp: for index, path in enumerate(sys.argv[1:]): py_compile.compile( path, cfile=str(Path(tmp) / f"{index}.pyc"), doraise=True, ) PY for unit in \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-agent.service \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-renderer.service \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-pill.service \ tails/config/chroot_local-includes/etc/systemd/user/elizaos.service do grep -q '^ConditionUser=1000$' "${unit}" done for executable in \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell \ tails/config/chroot_local-includes/usr/local/lib/elizaos/runtime-env \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-browser-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/create-persistent-storage-session \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-pill-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-renderer-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-health-check \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-manager \ scripts/dev-sign-update-manifest.sh \ scripts/run-cool-build.sh \ scripts/usb-write.sh \ scripts/security-smoke.sh \ scripts/sync-runtime-to-chroot.sh do mode="$(stat_mode "${executable}")" if [ "${mode}" != "755" ]; then echo "${executable} must be mode 755, got ${mode}" >&2 exit 1 fi done echo "==> elizaOS branding" for font in Poppins-Regular.ttf Poppins-Medium.ttf OFL.txt; do test -f "tails/config/chroot_local-includes/usr/share/fonts/truetype/elizaos/${font}" font_mode="$(stat_mode "tails/config/chroot_local-includes/usr/share/fonts/truetype/elizaos/${font}")" if [ "${font_mode}" != "644" ]; then echo "${font} must be mode 644, got ${font_mode}" >&2 exit 1 fi done grep -q "Poppins 10" \ tails/config/chroot_local-includes/etc/dconf/db/local.d/00_Tails_defaults grep -q "Poppins Medium 10" \ tails/config/chroot_local-includes/etc/dconf/db/local.d/00_Tails_defaults grep -q "color-scheme='prefer-light'" \ tails/config/chroot_local-includes/etc/dconf/db/local.d/00_Tails_defaults grep -q '#0b35f1' \ tails/config/chroot_local-includes/usr/share/gnome-shell/extensions/window-list@gnome-shell-extensions.gcampax.github.com/stylesheet-dark.css grep -q '^gir1.2-udisks-2.0$' \ tails/config/chroot_local-packageslists/tails-common.list grep -q '#0B35F1' scripts/generate-elizaos-brand-assets.sh grep -q 'logo_white_bluebg.svg' scripts/generate-elizaos-brand-assets.sh if rg -n '#FF5800|#FF0000|#ff5800|#ff0000|ORANGE|RED|#ffe600|#f0b90b|#08080a|#0a0a0a|#03061f' \ scripts/generate-elizaos-brand-assets.sh \ tails/config/chroot_local-includes/usr/share/tails/greeter/greeter.css \ tails/config/chroot_local-includes/usr/share/tails/persistent-storage/style.css \ tails/config/chroot_local-includes/usr/share/doc/elizaos/website/doc.en.html \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell then echo "Core visible elizaOS surfaces must use the blue/white/soft-grey brand palette." >&2 exit 1 fi grep -q 'font-family: "Poppins"' \ tails/config/chroot_local-includes/usr/share/tails/greeter/greeter.css if [ "${SOURCE_ONLY}" != "1" ]; then grep -q 'id="elizaos-live-theme"' \ tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/index.html grep -q '#F7F9FF' \ tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/index.html grep -q '"theme_color": "#F7F9FF"' \ tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/site.webmanifest if rg -n '#08080a|#0a0a0a|black-translucent' \ tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/index.html \ tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/site.webmanifest then echo "Packaged app renderer must not expose the old dark shell metadata." >&2 exit 1 fi if rg -n '#FF5800|#ff5800|#FF0000|#ff0000' \ tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/index.html \ tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/site.webmanifest then echo "Packaged app renderer metadata must use the blue/white elizaOS palette." >&2 exit 1 fi fi # StartupShell is a SHARED app-shell component (@elizaos/ui), and the elizaOS OS # ISO bundles it verbatim — there is no downstream OS theme override for the # boot splash. Per the per-surface accent system, the *app* surface owns the # splash and it uses the launch token whose current intentional fallback is # #000000 — the home shader's black base field, so boot flows seamlessly into # the home ember glow (#9565). OS chrome such as the greeter/dashboard # metadata/failure shell stays on the blue/white palette; first-run stays # inside the launch surface. So this gate asserts the splash's current # intentional launch token and the neutral bootstrap-gate surface, and only # rejects the genuinely-stale hardcoded dark/gradient/glow styling from the # pre-redesign shell (the token fallback is a host-overridable seam, not a # hardcoded surface). if rg -n 'bg-\[#08080a\]|bg-\[#0a0a0a\]|radial-gradient|blur-\[' \ "${REPO_ROOT}/packages/ui/src/components/shell/StartupShell.tsx" then echo "Startup shell must not reintroduce the old dark/gradient splash." >&2 exit 1 fi grep -Fq 'bg-[var(--launch-bg,#000000)]' \ "${REPO_ROOT}/packages/ui/src/components/shell/StartupShell.tsx" grep -q 'bg-\[#F7F6F4\]' \ "${REPO_ROOT}/packages/ui/src/components/shell/StartupShell.tsx" if rg -n 'bg-danger|text-danger|variant="danger"|radial-gradient' \ "${REPO_ROOT}/packages/ui/src/components/shell/StartupFailureView.tsx" then echo "Startup failure shell must stay on the clean elizaOS white/blue surface." >&2 exit 1 fi grep -q 'bg-bg' \ "${REPO_ROOT}/packages/ui/src/components/shell/StartupFailureView.tsx" grep -q 'text-txt' \ "${REPO_ROOT}/packages/ui/src/components/shell/StartupFailureView.tsx" grep -q 'text-destructive' \ "${REPO_ROOT}/packages/ui/src/components/shell/StartupFailureView.tsx" # First-run onboarding now renders inline in the real floating chat overlay: # #10302 deleted the dedicated FirstRunChat.tsx surface and seeds the onboarding # greeting/choices as the same inline widgets the live chat uses. The overlay's # text runs on the `text-txt` THEME token (hardcoded `text-white` literals were # retokenized so the surface follows the active theme). Gate that overlay # against the stale dark/gradient/glow styling from the pre-redesign first-run # shell (mirrors the #10167 repoint when CompactOnboarding was removed). first_run_shell="${REPO_ROOT}/packages/ui/src/components/shell/ContinuousChatOverlay.tsx" grep -q 'text-txt' "${first_run_shell}" if rg -n 'bg-\[#08080a\]|bg-\[#0a0a0a\]|radial-gradient|blur-\[' \ "${first_run_shell}" then echo "First-run onboarding (in-chat overlay) must not reintroduce the old dark/gradient shell." >&2 exit 1 fi onboarding_states_css="${REPO_ROOT}/packages/ui/src/components/onboarding/states/onboarding.css" if [ -f "${onboarding_states_css}" ]; then if rg -n '#ff8a24|#FF5800|#ff5800|#ffe600|#f0b90b' "${onboarding_states_css}" then echo "Legacy onboarding states must stay on the blue/white elizaOS palette." >&2 exit 1 fi fi if [ "${SOURCE_ONLY}" != "1" ]; then if rg -n '#FF5800|#ff5800|#ff8a24|#ffe600|#f0b90b' \ tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/brand \ --glob '*.svg' then echo "Packaged renderer SVG brand assets must not expose the old warm palette." >&2 exit 1 fi if rg -n '#FF5800|#ff5800|#ff8a24|#e54f00|#c94400|#ff6d1f|255, ?88, ?0' \ tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/assets \ --glob '*.css' then echo "Packaged renderer CSS assets must not expose the old orange palette." >&2 exit 1 fi fi grep -q 'export const handleWalletRoutes' \ "${REPO_ROOT}/packages/agent/src/api/index.ts" # Wallet routes must load via a lazy dynamic import (not a top-level static # import) at startup. Tolerate an inline /* @vite-ignore */ comment in the call. rg -q 'await import\((/\* @vite-ignore \*/ )?"@elizaos/plugin-wallet"\)' \ "${REPO_ROOT}/packages/agent/src/api/index.ts" if rg -n 'handleWalletRoutes,\\n type WalletAddressesSnapshot' \ "${REPO_ROOT}/packages/agent/src/api/index.ts" then echo "Agent API barrel must not hard-import plugin-wallet during startup." >&2 exit 1 fi python3 - <<'PY' try: import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk except (ImportError, ValueError): print("skip: python gi/gtk unavailable for GTK 3 greeter CSS parser check") else: Gtk.CssProvider().load_from_path( "tails/config/chroot_local-includes/usr/share/tails/greeter/greeter.css" ) PY grep -q -- '--iso-application="elizaOS"' tails/auto/config grep -q -- '--iso-publisher="https://elizaos.ai/"' tails/auto/config grep -q -- '--iso-volume="ELIZAOS ' tails/auto/config grep -q 'PRETTY_NAME="elizaOS"' tails/auto/config grep -q 'SUPPORT_URL="https://elizaos.ai/"' tails/auto/config grep -q 'BUG_REPORT_URL="https://elizaos.ai/"' tails/auto/config grep -qx 'elizaOS' tails/config/chroot_local-includes/etc/issue.net grep -q '^elizaOS \\n \\l$' tails/config/chroot_local-includes/etc/issue grep -q 'WEBSITE_URL = "https://elizaos.ai"' \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tailslib/website.py grep -q 'WEBSITE_LOCAL_PATH = "/usr/share/doc/elizaos/website"' \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tailslib/website.py grep -q 'file:///usr/share/doc/elizaos/website/doc.en.html' \ tails/config/chroot_local-includes/usr/local/bin/tails-documentation grep -q 'file:///usr/share/doc/elizaos/website/' \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tailsgreeter/ui/main_window.py if rg -n 'Documentation=https://tails\.net' \ tails/config/chroot_local-includes/usr/lib/systemd/user/*.service then echo "User systemd unit documentation must route to elizaOS help." >&2 exit 1 fi grep -q 'doc.en.html#storage' \ tails/config/chroot_local-includes/usr/share/tails/greeter/main.ui.in grep -q 'font-family: "Poppins"' \ tails/config/chroot_local-includes/usr/share/doc/elizaos/website/doc.en.html grep -q '#0B35F1' \ tails/config/chroot_local-includes/usr/share/doc/elizaos/website/doc.en.html grep -q '"distribution": "elizaOS"' \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tails_installer/config.py grep -q '"partition_label": "elizaOS"' \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tails_installer/config.py grep -q 'ConditionPathExists=/etc/elizaos/base-updates-enabled' \ tails/config/chroot_local-includes/usr/lib/systemd/user/tails-upgrade-frontend.service grep -q 'ELIZAOS_SECURITY_FEED_BASE_URL' \ tails/config/chroot_local-includes/usr/local/bin/tails-security-check grep -q 'support@elizaos.ai' \ tails/config/chroot_local-includes/etc/whisperback/config.py grep -q 'elizaOS Feedback' \ tails/config/chroot_local-includes/usr/share/whisperback/whisperback.ui.in if rg -n 'support@tails|whisperback\.tails|tails\.boum\.org|Tails-Version' \ tails/config/chroot_local-includes/etc/whisperback/config.py then echo "WhisperBack config must not route elizaOS reports to inherited Tails endpoints." >&2 exit 1 fi if command -v identify >/dev/null 2>&1; then image_paths=( tails/config/chroot_local-includes/usr/share/tails/desktop_wallpaper.png \ tails/config/chroot_local-includes/usr/share/tails/screensaver_background.png \ tails/config/binary_local-includes/EFI/debian/grub/splash.png \ tails/config/chroot_local-includes/usr/share/tails/greeter/icons/elizaos-logo.png \ tails/config/chroot_local-includes/usr/share/tails/elizaos-about-logo.png \ tails/config/chroot_local-includes/usr/share/plymouth/themes/elizaos/elizaos-wordmark.png \ tails/config/chroot_local-includes/usr/share/tails-installer/tails-liveusb-header.png \ tails/config/chroot_local-includes/usr/share/tails/bootx64.png \ tails/config/chroot_local-includes/usr/share/icons/hicolor/scalable/apps/elizaos.svg \ tails/config/chroot_local-includes/usr/share/pixmaps/elizaos.svg \ tails/config/chroot_local-includes/usr/share/pixmaps/elizaos.png \ ) if [ "${SOURCE_ONLY}" != "1" ]; then renderer_icon="tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/brand/favicons/android-chrome-512x512.png" if [ ! -f "${renderer_icon}" ]; then renderer_icon="tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/renderer/favicon-256x256.png" fi image_paths+=( tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/assets/appIcon.png "${renderer_icon}" ) fi identify "${image_paths[@]}" >/dev/null fi if rg -n \ 'Tails-based|Tails Cloner|Tails Documentation|Connect Tails|Tails USB stick|elizaOS \(Tails-based\)' \ README.md RELEASE_PATH.md docs/user-experience.md docs/mode-parity.md \ PLAN.md docs/build-infrastructure.md \ tails/auto/build tails/auto/config \ tails/config/chroot_local-includes/etc \ tails/config/chroot_local-includes/usr/share/tails \ tails/config/chroot_local-includes/usr/share/applications \ tails/config/chroot_local-includes/usr/share/doc/elizaos \ tails/config/chroot_local-includes/usr/share/tails-installer \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tailsgreeter \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tps_frontend \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tails_installer \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tca \ tails/config/chroot_local-includes/usr/local \ tails/config/binary_local-includes then echo "Visible elizaOS branding still contains stale Tails/elizaOS strings." >&2 exit 1 fi if rg -n \ 'Tails is up to date|This version of Tails|Restart Tails|Your Tails|Tails device|your Tails|restart Tails|when starting Tails|from Tails goes through|coming from a Tails user|Tails will|Tails failed|Tails couldn'\''t|improve Tails|Error Reading Data from Tails|reinstall Tails|tails\.net/doc|tails\.net/install|tails\.net/latest|tails\.net/gdm|tails\.net/ioerror|/usr/share/doc/tails/website' \ tails/config/chroot_local-includes/usr/src/iuk/lib/Tails/IUK/Frontend.pm \ tails/config/chroot_local-includes/usr/local/bin/tails-backup \ tails/config/chroot_local-includes/usr/local/bin/tails-security-check \ tails/config/chroot_local-includes/usr/local/bin/tails-upgrade-frontend-wrapper \ tails/config/chroot_local-includes/usr/local/lib/additional-software \ tails/config/chroot_local-includes/usr/local/lib/tails-gdm-error-message \ tails/config/chroot_local-includes/usr/local/lib/tails-low-ram-notify-user \ tails/config/chroot_local-includes/usr/local/lib/tails-uefi-ca-notify-user \ tails/config/chroot_local-includes/usr/local/lib/tails-report-disk-ioerrors \ tails/config/chroot_local-includes/usr/local/lib/tails-virt-notify-user \ tails/config/chroot_local-includes/usr/local/lib/polkit-policy-change-message \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tailsgreeter/ui/main_window.py \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tca/ui/main_window.py \ tails/config/chroot_local-includes/usr/share/tails/tca/main.ui.in \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tails_installer/gui.py \ tails/config/chroot_local-includes/usr/share/tails-installer/tails-installer.ui.in \ tails/config/chroot_local-includes/usr/share/whisperback/whisperback.ui.in \ tails/config/binary_local-includes/isolinux/sorry32.txt then echo "High-visibility inherited Tails strings still need elizaOS branding." >&2 exit 1 fi if rg -n \ 'Preparing Tails for first use|Checking the Tails system partition|Configuring Tails|Tails specific tools|Tails live user' \ tails/config/chroot_local-includes/usr/share/initramfs-tools/scripts/init-premount/partitioning \ tails/config/chroot_local-includes/usr/share/initramfs-tools/scripts/init-top/read-and-update-random-seed-sector \ tails/config/chroot_local-includes/usr/lib/live/config/2000-aesthetics \ tails/config/chroot_local-includes/usr/local/bin/elizaos \ tails/config/chroot_local-includes/usr/share/desktop-directories/Tails.directory.in then echo "First-boot and launcher polish still exposes inherited Tails wording." >&2 exit 1 fi launcher_paths=( tails/config/chroot_local-includes/usr/share/applications/tails-documentation.desktop tails/config/chroot_local-includes/usr/share/applications/tails-backup.desktop tails/config/chroot_local-includes/usr/share/applications/tails-installer.desktop tails/config/chroot_local-includes/usr/share/applications/tca.desktop tails/config/chroot_local-includes/usr/share/applications/org.boum.tails.AdditionalSoftware.desktop tails/config/chroot_local-includes/usr/share/applications/whisperback.desktop ) existing_launcher_paths=() for launcher_path in "${launcher_paths[@]}"; do if [ -e "${launcher_path}" ]; then existing_launcher_paths+=("${launcher_path}") fi done if [ "${#existing_launcher_paths[@]}" -gt 0 ]; then if rg -n '^(Name|Comment|Keywords)\[' "${existing_launcher_paths[@]}"; then echo "Brand-sensitive desktop launchers must fall back to curated elizaOS labels." >&2 exit 1 fi fi if command -v desktop-file-validate >/dev/null 2>&1; then echo "==> desktop entries" desktop-file-validate \ tails/config/chroot_local-includes/usr/share/applications/elizaos.desktop else echo "skip: desktop-file-validate not installed" fi if [ -e tails/config/chroot_local-includes/etc/xdg/autostart/elizaos.desktop ]; then echo "elizaOS must be supervised by systemd, not XDG autostart." >&2 exit 1 fi grep -q '^Name=elizaOS$' \ tails/config/chroot_local-includes/usr/share/applications/elizaos.desktop grep -q '^Icon=elizaos$' \ tails/config/chroot_local-includes/usr/share/applications/elizaos.desktop grep -q '^StartupWMClass=elizaOS$' \ tails/config/chroot_local-includes/usr/share/applications/elizaos.desktop grep -q 'IMG_FOOTPRINTS = "/usr/share/pixmaps/elizaos.svg"' \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tca/ui/main_window.py grep -q '^Icon=elizaos$' \ tails/config/chroot_local-includes/usr/share/applications/org.boum.tails.PersistentStorage.desktop.in grep -q 'elizaos' \ tails/config/chroot_local-includes/usr/share/tails/greeter/main.ui.in grep -q '72' \ tails/config/chroot_local-includes/usr/share/tails/greeter/main.ui.in grep -Fq 'Save documents, browser bookmarks, Wi-Fi passwords, and elizaOS settings in encrypted Persistent Storage.' \ tails/config/chroot_local-includes/usr/share/tails/greeter/main.ui.in grep -Fq 'Defaults are safe. Use "+" to add settings.' \ tails/config/chroot_local-includes/usr/share/tails/greeter/main.ui.in grep -q 'elizaos' \ tails/config/chroot_local-includes/usr/share/tails/persistent-storage/window.ui.in for persistent_storage_view in \ tails/config/chroot_local-includes/usr/share/tails/persistent-storage/locked_view.ui.in \ tails/config/chroot_local-includes/usr/share/tails/persistent-storage/welcome_view.ui.in \ tails/config/chroot_local-includes/usr/share/tails/persistent-storage/passphrase_view.ui.in do grep -q '/usr/share/pixmaps/elizaos-persistent-storage.svg' "${persistent_storage_view}" done grep -q '24' \ tails/config/chroot_local-includes/usr/share/tails/persistent-storage/passphrase_view.ui.in grep -q '24' \ tails/config/chroot_local-includes/usr/share/tails/persistent-storage/welcome_view.ui.in grep -q '^Exec=/usr/local/bin/elizaos$' \ tails/config/chroot_local-includes/usr/share/applications/elizaos.desktop echo "==> elizaOS launch policy" if grep -q 'ELECTROBUN_CONSOLE.*:-1' \ tails/config/chroot_local-includes/usr/local/bin/elizaos; then echo "elizaOS must not force Electrobun console mode in elizaOS Live." >&2 exit 1 fi grep -q 'ELIZA_DESKTOP_FORCE_CEF.*:-0' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZA_STARTUP_STATE_FILE' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZA_STARTUP_EVENTS_FILE' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q '/usr/local/lib/elizaos/runtime-env' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZAOS_RUNTIME_DIR:-/opt/elizaos' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZA_APP_ID.*org.elizaos.app' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZAOS_LIVE_EMBEDDING_FALLBACK.*:-1' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZA_DISABLE_PROACTIVE_AGENT.*:-1' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZAOS_CLOSE_MINIMIZES_TO_TRAY.*:-1' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZAOS_CEF_PROFILE_COMPAT.*:-1' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZAOS_BUNDLED_SKILLS_DIR' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q '@elizaos/skills/skills' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'normalize_tcp_port' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'normalize_loopback_bind' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZA_API_PORT.*:-31337' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZA_DESKTOP_API_BASE.*127.0.0.1' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZA_API_BASE.*ELIZA_DESKTOP_API_BASE' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZA_API_STRICT_PORT.*:-1' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ELIZA_API_STRICT_PORT.*:-1' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user grep -q '/usr/local/lib/elizaos/runtime-env' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user grep -q '/usr/local/lib/elizaos/runtime-env' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-renderer-user grep -q 'strictPortBindingEnabled' \ "${REPO_ROOT}/packages/agent/src/api/server.ts" grep -q 'Strict port binding is enabled' \ "${REPO_ROOT}/packages/agent/src/api/server.ts" grep -q '"Feather"' scripts/prepare-elizaos-app-overlay.mjs grep -q '"Maximize2"' scripts/prepare-elizaos-app-overlay.mjs grep -q 'Resources/app' scripts/prepare-elizaos-app-overlay.mjs grep -q 'matchAll(namedImportRe)' scripts/prepare-elizaos-app-overlay.mjs grep -q 'matchAll(destructuredImportRe)' scripts/prepare-elizaos-app-overlay.mjs grep -q 'shouldWriteLiveFallbackPackage' scripts/prepare-elizaos-app-overlay.mjs grep -q 'elizaos-live-overlay-manifest.json' scripts/prepare-elizaos-app-overlay.mjs grep -q 'expectedPorts' scripts/prepare-elizaos-app-overlay.mjs grep -q 'validate-runtime-overlay.mjs' docs/runtime-packaging.md grep -q 'closeMinimizesToTray: true' scripts/prepare-elizaos-app-overlay.mjs grep -q 'usr/lib/python3/dist-packages/tailsgreeter/ui/main_window.py' \ scripts/sync-runtime-to-chroot.sh grep -Fq 'runtime["closeMinimizesToTray"] = True' \ tails/config/chroot_local-hooks/9100-install-elizaos grep -q 'prepare_cef_profile' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'safe_cache_component' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'archive_cef_path' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'ln -sfn . "${cef_root}/partitions"' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'mkdir -p "${cef_root}/default"' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -Fq 'printf '"'"'2\n'"'"' > "${cef_root}/.electrobun_cef_cache_version"' \ tails/config/chroot_local-includes/usr/local/bin/elizaos if grep -q 'mkdir -p.*partitions/default' \ tails/config/chroot_local-includes/usr/local/bin/elizaos; then echo "elizaOS launcher must not create nested CEF partitions/default directories." >&2 exit 1 fi if grep -q 'rm -rf.*partitions/default' \ tails/config/chroot_local-includes/usr/local/bin/elizaos; then echo "elizaOS launcher must not wipe the persistent CEF profile on every start." >&2 exit 1 fi if grep -q 'rm -rf.*Partitions/default' \ tails/config/chroot_local-includes/usr/local/bin/elizaos; then echo "elizaOS launcher must not wipe the persistent CEF profile on every start." >&2 exit 1 fi grep -q '.electrobun_cef_cache_version' \ tails/config/chroot_local-includes/usr/local/bin/elizaos if grep -q "printf '3\\\\n'" \ tails/config/chroot_local-includes/usr/local/bin/elizaos; then echo "elizaOS launcher must write the CEF cache marker expected by the app." >&2 exit 1 fi grep -q 'org.elizaos.app/dev/CEF' \ tails/config/chroot_local-includes/usr/local/bin/elizaos echo "==> elizaOS privacy fail-closed" grep -q 'elizaos_privacy=0' \ tails/config/binary_local-includes/EFI/debian/grub.cfg grep -q 'elizaos_privacy=1' \ tails/config/binary_local-includes/EFI/debian/grub.cfg grep -q 'elizaos_privacy=0' \ tails/config/binary_local-hooks/10-syslinux_customize grep -q 'elizaos_privacy=1' \ tails/config/binary_local-hooks/10-syslinux_customize grep -q 'printf.*on.*> /etc/elizaos/privacy-mode' \ tails/config/chroot_local-includes/usr/lib/live/config/0001-elizaos-privacy-mode grep -q 'printf on' \ tails/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/00-firewall.sh grep -q 'printf on' \ tails/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/10-tor.sh grep -q 'printf on' \ tails/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/00-resolv-over-clearnet grep -q 'printf on' \ tails/config/chroot_local-includes/usr/local/bin/elizaos grep -q 'printf on' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/capability-runner echo "==> elizaOS persistence contract" python3 - <<'PY' from pathlib import Path path = Path("tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tps/configuration/features.py") text = path.read_text() required = [ 'Binding("elizaos/eliza", "/home/amnesia/.eliza")', 'Binding("elizaos/elizaos", "/home/amnesia/.elizaos")', 'Binding("elizaos/config", "/home/amnesia/.config/elizaOS")', 'Binding("elizaos/config-legacy", "/home/amnesia/.config/elizaos")', 'Binding("elizaos/config-legacy-caps", "/home/amnesia/.config/elizaOS")', 'Binding("elizaos/cef-cache", "/home/amnesia/.cache/org.elizaos.app")', 'Binding("elizaos/cef-cache-legacy", "/home/amnesia/.cache/org.elizaos.app")', 'translatable_name = "elizaOS Data"', 'name="elizaOS"', 'desktop_id="elizaos.desktop"', 'process_names=["launcher", "bun"]', 'self._run_persistence_maintenance("enter")', 'self._run_persistence_maintenance("leave")', ] missing = [item for item in required if item not in text] if missing: raise SystemExit(f"{path}: missing ElizaOSData entries: {missing}") PY for launcher in \ tails/config/chroot_local-includes/usr/local/bin/elizaos \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-browser-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-renderer-user \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-user do grep -q 'persistence-maintenance wait' "${launcher}" done grep -q '^ExecStart=/usr/local/lib/elizaos/create-persistent-storage-session$' \ tails/config/chroot_local-includes/usr/lib/systemd/user/tails-create-persistent-storage.service grep -q 'session_flag="${runtime_dir}/elizaos-persistence-setup"' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/create-persistent-storage-session grep -q 'ELIZAOS_PERSISTENCE_SESSION_ACTIVE=1 /usr/local/bin/tails-persistent-storage' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/create-persistent-storage-session grep -q 'create-persistent-storage-session' \ tails/config/chroot_local-includes/usr/local/bin/tails-persistent-storage grep -q 'ELIZAOS_PERSISTENCE_SESSION_ACTIVE' \ tails/config/chroot_local-includes/usr/local/bin/tails-persistent-storage grep -q 'maintenance_helper=/usr/local/lib/elizaos/persistence-maintenance' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/create-persistent-storage-session grep -q 'sudo "${maintenance_helper}" enter' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/create-persistent-storage-session grep -q 'sudo "${maintenance_helper}" leave' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/create-persistent-storage-session python3 - <<'PY' from pathlib import Path path = Path("tails/config/chroot_local-includes/usr/local/lib/elizaos/create-persistent-storage-session") text = path.read_text() if text.index("trap cleanup EXIT") > text.index('sudo "${maintenance_helper}" enter'): raise SystemExit(f"{path}: cleanup trap must be registered before sudo enter can fail") if "ELIZAOS_PERSISTENCE_SESSION_ACTIVE=1 /usr/local/bin/tails-persistent-storage \"$@\" &" not in text: raise SystemExit(f"{path}: persistence wrapper must set recursion guard before spawning wizard") PY grep -q 'systemctl --user start --no-block elizaos.service' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/create-persistent-storage-session grep -Fq 'args = ["enter"]' \ tails/config/chroot_local-includes/etc/generate-sudoers.d/elizaos-persistence-maintenance.toml grep -Fq 'args = ["leave"]' \ tails/config/chroot_local-includes/etc/generate-sudoers.d/elizaos-persistence-maintenance.toml grep -q '/etc/generate-sudoers.d/elizaos-persistence-maintenance.toml' \ tails/config/chroot_local-hooks/99-zzzzzz_permissions grep -q '/usr/local/lib/elizaos/persistence-maintenance enter' \ tails/config/chroot_local-includes/etc/gdm3/PostLogin/Default grep -q 'rm -f /run/elizaos/persistence-maintenance' \ tails/config/chroot_local-includes/etc/gdm3/PostLogin/Default session_helper_mode="$(stat_mode tails/config/chroot_local-includes/usr/local/lib/elizaos/create-persistent-storage-session)" if [ "${session_helper_mode}" != "755" ]; then echo "create-persistent-storage-session must be mode 755, got ${session_helper_mode}" >&2 exit 1 fi grep -q 'run_dir=/run/elizaos' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/persistence-maintenance grep -Fq 'flag="${run_dir}/persistence-maintenance"' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/persistence-maintenance grep -q 'user_persistence_flag="${runtime_dir}/elizaos-persistence-setup"' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/persistence-maintenance grep -q 'systemctl --user "$@"' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/persistence-maintenance grep -q 'kill --kill-whom=all --signal=TERM' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/persistence-maintenance grep -q 'kill --kill-whom=all --signal=KILL' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/persistence-maintenance if grep -q 'pkill .* -u amnesia' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/persistence-maintenance; then echo "persistence-maintenance must not use broad pkill patterns against the live user." >&2 exit 1 fi helper_mode="$(stat_mode tails/config/chroot_local-includes/usr/local/lib/elizaos/persistence-maintenance)" if [ "${helper_mode}" != "755" ]; then echo "persistence-maintenance must be mode 755, got ${helper_mode}" >&2 exit 1 fi echo "==> filesystem modes" if [ -d tails/config/chroot_local-includes/sbin ]; then echo "top-level chroot_local-includes/sbin would replace Tails' /sbin -> /usr/sbin symlink" >&2 exit 1 fi if [ -d tails/config/chroot_local-includes/lib ]; then echo "top-level chroot_local-includes/lib would replace Tails' /lib -> /usr/lib symlink" >&2 exit 1 fi if [ -e tails/config/chroot_local-includes/tmp ]; then tmp_mode="$(stat_mode tails/config/chroot_local-includes/tmp)" if [ "${tmp_mode}" != "1777" ]; then echo "tails/config/chroot_local-includes/tmp must be mode 1777, got ${tmp_mode}" >&2 exit 1 fi elif [ "${SOURCE_ONLY}" != "1" ]; then echo "tails/config/chroot_local-includes/tmp is missing from the full build tree" >&2 exit 1 fi swapon_mode="$(stat_mode tails/config/chroot_local-includes/usr/sbin/swapon.tails)" if [ "${swapon_mode}" != "755" ]; then echo "tails/config/chroot_local-includes/usr/sbin/swapon.tails must be mode 755, got ${swapon_mode}" >&2 exit 1 fi if [ -e tails/chroot ] && [ ! -L tails/chroot/sbin ]; then echo "tails/chroot/sbin must remain the usrmerge symlink to usr/sbin" >&2 exit 1 fi if [ -e tails/chroot ] && [ ! -L tails/chroot/lib ]; then echo "tails/chroot/lib must remain the usrmerge symlink to usr/lib" >&2 exit 1 fi if [ -e tails/chroot/etc/systemd/system/display-manager.service ]; then display_manager_target="$( readlink tails/chroot/etc/systemd/system/display-manager.service )" case "${display_manager_target}" in /usr/lib/systemd/system/gdm.service|/usr/lib/systemd/system/gdm3.service) ;; *) echo "display-manager.service must point at the real /usr/lib GDM unit, got ${display_manager_target}" >&2 exit 1 ;; esac fi grep -q 'clear_user_unit_override' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-keeper grep -q 'user_persistence_flag="${runtime_dir}/elizaos-persistence-setup"' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-keeper grep -q 'runuser -u amnesia -- env HOME=/home/amnesia sh -eu' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-keeper grep -Fq 'rm -rf -- "${path}"' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-keeper if grep -q 'ensure_plain_dir\|install -d -o amnesia\|chown .*amnesia' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-keeper; then echo "elizaos-keeper must not mutate /home/amnesia paths as root." >&2 exit 1 fi grep -q 'systemctl --user start --no-block elizaos.service' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-keeper grep -q 'systemctl --user start --no-block elizaos-agent.service' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-keeper grep -q 'systemctl --user start --no-block elizaos-renderer.service' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-keeper if grep -q 'systemctl --user start --no-block elizaos-pill.service' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-keeper; then echo "Voice pill must stay installed but opt-in until the pill renderer is production-ready." >&2 exit 1 fi grep -q 'ELIZA_API_PORT.*:-31337' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user grep -q 'ELIZAOS_LIVE_EMBEDDING_FALLBACK.*:-1' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user grep -q 'ELIZA_DISABLE_PROACTIVE_AGENT.*:-1' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user grep -q 'ELIZA_DISABLE_DIRECT_RUN.*:-1' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user grep -q 'window.iconify()' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'ELIZA_WORKSPACE_DIR.*ELIZA_STATE_DIR.*/workspace' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user grep -Fq 'cd "${ELIZA_WORKSPACE_DIR}"' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user grep -q 'unset LD_PRELOAD' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-agent-user grep -q 'has_display_env' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-user grep -q 'exit 75' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-user grep -q 'ELIZAOS_RENDERER_PORT.*:-5174' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-renderer-user grep -q 'renderer-server.mjs' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-renderer-user grep -q 'ELIZA_DESKTOP_API_BASE.*127.0.0.1' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-renderer-user grep -q '__ELIZAOS_APP_BOOT_CONFIG__' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/renderer-server.mjs grep -q 'branding: {' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/renderer-server.mjs grep -q 'appName: "elizaOS"' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/renderer-server.mjs grep -q 'getAppInfo: () => nativeInfo' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/renderer-server.mjs grep -q 'curl --noproxy' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-browser-user grep -q 'elizaos-webkit-shell' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-browser-user grep -q 'ELIZAOS_SHELL_URL' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-browser-user grep -q 'WEBKIT_DISABLE_DMABUF_RENDERER' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-browser-user grep -q 'gi.require_version("Gdk", "3.0")' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'gi.require_version("WebKit2", "4.1")' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'ELIZAOS_SHELL_MODE' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'configure_pill_window' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'set_keep_above(True)' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'def pick_pill_monitor' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'monitors-changed' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -Eq 'XDG_SESSION_TYPE|GtkLayerShell' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'ELIZAOS_PILL_MONITOR' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'Gdk.Device.get_position\|device.get_position' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'ELIZAOS_SHELL_MODE=pill' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-pill-user grep -q 'shell=pill' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-pill-user grep -q 'elizaos-webkit-shell' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-pill-user grep -q 'ELIZAOS_RENDERER_PORT.*:-5174' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-pill-user grep -q '^ExecStart=/usr/local/lib/elizaos/start-elizaos-pill-user$' \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-pill.service for unit in \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-agent.service \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-renderer.service \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-pill.service \ tails/config/chroot_local-includes/etc/systemd/user/elizaos.service do grep -q '^ConditionPathExists=!/run/elizaos/persistence-maintenance$' "${unit}" done if [ "${SOURCE_ONLY}" != "1" ]; then verify_materialized_file() { local rel="$1" local src="tails/config/chroot_local-includes/${rel}" local chroot_path="tails/chroot/${rel}" local squashfs="tails/binary/live/filesystem.squashfs" local tmp if [ -e "${chroot_path}" ] && ! cmp -s "${src}" "${chroot_path}"; then echo "${chroot_path} is stale; run scripts/sync-runtime-to-chroot.sh before binary rebuilds." >&2 exit 1 fi if [ -f "${squashfs}" ] && command -v unsquashfs >/dev/null 2>&1; then tmp="$(mktemp)" if ! unsquashfs -cat "${squashfs}" "${rel}" >"${tmp}" 2>/dev/null; then rm -f "${tmp}" echo "${squashfs} is missing ${rel}" >&2 exit 1 fi if ! cmp -s "${src}" "${tmp}"; then rm -f "${tmp}" echo "${squashfs}:${rel} is stale; rebuild the binary image after syncing the chroot." >&2 exit 1 fi rm -f "${tmp}" fi } for rel in \ etc/systemd/user/elizaos-agent.service \ etc/systemd/user/elizaos-renderer.service \ etc/systemd/user/elizaos.service \ usr/lib/systemd/user/tails-create-persistent-storage.service \ usr/local/lib/elizaos/create-persistent-storage-session \ usr/local/lib/elizaos/persistence-maintenance \ usr/local/lib/persistent-storage/on-activated-hooks/ElizaOSData/20-restart-elizaos \ usr/local/lib/persistent-storage/on-deactivated-hooks/ElizaOSData/20-restart-elizaos do verify_materialized_file "${rel}" done fi if grep -q 'systemctl --global enable elizaos-pill.service' \ tails/config/chroot_local-hooks/52-update-systemd-units; then echo "Voice pill must stay installed but opt-in until the pill renderer is production-ready." >&2 exit 1 fi grep -q 'set_network_proxy_settings(WebKit2.NetworkProxyMode.NO_PROXY' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'base_data_directory=data_dir' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell grep -q 'delete-event' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/elizaos-webkit-shell if grep -Eq 'tor-browser|firefox|MOZ_NO_REMOTE|-no-remote|-new-instance' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/start-elizaos-browser-user; then echo "elizaOS app shell must use WebKitGTK, not Tor Browser/Firefox profile launch." >&2 exit 1 fi if grep -q 'After=.*desktop.target' \ tails/config/chroot_local-includes/etc/systemd/user/elizaos.service; then echo "elizaOS user service must not wait for Tails desktop.target/Tor bootstrap." >&2 exit 1 fi if grep -q 'After=.*desktop.target' \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-agent.service; then echo "elizaOS agent service must not wait for Tails desktop.target/Tor bootstrap." >&2 exit 1 fi if grep -q 'After=.*desktop.target' \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-renderer.service; then echo "elizaOS renderer service must not wait for Tails desktop.target/Tor bootstrap." >&2 exit 1 fi grep -q '^WantedBy=default.target$' \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-agent.service grep -q '^WantedBy=default.target$' \ tails/config/chroot_local-includes/etc/systemd/user/elizaos-renderer.service grep -q 'Wants=elizaos-renderer.service' \ tails/config/chroot_local-includes/etc/systemd/user/elizaos.service grep -q 'ExecStart=/usr/local/lib/elizaos/start-elizaos-browser-user' \ tails/config/chroot_local-includes/etc/systemd/user/elizaos.service grep -q '^WantedBy=default.target$' \ tails/config/chroot_local-includes/etc/systemd/user/elizaos.service grep -q 'chown root:root' \ tails/config/chroot_local-hooks/99-zzzzzz_permissions grep -q '/usr/local/lib/elizaos/capability-runner' \ tails/config/chroot_local-hooks/99-zzzzzz_permissions grep -q '/etc/systemd/user/elizaos.service' \ tails/config/chroot_local-hooks/99-zzzzzz_permissions grep -q '/etc/systemd/user/elizaos-agent.service' \ tails/config/chroot_local-hooks/99-zzzzzz_permissions grep -q '/etc/systemd/user/elizaos-renderer.service' \ tails/config/chroot_local-hooks/99-zzzzzz_permissions grep -q 'systemctl --global enable elizaos-agent.service' \ tails/config/chroot_local-hooks/52-update-systemd-units grep -q 'systemctl --global enable elizaos-renderer.service' \ tails/config/chroot_local-hooks/52-update-systemd-units grep -q 'systemctl enable elizaos-update-verify.service' \ tails/config/chroot_local-hooks/52-update-systemd-units grep -q 'systemctl enable elizaos-root-mode.service' \ tails/config/chroot_local-hooks/52-update-systemd-units grep -q 'Wants=.*elizaos-update-verify.service' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos.service grep -q 'Wants=.*elizaos-update-health-check.service' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos.service grep -q 'After=display-manager.service elizaos-update-verify.service' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos.service grep -q 'DirectoryMode=0755' \ tails/config/chroot_local-includes/usr/lib/systemd/system/run-nosymfollow.mount.d/elizaos-root-mode.conf grep -q 'After=run-nosymfollow.mount systemd-tmpfiles-setup.service' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos-root-mode.service grep -q 'Before=sysinit.target basic.target dbus.service polkit.service gdm.service tails-persistent-storage.service' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos-root-mode.service grep -q 'ExecStart=/bin/chmod 0755 / /run/nosymfollow' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos-root-mode.service grep -q 'ExecStart=/usr/local/lib/elizaos/update-health-check' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos-update-health-check.service grep -q 'ELIZAOS_UPDATE_HEALTH_MARK_BAD_ON_TIMEOUT' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-health-check grep -q 'ExecStart=/usr/local/lib/elizaos/update-manager verify' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos-update-verify.service grep -q 'ReadWritePaths=/run/elizaos' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos-update-verify.service grep -q -- '-/live/persistence/TailsData_unlocked/elizaos-system' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos-update-verify.service grep -q -- '-/live/persistence/TailsData_unlocked/elizaos-system' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos-update-health-check.service grep -q '/live/persistence/TailsData_unlocked/elizaos-system' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos-update-verify.service grep -q 'ProtectHome=read-only' \ tails/config/chroot_local-includes/etc/systemd/system/elizaos-update-verify.service if [ -e tails/config/chroot_local-includes/etc/systemd/system/dbus.service.d/elizaos-working-directory.conf ] || [ -e tails/config/chroot_local-includes/etc/systemd/system/polkit.service.d/elizaos-working-directory.conf ]; then echo "D-Bus and polkit should not carry elizaOS working-directory workarounds; fix root filesystem mode instead." >&2 exit 1 fi grep -q 'ELIZAOS_RUNTIME_ROOT' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/runtime-env if grep -q 'ELIZAOS_ALLOW_RUNTIME_ENV_OVERRIDES' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/runtime-env; then echo "runtime-env must not expose caller-controlled runtime override escape hatches." >&2 exit 1 fi grep -q 'gpgv --keyring' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-manager grep -q 'write_fallback_selector "missing-keyring"' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-manager grep -q 'filesComplete.*true' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-manager grep -q 'runtime_store' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-manager grep -q 'contains unlisted file' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-manager grep -q 'materialized runtime hash mismatch' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/update-manager grep -q 'modelCatalog' \ schemas/update-manifest.schema.json grep -q 'filesComplete' \ schemas/update-manifest.schema.json grep -q 'elizaos.modelCatalog' \ schemas/model-catalog.schema.json grep -q 'ELIZAOS_RELEASE_KEYRING' scripts/usb-write.sh grep -q 'gpgv --keyring' scripts/usb-write.sh grep -q 'ELIZAOS_CREATE_USB_IMAGE_FROM_ISO' scripts/usb-write.sh grep -q 'Refusing to write ISO directly to USB' scripts/usb-write.sh grep -q 'sgdisk --move-second-header' scripts/usb-write.sh grep -q 'prepare a cloned USB image for Persistent Storage' scripts/usb-write.sh if [ "$(grep -c 'WARNING: writing an ISO directly is for explicit override/testing only' scripts/usb-write.sh)" != "1" ]; then echo "scripts/usb-write.sh must emit the direct-ISO warning exactly once" >&2 exit 1 fi grep -q 'PARTITION_LABEL = "Tails"' tails/auto/scripts/create-usb-image-from-iso grep -q 'FILESYSTEM_LABEL = "ELIZAOS"' tails/auto/scripts/create-usb-image-from-iso grep -q 'FILESYSTEM_LABEL.ljust(11)' tails/auto/scripts/create-usb-image-from-iso grep -q 'chroot_image = CHROOT_DIR / "tmp" / Path(self.image).name' tails/auto/scripts/create-usb-image-from-iso grep -q 'yield chroot_image_arg' tails/auto/scripts/create-usb-image-from-iso grep -q 'for mountpoint in reversed(mounted)' tails/auto/scripts/create-usb-image-from-iso grep -q '::ELIZAOS' tails/config/chroot_local-includes/usr/share/initramfs-tools/scripts/lib/first_boot_repartition if grep -q '::Tails' tails/config/chroot_local-includes/usr/share/initramfs-tools/scripts/lib/first_boot_repartition; then echo "first boot repartition must keep ELIZAOS filesystem label" >&2 exit 1 fi grep -q 'TAILS_ROOT = Path(__file__).resolve().parents\[2\]' \ tails/auto/scripts/create-usb-image-from-iso grep -q 'CHROOT_DIR = TAILS_ROOT / "chroot"' \ tails/auto/scripts/create-usb-image-from-iso grep -qx 'sudo' tails/config/chroot_local-packageslists/tails-common.list grep -Eq '^syslinux( \[amd64\])?$' tails/config/chroot_local-packageslists/tails-common.list grep -q 'elizaos.sbomLite' scripts/generate-release-evidence.mjs grep -q 'elizaos.releaseProvenance' scripts/generate-release-evidence.mjs grep -q 'elizaos.modelCatalog' scripts/validate-model-catalog.mjs if grep -Eq 'apt-(update|install)|restart-network' \ tails/config/chroot_local-includes/usr/local/lib/elizaos/capability-runner; then echo "capability-runner must not expose broad package/network mutation commands" >&2 exit 1 fi grep -q 'args = \["root-status"\]' \ tails/config/chroot_local-includes/etc/generate-sudoers.d/elizaos-capability-runner.toml if [ "${SOURCE_ONLY}" != "1" ] && [ -e tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/build.json ]; then echo "==> elizaOS live overlay" node scripts/prepare-elizaos-app-overlay.mjs --check node scripts/validate-runtime-overlay.mjs fi echo "==> elizaOS package exports" node - <<'NODE' const fs = require("fs"); for (const root of [ "tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app", "tails/chroot/opt/elizaos", ]) { if (!fs.existsSync(root)) continue; const versionPath = `${root}/Resources/version.json`; const version = JSON.parse(fs.readFileSync(versionPath, "utf8")); if (version.name !== "elizaOS") { throw new Error(`${versionPath}: name must be elizaOS`); } if (version.identifier !== "org.elizaos.app") { throw new Error(`${versionPath}: identifier must be org.elizaos.app`); } const brandPath = `${root}/Resources/app/brand-config.json`; const brand = JSON.parse(fs.readFileSync(brandPath, "utf8")); for (const [key, expected] of Object.entries({ appName: "elizaOS", appId: "org.elizaos.app", namespace: "eliza", urlScheme: "elizaos", configDirName: "elizaOS", })) { if (brand[key] !== expected) { throw new Error(`${brandPath}: ${key} must be ${expected}`); } } const entryPath = `${root}/Resources/app/eliza-dist/entry.js`; const appCoreEntryPath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/app-core/dist/entry.js`; if (!fs.existsSync(entryPath)) { throw new Error(`${entryPath}: missing agent runtime entry`); } if (!fs.existsSync(appCoreEntryPath)) { throw new Error(`${appCoreEntryPath}: missing bundled app-core runtime entry`); } const entry = fs.readFileSync(entryPath, "utf8"); if (entry.includes("../packages/") || entry.includes("src/entry.ts")) { throw new Error( `${entryPath}: live runtime entry must not point back to source checkout paths`, ); } if (!entry.includes("./node_modules/@elizaos/app-core/dist/entry.js")) { throw new Error(`${entryPath}: live runtime entry must import bundled app-core dist`); } } for (const path of [ "tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/Resources/app/eliza-dist/node_modules/@elizaos/agent/package.json", "tails/chroot/opt/elizaos/Resources/app/eliza-dist/node_modules/@elizaos/agent/package.json", ]) { if (!fs.existsSync(path)) continue; const pkg = JSON.parse(fs.readFileSync(path, "utf8")); const target = pkg.exports?.["./services/permissions/probers/index"]; if ( target?.import !== "./dist/packages/agent/src/services/permissions/probers/index.js" ) { throw new Error( `${path}: missing packaged permissions prober export required by Electrobun`, ); } } for (const [path, target] of [ [ "tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/node_modules", "Resources/app/eliza-dist/node_modules", ], [ "tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app/bin/node_modules", "../Resources/app/eliza-dist/node_modules", ], ["tails/chroot/opt/elizaos/node_modules", "Resources/app/eliza-dist/node_modules"], [ "tails/chroot/opt/elizaos/bin/node_modules", "../Resources/app/eliza-dist/node_modules", ], ]) { if (!fs.existsSync(path)) continue; const actual = fs.readlinkSync(path); if (actual !== target) { throw new Error(`${path}: expected symlink to ${target}, got ${actual}`); } } for (const packageName of [ "@elizaos/plugin-whatsapp", "@elizaos/plugin-streaming", "@elizaos/plugin-x402", "@elizaos/plugin-mcp", "@elizaos/plugin-imessage", "@elizaos/plugin-capacitor-bridge", "@elizaos/plugin-aosp-local-inference", "@elizaos/plugin-background-runner", "@elizaos/plugin-mlx", ]) { for (const root of [ "tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app", "tails/chroot/opt/elizaos", ]) { if (!fs.existsSync(root)) continue; const packagePath = `${root}/Resources/app/eliza-dist/node_modules/${packageName}/package.json`; const indexPath = `${root}/Resources/app/eliza-dist/node_modules/${packageName}/index.js`; const pkg = JSON.parse(fs.readFileSync(packagePath, "utf8")); if (pkg.version === "0.0.0-elizaos-live-stub") { if (pkg.type !== "module") { throw new Error(`${packagePath}: optional desktop connector stub must be ESM`); } const index = fs.readFileSync(indexPath, "utf8"); if (!index.includes("export default undefined")) { throw new Error(`${indexPath}: optional desktop connector stub is malformed`); } } } } for (const root of [ "tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app", "tails/chroot/opt/elizaos", ]) { if (!fs.existsSync(root)) continue; const nodeModules = `${root}/Resources/app/eliza-dist/node_modules`; const orchestratorIndex = `${nodeModules}/agent-orchestrator/index.js`; const orchestrator = fs.readFileSync(orchestratorIndex, "utf8"); if (!orchestrator.includes("ELIZAOS") || !orchestrator.includes("capability-runner")) { throw new Error(`${orchestratorIndex}: missing live OS broker action`); } const appControlPackagePath = `${nodeModules}/@elizaos/plugin-app-control/package.json`; const appControlPackage = JSON.parse(fs.readFileSync(appControlPackagePath, "utf8")); if (appControlPackage.main !== "./src/index.ts") { throw new Error(`${appControlPackagePath}: app-control must be source-staged`); } for (const packageName of [ "@elizaos/plugin-app-manager", "@elizaos/plugin-calendly", "@elizaos/plugin-health", "@elizaos/plugin-registry", ]) { const distIndex = `${nodeModules}/${packageName}/dist/index.js`; if (!fs.existsSync(distIndex)) { throw new Error(`${distIndex}: required runtime plugin dist is missing`); } } const forcedLiveStubs = new Map([ ["@elizaos/app-model-tester", "model-tester"], ["@elizaos/plugin-documents", "documents"], ["@elizaos/plugin-google", "google"], ["@elizaos/plugin-hyperliquid", "hyperliquid"], ["@elizaos/plugin-personal-assistant", "lifeops"], ["@elizaos/plugin-polymarket", "polymarket"], ["@elizaos/plugin-shopify", "shopify"], ["@elizaos/plugin-training", "training"], ]); for (const [packageName, marker] of forcedLiveStubs) { const stubPath = `${nodeModules}/${packageName}/index.js`; const packagePath = `${nodeModules}/${packageName}/package.json`; const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8")); if (packageJson.version !== "0.0.0-elizaos-live-stub") { throw new Error(`${packagePath}: ${packageName} must be a live-safe stub in the base USB runtime`); } const stub = fs.readFileSync(stubPath, "utf8"); if (!stub.includes(marker)) { throw new Error(`${stubPath}: ${packageName} live-safe stub is malformed`); } for (const subpath of ["plugin.js", "routes/plugin.js", "setup-routes.js"]) { const subpathFile = `${nodeModules}/${packageName}/${subpath}`; if (!fs.existsSync(subpathFile)) { throw new Error(`${subpathFile}: live-safe route subpath stub is missing`); } } } const sourceRuntimePackages = new Map([ ["@elizaos/cloud-sdk", "./src/index.ts"], ["@elizaos/plugin-agent-skills", "./src/index.ts"], ["@elizaos/plugin-browser", "./src/index.ts"], ["@elizaos/plugin-coding-tools", "./src/index.ts"], ["@elizaos/plugin-commands", "./src/index.ts"], ["@elizaos/plugin-elizacloud", "./src/index.node.ts"], ["@elizaos/plugin-video", "./src/index.ts"], ]); for (const [packageName, expectedExport] of sourceRuntimePackages) { const packagePath = `${nodeModules}/${packageName}/package.json`; const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8")); const rootExport = packageJson.exports?.["."] ?? packageJson.exports; const importTarget = typeof rootExport === "string" ? rootExport : rootExport?.import ?? rootExport?.default; if (importTarget !== expectedExport) { throw new Error(`${packagePath}: ${packageName} must export ${expectedExport} in the live runtime`); } const expectedSourcePath = `${nodeModules}/${packageName}/${expectedExport.replace(/^\.\//, "")}`; if (!fs.existsSync(expectedSourcePath)) { throw new Error(`${expectedSourcePath}: source-staged runtime package is missing`); } } const rendererRoot = `${root}/Resources/app/renderer`; const indexPath = `${rendererRoot}/index.html`; const manifestPath = `${rendererRoot}/site.webmanifest`; const wallpaperPath = "tails/config/chroot_local-includes/usr/share/tails/desktop_wallpaper.png"; if (fs.existsSync(indexPath)) { const index = fs.readFileSync(indexPath, "utf8"); if (!index.includes("elizaOS")) { throw new Error(`${indexPath}: browser shell title must be elizaOS`); } if (index.includes("elizaOS") || index.includes("app.elizaos.ai")) { throw new Error(`${indexPath}: browser shell metadata still contains elizaOS branding`); } } if (fs.existsSync(manifestPath)) { const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")); if (manifest.name !== "elizaOS" || manifest.short_name !== "elizaOS") { throw new Error(`${manifestPath}: web manifest must be branded elizaOS`); } } for (const name of ["splash-bg.png", "splash-bg-dark.png", "og-image.png"]) { const imagePath = `${rendererRoot}/${name}`; if ( fs.existsSync(imagePath) && fs.existsSync(wallpaperPath) && Buffer.compare(fs.readFileSync(imagePath), fs.readFileSync(wallpaperPath)) !== 0 ) { throw new Error(`${imagePath}: renderer splash image must use the elizaOS wallpaper`); } } for (const file of fs.readdirSync(`${rendererRoot}/assets`).filter((name) => name.endsWith(".js"))) { const text = fs.readFileSync(`${rendererRoot}/assets/${file}`, "utf8"); const forbidden = [ "WELCOME TO ELIZAOS", "Welcome to elizaOS", "elizaOS's HTTP API", 'appName:"elizaOS"', 'orgName:"elizaos"', 'repoName:"eliza"', 'cliName:"elizaos"', 'envPrefix:"ELIZAOS"', 'namespace:"elizaos"', 'urlScheme:"elizaos"', 'docsUrl:"https://docs.elizaos.ai"', 'appUrl:"https://app.elizaos.ai"', 'hashtag:"#elizaOSAgent"', 'fileExtension:".elizaos-agent"', 'packageScope:"elizaos"', "elizaos.ai", ]; for (const needle of forbidden) { if (text.includes(needle)) { throw new Error(`${rendererRoot}/assets/${file}: visible elizaOS launch branding remains: ${needle}`); } } } } for (const root of [ "tails/config/chroot_local-includes/usr/share/elizaos/elizaos-app", "tails/chroot/opt/elizaos", ]) { if (!fs.existsSync(root)) continue; const lucidePackagePath = `${root}/Resources/app/eliza-dist/node_modules/lucide-react/package.json`; const lucideIndexPath = `${root}/Resources/app/eliza-dist/node_modules/lucide-react/index.js`; const lucidePackage = JSON.parse(fs.readFileSync(lucidePackagePath, "utf8")); if (lucidePackage.version === "0.0.0-elizaos-live-stub") { const lucideIndex = fs.readFileSync(lucideIndexPath, "utf8"); for (const expected of [ "export function Icon()", "export const createLucideIcon", "export const Feather", "export const Loader2", "export const Maximize2", "export const Settings", ]) { if (!lucideIndex.includes(expected)) { throw new Error(`${lucideIndexPath}: missing ${expected}`); } } } const coreIndexPath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/core/src/index.node.ts`; if (fs.existsSync(coreIndexPath)) { const coreIndex = fs.readFileSync(coreIndexPath, "utf8"); if (coreIndex.includes('export * from "./testing";')) { throw new Error(`${coreIndexPath}: production runtime must not export @elizaos/core testing helpers`); } } const localInferenceIndexPath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/plugin-local-inference/dist/index.js`; const localInferenceRuntimePath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/plugin-local-inference/dist/runtime/index.js`; for (const path of [localInferenceIndexPath, localInferenceRuntimePath]) { if (!fs.existsSync(path)) continue; const text = fs.readFileSync(path, "utf8"); if (!text.includes("ELIZAOS_LIVE_EMBEDDING_FALLBACK")) { throw new Error(`${path}: missing elizaOS Live embedding fallback gate`); } } const localInferencePackageJsonPath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/plugin-local-inference/package.json`; const localInferencePackageJson = JSON.parse(fs.readFileSync(localInferencePackageJsonPath, "utf8")); const embeddingPresetsExport = localInferencePackageJson.exports?.["./runtime/embedding-presets"]; if (embeddingPresetsExport?.import !== "./src/runtime/embedding-presets.ts") { throw new Error(`${localInferencePackageJsonPath}: packaged embedding presets export must resolve to source`); } const embeddingPresetsPath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/plugin-local-inference/src/runtime/embedding-presets.ts`; if (!fs.existsSync(embeddingPresetsPath)) { throw new Error(`${embeddingPresetsPath}: missing packaged embedding presets source`); } const workerRuntimePackageJsonPath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/plugin-worker-runtime/package.json`; const workerRuntimePackageJson = JSON.parse(fs.readFileSync(workerRuntimePackageJsonPath, "utf8")); if (workerRuntimePackageJson.exports?.["."]?.import !== "./src/index.ts") { throw new Error(`${workerRuntimePackageJsonPath}: packaged worker runtime must resolve to source`); } const workerRuntimeErrorPath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/plugin-worker-runtime/src/error.ts`; if (!fs.existsSync(workerRuntimeErrorPath)) { throw new Error(`${workerRuntimeErrorPath}: missing packaged worker runtime source`); } const remoteManifestPackageJsonPath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/plugin-remote-manifest/package.json`; const remoteManifestPackageJson = JSON.parse(fs.readFileSync(remoteManifestPackageJsonPath, "utf8")); if (remoteManifestPackageJson.exports?.["."]?.import !== "./src/index.ts") { throw new Error(`${remoteManifestPackageJsonPath}: packaged remote manifest must resolve to source`); } const sqlPackageJsonPath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/plugin-sql/package.json`; const sqlPackageJson = JSON.parse(fs.readFileSync(sqlPackageJsonPath, "utf8")); if (sqlPackageJson.exports?.["."]?.import !== "./src/index.node.ts") { throw new Error(`${sqlPackageJsonPath}: packaged SQL plugin must resolve to node source`); } const sqlIndexPath = `${root}/Resources/app/eliza-dist/node_modules/@elizaos/plugin-sql/src/index.node.ts`; if (!fs.existsSync(sqlIndexPath)) { throw new Error(`${sqlIndexPath}: missing packaged SQL plugin node source`); } const bunIndexPath = `${root}/Resources/app/bun/index.js`; const bunIndex = fs.readFileSync(bunIndexPath, "utf8"); for (const expected of [ "ELIZAOS_CLOSE_MINIMIZES_TO_TRAY", "Window close requested - minimized to tray", "await this.hideWindow()", "win.minimize()", ]) { if (!bunIndex.includes(expected)) { throw new Error(`${bunIndexPath}: missing close-to-tray behavior: ${expected}`); } } } NODE if [ -e tails/chroot/opt/elizaos/Resources/build.json ]; then echo "==> elizaOS installed app config" node -e ' const fs = require("fs"); const path = "tails/chroot/opt/elizaos/Resources/build.json"; const build = JSON.parse(fs.readFileSync(path, "utf8")); if (build.defaultRenderer !== "native") { throw new Error(`${path}: defaultRenderer must be native for elizaOS Live`); } if (JSON.stringify(build.availableRenderers) !== JSON.stringify(["native"])) { throw new Error(`${path}: availableRenderers must be [\"native\"] for elizaOS Live`); } if (build.runtime?.exitOnLastWindowClosed !== false) { throw new Error(`${path}: runtime.exitOnLastWindowClosed must be false`); } if (build.runtime?.closeMinimizesToTray !== true) { throw new Error(`${path}: runtime.closeMinimizesToTray must be true`); } if ( build.chromiumFlags?.["user-data-dir"] !== "/home/amnesia/.cache/org.elizaos.app/dev/CEF/partitions" ) { throw new Error(`${path}: Chromium user-data-dir must target the CEF partitions symlink`); } ' fi if [ -e tails/chroot/opt/elizaos/bin/chrome-sandbox ]; then sandbox_mode="$(stat_mode tails/chroot/opt/elizaos/bin/chrome-sandbox)" if [ "${sandbox_mode}" != "755" ]; then echo "chrome-sandbox must not be setuid in native-renderer elizaOS Live, got ${sandbox_mode}" >&2 exit 1 fi fi if command -v xmllint >/dev/null 2>&1; then echo "==> XML" xmllint --noout \ tails/config/chroot_local-includes/usr/share/tails/persistent-storage/features_view.ui.in \ tails/config/chroot_local-includes/usr/share/tails/greeter/main.ui.in else echo "skip: xmllint not installed" fi echo "==> Python compile" python3 -m py_compile \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tps/configuration/features.py \ tails/config/chroot_local-includes/usr/lib/python3/dist-packages/tps_frontend/views/features_view.py find tails/config/chroot_local-includes/usr/lib/python3/dist-packages \ -type d -name __pycache__ -prune -exec rm -rf {} + if [ "${ELIZAOS_STATIC_TSC:-0}" = "1" ] && [ -x "${REPO_ROOT}/node_modules/.bin/tsc" ]; then echo "==> orchestrator TypeScript" (cd "${REPO_ROOT}" && nice -n 19 node_modules/.bin/tsc --noEmit \ -p plugins/plugin-agent-orchestrator/tsconfig.json --pretty false) fi echo "==> diff whitespace" git -C "${REPO_ROOT}" diff --check -- \ packages/os/linux \ plugins/plugin-agent-orchestrator/src/actions/elizaos-capability.ts \ plugins/plugin-agent-orchestrator/src/index.ts \ plugins/plugin-agent-orchestrator/src/services/acp-service.ts \ plugins/plugin-agent-orchestrator/src/services/pty-spawn.ts echo "static smoke passed"