Commit Graph

674 Commits

Author SHA1 Message Date
Dorian
dad184cfc6 fix: container DNS, nginx chown, onboarding guard, seed UX, install flow
Backend:
- Add --add-host host.containers.internal:host-gateway to LND and Bitcoin
  Knots containers (fixes DNS resolution failure in rootless podman)
- Add --user 0:0 and DAC_OVERRIDE to nginx UI sidecar containers
  (fixes chown crash in rootless podman for bitcoin-ui, electrs-ui, lnd-ui)
- Add hostadd to Rust Podman API client for web UI container installs
- Add Chromium privacy flags to kiosk launcher (disable telemetry)

Frontend:
- Fix onboarding reset on raw IP visits (trust localStorage as first-class
  signal, skip boot screen when server is up but not onboarded)
- Fix seed regression: persist challenge indices in sessionStorage so going
  back from Verify doesn't change which words are asked
- Remove glass container from seed Generate/Verify/Restore screens
- Add Back button to Restore from Seed screen
- Replace Network card: Tor (purple), VPN status (orange), Bitcoin sync (orange)
- Add ElectrumX to curated app list with correct .webp icon
- Install flow: navigate to My Apps immediately with toast, hide
  installed/installing apps from marketplace and discover views

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:06:57 +01:00
Dorian
19587687b4 fix: copy scripts/lib/ for unbundled ISO builds (TUI lib was missing)
The UNBUNDLED build path didn't copy scripts/lib/ to the ISO,
so install-tui.sh was never available on unbundled installs.
The installer sourced it but the file wasn't there — no animations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 10:38:41 +01:00
Dorian
4e0fc38612 feat: sequential build versioning, LND NET_RAW, status labels
Build versioning:
- Sequential build counter (/opt/archipelago/build-counter)
- Version format: 0.1.0-beta.N (written to build-info.txt)
- Backend reads version from build-info.txt at startup, falls
  back to Cargo.toml version — no recompile needed
- UI sidebar + settings show the build version automatically

LND fix (belt + suspenders):
- Added NET_RAW capability (config.rs, first-boot, container-specs)
- Combined with tlsextraip=0.0.0.0 from previous commit

Status labels:
- Both "exited" AND "stopped" states with non-zero exit codes
  now show "crashed" in the UI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 23:43:32 +01:00
Dorian
10fb05ec24 fix: add NET_RAW capability to LND container for TLS cert generation
LND crashes with "netlinkrib: address family not supported by protocol"
in rootless podman because it needs NET_RAW to enumerate network
interfaces during TLS certificate generation. Added to capabilities
in config.rs, first-boot-containers.sh, and container-specs.sh.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 23:19:09 +01:00
Dorian
b60288e051 fix: LND crash in rootless podman, improve container status labels
LND v0.18+ crashes with "netlinkrib: address family not supported"
because rootless podman blocks netlink access for TLS cert SAN
enumeration. Fix: add tlsextraip=0.0.0.0 and tlsextradomain=lnd
to lnd.conf so LND skips interface enumeration.

Also: fix status label to show "crashed" for both exited and
stopped containers with non-zero exit codes (previously only
caught "exited" state, but podman reports "stopped" for
restart-looping containers).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 23:01:51 +01:00
Dorian
7070410b49 feat: integrate demo TUI animations into real installer
Add install-tui.sh library with boot scan, logo decrypt reveal,
bouncing Bitcoin symbol progress bar, and celebration strobe.
The installer sources it if available, falls back to plain text
if missing (easy revert: just remove the source line).

Animations: CRT power-on scan, BIOS memory check simulation,
3D ASCII logo with character-by-character decrypt reveal,
progress bar with ₿ bouncing DVD-screensaver style during
long operations, logo color party on completion, flashing
"REMOVE THE USB DRIVE NOW" warning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 21:23:29 +01:00
Dorian
73fb961b9a fix: disable boot reconciler, fix onboarding loop, UI polish
Critical flow fixes:
- Disable boot reconciliation that auto-created ALL containers on
  unbundled installs (only FileBrowser should exist on first boot)
