Formal gate take-2 went 4/5: iteration 5's vaultwarden stop-wait saw 'restarting' for the full 120s window. A reconcile pass had queued every app into pending_boot_starts moments before the stop marker landed, and the scanner's overlay painted the deliberately-stopped app Restarting until the slow sequential pass reached it (legacy container, so no unit state to contradict it). Two filters: the scanner overlay skips user-stopped ids (the marker is written before the stop runs, so it's reliably present), and the reconciler no longer queues apps whose lifecycle op is in flight into the pending overlay (it skips them via the same probe anyway). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Archipelago
Self-Sovereign Bitcoin Node OS
Archipelago is a bootable personal server OS. Flash it to a USB drive, install on any x86_64 or ARM64 machine, and manage Bitcoin infrastructure, self-hosted apps, mesh communication, and decentralized identity through a glassmorphism web UI.
Philosophy
Archipelago is being built as a developer-ready app platform, not a fixed appliance:
- Manifest-driven apps. Every app is declared in a single
manifest.yml— image, ports, volumes, secrets, health checks, security policy. The orchestrator owns the entire lifecycle; there is no per-app installer code and no host-level provisioning. - Signed distribution. App manifests ship inside an Ed25519-signed catalog verified against a pinned release-root key, not as loose files on disk. OTA release manifests are signed the same way.
- Decentralized marketplace. Third-party developers publish apps via Nostr-based discovery (NIP-78) with DID-signed manifests and federation-weighted trust scoring — no gatekept central store.
- Rootless and secure by default. Rootless Podman only. Read-only root, no-new-privileges, capability allow-list, secrets materialised 0600 and never logged. Never rootful, never a Docker socket mount.
- 100%-uptime-capable. Every container is a systemd Quadlet unit under
user.slicethat survives backend restarts; a level-triggered reconciler self-heals drift every 30 seconds; migrations never destroy data.
Features
Bitcoin Infrastructure
- Bitcoin Core and Bitcoin Knots full nodes with per-app version pinning and bulletproof version switching, automatic prune/full mode based on disk size
- LND and Core Lightning with channel management
- ElectrumX Electrum server for wallet connectivity
- BTCPay Server for accepting Bitcoin payments
- Mempool block explorer and fee estimator
- Fedimint federation guardian, gateway, and client — plus Cashu ecash wallet support
Self-Hosted Apps (50+)
Storage (FileBrowser, Immich, Nextcloud), Productivity (Vaultwarden), Media (Jellyfin, PhotoPrism, IndeeHub), Search (SearXNG), Network (NetBird, Tailscale), Home (Home Assistant), Nostr (nostr-rs-relay, strfry), Dev/Ops (Gitea, Grafana, Portainer, Uptime Kuma), and more — 27 curated in the store UI, 50+ packaged as manifests.
Mesh Networking (tri-protocol)
- Meshtastic, MeshCore, and Reticulum (RNS/LXMF) LoRa transports behind one mesh chat UI
- End-to-end encryption with X3DH key agreement + double-ratchet
- RNode radio support with an OS-level
archy-rnodeconftool; interop verified against Sideband - Image/voice attachments, mesh AI assistant (
!ai), Bitcoin balance relay over mesh
Decentralized Identity
- Ed25519 node identity with DID Documents (did:key)
- Multi-identity management (Personal/Business/Anonymous)
- W3C Verifiable Credentials issuance and verification
- Nostr integration: NIP-33 node discovery, NIP-44/NIP-04 encryption, NIP-07 signer bridge for iframe apps, relay hosting
- Decentralized Web Node (DWN) record sync between federated nodes over Tor
Multi-Node Federation
- Invite-based node joining over Tor hidden services
- Trust levels (Trusted/Verified/Untrusted) with DID-based auth
- State sync and app deployment across federated nodes
- File sharing with access controls (free/peers-only/paid via Lightning, on-chain, or ecash)
System Updates
- OTA updates from a self-hosted Gitea release server, Ed25519-signature-verified against a pinned release-root key
- Resumable downloads, automatic pre-update backup, rollback with a post-update self-verify window
- Manual, scheduled-check, and auto-apply modes (auto-apply refuses unsigned manifests)
Security
- Argon2id password hashing (transparent upgrade from legacy hashes), ChaCha20-Poly1305 encrypted secrets at rest
- Rootless Podman: read-only root, cap-drop ALL with a reviewed allow-list, no-new-privileges
- Signed release manifests and signed app catalog (Ed25519, pinned trust anchor)
- TOTP two-factor authentication, per-endpoint rate limiting, CSRF protection
- AppArmor profiles for container confinement; Tor hidden services for inter-node traffic
- Independent security audit of an early version archived in
docs/archive/; top findings since remediated
Roadmap
Done
- Single-node production gate green — install / stop / start / restart / reinstall / reboot-survive / uninstall, 5 consecutive full runs with zero failures on real hardware
- Quadlet migration validated (all backends as
user.sliceservices on the canary node) - Release signing ceremony completed — release-root key pinned, catalog and OTA manifests signed
- Reticulum third mesh transport (real-RF LoRa gates passed), Bitcoin Core/Knots multi-version switching, decentralized marketplace backend, public demo
In progress
- Multinode pass: the same production gate across the whole test fleet (
docs/multinode-testing-plan.md) - Quadlet default flip fleet-wide + container-flapping elimination
- 1.8.0 release hardening tail (
docs/1.8.0-RELEASE-HARDENING-PLAN.md): OTA upgrade soak on real hardware, ISO/image hardening (per-device keys, no default creds, signed ISO)
Planned
- Developer CLI (
archy app validate/render/install/test) to open third-party app publishing - External marketplace trust UX + publishing tooling (
docs/marketplace-protocol.md) - DHT/P2P distribution of releases and app images (
docs/dht-distribution-design.md) - P2P encrypted voice/video over Tor, dual-ecash (Fedimint + Cashu) phases, paid streaming, hardware signer support
The live, priority-ordered task list is docs/UNIFIED-TASK-TRACKER.md; the full narrative plan is docs/PRODUCTION-MASTER-PLAN.md.
Quick Start
Install from ISO
- Build or download the ISO for your architecture (x86_64 or ARM64) — see
image-recipe/ - Flash to USB drive with Balena Etcher or
dd - Boot from USB on target hardware and follow the automated installer
- Access the web UI at
http://<device-ip> - Set your password and complete the onboarding wizard (seed backup, DID identity)
Supported Hardware
| Platform | Examples | Minimum |
|---|---|---|
| x86_64 | Intel NUC, mini PCs, any 64-bit PC | 4GB RAM, 32GB storage |
| ARM64 | Raspberry Pi 5, ARM64 SBCs | 4GB RAM, 32GB storage |
Recommended: 8GB+ RAM, 1TB+ NVMe SSD (for a full Bitcoin node). Optional: an RNode-compatible LoRa radio for mesh networking.
Development
Prerequisites
- macOS or Linux for frontend development
- Linux dev server (Debian 13) for backend builds — never build Rust on macOS for Linux
- Node.js 20+, Rust stable toolchain
Frontend Development
cd neode-ui
npm install
npm start # Dev server on http://localhost:8100 (mock backend on :5959)
npm run type-check # TypeScript validation
npm run build # Production build → web/dist/neode-ui/
Backend Development
cd core # Rust workspace root (no Cargo.toml at repo root)
cargo build
cargo test
Deploy to a Test Node
./scripts/deploy-to-target.sh --live # Deploy to primary dev server
./scripts/deploy-to-target.sh --both # Deploy to both LAN servers
Release (tarball-only)
Releases ship as a backend binary and a frontend tarball referenced by
releases/manifest.json, published to the self-hosted Gitea release server.
./scripts/create-release.sh 1.2.3
git push origin main --tags
Architecture
Debian 13 (Trixie)
├── Rootless Podman — every app a systemd Quadlet unit under user.slice
├── Nginx (reverse proxy, security headers, rate limiting)
├── Rust Backend (JSON-RPC API on 127.0.0.1:5678, ~380 RPC methods)
│ ├── core/archipelago/ — API, orchestrator + reconciler, mesh, identity,
│ │ federation, wallet, updates, marketplace
│ ├── core/container/ — Podman client, manifest schema, Quadlet compiler,
│ │ health monitor, signed app catalog
│ ├── core/security/ — AppArmor/seccomp policy, secrets manager
│ ├── core/openwrt/ — TollGate gateway provisioning (SSH/UCI)
│ └── core/performance/ — resource limits
├── Vue 3 Frontend (Composition API + TypeScript strict + Pinia + Tailwind, PWA)
│ └── Three UI modes (Pro/Easy/Chat) + gamepad navigation + i18n
├── Reticulum daemon (supervised Python/PyInstaller, one per LoRa radio)
└── System Tor (hidden services, SOCKS5 proxy)
~117,000 lines of Rust | ~69,000 lines of TypeScript/Vue | 51 packaged apps | Android companion app
Documentation
| Doc | Purpose |
|---|---|
| Architecture | System design, crate map, data paths |
| Developer Guide | Dev setup, workflow, code conventions |
| API Reference | RPC endpoint reference |
| App Developer Guide | Building and publishing apps |
| App Manifest Spec | The manifest.yml schema |
| User Walkthrough | End-user installation and usage guide |
| Troubleshooting | Diagnostic scenarios and solutions |
| Operations Runbook | Ops commands and emergency recovery |
| Production Master Plan | North star and workstream narrative |
| Unified Task Tracker | Live, priority-ordered open items |
| Test Gate | Production lifecycle test gate (definition of done) |
| Archive | Historical audits, session logs, shipped designs |
Contributing
- Fork the repository
- Create a feature branch (
feature/description) - Follow the coding standards in CONTRIBUTING.md and CLAUDE.md
- Submit a pull request
License
Acknowledgments
Built with: Rust, Vue.js, Podman, Bitcoin Core, LND, Reticulum, Debian