Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,43 @@ jobs:
skip-avatar-clone: "true"
no-vision-deps: "true"

- name: Check homepage smoke scope
id: homepage-scope
shell: bash
run: |
set -euo pipefail

if [ "${{ github.event_name }}" != "pull_request" ]; then
echo "run=true" >> "$GITHUB_OUTPUT"
exit 0
fi

git fetch --no-tags --depth=1 origin "${{ github.base_ref }}"
changed_files="$(git diff --name-only "origin/${{ github.base_ref }}...HEAD")"
if grep -Eq '^(packages/homepage/|packages/shared-brand/|packages/app-core/scripts/write-homepage-release-data\.mjs|\.github/workflows/(deploy-homepage|release-electrobun|release-orchestrator)\.yml)' <<< "${changed_files}"; then
echo "run=true" >> "$GITHUB_OUTPUT"
else
echo "run=false" >> "$GITHUB_OUTPUT"
fi

- name: Skip unrelated homepage smoke
if: steps.homepage-scope.outputs.run != 'true'
run: echo "Skipping homepage smoke; this PR does not touch homepage release surfaces."

- name: Build homepage
if: steps.homepage-scope.outputs.run == 'true'
working-directory: packages/homepage
run: bun run build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Install homepage browser
if: steps.homepage-scope.outputs.run == 'true'
working-directory: packages/homepage
run: ../../node_modules/.bin/playwright install --with-deps chromium

- name: Generate missing snapshot baselines
if: steps.homepage-scope.outputs.run == 'true'
id: gen-baselines
working-directory: packages/homepage
run: |
Expand All @@ -95,7 +121,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Commit new snapshot baselines
if: steps.gen-baselines.outputs.generated == 'true'
if: steps.homepage-scope.outputs.run == 'true' && steps.gen-baselines.outputs.generated == 'true'
continue-on-error: true
run: |
SNAP_DIR="packages/homepage/tests/e2e/visual.spec.ts-snapshots"
Expand All @@ -109,7 +135,7 @@ jobs:
fi

- name: Test homepage downloads
if: steps.gen-baselines.outputs.generated == 'false'
if: steps.homepage-scope.outputs.run == 'true' && steps.gen-baselines.outputs.generated == 'false'
working-directory: packages/homepage
run: bun run test:e2e
env:
Expand Down
58 changes: 58 additions & 0 deletions docs/apps/desktop/release-heavy-inventory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Desktop Release Heavy Inventory

This inventory tracks desktop-heavy checks referenced by
`packages/app-core/test/regression-matrix.json`. These are not omitted; they
are deferred from the required PR gate because they need packaged app lifecycle,
hardware, host OS integration, network services, or a fuller desktop harness.

## Heavy Checks

- gameOpenWindow — full round-trip with openGameWindow mock (needs canvas mock update)
- Abnormal window position (off-screen) is corrected to safe defaults (e2e)
- Microphone input works after permission is granted (hardware)
- Swabble fires 'wakeWordDetected' event when wake word is spoken (hardware)
- Audio transcription produces non-empty text for clear speech (hardware)
- Camera preview renders in the UI when stream is started (hardware)
- Switching between front/rear camera works (hardware)
- takeScreenshot returns a non-empty base64 PNG (hardware)
- Frame capture mode streams frames at configured interval (hardware)
- Deep link received while app is closed causes app to launch (e2e)
- Deep link received while app is open does not launch second instance (e2e)
- Shortcuts survive window focus changes (e2e)
- App launches automatically after system restart (e2e)
- Auto-launch survives app updates (e2e)
- Keyboard shortcut Cmd+Q triggers quit (e2e)
- Keyboard shortcut Cmd+R triggers reload (e2e)
- Keyboard shortcut Cmd+Option+I opens devtools (e2e)
- Gateway discovery sends gatewayDiscovery push event to renderer (integration)
- Canvas window is sandboxed — cannot access main app origin (integration)
- Canvas navigate blocks external URLs (integration)
- Agent port is reachable via HTTP after status reaches 'running' (integration)
- Agent crash triggers automatic restart (integration)
- Stopping agent while starting does not leave zombie process (integration)
- Check for updates contacts the release server (network)
- Applying update relaunches the app (e2e)
- Update check works on both canary and stable channels (network)
- Tray icon persists after main window is closed (e2e)
- Main window has native vibrancy effect on macOS (e2e)
- Context menu closes when clicking elsewhere (e2e)

## Manual Checklist Cross-Reference