- Fix onboarding loop: RootRedirect no longer clears the
  neode_onboarding_complete flag on boot screen completion
- Seed phrase persists when navigating back (no regeneration)

UI fixes:
- Boot screen: removed github and save icons from animation loop
- Seed screens: viewport height scaling with 100dvh
- Seed restore: removed outer card container from word input grid
- Seed screens use distinct background (bg-intro-1.jpg)
- Install progress simplified to "Installing" button style
- Uninstall state moved to global store (persists across navigation)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 21:00:01 +01:00
Dorian
08f7f58a9d fix: bulletproof first-boot container creation and install reliability
Remove the Bitcoin RPC 60-second gate that blocked 13+ dependent containers
(mempool, electrumx, btcpay, lnd, fedimint) from being created on first boot.
Containers now always get created and auto-restart via health monitor once
Bitcoin becomes responsive — the designed recovery path.

Additional hardening:
- Validate archy-net creation with retry (silent failure broke DNS)
- Verify critical images are loaded, re-load from tarballs if missing
- Create SearXNG settings.yml before container start (was missing)
- Run reconciler automatically after first-boot failures
- Add load-images as explicit systemd dependency with 900s timeout
- Propagate config write errors in install.rs (bitcoin.conf, lnd.conf)
- FileBrowser password change: retry loop (6 attempts) + 0o600 perms
- Post-start verification: detect containers that exit immediately
- Add 2s dependency waits between container starts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 18:31:00 +01:00
Dorian
a896ecd431 fix: container security hardening, onboarding viewport scaling, boot screen cleanup
Container security:
- Add --cap-drop ALL + --security-opt no-new-privileges:true to 12 containers
  missing hardening in first-boot-containers.sh (mempool-db, electrumx,
  mempool-api, mempool-web, electrs-ui, btcpay-db, nbxplorer, nostr-rs-relay,
  strfry, tailscale, bitcoin-ui, lnd-ui)
- Mirror same hardening in deploy-to-target.sh for consistency
- Add --read-only + tmpfs to nostr-rs-relay
- Fix filebrowser deploy to include security flags
- Remove duplicate UI image definitions in image-versions.sh
- Separate Jellyfin capabilities (needs FOWNER, exec tmpfs for CoreCLR JIT)
- Harden archy-net creation with existence check and error handling

UI fixes:
- Fix onboarding viewport scaling: all 7 screens now use h-full + max-h-full
  pattern so containers never overflow viewport regardless of padding
- Remove path-option-card wrappers from seed verify inputs, left-justify labels
- Remove batteries/barbarian icons from boot screen (keep bitcoin, cloud, github, save)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:35:34 +01:00
Dorian
f29fa2e729 feat: add Android Jetpack Compose app
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 12:48:40 +01:00
Dorian
808480e334 fix: add persistent container install/start logging
- Install, start, and failure events logged to
  /var/log/archipelago-container-installs.log with timestamps
- Enables post-mortem debugging of container lifecycle issues
- UI container hooks: try registry pull before local build fallback

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:09:49 +01:00
Dorian
9a556d7819 fix: CSRF race condition, UI containers, Tor ordering, seed layout
- session.rs: use OnceCell for remember_secret to prevent concurrent
  requests on first boot from generating different HMAC secrets, which
  caused CSRF token mismatch on every state-changing RPC call (app
  install, start, stop all failed with "CSRF token missing or invalid")

- install.rs: write lnd.conf with Bitcoin RPC credentials before LND
  container starts (prevents "bitcoin.mainnet must be specified" crash);
  inject Bitcoin RPC auth into bitcoin-ui nginx.conf; add proper error
  logging to UI container build/run steps; fix UI containers to use
  --network=host (they proxy to localhost backend/bitcoin RPC)

- Tor: remove After=tor.service from archipelago-tor-helper.path to
  break systemd ordering cycle that prevented Tor from starting on boot

