Commit Graph
100 Commits
Author SHA1 Message Date
DorianandClaude Opus 4.6 0abce929ba feat: QEMU headless boot test in CI, updated skills + references
CI now runs a headless QEMU boot test after the smoke test:
- Boots ISO with -nographic, captures serial output
- Watches for "Press Enter to start installation" (pass)
- Detects kernel panic or initramfs shell (fail)
- 120 second timeout, runs as continue-on-error

Also: updated iso-debug reference with embedded vs appended EFI
findings from real hardware testing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 5790fb97fe fix: remove sudo from installer (already root), reduce ISOLINUX timeout
- sudo not installed in minbase squashfs — caused "command not found"
  when pressing Enter to install. We're already root via auto-login.
- ISOLINUX timeout from 5s to 1s — reduces menu flicker/duplication

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 8d01572894 fix: installer auto-start via profile.d, revert to embedded EFI, dark ISOLINUX
Three fixes from real hardware testing:

1. Installer auto-start: replace systemd service with profile.d script.
   The service and getty raced on tty1 — service output was overwritten
   by the login prompt. Profile.d runs AFTER auto-login, same approach
   the working Debian Live build used.

2. xorriso: revert from -append_partition to embedded -e boot/grub/efi.img.
   The appended partition approach produces cyl-align-off with zero CHS
   geometry, which is why BIOS wouldn't recognize the USB. The embedded
   approach matches the working main ISO (cyl-align-on, proper CHS).

3. ISOLINUX: dark theme instead of ugly blue. Black background, orange
   title, dark selection highlight. No blue boxes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 6cfb8082c5 fix: xorriso append_partition for real USB boot + grub-mkstandalone
Root cause of USB boot failure: our xorriso used -e boot/grub/efi.img
to embed the EFI image inside the ISO. This works for CD-ROM and QEMU
but NOT for USB on real UEFI hardware.

Fix: use the Will Haley / Debian live-build approach:
- -append_partition 2 (GPT type EFI) appends efi.img AFTER ISO data
- -e --interval:appended_partition_2:all:: references the appended partition
- --mbr-force-bootable forces MBR active flag
- grub-mkstandalone with embedded bootstrap config (searches for grub.cfg)
- grub.cfg placed in both /boot/grub/ AND /EFI/BOOT/ on ISO
- grub.cfg uses search --label ARCHIPELAGO to find the ISO root

This is the exact approach used by StartOS, TAILS, and every production
custom Debian live ISO that boots from USB.

Also: iso-debug, iso-branding skills + reference docs, dev-start.sh
option 0 for branding dev, improved dev-branding.sh and test-iso-qemu.sh.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 b49f850c85 feat: add boot branding dev option (0) to dev-start.sh
Option 0 in dev-start.sh launches the branding development workflow:
- Finds latest ISO on Desktop or results/
- Patches branding files into the ISO
- Boots in QEMU for immediate visual feedback
- Lists editable files if no ISO is available

Edit background.png, theme.txt, or Plymouth files, re-run option 0,
see changes in ~10 seconds without a full CI build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 436f337a13 feat: custom boot branding, MBR fix, Plymouth theme, CI smoke tests
Boot fix:
- Ship proven Debian Live MBR (4552) as branding/isohdpfx.bin — the
  ISOLINUX package MBR (33ed) doesn't boot on all hardware. This was
  the root cause of "machine doesn't pick up the USB".

Branding:
- Custom GRUB background: pixel-art floating island (1024x574)
- Archipelago pixel-art logo for Plymouth boot splash
- GRUB theme: dark background, orange selected item, no broken font refs
- Plymouth theme: script-based with progress bar, LUKS prompt support
- Plymouth + splash added to target rootfs packages
- GRUB theme installed on both installer ISO and target system
- Serial console (ttyS0) added to kernel params for QEMU debugging

CI improvements:
- Smoke test step: mounts ISO, verifies all critical files, checks
  initrd has live-boot, confirms boot=live in grub.cfg. Fails build
  before copying to Builds if any check fails.

Dev workflow:
- dev-branding.sh: extract ISO, swap branding, repackage, boot in QEMU
  (~10 seconds vs 20 min full rebuild)
- generate-grub-background.py: procedural cyberpunk background generator
- generate-plymouth-logo.py: procedural logo generator
- Improved test-iso-qemu.sh: --bios/--nographic flags, serial logging