The release contract also requires these manual-only descriptions to stay
visible in a desktop inventory source:

- Left-clicking the tray icon opens the companion window (visual)
- Right-clicking the tray icon shows the tray context menu (visual)
- Window can be dragged by clicking the header region (visual)
- Photo quality is acceptable at default settings (hardware)
- Requesting accessibility opens System Preferences (OS interaction)
- Permission status reflects actual system state (OS interaction)
- Context menu appears at cursor position (visual)
- Power state reflects actual battery status (hardware)

## Release Use

Run the applicable subset for every release candidate. Record skipped items
with a reason, because these checks are intentionally outside deterministic PR
CI rather than out of scope.
23 changes: 23 additions & 0 deletions docs/apps/desktop/release-regression-checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Desktop Release Regression Checklist

This checklist tracks manual desktop regression checks required by
`packages/app-core/test/regression-matrix.json`. These items are intentionally
outside the deterministic PR contract suite because they need human visual
confirmation, hardware, or host OS permission dialogs.

## Manual Checks

- Left-clicking the tray icon opens the companion window (visual)
- Right-clicking the tray icon shows the tray context menu (visual)
- Window can be dragged by clicking the header region (visual)
- Photo quality is acceptable at default settings (hardware)
- Requesting accessibility opens System Preferences (OS interaction)
- Permission status reflects actual system state (OS interaction)
- Context menu appears at cursor position (visual)
- Power state reflects actual battery status (hardware)

## Release Use

Run this list against packaged desktop builds before promoting a release
candidate. Record the OS, architecture, package version, commit, and any
deviation in the release evidence bundle.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions packages/os/DOWNLOADS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ gaps, and a hardware-support matrix.

Current hardening status:

- Demo builds may still be ISO/raw-image candidates until QEMU and real-USB
validation are attached.
- A prior live-USB ISO passed QEMU greeter/desktop/app-service validation
and guarded USB flash/readback. Current HEAD still needs rebuild,
repeat QEMU, repeat flash/readback, real hardware boot, and real USB
persistence validation before stable release.
- v1 is USB-only; internal-disk install is deferred.
- A guarded developer writer exists in the live-USB variant. Production
still needs a signed GUI/CLI flasher for macOS, Windows, and Linux.
Expand Down
3 changes: 3 additions & 0 deletions packages/os/linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ Use the variant docs as the source of truth:
- [`variants/milady-tails/PLAN.md`](./variants/milady-tails/PLAN.md)
- [`variants/milady-tails/ROADMAP.md`](./variants/milady-tails/ROADMAP.md)
- [`variants/milady-tails/docs/production-readiness.md`](./variants/milady-tails/docs/production-readiness.md)
- [`variants/milady-tails/docs/security-model.md`](./variants/milady-tails/docs/security-model.md)
- [`variants/milady-tails/docs/runtime-packaging.md`](./variants/milady-tails/docs/runtime-packaging.md)
- [`variants/milady-tails/docs/inherited-tails-sudoers-review.md`](./variants/milady-tails/docs/inherited-tails-sudoers-review.md)
- [`variants/milady-tails/docs/distribution-and-updates.md`](./variants/milady-tails/docs/distribution-and-updates.md)
73 changes: 43 additions & 30 deletions packages/os/linux/variants/milady-tails/PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ turn-by-turn directions.
|---|---|
| **Phase 0 — Scaffold** | ✅ Done |
| **Phase 1 — Base ISO builds + boots** | ✅ Done — base image builds and boots through QEMU via `-cdrom` |
| **Phase 2 — elizaOS system branding** | 🔨 Source implemented; final rebuilt-ISO visual pass in progress |
| **Phase 3 — Privacy mode** | 🔨 Source implemented; needs rebuilt-ISO network/Tor validation |
| **Phase 4 — Bake elizaOS app** | 🔨 App payload staged + install hook/package list implemented; needs rebuilt-ISO runtime validation |
| **Phase 5 — Autolaunch** | 🔨 Desktop/systemd wrapper implemented; needs boot validation |
| **Phase 2 — elizaOS system branding** | Source implemented; QEMU visual path passed on prior artifact; latest polish needs rebuild |
| **Phase 3 — Privacy mode** | 🔨 Source implemented; needs current-HEAD network/Tor validation |
| **Phase 4 — Bake elizaOS app** | App payload/install path QEMU-passed on prior artifact; clean checkout still must run `just milady-app` before a full build |
| **Phase 5 — Autolaunch** | Desktop/systemd wrapper QEMU-passed on prior artifact |
| **Phase 6 — Agent/broker** | 🔨 OS broker/env path implemented; approval-gated privileged actions still need hardening |
| **Phase 7 — Persistence** | 🔨 Tails Persistent Storage row/hooks implemented; needs persistence validation |
| **Phase 7 — Persistence** | 🔨 Tails Persistent Storage row/hooks implemented; real USB persistence validation still pending |
| **Phases 8–9** | 📋 Spec/backlog ([`docs/specs/`](./docs/specs/)), not release-complete |
| **Phases 10–11** | ⏳ Not started |

