6.8 KiB
Archipelago
What This Is
Archipelago is a self-hosted personal-server platform: a Rust daemon (workspace at core/)
plus a Vue 3 frontend (neode-ui/, built to web/dist/neode-ui/) running on Debian nodes
with rootless Podman, managing ~40 declarative, manifest-driven apps (Bitcoin, Lightning,
mesh/LoRa, federation, media, and more). It ships as OTA-updated releases to a live fleet
and is actively shipping v1.7.x alpha releases. This milestone drives it to the
developer-ready app platform north star.
Core Value
A third-party developer can publish an app via the signed/decentralized registry and a user can install it on their node — every app manifest-driven, manifests shipped via the signed registry (not OTA disk files), all rootless, secure, robust, and 100%-uptime-capable.
Current State (brownfield baseline, 2026-07-29)
- Single-node production gate is GREEN (5/5 on .228, 2026-06-23) — that exit criterion is met.
- ~40 apps are manifest-based and Quadlet-migrated; all multi-container stacks use the orchestrator stack pattern; the legacy per-app installer anti-pattern is deleted.
- Workstream B (registry-distributed manifests) phases 1+2 are code-complete; the signing
ceremony is done (release-root pinned in
anchor.rs); the fleet flip is not yet authorized. - Workstream C (marketplace) is design-only (
docs/marketplace-protocol.md); no tooling or trust UX built. Developer CLI suite (archy app …) does not exist yet. - Phase-3 Quadlet default-flip is validated opt-in on .228/.198 but not default.
- Declared next exit criteria: the multinode pass (
docs/multinode-testing-plan.md) and the remaining workstreams.
Requirements
Validated
- ✓ Single-node lifecycle gate green 5× on .228 (install/UI/stop/start/restart/reinstall/ reboot-survive/daemon-restart-survive/uninstall) — 2026-06-23
- ✓ Manifest-driven app packaging for all ~40 apps incl. multi-container stacks (workstream A)
- ✓ Signed catalog + release-root signing ceremony (workstream B phases 1+2, code-complete)
Active
See .planning/REQUIREMENTS.md — 20 v1 requirements across MNODE / LIFE / REG / SEC / DEV / MKT,
all mapped to phases in .planning/ROADMAP.md.
Out of Scope
- Rootful containers, Docker, privileged containers — invariant (ADR-001/ADR-009)
- Per-app Rust installers / OS-level provisioning — the anti-pattern being deleted
- Centralized gatekept app store — decentralized Nostr marketplace instead (ADR-006)
- Web5 DWN spec compliance — deprioritized after TBD shutdown (ADR-011)
- Custom live voice-call protocol — deprioritized per user 2026-07-01; revisit later
- DHT/iroh distribution backbone (workstream D) — design-only, tracker-marked backlog; v2
Context
- Repo:
core/Rust workspace (no root Cargo.toml),neode-ui/Vue frontend,apps/manifests,tests/lifecycle/+tests/multinode/gates,docs/authoritative plans. - Authoritative narrative:
docs/PRODUCTION-MASTER-PLAN.md; day-to-day open list:docs/UNIFIED-TASK-TRACKER.md. Codebase map:.planning/codebase/ARCHITECTURE.md+.planning/codebase/CONCERNS.md. - Known debt informing this milestone (from CONCERNS.md): federation tombstone-write errors swallowed; reconciler has no flap observability and no failed-unit self-healing; generated AppArmor profiles are never applied; multinode test harness curl calls lack timeouts; SPEC validation is narrower than ADR-009's mandates (non-root UID, pinned tags, seccomp).
- Fleet is live and OTA-updated; all destructive verification happens on designated test nodes per the deploy roster — never uninvited on in-use nodes.
Constraints
- Security: Rootless Podman only; manifest-declared secrets (0600, never logged); mandatory container security defaults enforced at manifest level (ADR-009)
- Data safety: Migrations never destroy data — preserve
/var/lib/archipelago/<app>, secrets, credentials, ports, adoption container names; always a rollback path - Verification: Real-node verification before any tag; lifecycle gate runs ON the node, not via RPC; mesh changes need real-RF E2E tests; re-run the gate after orchestrator changes
- Process: Commit + push every unit of work (
git push gitea-ai main); stage by explicit path; deploy to the dev pair before any OTA; never commit secrets - Tech stack: Rust (Tokio/Hyper, JSON-RPC 2.0) backend; Vue 3 + Pinia frontend; Quadlet/systemd-user container units; Ed25519-signed release artifacts
Key Decisions
All ten ADRs below are locked (Status: Accepted; ingest source docs/adr/*.md). They are
non-negotiable inputs to planning and cannot be overridden without a new ADR.
| ID | Decision | Scope |
|---|---|---|
| ADR-001 | Podman over Docker — rootless, daemonless, systemd-native; archy-net for inter-container DNS |
Container runtime |
| ADR-002 | did:key (Ed25519) node identity — self-contained, offline-capable; gaps mitigated via federation trust lists |
Identity |
| ADR-003 | Nostr relays (NIP-78, kind 30078) for node + app discovery — multi-relay query, 15-min cache, trust scoring, Tor-compatible | Discovery |
| ADR-004 | Tor hidden services for inter-node RPC/control plane — bulk data via registries, not Tor | Federation transport |
| ADR-005 | ChaCha20-Poly1305 + Argon2id (64MB, 3 iter) for backup encryption | Backups |
| ADR-006 | Nostr relays for marketplace discovery — DID-signed manifests, trust tiers (Verified/Community/Unverified), signature verification before install | Marketplace |
| ADR-007 | Bilateral DID federation trust via single-use invite codes; Trusted/Observer/Untrusted levels | Federation trust |
| ADR-008 | Dual keys from one master seed — Ed25519 canonical identity, secp256k1 for Nostr/Bitcoin/Lightning, linked via NIP-05 | Keys |
| ADR-009 | Manifest-level container security enforcement — readonly_root, no_new_privileges, non-root UID, drop-ALL caps, pinned tags, seccomp; overrides explicit + audited | Container security |
| ADR-011 | DWN deprioritized — keep custom dwn_store.rs, stop branding as Web5, invest in Nostr + Tor federation instead |
Peer data sync |
(ADR-010 does not exist in the repo — numbering gap, noted in .planning/INGEST-CONFLICTS.md.)
Milestone-level decisions:
| Decision | Rationale | Outcome |
|---|---|---|
| Milestone version = 1.8.0-alpha | Decided 2026-07-08 per tracker | — Pending ship |
| Workstream D (DHT) deferred to v2 | Design-only, tracker-marked backlog; not needed for north-star metric | — Pending |
App manifest canonical schema = core/container/src/manifest.rs |
SPEC self-declares code wins over doc | ✓ Good |
| Phase-3 Quadlet flip gated on multinode gate reporting clean | Prior uncommitted-flip confusion; flip fresh as a 2-line change when gate is clean | — Pending |
Last updated: 2026-07-29 after intel ingest (10 ADRs + 1 SPEC) + codebase mapping