Cold-start node picker: when more than one node is saved, launching the app asks which one to connect to instead of silently reusing the last. The gate is process-scoped (LaunchGate), so rotation and returns from background never re-ask — only a genuinely cold start does. Non-FIPS nodes no longer raise our tunnel. ServerEntry.isFipsNode() is true only for nodes that arrived from a FIPS-capable pairing QR (npub or mesh ULA). Android permits exactly one VPN at a time, so starting ours for a hand-entered LAN box would silently steal the tunnel from whatever the user actually uses to reach it. QR scanning rebuilt on the ZXing-Java pipeline — flat per-frame cost, ROI + half-frame coverage, AE fps floor, 1s AF auto-cancel, and the zoom hunt calmed down (step after 4s, hold >=6s, snap to 1x on decode, never zoom and refocus on the same tick). The old escalation-on-failure and one-shot AF lock are gone and should not return; the zxing-cpp alternative is written up in docs/ and deliberately not actioned. FipsManager.registerNode/autoStartIfReady now self-dispatch to IO. Both are reached from Compose scopes, and dlopening the 7 MB mesh core plus the VpnService.prepare binder hop were freezing the frame right after a pairing QR decoded — which read as a slow scanner when the scan had already succeeded. Roaming: WebViewScreen re-probes its origin on any transport change (1.5s debounce) and hops LAN <-> mesh, since SPA XHR/WS failures never fire onReceivedError and left the page on a dead 192.168.x.x origin. ArchyVpnService coalesces the warmer restart behind a 2s debounce so marginal Wi-Fi flapping stops triggering a warmer pass per flip. Do NOT switch that to registerDefaultNetworkCallback — the app routes through its own TUN, so its default network IS the VPN and the callback would fire once and never again. Typography moves to Montserrat (OFL notice included), with a new SlidingLoader and refreshed mesh loading + splash logo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Archipelago
Self-sovereign Bitcoin node OS and manifest-driven app platform.
Archipelago is a bootable personal server OS for Bitcoin infrastructure,
self-hosted apps, mesh communication, decentralized identity, and federation.
Apps are packaged as declarative manifest.yml files and run as rootless
Podman containers managed by the Rust backend.
What is here
core/- Rust workspace: backend API, container runtime, security, OpenWrt helpers, and performance/resource management.neode-ui/- Vue 3 + TypeScript frontend.apps/- app manifests and custom app container sources.docker/- supporting container build contexts for UI companion surfaces.image-recipe/- bootable image/ISO build inputs.Android/- Android companion app.scripts/- development, release, deployment, and validation tooling.docs/- architecture, app packaging, operations, API, and roadmap docs.
Platform model
Archipelago is built as a developer-ready app platform, not a fixed appliance:
- Apps are declared in
apps/<app-id>/manifest.yml. - The Rust parser in
core/container/src/manifest.rsis the canonical schema. - The orchestrator compiles manifests to rootless Podman/Quadlet runtime state.
- App data lives under
/var/lib/archipelago/<app-id>/. - Secrets are generated or read from
/var/lib/archipelago/secrets/and injected through Podman secrets rather than static environment values. - Release and app catalogs are signed and verified against a pinned trust anchor.
Start with:
- Architecture
- Developer Guide
- App Developer Guide
- App Manifest Spec
- Nostr Git Source Hosting Plan
- Troubleshooting
Quick start
Frontend
cd neode-ui
npm install
npm start
The dev UI runs at http://localhost:8100 with a mock backend on :5959.
Backend
cd core
cargo build
cargo test --all-features
Linux is the supported backend runtime and release-build target. macOS is fine for frontend work and many Rust compile/test loops, but host integration tests that touch Podman, systemd, networking, or image build paths require Linux.
App manifests
./scripts/validate-app-manifest.sh apps/filebrowser/manifest.yml
python3 scripts/generate-app-catalog.py
python3 scripts/check-app-catalog-drift.py --release --strict
scripts/generate-app-catalog.py requires Python with PyYAML installed.
Documentation map
The full, grouped index lives at docs/README.md. The most common entry points:
| Doc | Purpose |
|---|---|
| Architecture | System layers, crates, data paths, security model |
| Developer Guide | Local setup, code workflow, testing |
| API Reference | JSON-RPC API overview |
| App Developer Guide | How to package and test apps |
| App Manifest Spec | Manifest schema and validation rules |
| Nostr Git Source Hosting Plan | ngit/NIP-34 contribution workflow and maintainer model |
| Apps README | Packaged app catalog overview |
| Image Recipe | Bootable image build flow |
| Roadmap | Shipped, in-progress, and planned work |
| Archive | Historical plans, audits, and handoffs |
Contributing
Read CONTRIBUTING.md before opening a pull request. For security issues, follow SECURITY.md and do not open a public issue.
License
Archipelago is licensed under the MIT License. Third-party notices are listed in NOTICE and generated license inventories in component release artifacts.