- Seed screen: compact grid layout (2 cols mobile, 4 cols sm+) with
  tighter padding to fit kiosk displays without scrolling

- Dockerfiles: remove nonexistent assets/ COPY from bitcoin-ui, fix
  electrs-ui to COPY qrcode.js and EXPOSE 50002 (matches nginx.conf)

- image-versions.sh: add UI container image variables for registry

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:06:19 +01:00
Dorian
bb17e3d46a fix: add missing tracing::warn import, hide QuickActionsCard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 08:44:08 +01:00
Dorian
1e283daf13 fix: overhaul container lifecycle — recovery, health, uninstall, UI state
Container recovery:
- Health monitor: MAX_RESTART_ATTEMPTS 3→10, interval 60s→120s
- Dependency-aware restarts: won't restart services before their deps
- Reset dependent counters when a dependency recovers
- Handle "created" state containers (were invisible to health monitor)
- Added IndeedHub, mempool-api, mysql to tier system
- Crash recovery: podman start timeout 30s→120s with retry
- Podman client: socket timeout 5s→30s, added restart policy

UI state representation:
- Exit code 0 shows "stopped" (gray), not "crashed" (red)
- Exit code 137 shows "killed (OOM)"
- Non-zero exit shows "crashed" (red)
- Added exit_code field to PackageDataEntry

Install/uninstall fixes:
- Install returns error when container doesn't start (was silent success)
- Post-install hooks awaited instead of fire-and-forget tokio::spawn
- Uninstall: graceful rm before force, volume prune, network cleanup
- Uninstall returns error on partial failure (was 200 OK)

Config consistency:
- DB passwords read from /var/lib/archipelago/secrets/ (was hardcoded)
- Bitcoin: added ZMQ ports 28332/28333 for LND block notifications
- IndeedHub port 7777→8190 (was conflicting with strfry)
- Marketplace versions: LND 0.17.4→0.18.4, Mempool 2.5.0→3.0.0

Performance:
- Metrics collector interval 60s→300s (was duplicating health monitor)
- Podman client: proper error propagation instead of unwrap_or_default

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 07:03:57 +01:00
Dorian
795e74bc50 fix: retry Tor address discovery in background after startup
Backend reads Tor address once at startup. If Tor hasn't started yet,
the address is null forever until restart. Now retries at 5, 10, 20,
30, 60 seconds in a background task until Tor is available.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 05:11:55 +01:00
Dorian
f6c41f9052 fix: add python3 to ISO packages, set Claude API key in proxy service
AIUI proxy requires python3 which was missing from rootfs packages.
Also sets the beta API key in the claude-api-proxy systemd service
so AIUI works out of the box on fresh installs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 05:01:13 +01:00
Dorian
72d8101045 fix: add python3 to ISO packages for Claude API proxy
The claude-api-proxy.py requires python3 which was missing from the
rootfs package list, breaking AIUI on fresh installs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 04:52:30 +01:00
Dorian
b3a3d3f9a8 fix: populate tor-hostnames dir in first-boot for backend onion discovery
Backend reads onion addresses from /var/lib/archipelago/tor-hostnames/.
This dir was never created on fresh installs, breaking connect wallet
and tor address display. Now copies from system Tor hidden service dirs.
Also fixed log() function ordering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 04:33:55 +01:00
Dorian
7d35827acb fix: inject Bitcoin RPC auth into bitcoin-ui before build in first-boot
The bitcoin-ui nginx proxy needs Basic Auth to talk to Bitcoin Core RPC.
The __BITCOIN_RPC_AUTH__ placeholder was not being replaced, causing a
browser login prompt. Now injects creds from secrets dir before build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 03:48:22 +01:00
Dorian
2344746ad5 fix: start Tor in first-boot, ensure hidden services on fresh installs
Tor was configured in torrc but never started by first-boot-containers.sh.
Connect wallet and .onion services were broken on fresh installs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 03:43:01 +01:00
Dorian
ba62e3f4f4 fix: increase package start/stop/uninstall RPC timeouts
Uninstall was timing out at 15s default while podman stop takes 30-600s.
Now: uninstall 120s, stop 120s, restart 120s, start 60s.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 03:21:16 +01:00
Dorian
9c9fd1ca1e fix: guard fleet containers iteration, prevent TypeError on null
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 03:05:52 +01:00
Dorian
959cd9e191 chore: hide Fleet tab from sidebar for beta
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 02:52:22 +01:00
Dorian
c3bd30c148 perf: reduce CPU — Chromium GPU flags, healthcheck 30s to 120s, app card fixed height
- Chromium kiosk: add --disable-gpu-compositing, --disable-gpu-rasterization,
  --disable-software-rasterizer, --renderer-process-limit=1
  drops GPU process from 64% to 12% CPU