Build:
- Simplified live-boot install (clean chroot, no complex fallbacks)
- Static branding images preferred, generators as fallback

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 93d05970e1 fix: GRUB theme font refs, improve QEMU test script
Theme: remove explicit font name references that don't match
grub-mkfont output names, remove select_*.png pixmap reference
(files don't exist). GRUB falls back to default when theme fails
to load — this was causing the Debian helmet to show.

QEMU test script: add --bios/--nographic flags, serial console
logging to /tmp/archipelago-qemu-serial.log, auto-detect latest
ISO, use -drive for OVMF firmware.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 a12e97ca72 fix: restore -partition_offset 16 to xorriso for USB boot compatibility
The old Debian Live ISO used -partition_offset 16 which reserves space
for a GPT partition table in the hybrid MBR layout. UEFI firmware on
some machines requires this to recognize the USB as bootable. We
removed it thinking it was Debian Live-specific but it's actually an
xorriso hybrid boot requirement.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 6eb6f8b27d fix: live-boot check — scripts/live is a file not a directory
The verification used [ -d ] but live-boot-initramfs-tools installs
scripts/live as a regular file, not a directory. Changed to [ -e ].
The chroot install was actually succeeding — only the check was wrong.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 8837c76ef4 fix: live-boot install — avoid chroot, use dpkg extraction fallback
The chroot /installer command fails inside the CI container because
the container exits after debootstrap completes (set -e + container
boundary). The chroot then runs on the host where /installer doesn't
exist.

Fix: use apt-get with Dir overrides first, fall back to dpkg-deb -x
extraction of live-boot .deb files directly into the installer root.
This bypasses chroot entirely and is more robust in container-in-
container environments.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 540438296e fix: install live-boot via apt after debootstrap, remove partition_offset
Two boot fixes:
- live-boot package must be installed via chroot apt-get, not debootstrap
  --include (minbase resolver can't handle its deps). Verified initrd was
  missing scripts/live* entirely.
- Remove -partition_offset 16 from xorriso — it was designed for the
  original Debian Live MBR, not the standard ISOLINUX isohdpfx.bin.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 709c135fab fix: boot chain — add live-boot, mount proc/sys/dev, fix kernel params
The first ISO build didn't boot. Three root causes:

1. No squashfs-as-root mechanism — the custom initramfs hook mounted
   boot media but had no way to use the squashfs as the root filesystem.
   Fix: add live-boot + live-boot-initramfs-tools to debootstrap includes.
   This is ~100KB and provides proven squashfs-as-root with overlayfs.

2. Broken initramfs — update-initramfs needs /proc, /sys, /dev mounted
   in the chroot to detect modules and generate a working initrd.
   Fix: bind-mount virtual filesystems before update-initramfs.

3. Missing kernel parameters — GRUB and ISOLINUX configs lacked
   boot=live components, so live-boot never activated.
   Fix: add boot=live components to all kernel command lines.

Also: add all_video/efi_gop/efi_uga modules to GRUB EFI image for
display output on real hardware, and update installer wrapper to
check /run/live/medium first (where live-boot mounts the ISO).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 4326f019c1 feat: replace Debian Live with custom debootstrap ISO base + branding
Major ISO build overhaul on dev-iso branch:

- Replace ~800MB Debian Live download with debootstrap --variant=minbase
  (~150MB installer squashfs built from scratch)
- Custom initramfs with archipelago-mount hook for boot media detection
- Systemd service auto-starts installer (replaces profile.d hack)
- GRUB + ISOLINUX configs written from scratch (no Debian Live dependency)
- EFI boot image built with grub-mkimage (no more MBR extraction)
- Archipelago GRUB theme: dark background, Bitcoin orange accents
- Theme installed on both installer ISO and target system
- Rootfs optimizations: --no-install-recommends, strip docs/man/locales,
  remove firmware-misc-nonfree/wget/htop, add explicit font deps
- Separate CI workflow (build-iso-dev.yml) for dev-iso branch
- Includes pre-existing fixes from main (build-iso.yml, middleware, Login)

Target: sub-2GB unbundled ISO (down from 3.9GB)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:34:29 +00:00
DorianandClaude Opus 4.6 018f3c84d3 fix: onboarding auth, stale CI build, autocomplete attrs
- Add identity.create + server.echo to UNAUTHENTICATED_METHODS
- Clear web/dist before frontend build to prevent stale artifacts
- Add autocomplete attrs to login inputs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 19:19:51 +00:00
DorianandClaude Opus 4.6 9741e73824 fix: filebrowser port bind, CSRF in tests, console-setup, auto-test scope
FileBrowser crash fix:
- Add --cap-add=NET_BIND_SERVICE (port 80 needs it with --cap-drop=ALL)
- Add --cap-add=DAC_OVERRIDE for rootless volume access
- Both in first-boot script and backend config.rs

Test script fixes:
- Extract csrf_token cookie and send as X-CSRF-Token header on RPC calls
- Add --phase1-only flag for safe install-only checks (no side effects)
- Auto-test service uses --phase1-only so it doesn't steal onboarding

Install fixes:
- Pre-create ~/.local/share/containers (ReadWritePaths mount namespace error)
- Fix console-setup.service: add After=tmp.mount + ExecStartPre mkdir /tmp

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:17:18 +00:00
DorianandClaude Opus 4.6 316dc4875a fix: run post-install tests automatically on first boot
Adds archipelago-post-install-tests.service — runs once after all
services are up, outputs to console + journal + log file at
/var/log/archipelago-post-install-tests.log. Tests password setup,
onboarding, and container lifecycle. Runs with default password
(password123) for automated validation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:19:33 +00:00
DorianandClaude Opus 4.6 7cd4d90ed8 fix: production onboarding, CI tests, container security, keyboard nav
Install & Onboarding:
- Remove DEV_MODE=true from production ISO service file (auto-created
  users, skipped password setup)
- Auto-install no longer overwrites rootfs service file with bad template
- Login.vue always checks auth.isSetup — shows password creation form
  on fresh install without requiring dev build flag
- Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes
- First-boot-containers sources image-versions.sh, runs podman as
  archipelago user (rootless), enables linger + podman.socket
- Correct volume ownership (100000:100000 for rootless UID mapping)

Container Security:
- FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access
- FileBrowser: add --read-only, /data volume for database, proper cmd args
- First-boot script matches backend config (security hardening + health check)

CI Pipeline:
- Add vue-tsc type check + vitest run to build-iso.yml (runs every push)
- Add post-install-tests.yml workflow (workflow_dispatch, SSH to target)
- Build report: set +eo pipefail, fix rootfs path, add || true guards
- Bundle run-post-install-tests.sh into ISO

E2E Test Suite (scripts/run-post-install-tests.sh):
- Phase 1: Install verification (files, services, podman, linger, DEV_MODE check)
- Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete)
- Phase 3: Container lifecycle (install 3 apps via package.install RPC,
  verify running, stop, verify stopped, restart, verify running, health)
- Phase 4: Log verification (first-boot log, diagnostics, journal errors)
- Correct package.install params: {"id", "dockerImage"}

Frontend:
- Fix backdrop-filter tab-switch bug (keep animations paused during rebuild)
- Dashboard glitch animations paused during tab-hidden
- Gamepad nav: auto-focus first container on route change
- Tab roving: Left/Right on role="tab" cycles and activates sibling tabs
- ContainerApps: data-controller-launch on running app cards
- 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
DorianandClaude Opus 4.6 bf14f9e5ad fix: CI report step uses sudo for root-owned files, continue-on-error
The Build report step was failing the entire job because `du -h` and
`tar tf` on root-owned rootfs.tar returned permission denied. Added
sudo and continue-on-error: true so the report never fails the build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:41:47 +00:00
DorianandClaude Opus 4.6 121f17e44e fix: container install flow, filebrowser auth, AppCard enrichment
- Fix .198-style fresh installs: systemd service ExecStartPre creates
  /run/user/1000, enable podman.socket, chmod 644 /etc/hosts
- Filebrowser: add /data volume for database (fixes read-only crash),
  secure auth with random password via backend RPC (no more admin/admin)
- AppCard: enrich installing state with marketplace metadata (icon,
  title, description, tier badge, author, version)
- Registry: btcpayserver 1.13.5 → 1.13.7, images mirrored
- ReadWritePaths: add home container paths for rootless podman

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:32:54 +00:00
DorianandClaude Opus 4.6 ef2922d909 docs: trim CLAUDE.md — lean, updated for CI/CD and registry
Removed duplication with rules/ files, updated infrastructure table
(git.tx1138.com, app registry, CI runner, ISO debugging), trimmed
from 404 lines to ~120. Security rules kept via reference to rules/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 12:03:04 +00:00
DorianandClaude Opus 4.6 32a37c13d1 fix: filebrowser registry, CI cleanup, autologin, auth debug logging
- CI: configure root podman with insecure registry so FileBrowser
  image can be pulled during ISO build
- CI: chmod u+rwX on workspace and act cache to fix cleanup failure
- ISO: auto-login on tty1 (no password prompt on console)
- Frontend: add console.log debug output for onboarding routing,
  health checks, and 401 redirects to diagnose session issues

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:13:01 +00:00
DorianandClaude Opus 4.6 546481bc15 fix: bundle FileBrowser, auto-login tty1, boot/auth debug logging
- ISO build: configure insecure registry for root podman so FileBrowser
  image can be pulled during build (was failing with HTTPS error)
- Auto-login on tty1 so no password prompt on console
- RootRedirect: persistent debug logging to sessionStorage
  (view in DevTools > Application > Session Storage > archipelago_boot_log)
- Logs: health check, onboarding state, routing decisions, 401 handling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:12:31 +00:00
DorianandClaude Opus 4.6 1fe72860fb fix: CI chown act cache to prevent false build failure
The checkout action post-cleanup fails on root-owned files in the
workspace, marking the build as failed even though the ISO was built.
Chown the entire act cache dir so cleanup succeeds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:02:43 +00:00
DorianandClaude Opus 4.6 9042ed134f fix: TS2532 undefined check in controller nav Enter handler
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:29:14 +00:00
DorianandClaude Opus 4.6 35ae7ff847 fix: kiosk cursor, Esc dead-end, PWA prompt, password overlay, gamepad Enter
- Kiosk: show cursor when active (removed -nocursor from Xorg),
  unclutter hides after 3s idle. X11 on VT7 for Ctrl+Alt+F1/F7 switching.
- Kiosk: keep getty@tty1 running so MOTD is accessible via Ctrl+Alt+F1
- Kiosk: disable Chromium password save overlay (--password-store=basic)
- Esc: don't navigate back from top-level pages (dashboard, login, kiosk)
  to prevent dead-end at root redirect
- PWA: suppress install prompt in kiosk mode (/kiosk path)
- Gamepad: Enter in text fields moves focus to next element (submit button)
  instead of submitting the form

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:16:07 +00:00
DorianandClaude Opus 4.6 16a5a9ae16 feat: add install log and first-boot diagnostics
- Installer: tee all output to /var/log/archipelago-install.log
  on the target disk for post-install debugging
- First boot: oneshot service captures system state 30s after boot:
  services, nginx, LUKS, EFI, SSL, containers, journal errors
- On-demand: sudo archipelago-diagnostics to re-run anytime

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:58:34 +00:00
DorianandClaude Opus 4.6 102434c041 feat: add build report and first-boot diagnostics
CI build report: checks rootfs contents (nginx, SSL, keyboard, kiosk,
lid config, backend, frontend) and ISO contents after build. Reports
in the Actions log so build issues are immediately visible.

First-boot diagnostics: one-shot systemd service runs 30s after first
boot, logs service status, nginx test, SSL certs, LUKS, podman,
kiosk, console-setup, disk, network, and journal errors to
/var/log/archipelago-first-boot-diag.log. Only runs once (ConditionPathExists).

SSH in and cat the log to debug any fresh install issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:54:32 +00:00
DorianandClaude Opus 4.6 e4b4519061 fix: onboarding 401 redirect, glass card rendering bugs
- rpc-client: don't redirect to /login on 401 during onboarding flow,
  which caused session expired kicks on fresh installs
- style.css: add translateZ(0) + isolation:isolate to glass-card,
  glass-strong, path-option-card to fix Chromium compositor bug where
  backdrop-filter + animated fixed overlays cause black rectangles
- App.vue: pause background animations when tab hidden, force
  compositor layer rebuild on tab return to prevent stale renders

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:06:09 +00:00
DorianandClaude Opus 4.6 6b857e59d0 fix: preseed keyboard config, enable kiosk by default
- Preseed keyboard-configuration and console-setup debconf values
  to prevent console-setup.service failure on boot
- Enable archipelago-kiosk.service by default on fresh installs
  so the system boots into the web UI display, not a login prompt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 19:50:59 +00:00
DorianandClaude Opus 4.6 66b1f35638 fix: nginx startup, kiosk fullscreen, reboot errors, kiosk toggle
- Remove hardcoded Tailscale IP from nginx listen (broke fresh install)
- Generate SSL cert in installer if rootfs missed it (safety net)
- Kiosk: add --start-fullscreen --start-maximized --window-size flags
- Kiosk: remove --disable-gpu (can prevent fullscreen rendering)
- Kiosk: add toggle command and Ctrl+Alt+F1/F7 docs in MOTD
- Reboot: suppress stderr during cleanup to hide flashing errors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:30:13 +00:00
DorianandClaude Opus 4.6 17eeb59a2b fix: purge shim-signed and clean EFI/BOOT to fix boot failure
Shim-signed package hooks reinstall shimx64.efi and BOOTX64.CSV
which cause 'Failed to open \EFI\BOOT\' with garbled filenames.
Purge the package before grub-install, then nuke everything from
EFI/BOOT except BOOTX64.EFI and grub.cfg.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 17:31:26 +00:00
DorianandClaude Opus 4.6 40fd95407a fix: load dm_mod/dm_crypt and mount /proc /sys for LUKS setup
The live installer environment doesn't have dm_mod loaded, causing
'Cannot initialize device-mapper' during LUKS2 encryption. Also
bind-mount /proc and /sys into chroot so cryptsetup can detect
hardware capabilities.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 17:28:08 +00:00
DorianandClaude Opus 4.6 55bceeda35 fix: CI pass absolute ARCHIPELAGO_BIN path through sudo
sudo doesn't inherit env vars. Use absolute path and pass it
explicitly so the ISO build finds the freshly built binary
instead of falling through to podman build from source.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:48:36 +00:00
DorianandClaude Opus 4.6 9e98c65dae fix: CI fix 'local' outside function and root-owned file cleanup
- Remove 'local' keyword in ISO build script (not in a function)
- Add workspace permission fix step so runner can clean up after sudo

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:24:30 +00:00
DorianandClaude Opus 4.6 bb356af6e4 fix: remove 'local' keyword outside function in ISO build script
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:23:19 +00:00
DorianandClaude Opus 4.6 152281b6bb fix: CI cache Debian Live ISO to avoid 1.4GB re-download
Copy the Debian Live ISO from the server's existing build cache
into the CI workspace before running the ISO build. Saves ~10 min.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:03:49 +00:00
DorianandClaude Opus 4.6 6504a13bb8 feat: ignore lid close on laptops so server keeps running
Adds logind.conf.d drop-in to HandleLidSwitch=ignore for all
lid close scenarios (battery, external power, docked). Archipelago
nodes installed on laptops won't suspend when the lid is closed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:58:16 +00:00
DorianandClaude Opus 4.6 de336c472d chore: remove dead core/parmanode crate
The parmanode compatibility layer was scaffolded but never wired up —
zero imports or calls from anywhere in the codebase. Closes gitea#1.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:33:13 +00:00
DorianandClaude Opus 4.6 9e39614ecb fix: CI don't replace live binary, pass build path to ISO script
Remove the cp to /usr/local/bin that caused 'Text file busy'.
The ISO build script now accepts ARCHIPELAGO_BIN env var to find
the freshly built binary instead of requiring it installed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:28:43 +00:00
DorianandClaude Opus 4.6 b2168751db fix: CI rm binary before cp to avoid 'Text file busy'
On Linux, rm on a running binary works (process keeps its fd).
Then cp creates a new inode. Restart service after.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:26:18 +00:00
DorianandClaude Opus 4.6 f632c4acd8 fix: CI add debug output for frontend build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:04:22 +00:00
DorianandClaude Opus 4.6 e1bda755f2 fix: CI stop archipelago service before replacing binary
The running binary locks the file, causing 'Text file busy' on cp.
Stop the service, copy, then restart.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 14:44:32 +00:00
DorianandClaude Opus 4.6 56938eb139 fix: CI increase timeout, cleared stale git lock on runner
Stale shallow.lock was blocking checkout. Removed it on the runner.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 14:30:21 +00:00
DorianandClaude Opus 4.6 f2f08fba12 fix: CI use actions/checkout@v4 (Gitea proxies to GitHub)
The full URL form was 404. The short form lets Gitea resolve from
its configured action sources (GitHub proxy). This worked for build #7.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 14:26:57 +00:00
DorianandClaude Opus 4.6 525779f4aa fix: CI checkout cd to home before cleanup to avoid cwd error
The runner cwd is the workspace itself, so deleting it removes the
shell's cwd. cd to home first, then clean workspace before clone.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 14:24:24 +00:00
DorianandClaude Opus 4.6 30cc2378d2 fix: CI checkout with token auth for private repo
Manual git clone needs GITHUB_TOKEN injected for private repos.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 14:21:48 +00:00
DorianandClaude Opus 4.6 5a850275b7 fix: CI checkout uses manual git clone instead of missing action
The actions/checkout@v4 action was 404 on git.tx1138.com causing
instant build failures. Use manual git clone for reliability with
host-mode runner.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 14:16:13 +00:00
DorianandClaude Opus 4.6 35c8420095 feat: migrate all container images to Archipelago app registry
All container image references now pull from 80.71.235.15:3000/archipelago/
instead of Docker Hub and ghcr.io. image-versions.sh is the single source
of truth; all scripts use $*_IMAGE variables instead of hardcoded refs.

Files updated:
- scripts/image-versions.sh: central ARCHY_REGISTRY variable
- core/*/config.rs: registry whitelist includes app registry
- core/*/stacks.rs: Immich + Penpot stack images
- scripts/{first-boot,deploy-to-target,container-specs}.sh: use variables
- docker/*/Dockerfile: nginx base image from registry
- image-recipe/: ISO build, podman config, menu script
- scripts/{container-doctor,deploy-bitcoin-knots,fix-indeedhub,validate-app-manifest}.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 14:06:21 +00:00
DorianandClaude Opus 4.6 18cd0cf387 feat: switch marketplace to Archipelago app registry
All app images now pull from 80.71.235.15:3000/archipelago/
instead of Docker Hub / ghcr.io. Insecure registry config
baked into ISO for fresh installs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:46:26 +00:00
DorianandClaude Opus 4.6 2e0b78ef42 fix: CI workflow use Gitea checkout action, unbundled only
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:34:11 +00:00
DorianandClaude Opus 4.6 81a38d6824 chore: CI builds unbundled ISO only (with FileBrowser)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:26:40 +00:00
DorianandClaude Opus 4.6 ed4a5470f9 chore: remove disabled workflows, keep only build-iso
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:20:12 +00:00
DorianandClaude Opus 4.6 b781136c34 feat: CI/CD builds both bundled and unbundled ISOs
Workflow builds both variants on push to main. Manual trigger
lets you choose bundled, unbundled, or both. ISOs auto-copied
to FileBrowser /Builds/ folder for easy download.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:13:31 +00:00
DorianandClaude Opus 4.6 b7e60af823 feat: LUKS2 encryption, boot sequence fixes, onboarding auth, CI/CD
- LUKS2 full-partition encryption for /var/lib/archipelago/ (TASK-42)
  4-partition layout: BIOS + EFI + root (30GB) + encrypted data
  AES-256-XTS with AES-NI detection, ChaCha20 fallback for ARM
  Auto-unlock via crypttab + random key file

- Fix EFI boot errors: remove shim-signed, clean shim artifacts
- Fix first-boot sequence: always show boot animation before onboarding
- Fix stale localStorage causing login instead of onboarding (BUG-47)

- Add auth.setup + auth.isSetup RPC handlers for password on clean install
- Add onboarding methods to UNAUTHENTICATED_METHODS (DID sign 403 fix)

- FileBrowser bundled in unbundled ISO, fix auto-login Secure cookie (BUG-46)
- Kiosk mode: xorg/chromium in rootfs, toggle script, MOTD instructions

- Add Gitea Actions CI/CD workflow for automatic ISO builds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:12:16 +00:00
DorianandClaude Opus 4.6 f90b407054 fix: add --no-cache to rootfs Docker build to prevent stale layer caching
Podman was caching the rootfs Docker layers, meaning firmware packages
and sources.list changes were never picked up on rebuild. Force fresh
build every time since the rootfs tar is the real cache.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:31:51 +00:00
DorianandClaude Opus 4.6 6813e6d506 fix: replace DEB822 sources with traditional sources.list for non-free-firmware
The sed commands to modify debian.sources DEB822 format were silently
failing — firmware packages never got installed. Replace the entire
sources config with traditional sources.list that explicitly includes
non-free-firmware component.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:21:27 +00:00
DorianandClaude Opus 4.6 57f97b9351 fix: remove Secure Boot shim chain — causes EFI boot failure on most hardware
The shim (shimx64.efi.signed) was being installed as BOOTX64.EFI but it
tries to load a second-stage binary with a garbled name, causing
"Failed to open \EFI\BOOT\" errors on machines with Secure Boot disabled.

Fix: use grub-install --removable directly (unsigned GRUB as BOOTX64.EFI).
This works on all UEFI hardware. Users with Secure Boot must disable it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 20:47:14 +00:00
DorianandClaude Opus 4.6 17924c73d7 fix: EFI Secure Boot chain with grub.cfg, fix non-free-firmware repo
EFI boot fix:
- Shim needs grub.cfg in same directory to find the root partition
- Create minimal grub.cfg in /EFI/BOOT/ that chains to /boot/grub/grub.cfg
- Preserve unsigned GRUB as fallback for non-Secure-Boot systems
- Copy full chain to both /EFI/BOOT/ and /EFI/archipelago/ paths
- Log EFI directory contents for debugging

Firmware fix:
- DEB822 format sed was wrong — fix Components line replacement
- Add fallback sources.list entry to guarantee non-free-firmware repo
- Ensures firmware-realtek, intel-microcode actually get installed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 19:25:55 +00:00
DorianandClaude Opus 4.6 ec32b336a6 fix: zero BIOS boot partition to prevent FAT-fs errors, add CPU microcode
- dd zero the 1MB BIOS boot partition before formatting to prevent
  kernel FAT-fs bread() errors during boot (sda1 had stale data)
- Add intel-microcode and amd64-microcode packages to suppress
  TSC_DEADLINE and similar CPU firmware bug warnings on boot

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 18:25:01 +00:00
DorianandClaude Opus 4.6 273de288c3 fix: move mobile nav outside main for fixed positioning, add container scripts
- Dashboard.vue: move DashboardMobileNav outside <main> so position:fixed
  isn't broken by will-change:transform on the perspective container
- Add container-specs.sh and reconcile-containers.sh utility scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 18:13:22 +00:00
DorianandClaude Opus 4.6 b0ac506899 fix: robust ISO download detection, fix color escape codes in installer
- Use find instead of hardcoded filename for downloaded ISO detection
  (wget may save with redirect filename or partial name)
- Fix color escape codes: use $'\033' syntax instead of '\033' for
  reliable ANSI color rendering in installer output

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:03:21 +00:00
DorianandClaude Opus 4.6 e88b759b52 fix: add hardware firmware, suppress GRUB warning, eject USB after install
- Add firmware-realtek, firmware-iwlwifi, firmware-misc-nonfree to rootfs
  (fixes missing r8169 NIC firmware on Dell and other common hardware)
- Enable non-free-firmware repo in rootfs Dockerfile
- Suppress os-prober GRUB warning (GRUB_DISABLE_OS_PROBER=true)
- Auto-eject USB boot media before reboot to prevent re-entering installer

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 16:56:02 +00:00
DorianandClaude Opus 4.6 5918185a3a fix: use Debian 12 (Bookworm) live ISO base, remove squashfs boot artifacts
The ISO build was using Debian 13 (Trixie) as the live installer base
while the rootfs was built from Debian 12 (Bookworm). This caused:
- Debian 13 kernel/hostname/user in the live environment
- Squashfs errors on reboot from live-boot initramfs hooks

Fixes:
- Pin live ISO to Debian 12.10.0 (archive URL)
- Remove live-boot/live-config packages before initramfs regeneration
- Clean out any live-boot initramfs hooks/scripts from installed rootfs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 16:51:14 +00:00
DorianandClaude Opus 4.6 207e53144c feat: architecture review fixes, self-update system, CI pipeline, supply chain hardening
Architecture review (all P0+P1 issues now fixed):
- Add 10s timeout to 6 bare Nostr client.connect() calls
- Pin all 12 crypto deps to exact versions from Cargo.lock
- Pin all 15 floating container image tags to exact patch versions
- Add CI pipeline (cargo fmt + clippy + tests, frontend type-check + build)

Self-update system (git.tx1138.com):
- scripts/self-update.sh: pull, build, install, restart with rollback
- systemd timer checks daily at 3 AM
- update.check RPC does git-based checks when repo is present
- update.git-apply RPC triggers self-update from UI
- Default update URL changed from GitHub to git.tx1138.com
- Git added to ISO package list for fresh installs

Documentation:
- CHANGELOG v1.3.1 with all changes
- README updated (version, update system section)
- BETA-PROGRESS session #6 logged
- architecture-review.html: 4 issues marked FIXED, 8/12 refactoring done

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:52:26 +00:00
DorianandClaude Opus 4.6 4d1df4a319 docs: update deploy session memory with session 3 fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:06:57 +00:00
DorianandClaude Opus 4.6 a802b2e478 fix: correct health check endpoints for fedimint, nextcloud, filebrowser
- Fedimint: check port 8175 (UI) not 8174 (websocket API)
- Nextcloud: check / not /status.php (returns 302 during setup)
- FileBrowser: check / not /health (endpoint doesn't exist)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 00:47:49 +00:00
DorianandClaude Opus 4.6 de07b48876 fix: health check escaping for SSH heredoc context
- Remove || exit 1 from health-cmd (redundant, breaks SSH heredoc)
- Use --health-cmd 'cmd' format (space, not equals) for proper quoting
- Simplify bitcoin health check to bitcoin-cli getnetworkinfo (no creds needed)
- Fix MariaDB health check nested quote issue

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 23:45:32 +00:00
DorianandClaude Opus 4.6 47c42d4d1b fix: LND config escaping in SSH heredoc, Tailscale fallback for build source
- Fix shell escaping in LND config sync block (single-quoted SSH context
  doesn't need backslash-escaped dollars)
- deploy-tailscale.sh BUILD_SOURCE auto-detects Tailscale IP when LAN
  unreachable (fixes "No binary on .228" error)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 17:01:02 +00:00
DorianandClaude Opus 4.6 ed9b63fa72 fix: suppress tar xattr spam in AIUI deploy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 16:54:54 +00:00
DorianandClaude Opus 4.6 4441473f2f fix: fleet deploy falls back to Tailscale when LAN unreachable
- Add --all as alias for --fleet
- Fleet deploy auto-detects Tailscale IP when LAN SSH fails
- Skip .198 gracefully when unreachable instead of failing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 16:51:49 +00:00
DorianandClaude Opus 4.6 c2ac572d9a fix: deploy credential sync, health checks, rootless port binding
- LND config always synced with secrets/bitcoin-rpc-password before
  starting (both deploy scripts) — fixes 401 auth errors on all nodes
- Replace eval "$DB_PASSWORDS" with safe individual SSH reads in
  deploy-tailscale.sh (eliminates command injection risk)
- Add MariaDB password sync step after container start (ALTER USER)
- Add --health-cmd to all 25 containers in deploy-tailscale.sh
- FileBrowser uses --user 0:0 for rootless port 80 binding (both scripts)
- Fedimint env var fixed: FM_REL_NOTES_ACK=0_4_xyz

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:16:11 +00:00
Dorian e4e0ef4f11 bug fixing and deploy and build diagnostics 2026-03-22 03:30:21 +00:00
DorianandClaude Opus 4.6 1f8287c4c3 docs: mark all overnight plan tasks complete
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 03:08:52 +00:00
DorianandClaude Opus 4.6 b2bb5f319e feat: add E2E smoke test script and CI/CD pipeline plan
- Create scripts/smoke-test.sh for live server verification (7 checks)
- Document planned GitHub Actions CI/CD pipeline in docs/ci-cd-plan.md
- Integration tests deferred to future task (require test harness setup)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 03:08:00 +00:00
DorianandClaude Opus 4.6 23d67c0672 refactor: create shared script library, fix ISO image pinning, document planned splits
- S21: Create scripts/lib/common.sh with shared logging, SSH, health check, mem_limit functions
- S18: Source common.sh from deploy-to-target.sh, deploy-tailscale.sh, first-boot-containers.sh
- S16: Fix 2 hardcoded images in ISO build, add missing image variables
- S19: Document planned 7-module split of build-auto-installer-iso.sh
- S20: Document planned 8-module split of first-boot-containers.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 03:06:29 +00:00
DorianandClaude Opus 4.6 69e25410b0 refactor: split Marketplace, Server, Home, AppDetails views; minor frontend quality fixes
- F29-F32: Split 4 views (Marketplace 1293→505, Server 1132→486, Home 1059→394, AppDetails 1036→386)
- F20: Add aria-current="page" to Dashboard nav links
- F21: Add 150ms search debounce in Marketplace and Apps views
- F22: Reduce backdrop-filter blur to 8px on mobile for GPU performance
- F23: Track and clear WebSocket connect check interval in all paths

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 03:01:38 +00:00
DorianandClaude Opus 4.6 afd7405b1a refactor: split Web5.vue, Settings.vue, and Mesh.vue into focused subcomponents
- F25: Split Web5.vue (3940 lines) into 14 files under views/web5/
- F26: Split Mesh.vue (2106→840 lines) extracting Bitcoin and Deadman panels
- F27: Dashboard.vue assessed — layout shell, no split needed
- F28: Split Settings.vue (1792 lines) into AccountSection + SystemSection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 02:43:28 +00:00
DorianandClaude Opus 4.6 618244eab0 refactor: split package.rs, mod.rs, listener.rs, and lnd.rs into focused submodules
- R35: Split package.rs (1794 lines) into package/{mod,config,validation,lifecycle}.rs
- R36: Split mesh/listener.rs (1799 lines) into listener/{mod,session,frames,decode,dispatch,bitcoin}.rs
- R37: Split rpc/mod.rs into mod.rs + dispatcher.rs, middleware.rs, response.rs (54% reduction)
- R38: Split lnd.rs (1064 lines) into lnd/{mod,info,channels,wallet,payments}.rs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 02:26:28 +00:00
DorianandClaude Opus 4.6 d8b753e1e4 fix: deploy error visibility, trap cleanup, variable quoting, frontend resilience
- S10: Add warnings to silent health check failures in deploy scripts
- S11: Add trap cleanup for temp dirs in deploy and tailscale scripts
- S12: Quote 20+ critical unquoted variables across deploy scripts
- S13: Extract hardcoded IPs to deploy-config-defaults.sh
- S15: Add --memory=256m to UI container runs
- F16: Remove in-memory JWT, use cookie-only auth in filebrowser client
- F17: Add meta tag fallback for CSRF token in RPC client
- F19: Track and clear setTimeout in AppSession on unmount

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 02:06:08 +00:00
DorianandClaude Opus 4.6 8e38342d53 fix: WebSocket reconnect race, parse error tracking, RPC timeout reduction, vendor chunk split
- F8: Add isReconnecting flag to prevent parallel reconnection attempts
- F9: Track JSON parse errors, force reconnect after 3 consecutive failures
- F11: Reduce RPC timeout to 15s, add jitter to retry backoff
- F12: Add vendor chunk splitting for vue/router/pinia
- F13: DOMPurify already applied to QR SVGs — verified
- F14: Replace O(n) goals alias lookup with Map-based O(1)
- F15: Wrap 7 localStorage.setItem calls in try/catch across 5 stores

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 01:57:05 +00:00
DorianandClaude Opus 4.6 94f2de4a64 refactor: centralize constants, eliminate unwraps, remove dead code, resolve TODOs
- R13+R16: Replace .expect() with .context()? in main.rs and identity.rs
- R17+R18+R19: Fix unwrap() calls in helpers and js-engine
- R20+R21: Remove #[allow(dead_code)] annotations and delete truly dead code
- R22-R26: Create constants.rs module, replace 21 hardcoded values across 12 files
- R28+R29: LND/DWN timeouts already present — verified
- R30-R33: Remove TODO comments, implement marketplace payment check

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 01:54:35 +00:00
DorianandClaude Opus 4.6 c3d4a7063b fix: systemd resource limits, Tor rotation transition, unwrap elimination, RPC timeouts
- I2: Add MemoryMax=4G, LimitNOFILE=65535, TasksMax=2048 to systemd service
- I3: Tor rotation keeps old service for 1h transition before cleanup
- R14: Replace .parse().unwrap() with .unwrap_or(localhost) in rate limiter
- R15: Replace 7 unwrap/expect in mesh protocol with proper error propagation
- R27: Add 10s timeouts to mesh Bitcoin RPC calls

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 01:46:40 +00:00
DorianandClaude Opus 4.6 95fbb094b0 fix: deploy locking, safe eval replacement, first-boot error handling, script hardening
- S4: Add Bitcoin readiness gate and container tracking with final summary
- S5: Replace eval "$DB_PASSWORDS" with safe case-based variable parsing
- S6: Add deploy locking with stale lock detection (30min timeout)
- S7: Deploy rollback already implemented — verified existing mechanism
- S8: Switch trust-archipelago-cert.sh to SSH key auth, sshpass as fallback
- S9: Pipe MariaDB SQL via stdin to avoid password in ps output
- S17: Add disk space pre-flight check (abort if >85% full)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 01:39:22 +00:00
DorianandClaude Opus 4.6 0cca539a0f fix: WebSocket reconnect state refresh, listener leak fixes, pin container images
- F4: Fetch fresh server state after WebSocket reconnect
- F5: Guard message polling timer with auth check, stop on logout
- F6: Remove NIP-07 listener in appLauncher close()
- F7: Initialize audio player once to prevent listener stacking
- S3: Pin all container images to specific versions, create image-versions.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 01:32:28 +00:00
DorianandClaude Opus 4.6 2443ae6bba refactor: replace blocking std::fs and TCP I/O with async tokio equivalents
- R6: Convert 6 std::fs calls in session.rs to tokio::fs async
- R7: Convert std::fs::read_to_string in docker_packages.rs to async
- R8: Convert 3 std::fs calls in port_allocator.rs to async, switch to tokio::sync::Mutex
- R9+R10+R11: Fix blocking I/O in node_message.rs and nostr_discovery.rs
- R12: Convert electrs_status.rs from sync TCP to async tokio::net with 5s timeouts
- R4+R5: Spawn periodic cleanup tasks for endpoint and login rate limiters

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 01:21:08 +00:00
DorianandClaude Opus 4.6 1d98de24d0 fix: WebSocket race conditions, Vue error handler, remove sudo podman, add container health checks
- F1: Guard connectWebSocket against concurrent calls with isWsConnecting flag
- F2: Serialize mesh send operations with sendQueue to prevent fetchMessages races
- F3: Add global Vue error handler with toast notification
- S1: Replace sudo podman with podman across all scripts (rootless Podman)
- S2: Add health-cmd to all 40 container run commands in first-boot-containers.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 01:11:05 +00:00
DorianandClaude Opus 4.6 b57ca4f171 fix: add health RPC handler, Nostr connect timeouts, atomic backup restore, nginx rate limits
- R1: Add health RPC endpoint with crash recovery status, uptime, and version
- R2: Wrap all 5 Nostr client.connect() calls in 10s timeout
- R3: Make backup restore atomic with staging dir and rollback on failure
- I1: Add rate limiting, body size, and proxy timeouts to unauthenticated nginx endpoints

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 01:02:16 +00:00
DorianandClaude Opus 4.6 9fc13f3079 fix: sync-aware UI for Bitcoin-dependent apps
AppDetails.vue now checks Bitcoin sync progress for LND, ElectrumX,
BTCPay, and Mempool. Shows orange warning banner with sync progress
bar and block height when Bitcoin is still syncing. Users see clear
feedback instead of broken wallet connect pages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:26:05 +00:00
DorianandClaude Opus 4.6 2295a34667 fix: LND and ElectrumX Tor onion address resolution
- lnd.rs: check tor-hostnames readable copy, then /var/lib/tor/, then
  legacy /var/lib/archipelago/tor/ with sudo fallback for each
- electrs_status.rs: same multi-path resolution for ElectrumX onion
- Both servers: created /var/lib/archipelago/tor-hostnames/ with readable
  copies of onion addresses (avoids sudo on every API call)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:31:30 +00:00
DorianandClaude Opus 4.6 6f5188ef7f fix: rpcauth credentials, reboot survival, system Tor for all containers
- Bitcoin RPC: switch to rpcauth (salted hash in bitcoin.conf, no plaintext
  in config or CLI). Password stable across reboots/restarts/deploys.
- Remove daily-reboot-test.sh cron on both servers
- Enable podman-restart.service for container auto-start after reboot
- System Tor: SocksPort 0.0.0.0:9050 with SocksPolicy for container access
- LND: tor.socks=host.containers.internal:9050 (system Tor, not container)
- Bitcoin: -proxy=host.containers.internal:9050 for Tor outbound
- bitcoin_rpc.rs: reads from secrets file, cached, stable credentials
- package.rs: dynamic rpc_user/rpc_pass, rpcauth hash generation
- network.rs: fix missing send_to_peer args (mesh encryption update)
- first-boot-containers.sh: rpcauth generation, system Tor config
- deploy-to-target.sh: rpcauth credentials, LND config migration
- Mesh: encrypted channel message support (ChaCha20-Poly1305 updates)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 11:56:20 +00:00
DorianandClaude Opus 4.6 adf0aa465f feat: reboot button in Settings with password confirmation
- system.reboot RPC endpoint requires password re-verification
- Uses systemd path unit pattern (tor-helper.sh) for privilege escalation
- 2-second delay before reboot to allow RPC response to reach client
- Clean UI: password input modal, loading state, error feedback

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:48:06 +00:00
DorianandClaude Opus 4.6 1f3c86687d refactor: PodmanClient uses REST API socket instead of CLI
Replace all `podman` CLI shell-outs with HTTP requests to the rootless
Podman API unix socket (/run/user/{UID}/podman/podman.sock).

Benefits:
- No process spawning overhead — direct HTTP over unix socket
- Structured JSON responses — no string parsing fragility
- Proper timeouts on all operations (5s connect, 30s default, 120s create)
- Health check method to verify socket availability
- Restart container as first-class operation

Still uses CLI for:
- Image pulls (streaming operation better suited to CLI)
- Container logs (raw text stream, not JSON)

The Podman socket is rootless (runs as archipelago user), local-only
(unix socket), and already behind our session auth in the backend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:13:49 +00:00
DorianandClaude Opus 4.6 1f81a0d804 feat: E2E encrypted Tor channel messages (ChaCha20-Poly1305)
Messages between federated nodes are now end-to-end encrypted:
- X25519 ECDH key agreement from existing ed25519 node identities
- HKDF-SHA256 key derivation with domain separation
- ChaCha20-Poly1305 authenticated encryption per message
- Random 12-byte nonce per message via OsRng (CSPRNG)
- Graceful fallback to plaintext if encryption fails
- Receiver auto-detects encrypted vs plaintext messages

The Tor transport was already encrypted (onion routing), this adds
application-layer E2E encryption so even a compromised receiving
backend can't read messages without the node's private key.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:04:43 +00:00
DorianandClaude Opus 4.6 3aa37137ed fix: persistent Tor channel messages, bulletproof Tor after deploys
- Messages persisted to disk (messages.json) — survive restarts
- Sent messages stored on backend via node-store-sent RPC
- Message deduplication (same pubkey + message within 30s)
- Max 200 messages in circular buffer
- Direction field (sent/received) for proper UI display
- Container doctor: prefer system Tor, remove archy-tor container
- Deploy torrc generator: read from tor-config/services.json,
  web apps map port 80→local port for clean .onion URLs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 08:26:40 +00:00
DorianandClaude Opus 4.6 cffcc9f665 fix: Tor management system, bug fixes, federation name sync
Major changes:
- Full Tor hidden service management via systemd path unit pattern
  (tor-helper.sh + archipelago-tor-helper.path/service) — respects
  NoNewPrivileges=yes, no sudo needed from backend
- Container doctor: prefer system Tor over container, remove archy-tor
- Deploy script: fix torrc generation (read correct services.json path),
  web apps map port 80→local port, enable both tor and tor@default
- Federation: server rename pushes name to peers via background sync
- Server name: fix root-owned file, optimistic store update
- Mesh: local echo for sent messages, sendingArch loading state
- Web5: Message button → Mesh redirect, node name lookup in messages
- PeerFiles: show DID not onion in header
- Connected Nodes: flex-1 instead of fixed max-h
- Toast notifications route to Mesh
- Deploy script: fix single-quote syntax in SSH block

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 02:59:29 +00:00
DorianandClaude Opus 4.6 f7872e2914 chore: session state save — active bugs and outstanding tasks documented
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:03:11 +00:00
DorianandClaude Opus 4.6 eb00d8f064 fix: file sharing path, Tor status consistency, Archipelago channel fixes
- ShareModal: strip leading / from filepath (was causing "absolute paths not allowed")
- Server.vue: Tor status in Local Network section now uses same source as header
- Both fixes needed for file sharing and Tor to work consistently

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:56:37 +00:00
DorianandClaude Opus 4.6 0de8b4f698 feat: Archipelago public channel (Tor), FileBrowser auto-login
Public Channel:
- "Archipelago" channel in Mesh — broadcasts to all federation peers over Tor
- Shows received messages from all peers with pubkey label
- Auto-polls every 15s for new messages
- Orange-branded channel icon with unread badge
- Send handler routes to Tor broadcast when arch channel is active

FileBrowser Auto-Login:
- All filebrowser-client methods now call ensureAuth() before requests
- Auto-authenticates with default credentials if not logged in
- Fixes "files don't work when FileBrowser hasn't been logged into"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:24:27 +00:00
DorianandClaude Opus 4.6 05dd851939 feat: Lightning channel backup, Web5 mobile tab active, file path fix
Task 14: Lightning Channel Backup
- New lnd.export-channel-backup RPC — exports SCB (Static Channel Backup)
- Settings UI: "Lightning Channel Backup" section with export + copy
- Returns base64 backup data, channel count, timestamp

Web5 mobile tab active state
- Fixed combined tab matching for Web5: includes /web5, /federation, /mesh routes
- Previously only matched /cloud and /server (wrong branch)

Content file path fix
- Allow forward slashes in filenames for subdirectories (Music/song.mp3)
- Still block .., \, null bytes, hidden files, absolute paths

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 21:47:18 +00:00
DorianandClaude Opus 4.6 f19ce148a6 fix: persist install progress across page navigation (Task 11)
Marketplace picks up in-progress installs from WebSocket store even
if install was started before page was opened. Removed nested .git.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 21:24:04 +00:00