Expand All @@ -43,7 +43,8 @@ What exists right now:
product hardening plan for distribution, updates, production readiness,
and the demo debt that still blocks a real release.
- **elizaOS OS-branding overlays** for boot menus, Plymouth, greeter,
dark GNOME defaults, wallpaper, identity strings, and Tails attribution.
light blue/white GNOME defaults, wallpaper, identity strings, and Tails
attribution.
- The **elizaOS desktop app** builds and is staged into the Tails
overlay. The ISO install hook copies it to `/opt/milady`, fixes
permissions, and removes the staging copy. `/opt/milady` is an internal
Expand All @@ -54,8 +55,10 @@ What exists right now:
sudo only for `root-status`; package/network mutation is deferred until an
approval-gated policy layer exists.
- Privacy-mode, autolaunch, and `~/.eliza` Persistent Storage overlays are
implemented locally. A low-CPU full rebuild/test pass is the current gate
for calling the demo complete.
implemented locally. QEMU has proven the normal greeter/desktop/app path
on a prior ISO, and USB flash/readback passed for that same artifact. The
current gate is rebuilding HEAD, re-running QEMU, then validating real USB
boot, persistence, and privacy behavior.
- The old root-level usbeliza Linux prototype was removed from this branch;
this variant is the active Linux distro path.

Expand Down Expand Up @@ -105,10 +108,10 @@ feature loss. Phase 8 builds the harness that proves this. Until the
rebuilt ISO passes QEMU and real-USB validation, the matrix is an
acceptance target, not production evidence.

The one **known v1.0 gap**: Electrobun's CEF Chromium WebView doesn't
auto-inherit the SOCKS proxy. In Privacy Mode, the elizaOS agent path is
intended to route through Tor, but Chromium *windows* may leak until
Electrobun injects an explicit proxy setting. Documented in
Known **v1.0 privacy gap**: embedded browser/OAuth surfaces are not
production-claimable in Privacy Mode until explicit proxy behavior is
proven. The live OS routing exists, but the app/browser layer still needs
validation and possibly runtime proxy injection. Documented in
`docs/privacy-mode-v1-gap.md`. Closing this is v1.1 work.

---
Expand Down Expand Up @@ -312,8 +315,8 @@ elizaOS product surface, with speed/provider caveats documented.
Goal: `/opt/milady/` exists in the chroot, contains a runnable binary.

**Spec:** [`docs/specs/phase-4-bake-milady-app.md`](./docs/specs/phase-4-bake-milady-app.md)
— the real (fragile) build sequence, the `9100-install-milady` hook
design, and the `ldd`-derived `milady-runtime.list`.
— the real build sequence, the `9100-install-milady` hook design, and the
runtime-package validation direction.