- Container healthchecks: 30s to 120s interval in first-boot and reconcile
- AppCard: min-height on description so cards dont shift

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 02:42:44 +01:00
Dorian
e970ae172d fix: add missing BitcoinFaceAscii.vue (CI build fix)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 02:05:44 +01:00
Dorian
19dcfd4f31 feat: BIP-39 master seed for unified key derivation
Replace fragmented random key generation with a single 24-word BIP-39
mnemonic that deterministically derives all node keys: Ed25519 (DID),
secp256k1 (Nostr/Bitcoin), BIP-84 xprv (Bitcoin Core), and LND aezeed
entropy. New onboarding flow: seed generate → word verification → identity
naming. Restore path enabled via 24-word entry. Includes seed RPC handlers,
mock backend support, LND/Bitcoin Core wallet-from-seed integration, and
UI polish across settings and discover views.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 01:41:24 +01:00
Dorian
5da9e217e6 feat: auto-detect and enable mesh radio on startup
When no mesh config exists (fresh install), scan for serial devices
at /dev/ttyUSB* and /dev/ttyACM*. If a radio is found, auto-enable
mesh and save the config so subsequent boots connect immediately.

Previously, mesh defaulted to disabled and the radio was never probed
unless the user manually created a mesh-config.json file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 00:50:43 +01:00
Dorian
9a294fbb94 fix: disk stats show LUKS data partition, not 29GB root
system.stats (Home page) and monitoring collector both used df /
which shows the small 29GB root partition. Now prefers
/var/lib/archipelago (the LUKS encrypted data partition) when it
exists — showing the actual 1.8TB storage users care about.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 00:29:58 +01:00
Dorian
adeb57edbf fix: force UTF-8 console with Terminus font for ASCII logo
The Archipelago ASCII logo uses Unicode block characters (▄▀█) which
render as garbled symbols when the console font doesn't support them.
Force Uni2 codeset + Terminus font in both the live ISO and installed
system's console-setup config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 23:47:15 +01:00
Dorian
7bfe4d7608 docs: complete overnight container resilience plan — all cycles pass
All 6 cycles completed successfully:
- C1: Full baseline diagnosis of all Bitcoin stack containers
- C2: Fixed DAC_OVERRIDE caps, health checks, container specs
- C3: Resilience testing — kill/recover for all containers + cascade
- C4: Complete test suite pass — all health checks green
- C5: 5-minute soak test passes with zero state changes
- C6: Code quality gate — all checks pass

Critical bugs found and fixed:
- Rootless volume permission denied (missing DAC_OVERRIDE capability)
- LND health check requiring macaroon auth
- Electrumx health check using missing curl binary
- Container-doctor killing active conmon processes (root/rootless mismatch)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 23:33:32 +01:00
Dorian
d6441082fd fix: use rootless podman to check conmon ownership in doctor
Critical bug: the doctor runs as root but containers are rootless
under the archipelago user. When checking if a conmon process has an
associated container, the root podman database was queried (empty),
causing ALL conmon processes to be identified as orphaned and killed.
This terminated running containers every 30 minutes.

