archy/.planning/REQUIREMENTS.md
archipelago 1d6b6c22c1 docs(02-10): three-way timing verdict for verification gap 2's six named surfaces
- New `## Re-measurement (gap closure)` section in 02-FINDINGS.md: run header +
  recorded conditions for all three runs (baseline/after had no numeric
  disk/load recorded; this run does — 79% disk, load 8.70-11.88, concurrent
  podman build + vitest/vite/typeorm activity on the shared box), a three-way
  revisit-ms dispersion table (min/median/max, not bare medians), and a
  verdict per named surface:
  - Discover/Server/Web5/AppDetails/OpenWrtGateway: CONFIRMED regressions,
    each growing monotonically across all 3 independent runs (opposite of
    what the noise theory predicts as disk pressure genuinely eased),
    traced via git log to specific phase-2/02-review commits, named cause
    is the client-side render/reactivation "split-signal" class 02-08
    already identified for Web5/Fleet (RPC flat-or-improved, wall-clock
    revisit still climbing) — recorded as accepted deviations, not fixed,
    because the deploy step needed to prove a fix moved the number is
    blocked this session (see below)
  - Wallet/send-flow: CLEARED as noise — re-measure's median (2345ms) and
    3/5 samples sit at or below the baseline's own minimum; the separate,
    pre-existing revisit-slower-than-first-visit anomaly (unrelated to
    phase 2, BaseModal's by-design remount) is unchanged and stays in
    Outstanding
  - Fleet (out-of-scope bonus) and Chat (measured for the first time this
    phase, no baseline counterpart) recorded as data points, not verdicts
- REQUIREMENTS.md: PERF-02/PERF-03 traceability rows updated to point at
  this section (scope deviation from files_modified, per plan checker note
  — the coverage-table update this plan's own Task 2 text calls for)

Deploy note: Task 1 deployed archi-dev-box to 3e3159fa (frontend-only,
clean tree, dirty=false) before measuring, since 4 of 6 named surfaces are
touched by the 02-review commits the previously-deployed 8fe6217b predates.
Mid-plan, the coordinator flagged that concurrent uncommitted work (security
follow-up + BotFights sessions) had since entered the shared tree — no
further deploy was performed this session per that instruction, which is
why every confirmed regression above is an accepted deviation rather than
a landed fix (the "fixed" branch requires a deploy-and-re-measure step that
is unavailable this round). `neode-ui/e2e/perf/02-REVIEW.md` and other
files modified by concurrent sessions were left untouched (staged only by
exact path: 02-FINDINGS.md, REQUIREMENTS.md).

Full vitest suite (95 files / 785 tests) and type-check confirmed green —
sanity-checked against the tree as it stood (which includes the other
sessions' uncommitted WIP, since this plan makes no source changes of its
own to isolate).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 06:53:59 -04:00

12 KiB
Raw Blame History

Requirements: Archipelago (v1.8.0 — Developer-Ready App Platform)

Defined: 2026-07-29 Core Value: A third-party developer can publish an app via the signed/decentralized registry and a user can install it on their node — manifest-driven, rootless, secure, robust.

No PRDs existed in the ingest set; these requirements are derived from the master plan's declared exit criteria (multinode pass + workstreams B/C/F), .planning/codebase/CONCERNS.md, docs/UNIFIED-TASK-TRACKER.md, and the user-chosen success metric. Constraints from docs/app-manifest-spec.md and the locked ADRs (see PROJECT.md) bound how each is built.

v1 Requirements

Federation & Mesh Hardening (FED)

  • FED-01: Removing a federation node sticks — it disappears from every UI surface, tombstones propagate, it never reappears via later sync cycles, and a failed removal surfaces an error (never a silent no-op)
  • FED-02: Federation sync converges and is observable — after sync settles, fleet nodes agree on the node list with fresh status; stale entries, duplicates, and silent sync failures are eliminated and sync errors are operator-visible
  • FED-03: A structured code review of the federation/fleet area (core/archipelago/src/federation, node sync, FIPS/transport dial layer) and mesh area (core/archipelago/src/mesh, mesh RPC surface) is completed, with every finding fixed or explicitly deferred with a reason
  • FED-04: Mesh messaging parity — attachment send (and the rest of the mesh chat surface) behaves identically on the demo and on real nodes: the demo backend implements the same RPC surface the UI calls, transport decisions mirror the real size-based tier logic, and no demo-only modals exist
  • FED-05: Inter-node Lightning channel opening UX — the UI shows the node's shareable Lightning URI; lists trusted (federated) nodes by hostname for one-click channel opening; and lets the user browse/request channels with public nodes — using the existing design system and components, verified on the :8100 dev preview against archi-dev before deploy
  • FED-06: On-brand payment success animation — the invoice "paid" tick's circle uses the screensaver-style ring with outer EQ-segment lines (reuse ScreensaverRing.vue's compact size) in place of the current success burst, applied consistently everywhere the paid tick shows
  • FED-07: Fedimint gateway never installs with a pre-set password — gateway credentials are generated per-install via manifest-declared generated_secrets (or explicitly set by the user), never baked into the image/manifest; existing installs with the default password get a migration path (BLOCKER — default credentials are a security hole)

UI Fixes (UIFIX) — user-reported blockers, added 2026-07-30

  • UIFIX-01: The FIPS/Tor pills on cloud files are kept (never removed by cleanups) and render at mobile widths — on mobile, users can see each file's security/transport state (BLOCKER)
  • UIFIX-02: The connected-nodes list scrolls at row-matched height — its height tracks the taller right-hand sibling in the row and the inner list scrolls within it, never growing to fit all rows scroll-free (BLOCKER)
  • UIFIX-03: On short viewports the onboarding confirmation tickbox is discoverably visible — an on-brand affordance (scroll cue, sticky footer, or equivalent) makes it obvious without altering tall-screen appearance (BLOCKER)
  • UIFIX-04: Paid Files pictures open in the app's lightbox, not a browser tab — consistent with the rest of the app's media UX
  • UIFIX-05: Picture-in-picture is robust — entering PiP closes the lightbox with a fluid on-brand animation, and an active PiP session survives main-tab changes and video buffering pauses (only an explicit user stop ends it)
  • UIFIX-06: Surfaces with genuinely slow opens show house-style loader states — no dead-feeling clicks (cached revisits stay spinner-free per PERF-02)

UI Performance (PERF)

  • PERF-01: The slowest tab switches and secondary-screen opens are profiled with causes named (remount storms, serial RPC waterfalls, uncached fetches) — fixes are targeted, not guessed
  • PERF-02: Main-tab switches render immediately from cached state with background refresh — no blank screens or long spinners on tabs already visited this session
  • PERF-03: Secondary screens (screens reached from a tab's main page) open without a blocking full reload and are instant on repeat visits — verified on real node hardware, not just the dev box

Multinode Verification (MNODE)

  • MNODE-01: The 5× destructive lifecycle gate passes on a second fleet node (archy-x250-beta) with 0 failures, run on-node per gate policy
  • MNODE-02: Cross-node federation/mesh/transport suites (tests/multinode/smoke.sh, meshtastic.sh) pass between fleet nodes, with all harness RPC calls time-bounded (no indefinite curl hangs)
  • MNODE-03: Removing a federation peer sticks — tombstone-write failures are surfaced (not swallowed) and a removed peer never silently reappears after subsequent sync cycles

Lifecycle Perfection (LIFE)

  • LIFE-01: Quadlet backends are the default — restarting archipelago.service leaves every app container running (no SIGKILL-the-world, no multi-minute rebuild storm)
  • LIFE-02: The reconciler self-heals failed Quadlet units — a .service in failed state (and not user-stopped) is reset-failed + started automatically, with backoff against busy-looping
  • LIFE-03: Per-app restart/flap observability — restart counters, a threshold log line when an app restarts >N times in M minutes, and restart counts surfaced in health/status RPC output
  • LIFE-04: Cascade uninstall→reinstall is gate-verified for multi-container stacks and installed apps — no ghost entries, no orphan containers, data preserved per policy, reinstall returns healthy
  • LIFE-05: Install and uninstall report real, monotonic progress driven by backend progress events, always reaching a terminal success/failure state — asserted in the gate, never a fake or stuck bar

Registry-Distributed Manifests (REG)

  • REG-01: The published signed catalog embeds full app manifests; nodes install/update from signature-verified catalog manifests (disk manifests remain the fallback for build-source apps); tampered catalogs are rejected with safe fallback
  • REG-02: The fleet is flipped to registry-distributed manifests — adding or bumping an image-only app requires only a re-signed catalog publish, no binary OTA or disk rsync

Security Enforcement (SEC)

  • SEC-01: AppManifest::validate() enforces the full ADR-009 mandate set — non-root UID, pinned image tags (no latest), capability allow-list, seccomp — with explicit, documented, auditable overrides
  • SEC-02: Generated AppArmor/seccomp security profiles are actually applied at container creation (--security-opt) and verified effective on running apps

Developer Tooling (DEV)

  • DEV-01: archy app validate checks a manifest locally and returns the same pass/fail verdict the node enforces (schema + security rules)
  • DEV-02: archy app render previews the exact Quadlet/podman configuration a manifest produces
  • DEV-03: A developer can local-install and lifecycle-test an app against a dev node from the CLI (archy app local-install / lifecycle-test)
  • DEV-04: The developer guide walks a new third-party developer from an empty directory to an installed, running app using only the CLI and docs

Decentralized Marketplace (MKT)

  • MKT-01: A third-party developer can publish a DID-signed app manifest to public Nostr relays (NIP-78, kind 30078) via the tooling
  • MKT-02: A node discovers marketplace apps from multiple relays and displays each app's trust tier (Verified / Community / Unverified) per ADR-006 trust scoring
  • MKT-03: Manifest signatures are verified before installation; tampered or invalid marketplace manifests cannot be installed
  • MKT-04: End-to-end north star: a user installs a third-party marketplace-published app on their node and it runs healthy under the standard lifecycle guarantees

v2 Requirements

Deferred to a future milestone. Tracked but not in the current roadmap.

Distribution Backbone (DIST)

  • DIST-01: BLAKE3 content-addressed catalog distribution via iroh swarm, origin-always-wins (workstream D — design-only today, tracker-marked backlog)

Fleet & Hardening (FLEET)

  • FLEET-01: Bitcoin multi-version fleet-wide OTA rollout (user-gated on timing per docs/bitcoin-version-bulletproof-rollout.md)
  • FLEET-02: App-specific health assertions for the ~34 apps with only baseline lifecycle coverage
  • FLEET-03: LUKS2 full-partition encryption for /var/lib/archipelago/
  • FLEET-04: Dynamic per-app resource rebalancing (cgroup-stats feedback loop)

Out of Scope

Feature Reason
Rootful/privileged containers, Docker Invariant — ADR-001/ADR-009
Per-app Rust installers / host provisioning The anti-pattern workstream A deleted
Centralized gatekept app store ADR-006 chose decentralized Nostr marketplace
Web5 DWN spec compliance ADR-011 — deprioritized after TBD shutdown
Custom live voice-call protocol Deprioritized 2026-07-01 per user; no scope decided

Traceability

Which phases cover which requirements. Updated during roadmap creation.

Requirement Phase Status
FED-01 Phase 1 Pending
FED-02 Phase 1 Pending
FED-03 Phase 1 Pending
FED-04 Phase 1 Pending
FED-05 Phase 1 Pending
FED-06 Phase 1 Pending
FED-07 Phase 1 Pending
UIFIX-01 Phase 1 Pending
UIFIX-02 Phase 1 Pending
UIFIX-03 Phase 1 Pending
UIFIX-04 Phase 1 Pending
UIFIX-05 Phase 1 Pending
UIFIX-06 Phase 1 Pending
PERF-01 Phase 2 Complete
PERF-02 Phase 2 Complete (02-02 tracer + 02-04..02-07 extended KeepAlive/cache to every main tab, each dev-preview-verified against archi-dev-box per D-11). Timing-regression verdict closed by 02-10 (02-FINDINGS.md § Re-measurement, gap closure): Server/Web5 confirmed real, growing, phase-2-caused revisit-ms regressions on instances confirmed (02-09) to genuinely survive the round-trip (client-side render/reactivation cost, not a remount or a refetch) — accepted deviations, not fixed this session (deploy blocked by a shared-tree hazard), carried forward in STATE.md Blockers/Concerns
PERF-03 Phase 2 Complete. Timing-regression verdict closed by 02-10 (02-FINDINGS.md § Re-measurement, gap closure): Discover/AppDetails/OpenWrtGateway confirmed real, growing, phase-2-caused revisit-ms regressions (same client-side split-signal cause) — accepted deviations, not fixed this session; Wallet/send-flow's apparent regression cleared as environmental noise (re-measure returned at/below baseline)
MNODE-01 Phase 3 Pending
MNODE-02 Phase 3 Pending
MNODE-03 Phase 3 Pending
LIFE-01 Phase 4 Pending
LIFE-02 Phase 4 Pending
LIFE-03 Phase 4 Pending
LIFE-04 Phase 4 Pending
LIFE-05 Phase 4 Pending
REG-01 Phase 5 Pending
REG-02 Phase 5 Pending
SEC-01 Phase 6 Pending
SEC-02 Phase 6 Pending
DEV-01 Phase 7 Pending
DEV-02 Phase 7 Pending
DEV-03 Phase 7 Pending
DEV-04 Phase 7 Pending
MKT-01 Phase 8 Pending
MKT-02 Phase 8 Pending
MKT-03 Phase 8 Pending
MKT-04 Phase 8 Pending

Coverage:

  • v1 requirements: 29 total
  • Mapped to phases: 29
  • Unmapped: 0

Requirements defined: 2026-07-29 Last updated: 2026-07-29 — added FED (federation/mesh hardening) and PERF (UI performance) requirement groups; phases renumbered after inserting them as Phases 12