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 documentation
Start here. This index groups the docs by what you're trying to do. The
authoritative behaviour is always the code in core/; where a doc and the code
disagree, the code wins and the doc is a bug.
Getting started
- User Walkthrough — setting up and using a node, from hardware to daily use
- Talking to your node — the conversational command surface
- Seed Verification — independently verify your 24-word backup
- Troubleshooting — common problems and how to resolve them
- Gamepad / Controller Navigation — driving the UI from a controller
- Pine voice commands — the voice-satellite phrase surface
Architecture
- Architecture — the system at a glance
- Multi-Node Architecture — how nodes relate across a fleet
- API Reference — the JSON-RPC surface
Contributing to Archipelago itself
- Developer Guide — building the workspace, the frontend, and an ISO
- Contributor guide (
CLAUDE.md) — invariants, build/verify, the production test gate - Bulletproof containers — why the reconciler is level-triggered
- Release signing runbook — the ceremony and key handling
- 1.8.0 Release Hardening Plan — the release-blocking checklist
- Third-party license audit — dependency licensing posture
- Demo build info — operating the public demo sandbox
App development
- App Developer Guide — build and package a containerized app
- App Manifest Specification — the manifest schema, field by field
- Manifest → Quadlet unit — how a manifest compiles to a systemd-owned container unit
- Container lifecycle — the reconciler state machine: install/adopt/start/stop/self-heal
- App secrets — declaring, generating and injecting per-install credentials
- Registry-Distributed Manifests — how manifests reach nodes via the signed catalog
- Decentralized Marketplace Protocol — publishing apps via an external registry
- Bitcoin RPC Relay — letting an external wallet reach the node's Bitcoin RPC
- Companion Pairing QR — the pairing handoff contract
- TV input inside iframe apps — keyboard/gamepad routing into embedded apps
Design docs
These record why a thing is built the way it is. They are design records, not step-by-step guides, and some predate the current implementation.
- Registry-Distributed Manifests
- DHT Distribution
- Bitcoin Multi-Version
- Dual Ecash
- Hardware Signer
- Manifest Hooks
- Meshroller Integration
- Nostr Git Source Hosting
- Nostr Identity Import · Nostr Signer Login (research)
- Streaming Ecash (phase 4)
- App Packaging Migration
Decisions (ADRs)
- ADR-001: Podman over Docker
- ADR-002: DID Key Method for Node Identity
- ADR-003: Nostr Relays for Discovery
- ADR-004: Tor Hidden Services for Peer Communication
- ADR-005: ChaCha20-Poly1305 for Backup Encryption
- ADR-006: Nostr Relays for Marketplace Discovery
- ADR-007: DID-Based Federation Trust
- ADR-008: Dual Key Strategy (Ed25519 + Secp256k1)
- ADR-009: Manifest-Level Container Security
- ADR-011: DWN Deprioritization
There is no ADR-010 — the number was never issued, so the gap is not a missing file.
Security
- Security Policy — how to report a vulnerability
- PSBT Signing Architecture
- Bitcoin RPC Proxy Exposure
- Entropy Enforcement (KEY-05)