Fix: use sudo -u archipelago to query the rootless podman database.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 23:22:28 +01:00
Dorian
b36b867d01 fix: add required capabilities to UI container specs for nginx startup
Nginx needs CHOWN, SETUID, SETGID to chown cache directories and drop
privileges on startup. LND UI additionally needs NET_BIND_SERVICE to
bind port 80 inside the container. Without these, cap-drop ALL causes
nginx to crash with "Operation not permitted" on chown or bind.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 23:03:27 +01:00
Dorian
dba087b11c fix: run rootless podman commands as archipelago user in doctor
The doctor runs as root (for tor permissions, process cleanup) but
containers are rootless under the archipelago user. Use sudo -u to
switch user context for podman commands.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 22:49:36 +01:00
Dorian
015a2cb7fa fix: add stopped core container restart to doctor
Rootless Podman 4.x restart policies don't auto-restart containers
after crashes. The doctor (which runs on a timer) now checks for
exited core containers (tiers 0-2) and restarts them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 22:46:06 +01:00
Dorian
a5c984630c fix: escape quotes in electrumx health check for eval pass-through
The health check command goes through multiple shell layers
(assignment → variable expansion → eval → podman → sh -c). Inner
double quotes need \\\" escaping to survive as literal " in Python.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 22:29:28 +01:00
Dorian
55fc67c5f9 fix: use python3 socket health check for electrumx (no curl in image)
The electrumx container image doesn't include curl. Replace the HTTP
health check with a Python socket connection test to the RPC port.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 22:19:46 +01:00
Dorian
4468b6d611 fix: add DAC_OVERRIDE cap for rootless volume access, fix LND health check
- electrumx: add DAC_OVERRIDE to SPEC_CAPS — rootless podman maps container
  UID 0 to host UID 1000, but volumes are owned by host UID 100000; without
  DAC_OVERRIDE the container can't write to its own data directory
- lnd: replace curl-based health check with lncli using readonly macaroon —
  the REST API requires macaroon auth, so unauthenticated curl always fails