- [x] `just milady-app` recipe — builds the current desktop app package on the host
(the build needs the `eliza`-first install + `setup-upstreams.mjs` +
Expand All @@ -323,11 +326,14 @@ design, and the `ldd`-derived `milady-runtime.list`.
- [x] `tails/config/chroot_local-hooks/9100-install-milady` — installs to
`/opt/milady/`, guards `version.json`, fixes perms incl. `chrome-sandbox`
setuid, then `rm -rf`'s the staging copy (critical for ISO size)
- [x] `tails/config/chroot_local-packageslists/milady-runtime.list` — the
CEF/Electrobun runtime libs (NOT `libwebkit2gtk-4.1` — Electrobun bundles
its own CEF)
- [x] Runtime package support lives in `tails-common.list` plus the staged
app bundle. There is no committed `milady-runtime.list` in the current
tree; production should replace this with a generated, audited package
manifest instead of stale docs.
- [x] Static `usr/share/applications/milady.desktop`
- [ ] Build ISO, boot, launch the elizaOS app, confirm chat UI renders
- [x] Build ISO, boot, launch the elizaOS app, confirm app services in QEMU
on the prior validated artifact
- [ ] Repeat for current HEAD after the latest branding/docs polish

⚠ **Top risk**: the app tree is ~2.9 GB uncompressed (`eliza-dist/` alone is
2.2 GB) — much larger than first estimated. The resulting ISO could be
Expand Down Expand Up @@ -355,10 +361,12 @@ supervision plus live-user services.
- [x] `/usr/local/bin/milady` — pins `ELIZA_STATE_DIR=/home/amnesia/.eliza`
plus XDG dirs in the launch env and uses a lock to avoid duplicate app
instances
- [x] `etc/dconf/db/local.d/00_Tails_defaults` — dark theme, wallpaper,
- [x] `etc/dconf/db/local.d/00_Tails_defaults` — light elizaOS theme, wallpaper,
disable GNOME welcome dialog (don't clobber Tails' `enabled-extensions`)
- [x] chroot hook runs `dconf update`
- [ ] Verify in QEMU: boot → greeter → Start → GNOME → elizaOS app
- [x] Verify in QEMU on prior artifact: boot → greeter → Start → GNOME →
elizaOS app/services
- [ ] Repeat for current HEAD

---

Expand Down Expand Up @@ -432,9 +440,9 @@ chat with elizaOS orchestrating Linux underneath.
— most substrate already exists (`INSTALL_PACKAGE` + its confirmation
flow, `OPEN_TERMINAL`, `SET_WALLPAPER`).

- [ ] `SHELL` action — a thin gating layer over the existing apt infra +
build-time polkit `.rules` / sudoers `.toml` overlays for passwordless
privileged ops
- [ ] `SHELL` action — a thin gating layer over existing install intent plus
the elizaOS capability broker. Passwordless apt sudoers/polkit overlays are
not accepted in the current security model.
- [ ] `SET_DESKTOP`, `THEME`, `NOTIFICATIONS` actions (compose the existing
install flow)
- [ ] Shared `customization.ts` persistence-awareness helper
Expand All @@ -444,7 +452,9 @@ flow, `OPEN_TERMINAL`, `SET_WALLPAPER`).

## Phase 10 — Bare-metal USB validation ⏳ NOT STARTED

- [ ] Write ISO to real USB via `dd`
- [x] Write ISO to real USB with guarded writer and readback verification
for prior artifact
- [ ] Repeat USB write/readback for current HEAD
- [ ] Boot on real hardware (2–3 machines: Intel, AMD, NVIDIA GPU)
- [ ] Verify all Phase 1–9 features work bare-metal
- [ ] Verify persistence flow on a real USB stick
Expand Down Expand Up @@ -507,11 +517,13 @@ install UX (Calamares vs. an elizaOS app flow), and the Tails community
pulse on the derivative. **Planned target: v2.0**, after v1.0 ships and
real users tell us what they want. **For now: don't add it.**

### Chromium WebView proxy patches (v1.1)
### Embedded web/OAuth proxy patches (v1.1)

Closes the Privacy-Mode-Chromium-leak gap. Patch Electrobun to inject
`--proxy-server=socks5://127.0.0.1:9050` into Chromium launch flags
when `elizaos.privacy=on`. Likely an upstream PR to Electrobun.
Closes the Privacy Mode embedded-web gap. Patch the active app shell/runtime
to inject an explicit Tor proxy into any external web/OAuth surface when
`elizaos.privacy=on`. If CEF/Electrobun is active, that likely means
`--proxy-server=socks5://127.0.0.1:9050`; if WebKit is active, it needs the
equivalent WebKit/network-context proof.

### Runtime privacy toggle (v1.2 or later)

Expand Down Expand Up @@ -549,8 +561,9 @@ the product.
PR maintainers may push back; submodule pattern is the fallback.
7. **Tor blocking cloud APIs** — Anthropic/OpenAI often refuse Tor exit
IPs. In Privacy Mode cloud chat may fail; local LLM still works.
8. **Chromium proxy gap (v1.0)** — WebView windows can leak in Privacy
Mode. Real security gap, targeted for v1.1.
8. **Embedded web/OAuth proxy gap (v1.0)** — live OS routing exists, but
embedded browser/OAuth surfaces are not production-claimable in Privacy
Mode until explicit proxy behavior is proven.
9. **Cold-boot RAM attacks** — theoretical threat against amnesia. Tails'
`memlockd` zeros RAM on shutdown; we keep it.

Expand Down
Loading
Loading