docs: ingest 11 docs from docs/ (#2387)

This commit is contained in:
archipelago 2026-07-29 10:45:57 -04:00
parent 49ec294dea
commit 938dfb1453
21 changed files with 791 additions and 0 deletions

View File

@ -0,0 +1,32 @@
# Ingest Conflict Report
Mode: new (fresh bootstrap — no existing .planning/ context to check against)
Precedence: ADR > SPEC > PRD > DOC (no per-doc overrides present)
## Conflict Detection Report
### BLOCKERS (0)
(none)
### WARNINGS (0)
(none)
### INFO (4)
[INFO] Overlapping locked ADRs on Nostr marketplace discovery — consistent, not contradictory
Found: docs/adr/003-nostr-for-discovery.md and docs/adr/006-nostr-marketplace-discovery.md are both locked and both decide "Nostr relays (NIP-78, kind 30078) for app manifest discovery" over the same scope
Note: The decisions agree; ADR-006 refines ADR-003 with concrete trust tiers (Verified/Community/Unverified), curated built-in app list, and pre-install signature verification. Both preserved as separate entries in intel/decisions.md; no resolution needed. Consider marking one as superseding/refining the other in the docs for hygiene.
[INFO] SPEC security validation list narrower than ADR-009 mandatory defaults
Found: docs/adr/009-manifest-container-security.md (locked) mandates non-root UID (> 1000), pinned image tags (no `latest`), and a default seccomp profile as non-negotiable defaults; docs/app-manifest-spec.md's documented SecurityPolicy schema and AppManifest::validate() list do not mention these three (SecurityPolicy has apparmor_profile but no seccomp field)
Note: This is SPEC silence, not contradiction — no auto-resolution applied. ADR-009 governs by precedence (ADR > SPEC) and lock status. The SPEC itself declares `core/container/src/manifest.rs` canonical over the doc, so the gap may be documentation drift rather than implementation drift. Flagged for downstream verification, recorded as absent in intel/constraints.md.
[INFO] ADR numbering gap — ADR-010 absent from ingest set
Found: Classified ADRs run 001009 and 011; no classification exists for an ADR-010
Note: Either ADR-010 does not exist, was withdrawn, or was not included in the ingest. No action required for synthesis; noted for completeness of the decision record.
[INFO] Cross-reference graph is acyclic
Found: cross_refs edges: ADR-007 → ADR-003; ADR-009 → docs/app-manifest-spec.md (+ code paths); SPEC → out-of-set docs and code only (app-developer-guide.md, manifest-hooks-design.md, marketplace-protocol.md, core/container/src/manifest.rs, api/rpc/package/stacks.rs)
Note: DFS cycle detection found no cycles; all 11 docs were synthesized. Several SPEC cross-refs point to documents not in the ingest set — they were not followed.

115
.planning/PROJECT.md Normal file
View File

@ -0,0 +1,115 @@
# 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*

110
.planning/REQUIREMENTS.md Normal file
View File

@ -0,0 +1,110 @@
# 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
### 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 |
|-------------|-------|--------|
| MNODE-01 | Phase 1 | Pending |
| MNODE-02 | Phase 1 | Pending |
| MNODE-03 | Phase 1 | Pending |
| LIFE-01 | Phase 2 | Pending |
| LIFE-02 | Phase 2 | Pending |
| LIFE-03 | Phase 2 | Pending |
| LIFE-04 | Phase 2 | Pending |
| LIFE-05 | Phase 2 | Pending |
| REG-01 | Phase 3 | Pending |
| REG-02 | Phase 3 | Pending |
| SEC-01 | Phase 4 | Pending |
| SEC-02 | Phase 4 | Pending |
| DEV-01 | Phase 5 | Pending |
| DEV-02 | Phase 5 | Pending |
| DEV-03 | Phase 5 | Pending |
| DEV-04 | Phase 5 | Pending |
| MKT-01 | Phase 6 | Pending |
| MKT-02 | Phase 6 | Pending |
| MKT-03 | Phase 6 | Pending |
| MKT-04 | Phase 6 | Pending |
**Coverage:**
- v1 requirements: 20 total
- Mapped to phases: 20
- Unmapped: 0
---
*Requirements defined: 2026-07-29*
*Last updated: 2026-07-29 after roadmap creation*

108
.planning/ROADMAP.md Normal file
View File

@ -0,0 +1,108 @@
# Roadmap: Archipelago — v1.8.0 Developer-Ready App Platform
## Overview
Brownfield milestone starting from a green single-node production gate (5/5 on .228,
2026-06-23). The journey: prove the platform across the fleet (multinode pass), make the
container lifecycle bulletproof (Quadlet default, self-healing, honest progress, no ghosts),
flip manifest distribution from OTA disk files to the signed registry, harden manifest
security enforcement to the full ADR-009 bar, ship the `archy app` developer CLI, and land
the decentralized Nostr marketplace — ending at the north star: a third-party developer
publishes an app via the signed/decentralized registry and a user installs it on their node.
## Phases
**Phase Numbering:**
- Integer phases (1, 2, 3): Planned milestone work
- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED)
- [ ] **Phase 1: Multinode Verification Pass** - Lifecycle gate green on a second node; cross-node federation/mesh/transport suites pass; federation removal sticks
- [ ] **Phase 2: Lifecycle Perfection & Quadlet Default** - Quadlet backends default, failed-unit self-healing, flap observability, cascade gate, truthful progress
- [ ] **Phase 3: Registry-Distributed Manifests** - Signed catalog carries full manifests; fleet flipped off OTA disk-file distribution
- [ ] **Phase 4: Manifest Security Enforcement** - Validation matches ADR-009 mandates; generated security profiles actually applied
- [ ] **Phase 5: Developer Tooling CLI** - `archy app validate/render/local-install/lifecycle-test` + developer guide
- [ ] **Phase 6: Decentralized Marketplace** - DID-signed publish to Nostr relays, trust-tier discovery, verified third-party install end-to-end
## Phase Details
### Phase 1: Multinode Verification Pass
**Goal**: The platform's lifecycle and federation guarantees are proven across the fleet, not just on .228 — the declared next exit criterion
**Depends on**: Nothing (first phase)
**Requirements**: MNODE-01, MNODE-02, MNODE-03
**Success Criteria** (what must be TRUE):
1. The 5× destructive lifecycle gate reports 0 failures on a second fleet node (archy-x250-beta), run on-node
2. The cross-node smoke suite (federation pairing both directions, FIPS anchors, peer content browse) passes between two fleet nodes with every harness RPC time-bounded — a slow node produces a test failure, never an indefinite hang
3. An operator who removes a federation peer never sees it reappear in the peer list after later sync cycles; a tombstone-write failure is surfaced as an error instead of silently swallowed
4. The on-air mesh suite passes between two radio-equipped nodes over real RF
**Plans**: TBD
### Phase 2: Lifecycle Perfection & Quadlet Default
**Goal**: An insanely-reliable container environment — every app installs, runs, restarts, uninstalls, and reinstalls cleanly with honest progress, no ghosts, and automatic recovery
**Depends on**: Phase 1 (Quadlet default-flip is gated on the second-node gate reporting clean)
**Requirements**: LIFE-01, LIFE-02, LIFE-03, LIFE-04, LIFE-05
**Success Criteria** (what must be TRUE):
1. Restarting `archipelago.service` on a fleet node leaves every app container running — no SIGKILL-the-world, no multi-minute reconciler rebuild
2. An app whose Quadlet unit enters `failed` state (and was not user-stopped) comes back automatically within a bounded window, with backoff on persistent failure — no operator intervention
3. An operator can see per-app restart counts in status output, and a flapping app (>N restarts in M minutes) is flagged in logs instead of being invisible
4. Uninstalling then reinstalling any gated app — including multi-container stacks like immich/btcpay — leaves no ghost My-Apps entries or orphan containers, preserves data per policy, and returns the app healthy, verified by the cascade gate tier
5. Install and uninstall progress bars move monotonically from real backend progress events and always land on a terminal success/failure state — asserted in the gate, and the single-node gate stays green after all orchestrator changes
**Plans**: TBD
**UI hint**: yes
### Phase 3: Registry-Distributed Manifests
**Goal**: Manifests ship via the signed registry, not OTA disk files — bumping or adding an app becomes a signed catalog change
**Depends on**: Phase 2 (fleet lifecycle stable under Quadlet default before changing the distribution channel)
**Requirements**: REG-01, REG-02
**Success Criteria** (what must be TRUE):
1. A fleet node installs and updates an image-only app from the full manifest embedded in the signed catalog, verified against the pinned release-root key, with no corresponding OTA disk file present (disk remains the fallback for build-source apps)
2. A tampered or unsigned catalog manifest is rejected and the node falls back safely — it never installs from an unverified manifest
3. Bumping an app version fleet-wide requires only regenerating, re-signing, and publishing the catalog — no binary OTA, no disk rsync — proven live on the fleet
**Plans**: TBD
### Phase 4: Manifest Security Enforcement
**Goal**: A third-party manifest cannot weaken node security — declared security policy is fully validated and actually enforced at runtime
**Depends on**: Phase 3 (enforcement guards the registry channel third-party manifests will arrive through)
**Requirements**: SEC-01, SEC-02
**Success Criteria** (what must be TRUE):
1. A manifest violating ADR-009 mandates (root user, unpinned `latest` tag, capability outside the allow-list, disabled seccomp) is rejected at validation with a clear error naming the violation
2. Security overrides (`readonly_root: false`, extra capabilities) work only when explicitly listed in the manifest and leave an audit trail
3. Generated AppArmor/seccomp profiles are applied to containers at creation and verifiably effective on a running app — not just generated and ignored
4. The single-node lifecycle gate stays green with enforcement on — existing catalog apps all pass the strengthened validation (or carry documented overrides)
**Plans**: TBD
### Phase 5: Developer Tooling CLI
**Goal**: A third-party developer can build, validate, and test an Archipelago app locally without reading platform internals
**Depends on**: Phase 4 (CLI validation must mirror the final enforced rule set)
**Requirements**: DEV-01, DEV-02, DEV-03, DEV-04
**Success Criteria** (what must be TRUE):
1. A developer runs `archy app validate` on a manifest directory and gets the same pass/fail verdict — including security rules — that a node would enforce at install
2. A developer runs `archy app render` and sees the exact Quadlet/podman configuration their manifest produces before ever touching a node
3. A developer can install their app onto a dev node and run its lifecycle test (install/UI/stop/start/restart/uninstall) from the CLI
4. A new developer following only the developer guide goes from an empty directory to a running app on a node — no tribal knowledge required
**Plans**: TBD
### Phase 6: Decentralized Marketplace
**Goal**: The north star — third-party developers publish apps via the decentralized registry and users install them on their nodes
**Depends on**: Phase 5 (publish rides the CLI; installs ride registry distribution from Phase 3 and enforcement from Phase 4)
**Requirements**: MKT-01, MKT-02, MKT-03, MKT-04
**Success Criteria** (what must be TRUE):
1. A third-party developer publishes a DID-signed app manifest to public Nostr relays (NIP-78, kind 30078) using the tooling
2. A node discovers the published app from multiple relays and the app store UI shows its trust tier (Verified / Community / Unverified) per ADR-006 scoring
3. The node verifies the manifest signature before installation; a tampered or invalid marketplace manifest cannot be installed
4. A user installs the third-party marketplace-published app on their node and it runs healthy under the standard lifecycle guarantees — the user-chosen success metric, demonstrated end-to-end
**Plans**: TBD
**UI hint**: yes
## Progress
**Execution Order:**
Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6
| Phase | Plans Complete | Status | Completed |
|-------|----------------|--------|-----------|
| 1. Multinode Verification Pass | 0/TBD | Not started | - |
| 2. Lifecycle Perfection & Quadlet Default | 0/TBD | Not started | - |
| 3. Registry-Distributed Manifests | 0/TBD | Not started | - |
| 4. Manifest Security Enforcement | 0/TBD | Not started | - |
| 5. Developer Tooling CLI | 0/TBD | Not started | - |
| 6. Decentralized Marketplace | 0/TBD | Not started | - |