- grafana: add DAC_OVERRIDE to SPEC_CAPS for the same rootless volume issue

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 22:14:01 +01:00
Dorian
76585656a7 feat: mobile UI overhaul — iPhone-style app grid, icon-only tab bar, fullscreen app sessions
- Add AppIconGrid: 4-column swipeable icon grid with page dots for My Apps on mobile
- Tab bar: remove text labels, square icon-only buttons (w-14 h-14), doubled padding
- Hide tab bar and top context tabs when app session is open
- App session header hidden on mobile, replaced with floating glass close button
- App sessions now render fullscreen on mobile without nav chrome

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 21:03:00 +01:00
Dorian
afda9897f1 fix: embed netavark/aardvark-dns in ISO at build time
Previous fix tried to copy from the live system at install time, but
the live ISO doesn't have netavark. Now: binaries are embedded in the
ISO during build (from the build host's /usr/lib/podman/), then copied
to the target at install time from the ISO filesystem.

This fixes container DNS on fresh installs — LND can now resolve
bitcoin-knots, mempool-api can resolve electrumx, etc.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:52:01 +01:00
Dorian
87bc0baa94 fix: add debian-tor group to backend service for onion address access
The backend couldn't read Tor hidden service hostnames because the
systemd service only had SupplementaryGroups=dialout. Adding debian-tor
allows the backend to read /var/lib/tor/hidden_service_*/hostname
without needing sudo (which is blocked by NoNewPrivileges=yes).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 19:14:27 +01:00
Dorian
b515d3883f fix: install netavark + aardvark-dns for container DNS resolution
Fresh ISO installs use podman with CNI backend which lacks DNS.
Containers on archy-net can't resolve each other by name, causing:
- LND: "lookup bitcoin-knots: no such host"
- Any inter-container communication to fail

Fix: copy netavark + aardvark-dns from build host into ISO rootfs
and configure podman to use netavark backend. This enables automatic
DNS resolution on custom bridge networks (archy-net).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 18:57:17 +01:00
Dorian
f3fd8e9414 fix: AI Assistant placeholder text unreadable on background
Added glass-card backdrop, increased text opacity for readability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 18:41:59 +01:00
Dorian
8e15d5c94b fix: all curated apps pull from registry, not Docker Hub
Every app in curatedApps.ts was hardcoded to docker.io/* instead of
our registry (80.71.235.15:3000/archipelago/*). This caused Bitcoin
Knots and all Discover tab installs to fail with pull errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 18:34:06 +01:00
Dorian
44bffee473 fix: container installs, Tor, kiosk, GRUB, LUKS display, error messages
Critical:
- fix: container installs fail with "statfs: no such file or directory"
  Root cause: NoNewPrivileges=yes in systemd blocks sudo inside backend.
  Fix: use std::fs::create_dir_all + podman unshare chown (no sudo needed)
- fix: Tor services.json never written — \$ARCHY_TOR_DIR escaping bug
- fix: kiosk white screen — increase health wait to 60s, add --disable-gpu

Improvements:
- feat: LUKS encryption badge in Server disk stats (backend detects dm-crypt)
- fix: GRUB theme text scaling on 4:3 monitors — explicit fonts, wider menu
- fix: suppress default Debian MOTD (custom profile.d welcome is enough)
- fix: install error messages now show "Failed to pull/start" instead of
  generic "Operation failed" (middleware.rs allowlist expanded)
- fix: container-tests CI — source cargo env before running tests
- docs: interactive container architecture diagram (HTML)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 16:35:06 +01:00
Dorian
77765c90d0 chore: unbundled ISO builds on main, full Debian ISO manual-only
- build-iso-dev.yml now triggers on both main and dev-iso
- build-iso.yml (full Debian) is workflow_dispatch only

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:57:40 +01:00
Dorian
fdd69ce1b5 fix: auth, container resilience, ISO build, gamepad polish
- fix: login disconnect — verify session before WebSocket connect
- fix: 403 on app install — distinguish CSRF vs RBAC errors, only retry CSRF
- fix: health monitor now watches ALL containers (removed skip list for
  backend services like nbxplorer, databases, UI containers)
- fix: server.get-state added to CSRF-exempt list (read-only)
- fix: ISO build includes container-specs.sh and lib/common.sh in rootfs
  so reconcile actually works on fresh installs
- fix: gamepad nav — improved Server tab zone nav, focus styles, autofocus
- chore: move L484 web-only apps to Services tab
- chore: install store for cross-view install tracking

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:35:02 +01:00
Dorian
68f2a9c5bf feat: gamepad navigation for Mesh tab — zone-based panel nav
- Peer rows: tabindex + role=button + Enter handler for D-pad selection
- Zone attributes: mesh-left, mesh-chat, mesh-tools for cross-panel nav
- Actions row: data-controller-container for Up from peers
- Right from peers → chat input, Right from chat → tools tabs (wide)
- Down from tabs → panel fields/buttons in grid fashion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 10:24:48 +01:00
Dorian
e104a214a4 fix: onboarding gamepad — autofocus, click sounds, focus styles
All screens:
- playNavSound('action') on every button click
- path-action-button orange focus glow (removed from suppression list)

Per-screen autofocus:
- Intro: CTA button (after animation)
- Path: Continue button
- Identity: name input
- Backup: passphrase input, Continue after download
- Verify: Sign Challenge, then Finish after verification
- Done: Set Password button

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:52:09 +01:00
Dorian
6fbdda772f fix: vertical nav prefers closest element over widest overlap
Down from Identity name input now lands on Personal button (closest)
instead of Continue (wider overlap but further away).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:50:50 +01:00
Dorian
18b65cd434 fix: backup screen — autofocus passphrase, rename button, focus Continue after download
- Passphrase input autofocused on mount
- "Download Backup" renamed to "Backup to Continue"
- Continue button autofocused after successful backup download

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:42:26 +01:00