Files
archy/.planning/PROJECT.md
T

116 lines
6.8 KiB
Markdown
Raw Normal View History

2026-07-29 10:45:57 -04:00
# 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
<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`.)
</decisions>
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*