docs: converge the stack on iroh + Automerge (+ iroh-blobs, iroh-gossip, BLE)

Banks the adoption decision after the spikes. The hand-rolled transport ladder
(LAN/RTC/SSE) collapses into iroh's one key-addressed substrate; the media we'd
have built ourselves are iroh's:
- iroh QUIC = the Mesh (key-dial, holepunch, relay, 0-RTT)
- iroh BLE (iroh-ble-transport, add_custom_transport) = the "BT later" item as a
  feature flag, not a Transport impl — same connection over BLE or IP. Caveats:
  experimental unstable-custom-transports, ~100kbps, AGPL.
- Sync = Automerge (automerge + automerge::sync over an iroh bi-stream); the
  clipboard becomes a CRDT document.
- iroh-blobs subsumes the hand-rolled M/C/E file-frame protocol (content-
  addressed, resumable) — deletes that plumbing.

The convergence is the validation: independently re-deriving QUIC + dial-keys-
not-IPs + key-exchange + holepunch, then finding iroh implements exactly that,
means it's the right substrate — adopted knowingly, not cargo-culted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 00:21:50 -05:00
parent 106e1283cc
commit 069641be4e

View File

@@ -85,20 +85,25 @@ the Mesh. Get them right once and the transport medium becomes a detail.
The Mesh sees every medium through one `Transport` trait. The upper tiers never
know which one carried a byte. Today's ladder, with room to grow downward:
**Decided: adopt iroh as the Mesh** (spike proven, §8 M1M3). The hand-rolled
ladder below collapses into iroh's one key-addressed substrate — and crucially,
the media we'd have hand-rolled (`QUIC`, `BLE`) are iroh's, not ours.
| Transport | Status | Reach | Notes |
|-----------|--------|-------|-------|
| **LAN** (mDNS + length-prefixed TCP) | shipped | same L2 | zero-infra, fastest, works server-down |
| **RTC** (WebRTC data channel) | shipped | cross-network | STUN/TURN via supernode; the web-reachable transport |
| **SSE relay** | shipped | cross-network | signaling + last-resort carry of (E2E) ciphertext |
| **QUIC** | target | cross-network | likely via Iroh; better than hand-rolled RTC |
| **Bluetooth LE** | someday | proximity, no IP | "bitchat-style" — works with no network at all |
| **LoRa / other** | someday | long-range, low-bw | same trait, tiny MTU; sync layer must tolerate it |
| **LAN** (mDNS + length-prefixed TCP) | shipped, *to retire* | same L2 | hand-rolled; iroh does same-LAN direct natively |
| **RTC** (WebRTC data channel) | shipped, *to retire* | cross-network | hand-rolled STUN/TURN; iroh's holepunch+relay replaces it |
| **SSE relay** | shipped, *to retire* | cross-network | signaling + fallback; iroh relay replaces it |
| **iroh QUIC** | **adopted** | LAN + cross-network | one substrate: key-dial, holepunch, relay, 0-RTT |
| **iroh BLE** | feature flag | proximity, no IP | `iroh-ble-transport` via `add_custom_transport()`*same connection over BLE*. Experimental (`unstable-custom-transports`), ~100kbps, **AGPL** |
| **LoRa / other** | someday | long-range, low-bw | iroh custom-transport API (same hook as BLE) if ever needed |
The reason BT/LoRa are *plausible later* rather than *fantasy* is precisely the
trait boundary: a transport only has to (a) discover peers on its medium and
(b) move framed bytes between them. The sync layer already tolerates
multi-transport delivery (it dedups across transports today), which is the same
discipline a high-latency / low-MTU medium demands.
The payoff of adopting iroh: BT is no longer a `Transport` we write — it's a
flag, and the *same* `EndpointId` peer is reachable over BLE or IP with iroh
choosing the path. The convergence is the validation — re-deriving QUIC +
dial-keys-not-IPs + key-exchange + holepunch independently, then finding iroh
already implements exactly that, means it's the correct substrate, adopted
knowingly rather than cargo-culted.
---
@@ -254,10 +259,14 @@ Sync/App tiers above don't change.
The hard networking kernel exists. To become a general substrate:
1. **State sync, not just messages.** Apps need replicated *state* (a doc, list,
board), conflict-free across peers**CRDTs (Automerge / Yjs).** This is the
biggest single addition and the heart of the Sync tier. The clipboard is
stateless message-passing; a backbone is replicated state.
1. **State sync, not just messages — adopt Automerge.** Apps need replicated
*state* (a doc, list, board), conflict-free across peers. **`automerge` (Rust)
+ its transport-agnostic `automerge::sync` protocol over an iroh bi-stream.**
The clipboard becomes an Automerge document (history as a CRDT list) synced
per-peer; app #2 is another document. This is the heart of the Sync tier and
the biggest single addition. **Bonus reuse — `iroh-blobs`** subsumes the
hand-rolled `M/C/E` file-frame protocol entirely: content-addressed,
resumable, deduped blob transfer for files/images, for free.
2. **An app API / SDK.** A clean surface: declare data, subscribe, send. The
thing a developer building app #2 actually touches.
3. **Web target = WASM (resolved by iroh).** The future web client is just