2026-03-27 12:03:04 +00:00
# CLAUDE.md — Archipelago (Archy)
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
## Overview
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
Archipelago is a **Bitcoin Node OS** — bootable, self-sovereign personal server. Flash to USB, install on hardware, manage via web UI.
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
**Stack**: Rust backend + Vue 3 + TypeScript (strict) + Vite 7 + Tailwind + Pinia + Podman on Debian 12
2026-04-02 01:28:11 +01:00
**Version**: 1.3.0 | **Target** : x86_64 and ARM64
2026-03-04 05:23:42 +00:00
feat: rootless podman, session hardening, boot stability, sidebar fix
Rootless podman migration (TASK-11):
- Remove sudo from all podman calls in PodmanClient + 8 backend files
- Remove sudo from all podman/docker calls in deploy script
- Restore full systemd security hardening: NoNewPrivileges,
RestrictAddressFamilies, MemoryDenyWriteExecute, RestrictRealtime,
RestrictNamespaces, RestrictSUIDSGID, SystemCallFilter, ProtectSystem=strict
- Enable loginctl linger for rootless container persistence
- Remove Ollama from auto-deploy (marketplace-only)
Session & auth hardening:
- Increase MAX_CONCURRENT_SESSIONS 20→50 (prevents eviction storms)
- Debounced 401 redirect in rpc-client.ts (prevents redirect storms)
Boot stability:
- optimize-debian.sh: adds chrony, swap, removes policy-rc.d
- deploy script: pre-restart chrony + swap setup
- ISO build: chrony package, swap file creation
- BootScreen: no longer clears localStorage (prevents splash replay)
- RootRedirect: sole owner of localStorage clearing on server ready
UI fixes:
- Sidebar opacity default changed from 0→visible (fixes missing sidebar
after page-persistence login without entrance animation)
- Console.log/error wrapped in import.meta.env.DEV guards
- Remove unused route import from RootRedirect
Beta tracking:
- CLAUDE.md: beta freeze protocol added
- MASTER_PLAN.md: TASK-11, TASK-17, phase structure
- BETA-PROGRESS.md: initial tracking doc
- Tagged v1.2.0-alpha.1 as pre-rootless baseline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 13:53:27 +00:00
---
2026-03-27 12:03:04 +00:00
## Beta Freeze (2026-03-18)
feat: rootless podman, session hardening, boot stability, sidebar fix
Rootless podman migration (TASK-11):
- Remove sudo from all podman calls in PodmanClient + 8 backend files
- Remove sudo from all podman/docker calls in deploy script
- Restore full systemd security hardening: NoNewPrivileges,
RestrictAddressFamilies, MemoryDenyWriteExecute, RestrictRealtime,
RestrictNamespaces, RestrictSUIDSGID, SystemCallFilter, ProtectSystem=strict
- Enable loginctl linger for rootless container persistence
- Remove Ollama from auto-deploy (marketplace-only)
Session & auth hardening:
- Increase MAX_CONCURRENT_SESSIONS 20→50 (prevents eviction storms)
- Debounced 401 redirect in rpc-client.ts (prevents redirect storms)
Boot stability:
- optimize-debian.sh: adds chrony, swap, removes policy-rc.d
- deploy script: pre-restart chrony + swap setup
- ISO build: chrony package, swap file creation
- BootScreen: no longer clears localStorage (prevents splash replay)
- RootRedirect: sole owner of localStorage clearing on server ready
UI fixes:
- Sidebar opacity default changed from 0→visible (fixes missing sidebar
after page-persistence login without entrance animation)
- Console.log/error wrapped in import.meta.env.DEV guards
- Remove unused route import from RootRedirect
Beta tracking:
- CLAUDE.md: beta freeze protocol added
- MASTER_PLAN.md: TASK-11, TASK-17, phase structure
- BETA-PROGRESS.md: initial tracking doc
- Tagged v1.2.0-alpha.1 as pre-rootless baseline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 13:53:27 +00:00
2026-03-27 12:03:04 +00:00
**Phase 1: Feature Testing (internal) — WE ARE HERE**
feat: rootless podman, session hardening, boot stability, sidebar fix
Rootless podman migration (TASK-11):
- Remove sudo from all podman calls in PodmanClient + 8 backend files
- Remove sudo from all podman/docker calls in deploy script
- Restore full systemd security hardening: NoNewPrivileges,
RestrictAddressFamilies, MemoryDenyWriteExecute, RestrictRealtime,
RestrictNamespaces, RestrictSUIDSGID, SystemCallFilter, ProtectSystem=strict
- Enable loginctl linger for rootless container persistence
- Remove Ollama from auto-deploy (marketplace-only)
Session & auth hardening:
- Increase MAX_CONCURRENT_SESSIONS 20→50 (prevents eviction storms)
- Debounced 401 redirect in rpc-client.ts (prevents redirect storms)
Boot stability:
- optimize-debian.sh: adds chrony, swap, removes policy-rc.d
- deploy script: pre-restart chrony + swap setup
- ISO build: chrony package, swap file creation
- BootScreen: no longer clears localStorage (prevents splash replay)
- RootRedirect: sole owner of localStorage clearing on server ready
UI fixes:
- Sidebar opacity default changed from 0→visible (fixes missing sidebar
after page-persistence login without entrance animation)
- Console.log/error wrapped in import.meta.env.DEV guards
- Remove unused route import from RootRedirect
Beta tracking:
- CLAUDE.md: beta freeze protocol added
- MASTER_PLAN.md: TASK-11, TASK-17, phase structure
- BETA-PROGRESS.md: initial tracking doc
- Tagged v1.2.0-alpha.1 as pre-rootless baseline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 13:53:27 +00:00
2026-03-27 12:03:04 +00:00
Feature set is LOCKED. Only: bug fixes, security hardening, ISO build fixes, UI polish, testing.
No new features, no new apps, no new deps, no scope creep.
feat: rootless podman, session hardening, boot stability, sidebar fix
Rootless podman migration (TASK-11):
- Remove sudo from all podman calls in PodmanClient + 8 backend files
- Remove sudo from all podman/docker calls in deploy script
- Restore full systemd security hardening: NoNewPrivileges,
RestrictAddressFamilies, MemoryDenyWriteExecute, RestrictRealtime,
RestrictNamespaces, RestrictSUIDSGID, SystemCallFilter, ProtectSystem=strict
- Enable loginctl linger for rootless container persistence
- Remove Ollama from auto-deploy (marketplace-only)
Session & auth hardening:
- Increase MAX_CONCURRENT_SESSIONS 20→50 (prevents eviction storms)
- Debounced 401 redirect in rpc-client.ts (prevents redirect storms)
Boot stability:
- optimize-debian.sh: adds chrony, swap, removes policy-rc.d
- deploy script: pre-restart chrony + swap setup
- ISO build: chrony package, swap file creation
- BootScreen: no longer clears localStorage (prevents splash replay)
- RootRedirect: sole owner of localStorage clearing on server ready
UI fixes:
- Sidebar opacity default changed from 0→visible (fixes missing sidebar
after page-persistence login without entrance animation)
- Console.log/error wrapped in import.meta.env.DEV guards
- Remove unused route import from RootRedirect
Beta tracking:
- CLAUDE.md: beta freeze protocol added
- MASTER_PLAN.md: TASK-11, TASK-17, phase structure
- BETA-PROGRESS.md: initial tracking doc
- Tagged v1.2.0-alpha.1 as pre-rootless baseline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 13:53:27 +00:00
2026-03-27 12:03:04 +00:00
Track: `docs/BETA-PROGRESS.md` | Checklist: `docs/BETA-RELEASE-CHECKLIST.md`
feat: rootless podman, session hardening, boot stability, sidebar fix
Rootless podman migration (TASK-11):
- Remove sudo from all podman calls in PodmanClient + 8 backend files
- Remove sudo from all podman/docker calls in deploy script
- Restore full systemd security hardening: NoNewPrivileges,
RestrictAddressFamilies, MemoryDenyWriteExecute, RestrictRealtime,
RestrictNamespaces, RestrictSUIDSGID, SystemCallFilter, ProtectSystem=strict
- Enable loginctl linger for rootless container persistence
- Remove Ollama from auto-deploy (marketplace-only)
Session & auth hardening:
- Increase MAX_CONCURRENT_SESSIONS 20→50 (prevents eviction storms)
- Debounced 401 redirect in rpc-client.ts (prevents redirect storms)
Boot stability:
- optimize-debian.sh: adds chrony, swap, removes policy-rc.d
- deploy script: pre-restart chrony + swap setup
- ISO build: chrony package, swap file creation
- BootScreen: no longer clears localStorage (prevents splash replay)
- RootRedirect: sole owner of localStorage clearing on server ready
UI fixes:
- Sidebar opacity default changed from 0→visible (fixes missing sidebar
after page-persistence login without entrance animation)
- Console.log/error wrapped in import.meta.env.DEV guards
- Remove unused route import from RootRedirect
Beta tracking:
- CLAUDE.md: beta freeze protocol added
- MASTER_PLAN.md: TASK-11, TASK-17, phase structure
- BETA-PROGRESS.md: initial tracking doc
- Tagged v1.2.0-alpha.1 as pre-rootless baseline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 13:53:27 +00:00
---
2026-03-04 05:23:42 +00:00
## Quick Reference
```bash
2026-03-27 12:03:04 +00:00
cd neode-ui & & npm start # Local dev (mock backend :5959, Vite :8100)
cd neode-ui & & npm run build # Build (outputs to web/dist/neode-ui/)
./scripts/deploy-to-target.sh --live # Deploy to live server (.228)
2026-03-04 05:23:42 +00:00
```
2026-03-27 12:03:04 +00:00
## Infrastructure
| What | Where |
|------|-------|
| Dev server | `192.168.1.228` (SSH key: `~/.ssh/archipelago-deploy` ) |
| Secondary | `192.168.1.198` |
| Git remote | `git.tx1138.com` (remote name: `tx1138` ) |
| App registry | `80.71.235.15:3000/archipelago/` (HTTP, insecure) |
| CI runner | act_runner on .228, workflow: `.gitea/workflows/build-iso.yml` |
| ISO builds | FileBrowser at `http://192.168.1.228:8083` → Builds/ |
| SSH creds | Gitignored `scripts/deploy-config.sh` |
| Web password | `password123` |
2026-03-04 05:23:42 +00:00
## Architecture
```
2026-03-27 12:03:04 +00:00
Debian 12
├── Podman (rootless, user archipelago)
├── Nginx (80/443 → backend, app proxies)
├── Rust Backend (core/) on 127.0.0.1:5678
│ ├── core/archipelago/ — Binary, RPC, auth, sessions
│ └── core/container/ — PodmanClient, manifests, health
2026-03-04 05:23:42 +00:00
└── Vue.js UI (neode-ui/)
2026-03-27 12:03:04 +00:00
├── src/api/rpc-client.ts — All backend communication
├── src/stores/ — Pinia state
├── src/views/ — Pages
└── src/style.css — ALL styling (global classes only)
2026-03-04 05:23:42 +00:00
```
2026-03-27 12:03:04 +00:00
**Data paths**: `/var/lib/archipelago/{app-id}/` (data), `/opt/archipelago/web-ui/` (frontend), `/usr/local/bin/archipelago` (binary)
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
## Critical Rules
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
1. **Never build Rust on macOS** — deploy script handles cross-compilation via rsync + remote build
2. **Always deploy after changes** — `./scripts/deploy-to-target.sh --live`
3. **Frontend builds to `web/dist/neode-ui/`** — not `neode-ui/dist/`
4. **Container images** : `scripts/image-versions.sh` is the single source of truth. All scripts use `$*_IMAGE` variables, never hardcoded registry paths.
5. **Type-check before committing** — `cd neode-ui && npx vue-tsc -b --noEmit`
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
## Frontend
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
- `<script setup lang="ts">` always — no Options API
- Global CSS in `style.css` — **never inline Tailwind**
- `.glass-button` for ALL buttons — `.gradient-button` is BANNED
- `.glass-card` for containers, `.path-option-card` for interactive cards
- `translateZ(0)` + `isolation: isolate` on glass elements (Chromium compositor fix)
- Pinia for state, typed RPC client, handle loading/error/empty states
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
## Backend (Rust)
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
- No `unwrap()` /`expect()` — use `?` with `.context()`
- `tracing` for logging, never `println!` or log secrets
- Backend binds `127.0.0.1` only — nginx handles external access
- Validate all input before path construction — reject `..` , `/` , null bytes
- `tokio` runtime, timeouts on all external ops
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
## Security (Post-Pentest)
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
- RBAC: explicit method allowlists, never prefix matching
- Session cookies: `SameSite=Lax; HttpOnly; Path=/`
- Rate-limit auth endpoints, rotate tokens after privilege escalation
- Validate redirect URLs with `isLocalRedirect()` , never `v-html` with user input
- Container security: drop ALL caps, add only required, `no-new-privileges` , memory limits, health checks
- See `.claude/rules/` for detailed crypto, API, container, and Bitcoin rules
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
## ISO Build & CI
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
CI builds on every push to `main` via git.tx1138.com Actions.
2026-03-04 05:23:42 +00:00
```bash
2026-03-27 12:03:04 +00:00
# Manual build on .228:
ssh archipelago@192 .168.1.228
cd ~/archy/image-recipe
sudo UNBUNDLED=1 DEV_SERVER=localhost BUILD_FROM_SOURCE=0 ./build-auto-installer-iso.sh
2026-03-04 05:23:42 +00:00
```
2026-03-27 12:03:04 +00:00
**Debugging fresh installs** — SSH in and check:
```bash
cat /var/log/archipelago-install.log # Full installer output
cat /var/log/archipelago-first-boot-diagnostics.log # Service status, nginx, LUKS, etc.
sudo archipelago-diagnostics # Re-run diagnostics anytime
2026-03-04 05:23:42 +00:00
```
2026-03-27 12:03:04 +00:00
**Kiosk**: X11 on VT7, console on VT1. `Ctrl+Alt+F1` for terminal, `Ctrl+Alt+F7` for kiosk.
Toggle: `sudo archipelago-kiosk enable|disable|toggle`
2026-03-04 05:23:42 +00:00
## App Integration Checklist
2026-03-27 12:03:04 +00:00
When adding/fixing apps, check ALL of these:
- `core/archipelago/src/api/rpc/package/` — config, capabilities, deps
- `neode-ui/src/views/marketplace/marketplaceData.ts` — marketplace entry
- `image-recipe/configs/nginx-archipelago.conf` — proxy rules (HTTP + HTTPS)
- `scripts/image-versions.sh` — pinned image version
- `scripts/first-boot-containers.sh` — first boot creation
- `scripts/deploy-to-target.sh` — deploy logic
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
## Git
2026-03-04 05:23:42 +00:00
2026-03-27 12:03:04 +00:00
Commits: `type: description` (`feat:` , `fix:` , `docs:` , `refactor:` , `test:` , `chore:` , `perf:` )
Push to: `git push tx1138 main`