79
.planning/STATE.md Normal file
View File

@ -0,0 +1,79 @@
---
gsd_state_version: '1.0'
status: planning
progress:
total_phases: 6
completed_phases: 0
total_plans: 0
completed_plans: 0
percent: 0
---
# Project State
## Project Reference
See: .planning/PROJECT.md (updated 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.
**Current focus:** Phase 1 — Multinode Verification Pass
## Current Position
Phase: 1 of 6 (Multinode Verification Pass)
Plan: 0 of TBD in current phase
Status: Ready to plan
Last activity: 2026-07-29 — Project initialized from doc ingest (10 ADRs + 1 SPEC) + codebase map; roadmap created (6 phases, 20 requirements, 100% coverage)
Progress: [░░░░░░░░░░] 0%
## Performance Metrics
**Velocity:**
- Total plans completed: 0
- Average duration: —
- Total execution time: —
**By Phase:**
| Phase | Plans | Total | Avg/Plan |
|-------|-------|-------|----------|
| - | - | - | - |
## Accumulated Context
### Decisions
Decisions are logged in PROJECT.md (10 locked ADRs in the `<decisions>` block + milestone decisions table). Recent decisions affecting current work:
- Milestone version = 1.8.0-alpha (decided 2026-07-08)
- Phase-3 Quadlet default-flip is gated on the second-node gate reporting clean (do fresh, never stage uncommitted)
- Workstream D (DHT distribution) deferred to v2 — design-only backlog
- Canonical manifest schema = `core/container/src/manifest.rs` (code wins over spec doc)
### Pending Todos
None yet.
### Blockers/Concerns
- [Phase 1] Multinode gate on archy-x250-beta was launched 2026-07-01 (log on-node); verify outcome before re-running
- [Phase 1] Federation tombstone fix touches trust code — fix carefully, re-verify with `tests/multinode/smoke.sh`, don't patch blind
- [Phase 3] Fleet registry flip awaits explicit user authorization + timing call
- [Phase 4] Strengthened ADR-009 validation may reject existing catalog apps — audit manifests before enforcement lands
- [Global] Live OTA fleet: deploy to the dev pair before any OTA; gate re-runs required after orchestrator changes; some verification is user/hardware-gated (radios, on-device tests)
## Deferred Items
| Category | Item | Status | Deferred At |
|----------|------|--------|-------------|
| Distribution | DIST-01 DHT/iroh backbone (workstream D) | v2 | 2026-07-29 |
| Fleet | FLEET-01 Bitcoin multi-version fleet OTA (user-gated) | v2 | 2026-07-29 |
| Fleet | FLEET-02 per-app deep health assertions (~34 apps) | v2 | 2026-07-29 |
| Fleet | FLEET-03 LUKS2 data-partition encryption | v2 | 2026-07-29 |
## Session Continuity
Last session: 2026-07-29
Stopped at: Roadmap + state initialized from ingest; next step is `/gsd-plan-phase 1`
Resume file: None

View File

@ -0,0 +1,66 @@
# Synthesis Summary
Ingest mode: new (fresh bootstrap; no existing PROJECT.md/REQUIREMENTS.md/ROADMAP.md)
Synthesized: 2026-07-29
Precedence applied: ADR > SPEC > PRD > DOC (no per-doc overrides)
## Doc counts by type
- ADR: 10 (all locked, Status: Accepted, confidence: high)
- SPEC: 1 (confidence: high)
- PRD: 0
- DOC: 0
- UNKNOWN: 0
- Total: 11
## Decisions locked (10)
All in `intel/decisions.md`:
- ADR-001 Podman over Docker — docs/adr/001-podman-over-docker.md
- ADR-002 did:key (Ed25519) node identity — docs/adr/002-did-key-method.md
- ADR-003 Nostr relays for node + app discovery — docs/adr/003-nostr-for-discovery.md
- ADR-004 Tor hidden services for inter-node RPC/control plane — docs/adr/004-tor-for-peer-communication.md
- ADR-005 ChaCha20-Poly1305 + Argon2id backup encryption — docs/adr/005-chacha20-backup-encryption.md
- ADR-006 Nostr relays for marketplace discovery (trust tiers) — docs/adr/006-nostr-marketplace-discovery.md
- ADR-007 Bilateral DID federation trust via single-use invite codes — docs/adr/007-did-federation-trust.md
- ADR-008 Dual keys (Ed25519 + secp256k1) from one master seed — docs/adr/008-dual-key-strategy.md
- ADR-009 Manifest-level container security enforcement — docs/adr/009-manifest-container-security.md
- ADR-011 DWN deprioritization (Nostr + Tor federation instead) — docs/adr/011-dwn-deprioritization.md
## Requirements extracted (0)
No PRDs in ingest set. `intel/requirements.md` records the absence.
## Constraints (7 entries)
From docs/app-manifest-spec.md, in `intel/constraints.md`:
- schema: 4 (top-level `app:` block, ContainerConfig, SecurityPolicy + validation, Volumes)
- api-contract: 1 (lifecycle hooks)
- protocol: 2 (Quadlet installation/reconciler semantics, distribution channels: signed catalog + Nostr marketplace)
- nfr: 0
## Context topics (0)
No DOC-type documents. `intel/context.md` records the absence.
## Conflicts
- Blockers: 0
- Competing variants: 0
- Auto-resolved: 0
- Informational notes: 4 (ADR-003/006 consistent overlap; SPEC validation narrower than ADR-009 mandates — silence, not contradiction; ADR-010 numbering gap; acyclic cross-ref graph)
Detail: `.planning/INGEST-CONFLICTS.md`
## Cycle detection
Cross-ref graph acyclic (max depth well under cap). All 11 docs synthesized; no docs excluded.
## Files
- Decisions: `.planning/intel/decisions.md`
- Requirements: `.planning/intel/requirements.md`
- Constraints: `.planning/intel/constraints.md`
- Context: `.planning/intel/context.md`
- Conflict report: `.planning/INGEST-CONFLICTS.md`
- Raw classifications: `.planning/intel/classifications/*.json`

View File

@ -0,0 +1,13 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/adr/001-podman-over-docker.md",
"type": "ADR",
"confidence": "high",
"manifest_override": false,
"title": "ADR-001: Podman Over Docker",
"summary": "Chose Podman over Docker as the container runtime for rootless, daemonless operation with native systemd integration.",
"scope": ["Podman", "Docker", "container runtime", "rootless containers", "systemd integration", "archy-net network"],
"cross_refs": [],
"locked": true,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,13 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/adr/002-did-key-method.md",
"type": "ADR",
"confidence": "high",
"manifest_override": false,
"title": "ADR-002: DID Key Method for Node Identity",
"summary": "Chose did:key (Ed25519) as the primary DID method for node identity; self-contained and offline-capable, with federation trust lists mitigating rotation/revocation gaps.",
"scope": ["did:key", "node identity", "DID methods", "Ed25519 keys", "peer authentication", "federation trust lists", "verifiable credentials"],
"cross_refs": [],
"locked": true,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,22 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/adr/003-nostr-for-discovery.md",
"type": "ADR",
"confidence": "high",
"manifest_override": false,
"title": "ADR-003: Nostr Relays for Node and App Discovery",
"summary": "Chose Nostr relays (NIP-78, kind 30078) for decentralized node discovery and marketplace app manifest distribution.",
"scope": [
"Nostr relays",
"node discovery",
"app discovery",
"marketplace app manifests",
"NIP-78",
"NIP-33 replaceable events",
"trust scoring",
"relay caching"
],
"cross_refs": [],
"locked": true,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,13 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/adr/004-tor-for-peer-communication.md",
"type": "ADR",
"confidence": "high",
"manifest_override": false,
"title": "ADR-004: Tor Hidden Services for Peer Communication",
"summary": "Chose Tor hidden services (.onion) for all inter-node RPC/control-plane communication; bulk data pulled from registries instead.",
"scope": ["Tor hidden services", "inter-node communication", "federation sync", "archy-tor container", "RPC/control plane", "NAT traversal"],
"cross_refs": [],
"locked": true,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,13 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/adr/005-chacha20-backup-encryption.md",
"type": "ADR",
"confidence": "high",
"manifest_override": false,
"title": "ADR-005: ChaCha20-Poly1305 for Backup Encryption",
"summary": "Chose ChaCha20-Poly1305 AEAD with Argon2id key derivation for encrypting backups at rest, over AES-256-GCM and XChaCha20-Poly1305.",
"scope": ["backup encryption", "ChaCha20-Poly1305", "Argon2id key derivation", "AEAD", "nonce handling"],
"cross_refs": [],
"locked": true,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,13 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/adr/006-nostr-marketplace-discovery.md",
"type": "ADR",
"confidence": "high",
"manifest_override": false,
"title": "ADR-006: Nostr Relays for Marketplace Discovery",
"summary": "Chose Nostr relays (NIP-78, kind 30078 events) for decentralized app manifest discovery instead of a centralized marketplace server.",
"scope": ["Nostr relays", "app manifest discovery", "marketplace", "trust scoring", "trust tiers", "manifest signature verification"],
"cross_refs": [],
"locked": true,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,13 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/adr/007-did-federation-trust.md",
"type": "ADR",
"confidence": "high",
"manifest_override": false,
"title": "ADR-007: DID-Based Federation Trust",
"summary": "Chose bilateral DID-based verification with single-use invite codes over Tor for establishing federation trust between nodes, with Trusted/Observer/Untrusted levels.",
"scope": ["federation", "DID verification", "invite codes", "trust levels", "Tor hidden services", "Ed25519 keys"],
"cross_refs": ["ADR-003"],
"locked": true,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,13 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/adr/008-dual-key-strategy.md",
"type": "ADR",
"confidence": "high",
"manifest_override": false,
"title": "ADR-008: Dual Key Strategy (Ed25519 + Secp256k1)",
"summary": "Maintain two key pairs per node identity: Ed25519 for DID/Web5 operations, secp256k1 for Nostr/Bitcoin/Lightning, both derived from one master seed.",
"scope": ["node identity", "Ed25519", "secp256k1", "DID documents", "verifiable credentials", "federation authentication", "backup encryption", "Nostr event publishing", "node discovery", "Lightning Network", "key derivation", "master seed"],
"cross_refs": [],
"locked": true,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,13 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/adr/009-manifest-container-security.md",
"type": "ADR",
"confidence": "high",
"manifest_override": false,
"title": "ADR-009: Manifest-Level Container Security Enforcement",
"summary": "Enforce mandatory container security defaults (readonly root, no-new-privileges, non-root UID, dropped capabilities, pinned tags) at the manifest level during container creation.",
"scope": ["container security", "app manifests", "manifest validation", "podman container creation", "security defaults", "capability restrictions", "seccomp", "core/container module"],
"cross_refs": ["docs/app-manifest-spec.md", "core/container/src/", "core/security/src/"],
"locked": true,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,13 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/adr/011-dwn-deprioritization.md",
"type": "ADR",
"confidence": "high",
"manifest_override": false,
"title": "ADR-011: DWN Deprioritization",
"summary": "Deprioritizes Web5 DWN spec compliance after TBD's shutdown; keeps existing custom DWN store code and prioritizes Nostr plus Tor federation for peer sync.",
"scope": ["DWN (Decentralized Web Node)", "Web5", "dwn_store.rs", "Nostr", "federation", "peer discovery", "peer data sync"],
"cross_refs": [],
"locked": true,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,29 @@
{
"source_path": "/home/archipelago/Projects/archy/docs/app-manifest-spec.md",
"type": "SPEC",
"confidence": "high",
"manifest_override": false,
"title": "App Manifest Specification",
"summary": "Defines the declarative manifest.yml schema for apps: top-level fields, container config, security policy, volumes, hooks, installation semantics, and signed-catalog/marketplace distribution.",
"scope": [
"app manifest.yml schema",
"ContainerConfig (image/build, networks, derived_env, secret_env, generated_secrets, generated_certs)",
"SecurityPolicy (capabilities allow-list, network_policy, readonly_root)",
"volumes and bind-mount confinement",
"lifecycle hooks (post_install, pre_start)",
"health checks and interfaces",
"Quadlet installation and reconciler semantics",
"signed app catalog distribution",
"decentralized marketplace distribution"
],
"cross_refs": [
"app-developer-guide.md",
"manifest-hooks-design.md",
"marketplace-protocol.md",
"core/container/src/manifest.rs",
"api/rpc/package/stacks.rs"
],
"locked": false,
"precedence": null,
"notes": ""
}

View File

@ -0,0 +1,38 @@
# Constraints (from SPECs)
Extracted from 1 classified SPEC: `docs/app-manifest-spec.md` (accurate as of 2026-07-08). The SPEC self-declares that the canonical schema is the Rust parser in `core/container/src/manifest.rs` — if doc and code disagree, the code wins.
## App manifest top-level schema (`app:` block)
- source: docs/app-manifest-spec.md
- type: schema
- content: Every app is a directory `apps/<id>/` with a `manifest.yml` containing a single top-level `app:` block. Apps are purely declarative — the orchestrator owns the entire lifecycle; no per-app installer code. Required fields: `id` (lowercase alphanumeric + `-`/`_`, must match directory name), `name`, `version`. Optional fields: `description`, `container` (ContainerConfig), `dependencies` (storage/app_id+version/bare string), `resources` (cpu_limit, memory_limit, disk_limit), `security` (SecurityPolicy), `ports` (host/container/protocol), `volumes`, `files` (GeneratedFile: path/content/overwrite; path must sit under a declared bind mount), `environment` (static KEY=value), `health_check` (type/endpoint/path/interval/timeout/retries; `http` is what the monitor exercises), `devices` (must start with `/dev/`), `interfaces` (launch surfaces keyed by name), `hooks` (LifecycleHooks). Unknown keys are absorbed into an `extensions` map (serde flatten) as transitional metadata — not typed schema, not validated.
## ContainerConfig schema
- source: docs/app-manifest-spec.md
- type: schema
- content: Exactly one of `image` or `build` must be present (image XOR build). Fields: `image` (registry reference), `image_signature` (optional), `pull_policy` (default `if-not-present`), `build` ({context, dockerfile default "Dockerfile", tag, build_args}), `network` (literal podman `--network` value; omitted = rootless default isolated network), `network_aliases` (extra DNS names on the network), `entrypoint`, `custom_args`, `derived_env` ({key, template} rendered against host facts at apply time; allowed placeholders only: {{HOST_IP}}, {{HOST_MDNS}}, {{DISK_GB}} plus dependency-resolved facts — never hard-code host specifics), `secret_env` ({key, secret_file} read from /var/lib/archipelago/secrets/<secret_file>, injected as a podman secret so it never appears in `podman inspect` or unit files; secret_file must be a bare filename, no `/` or `..`), `generated_secrets` ({name, kind} materialised by the orchestrator on first use, 0600, rootless service user, idempotent + self-healing; kind ∈ hex16|hex32|base64|bcrypt; bcrypt writes <name>=hash and <name>.pw=plaintext), `generated_certs` ({crt, key, common_name?, sans?} self-signed TLS materialised before create), `data_uid` ("UID:GID" applied to the app's bind-mounted data dir before create).
## SecurityPolicy schema and validation rules
- source: docs/app-manifest-spec.md
- type: schema
- content: Security block defaults: `readonly_root: true`, `no_new_privileges: true`, `capabilities: []` (cap-drop ALL, add back only listed), `network_policy: isolated` (isolated | bridge | host), `apparmor_profile: null` (optional). Validation enforced at `AppManifest::validate()`: capabilities must come from the reviewed allow-list (CHOWN, DAC_OVERRIDE, FOWNER, NET_ADMIN, NET_BIND_SERVICE, NET_RAW, SETGID, SETUID, SYS_ADMIN); `network_policy` must be exactly isolated/bridge/host; no `container:`/`ns:` network modes; devices must be `/dev/*`; bind-mount sources confined to `/var/lib/archipelago` (reviewed exceptions: rootless podman socket and dbus); `derived_env` templates limited to the placeholder allow-list; `secret_env`/`generated_secrets` names must be bare filenames; hook steps validated against the hook allow-list. (Note: the SPEC's documented validation list does not mention ADR-009's non-root UID, pinned-image-tag, or seccomp mandates — see INGEST-CONFLICTS.md INFO entry.)
## Volumes schema
- source: docs/app-manifest-spec.md
- type: schema
- content: Volume entries: `type` ∈ bind | volume | tmpfs; bind entries take `source` (confined to /var/lib/archipelago per validation), `target`, `options` from an allow-list (rw, ro, z, Z, shared, …); tmpfs entries take `target` and `tmpfs_options` (e.g. "rw,noexec,nosuid,size=256m").
## Lifecycle hooks contract
- source: docs/app-manifest-spec.md
- type: api-contract
- content: Hooks are declarative, allow-listed operations that run against the app's own container — never the host (design: manifest-hooks-design.md). `post_install` runs once after install with the container running; supported steps: `copy_from_host` (src relative to an allow-listed root — data dir / web-ui; no absolute paths, no '..') and `exec` (podman exec inside the container). `pre_start` is reserved in the schema; its executor is not yet wired.
## Installation semantics (Quadlet + reconciler)
- source: docs/app-manifest-spec.md
- type: protocol
- content: The orchestrator compiles the manifest into a rootless Podman Quadlet unit under `user.slice` — the container survives backend restarts and reboots. A level-triggered reconciler converges drift every 30 seconds. Multi-container apps are sets of per-member manifests installed together via the stack orchestrator (`api/rpc/package/stacks.rs`) on an app-local network.
## Manifest distribution channels
- source: docs/app-manifest-spec.md
- type: protocol
- content: Manifests ship two ways. (1) Signed catalog (primary): `releases/app-catalog.json` embeds the full manifest per app with an Ed25519 detached signature verified against the pinned release-root anchor; nodes overlay catalog manifests over disk files — catalog wins for image-only apps; `apps/<id>/manifest.yml` on disk remains the fallback and is still required for build-source apps. (2) Decentralized marketplace: Nostr NIP-78 discovery with DID-signed manifests (marketplace-protocol.md); the marketplace uses its own flatter manifest schema, not this one. Tooling: validate with `scripts/validate-app-manifest.sh`, regenerate catalog with `scripts/generate-app-catalog.py`, drift-checked in CI by `scripts/check-app-catalog-drift.py`.

View File

@ -0,0 +1,5 @@
# Context (from DOCs)
No DOC-type documents were present in the ingest set (10 ADRs + 1 SPEC). No context notes extracted.
This file intentionally records absence rather than repurposing ADR/SPEC content as context.

View File

@ -0,0 +1,65 @@
# Decisions (from ADRs)
Extracted from 10 classified ADRs. All are `locked: true` (Status: Accepted) and cannot be auto-overridden by any lower-precedence source.
## ADR-001: Podman Over Docker
- source: docs/adr/001-podman-over-docker.md
- status: locked (Accepted)
- decision: Use Podman as the container runtime instead of Docker. Rootless by default, daemonless, Docker-compatible, native systemd integration, OCI-compliant. Use `archy-net` custom network for inter-container DNS.
- scope: container runtime, rootless containers, systemd integration, archy-net network
## ADR-002: DID Key Method for Node Identity
- source: docs/adr/002-did-key-method.md
- status: locked (Accepted)
- decision: Use `did:key` (Ed25519) as the primary DID method for node identity. Self-contained, offline-capable, local resolution. Known gaps (no rotation, no service endpoints, no revocation) mitigated via federation trust lists and separately-stored service endpoints; future migration to did:peer/did:web possible if rotation is needed.
- scope: node identity, DID methods, Ed25519 keys, peer authentication, federation trust lists, verifiable credentials
## ADR-003: Nostr Relays for Node and App Discovery
- source: docs/adr/003-nostr-for-discovery.md
- status: locked (Accepted)
- decision: Use Nostr relays (NIP-78, kind 30078) for both node discovery and marketplace app manifests. Query multiple relays in parallel with dedupe; local cache with 15-minute TTL; trust scoring (DID verification, relay consensus, federation trust); hashtag filtering (`archipelago-marketplace`); NIP-33 replaceable events for updates; Tor-compatible via SOCKS proxy.
- scope: node discovery, app discovery, marketplace app manifests, NIP-78, NIP-33 replaceable events, trust scoring, relay caching
## ADR-004: Tor Hidden Services for Peer Communication
- source: docs/adr/004-tor-for-peer-communication.md
- status: locked (Accepted)
- decision: Use Tor hidden services (.onion addresses) for all inter-node communication. Scoped to RPC/control plane only — bulk data (container images) pulled from registries. Retry with backoff; `archy-tor` container runs automatically with host networking; federation sync interval (5 min) tolerates occasional failures.
- scope: inter-node communication, federation sync, archy-tor container, RPC/control plane, NAT traversal
## ADR-005: ChaCha20-Poly1305 for Backup Encryption
- source: docs/adr/005-chacha20-backup-encryption.md
- status: locked (Accepted)
- decision: Use ChaCha20-Poly1305 (AEAD) with Argon2id key derivation for backup encryption at rest, chosen over AES-256-GCM and XChaCha20-Poly1305. Random nonce per backup stored alongside ciphertext; Argon2id with 64MB memory cost and 3 iterations for password-to-key derivation.
- scope: backup encryption, AEAD, Argon2id key derivation, nonce handling
## ADR-006: Nostr Relays for Marketplace Discovery
- source: docs/adr/006-nostr-marketplace-discovery.md
- status: locked (Accepted)
- decision: Use Nostr relays (NIP-78, kind 30078 events) for decentralized app manifest discovery instead of a centralized marketplace server. Developers publish signed manifests to public relays; nodes query multiple relays; trust scoring via cross-relay verification count, DID-linked developer reputation, optional community endorsements. Trust tiers: Verified (known developer, 3+ relays, DID-verified), Community (2+ relays, valid manifest, unsigned/new developer), Unverified (single relay, new developer). Local relay-response caching; built-in curated list for essential apps; manifest signature verification before installation.
- scope: marketplace, app manifest discovery, trust scoring, trust tiers, manifest signature verification
## ADR-007: DID-Based Federation Trust
- source: docs/adr/007-did-federation-trust.md
- status: locked (Accepted)
- decision: Use bilateral DID-based verification with single-use invite codes for federation trust establishment. Invite code carries DID, .onion address, and shared secret; exchanged out-of-band; both nodes verify DIDs via signed challenges over Tor; ongoing communication is DID-authenticated over Tor hidden services. Trust levels: Trusted (full access), Observer (read-only), Untrusted (blocked). Discovery (ADR-003) finds nodes; federation trusts them.
- scope: federation, DID verification, invite codes, trust levels, Tor hidden services, Ed25519 keys
- cross-refs: ADR-003
## ADR-008: Dual Key Strategy (Ed25519 + Secp256k1)
- source: docs/adr/008-dual-key-strategy.md
- status: locked (Accepted)
- decision: Maintain two key pairs per node identity, both derived from one master seed: Ed25519 as canonical identity (DID documents, verifiable credentials, federation auth, backup encryption via X25519 DH) and secp256k1 for Nostr/Bitcoin/Lightning (event publishing, node discovery, Lightning channel auth). Secp256k1 key linked to the DID via Nostr profile (NIP-05). Backup captures the master seed; DID document includes both verification methods.
- scope: node identity, key derivation, master seed, Ed25519, secp256k1, DID documents, federation authentication, backup encryption, Nostr event publishing, node discovery, Lightning Network
## ADR-009: Manifest-Level Container Security Enforcement
- source: docs/adr/009-manifest-container-security.md
- status: locked (Accepted)
- decision: Enforce mandatory container security defaults at the manifest level, applied automatically during container creation. Non-negotiable defaults: `readonly_root: true`, `no_new_privileges: true`, non-root user (UID > 1000), drop ALL capabilities (add back only required), pinned image tags (no `latest`), default seccomp profile. `core/container/` validates manifests (parse → validate → reject violations → apply security context at `podman create`). Optional overrides (`readonly_root: false`, extra capabilities like NET_ADMIN) require explicit listing and documented justification, with audit trail.
- scope: container security, app manifests, manifest validation, podman container creation, security defaults, capability restrictions, seccomp
- cross-refs: docs/app-manifest-spec.md, core/container/src/, core/security/src/
## ADR-011: DWN Deprioritization
- source: docs/adr/011-dwn-deprioritization.md
- status: locked (Accepted)
- decision: Deprioritize Web5 DWN spec compliance following TBD's November 2024 shutdown. Keep existing custom DWN store code (`core/archipelago/src/network/dwn_store.rs`) for peer file catalogs and federation state; stop calling it "Web5 DWN" in user-facing text; do not invest in DWN spec compliance; prioritize Nostr + Tor federation for peer discovery and data exchange; re-evaluate only if DIF produces a viable Rust SDK or the spec regains maintainers.
- scope: DWN, Web5, dwn_store.rs, Nostr, federation, peer discovery, peer data sync

View File

@ -0,0 +1,5 @@
# Requirements (from PRDs)
No PRD documents were present in the ingest set (10 ADRs + 1 SPEC). No requirements extracted.
Downstream note: requirements for the roadmap must be derived elsewhere (e.g. from user input or a future PRD ingest); this file intentionally records absence rather than inferring requirements from ADR/SPEC content.