phase4-streaming-ecash-plan.md: design for ecash-paid swarm transport, paying across different mints (§2a, Lightning-bridged swaps), networking-through-nodes relay, and an IndeeHub "Archipelago" content source. Records the resolved iroh-blobs paid-serving spike. dht-RESUME.md: task #12 + step F marked done. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
122 lines
6.9 KiB
Markdown
122 lines
6.9 KiB
Markdown
# DHT work — RESUME HERE
|
|
|
|
**Last updated:** 2026-06-16 · **Branch:** `agent-trust-wip` · **Worktree:** `~/Projects/archy-dht`
|
|
|
|
This file is the single source of truth for resuming the DHT / peer-distribution
|
|
work after a restart. Read it top to bottom, run the **Verify state** block, then
|
|
continue at **Next step**.
|
|
|
|
---
|
|
|
|
## ⚠️ CRITICAL — where to work (do not skip)
|
|
|
|
- **Work ONLY in the worktree `~/Projects/archy-dht` on branch `agent-trust-wip`.**
|
|
- **NEVER run git checkout / branch-switch / commit in the shared tree `~/Projects/archy`.**
|
|
Another agent cuts releases on `main` there. Git branch state is **global to one
|
|
working tree**, so a checkout in the shared tree drags every session onto that
|
|
branch and can clobber uncommitted work. That already happened once — the worktree
|
|
exists specifically to prevent it. See memory `feedback_concurrent_agent_tree`.
|
|
- The shared tree stays on `main` for the release agent. Leave it alone.
|
|
|
|
## Build facts (so you don't get surprised)
|
|
|
|
- It's a **binary** crate: test with `cargo test --bin archipelago -- <filter>`
|
|
(there is no lib target).
|
|
- The **test profile is opt-level=3** → every incremental test rebuild of the
|
|
`archipelago` crate is **~5 min**; a cold build of the iroh feature tree is ~19 min.
|
|
Budget for it. Run builds in the background and poll.
|
|
- Default build = no iroh. The iroh swarm engine is behind the **`iroh-swarm`**
|
|
Cargo feature (off by default): `cargo build --features iroh-swarm`.
|
|
- Plain `cargo build` (no feature) is the fleet build and is unaffected by any DHT work.
|
|
|
|
## Verify state (run these first on resume)
|
|
|
|
```bash
|
|
cd ~/Projects/archy-dht
|
|
git branch --show-current # → agent-trust-wip
|
|
git log --oneline -7 # see the commit list below
|
|
git status --short # should be clean (or your in-progress edits)
|
|
git worktree list # archy-dht → agent-trust-wip; archy → main
|
|
# sanity compile (default, fast-ish):
|
|
cargo build --bin archipelago 2>&1 | tail -3
|
|
```
|
|
|
|
---
|
|
|
|
## What is DONE (committed on `agent-trust-wip`)
|
|
|
|
Design doc: `docs/dht-distribution-design.md` (the full plan).
|
|
|
|
| Commit | Phase | Summary |
|
|
| --- | --- | --- |
|
|
| `0fef8086` | base | parked trust module + `seed::derive_release_root_ed25519` (pre-existing) |
|
|
| `27f11bf8` | **0** | signed-catalog authenticity wired: `trust/` module verifies the release-root detached signature in `app_catalog::fetch_one`; release-root KAT pinned |
|
|
| `f0cb91ed` | **1** | BLAKE3 alongside SHA-256: `content_hash.rs`, `ComponentUpdate.blake3`, `BlobMeta.blake3` |
|
|
| `2523c9e3` | **2 seam** | `swarm/mod.rs` — `BlobProvider` + `fetch_content_addressed` (verify peer bytes, origin-always-wins); `iroh-swarm` flag; wired into `update.rs` |
|
|
| `082946aa` | **2 engine** | real `swarm/iroh_provider.rs` over iroh 1.0 + iroh-blobs 0.103 (optional deps). Dep tree proven to resolve+compile against the pinned stack |
|
|
| `9fa56a82` | **3 core** | `swarm/seed_advert.rs` — signed Nostr seed-advertisement protocol (NIP-33 kind 30081, d-tag=blake3) |
|
|
|
|
All tests green at each step. Total new modules: `trust/`, `content_hash.rs`, `swarm/`.
|
|
|
|
## task #12 — Phase 3 glue + wiring — DONE (2026-06-17, NOT yet committed)
|
|
|
|
Implemented in the worktree, **uncommitted** (release in flight — do not commit/merge
|
|
until the user says so). Verified: default `cargo build` clean, `cargo build
|
|
--features iroh-swarm` clean, `cargo test --bin archipelago -- swarm::` → **8/8 pass**.
|
|
|
|
1. **`NostrSeedDiscovery`** (`swarm/iroh_provider.rs`) — `ProviderDiscovery` made
|
|
**async** (`#[async_trait]`); impl queries relays via the new
|
|
`seed_advert::fetch_seed_endpoint_ids` and parses each string with
|
|
`EndpointId::from_str` (`EndpointId = PublicKey`, has `FromStr`/`Display`),
|
|
skipping unparseable. `try_fetch` now `.await`s discovery.
|
|
2. **Publish path** — dep-free `seed_advert::fetch_seed_endpoint_ids` +
|
|
`publish_seed_advert` (reuse now-`pub(crate)` `build_nostr_client` /
|
|
`load_or_create_nostr_keys`); `IrohProvider::seed_and_advertise` imports the blob
|
|
into the FsStore (`blobs().add_path` → `TagInfo`) with a defensive hash-match,
|
|
then publishes. Scope: releases/catalog only.
|
|
3. **Wiring** — `swarm::init()` builds the `IrohProvider` once at startup into a
|
|
`OnceLock<SwarmRuntime>` (keeps endpoint/router alive → keeps seeding);
|
|
`providers()` returns the registered provider; `announce_held_blob()` is called
|
|
from `update.rs` after each release component passes both hash gates. New config
|
|
`swarm_enabled` (`ARCHIPELAGO_SWARM_ENABLED`, default false); `server.rs` calls
|
|
`swarm::init`. All iroh code stays behind `iroh-swarm`; default build inert.
|
|
|
|
**iroh-blobs paid-serving spike (open Q#1) — RESOLVED:** `BlobsProtocol::new(&store,
|
|
Some(EventSender))` + `EventMask` intercept gives native per-request allow/deny
|
|
(`RequestMode::Intercept` → `Result<(), AbortReason>`), connection-level reject
|
|
(`ConnectMode::Intercept`), and per-request throttle/meter (`ThrottleMode::Intercept`).
|
|
|
|
## NEW: Phase 4+ plan (paid streaming / relay / IndeeHub) — `docs/phase4-streaming-ecash-plan.md`
|
|
|
|
Design for: (1) ecash-paid swarm transport, (2) networking through nodes / relay,
|
|
(3) IndeeHub "Archipelago" content source (signed Nostr film catalog, kind 30082).
|
|
Headline: ~80% already exists (Cashu wallet, `streaming/` payment gate + metering,
|
|
4-tier transport, the swarm above). Also shipped this session: a **Networking Profits
|
|
→ Settings** UI in `neode-ui` (new `views/web5/Web5NetworkingProfitsSettings.vue` +
|
|
route + button in `Web5QuickActions.vue` + `common.settings` i18n) that drives the
|
|
existing `streaming.list-services`/`configure-service` RPCs; free-everything is the
|
|
default (all services ship `enabled:false`). Frontend typechecks clean (pre-existing
|
|
`Web5ConnectedNodes.vue` `.did` errors are NOT ours). `neode-ui` deps were
|
|
`npm install`ed to complete a partial install.
|
|
|
|
## After Phase 3
|
|
|
|
- **Phase 4** — IndeeHub films on the same blob layer (Blossom catalog + iroh swarm;
|
|
MinIO origin). Each HLS `.ts` segment = a content-addressed blob.
|
|
- **Phase 0 GO-LIVE (needs the user)** — the catalog/manifest signature anchor
|
|
`trust::anchor::RELEASE_ROOT_PUBKEY_HEX` is still `None`; the pinned KAT is the
|
|
TEST mnemonic, not the real key. Going live = signing ceremony with the **real
|
|
release master seed** (only the user has it) → derive release-root → bake its pubkey
|
|
into `anchor.rs` → sign the real `releases/app-catalog.json`. Until then verification
|
|
is advisory (verify-if-present, anchor not enforced).
|
|
|
|
## Mergeability
|
|
|
|
As of last check we were only ~4 commits diverged from `main`; the only shared-file
|
|
overlap is `seed.rs` + `update.rs`. **Do NOT merge to `main` while the release is in
|
|
flight** — that's the user's call. Sync (merge main → agent-trust-wip) once the
|
|
release lands and `main` is clean.
|
|
|
|
## Background build logs from the last session (may be stale)
|
|
`/tmp/dht-*.log` — phase test/build outputs. Safe to ignore/delete on resume.
|