/ architecture / choices.md
choices.md
  1  Great — now we’re at the point where we can stop being abstract and be **opinionated**.
  2  
  3  Below is a **cohesive, end-to-end architecture** where **each layer uses the option that makes the most sense together**, not just individually. This is essentially a **reference P2P system design** optimized for:
  4  
  5  * browser + native
  6  * offline-first
  7  * capability security
  8  * minimal ceremony
  9  * maximal leverage of Cap’n Web
 10  
 11  I’ll flag when a choice is a *layer* vs a *cross-cutting concern*.
 12  
 13  ---
 14  
 15  # The “sane default” P2P stack (opinionated)
 16  
 17  ---
 18  
 19  ## 0. Threat model & trust assumptions *(foundation)*
 20  
 21  **Choice**
 22  
 23  * Zero central authority
 24  * Mutual distrust by default
 25  * Explicit capability delegation
 26  * Eventual consistency
 27  * Offline-first
 28  
 29  **Why**
 30  This aligns with:
 31  
 32  * CRDTs
 33  * content addressing
 34  * UCAN
 35  * Cap’n Web’s authority-by-reference
 36  
 37  ---
 38  
 39  ## 1. Identity *(layer)*
 40  
 41  ### ✅ Choice
 42  
 43  **ed25519 keypair → `did:key`**
 44  
 45  **Why this is the sweet spot**
 46  
 47  * Small keys
 48  * Fast signatures
 49  * Browser-compatible
 50  * DID gives structure without infrastructure
 51  
 52  **Result**
 53  
 54  ```text
 55  did:key:z6Mk…
 56  ```
 57  
 58  ---
 59  
 60  ## 2. Secure transport *(layer)*
 61  
 62  ### ✅ Choice
 63  
 64  **Noise protocol (XX or IK)**
 65  
 66  **Why**
 67  
 68  * Mutual auth
 69  * No PKI
 70  * Works in P2P
 71  * Used by libp2p, WireGuard
 72  
 73  **Browser note**
 74  
 75  * WebRTC DTLS (fallback)
 76  * Identity bound via fingerprint
 77  
 78  ---
 79  
 80  ## 3. Peer discovery *(layer)*
 81  
 82  ### ✅ Choice
 83  
 84  **Hybrid discovery**
 85  
 86  * DHT (Kademlia)
 87  * QR / invite links
 88  * Optional rendezvous server
 89  
 90  **Why**
 91  
 92  * Pure P2P alone has bad UX
 93  * Hybrid keeps decentralization while being usable
 94  
 95  ---
 96  
 97  ## 4. Session establishment *(layer)*
 98  
 99  ### ✅ Choice
100  
101  **Noise handshake + UCAN presentation**
102  
103  Flow:
104  
105  1. Secure channel established
106  2. UCAN sent once
107  3. Verified locally
108  4. Cap’n Web session starts
109  
110  **Why**
111  
112  * Cryptographic trust
113  * No ambient authority
114  * No OAuth servers
115  
116  ---
117  
118  ## 5. Portable authorization *(layer)*
119  
120  ### ✅ Choice
121  
122  **UCAN**
123  
124  **Why UCAN over Biscuit here**
125  
126  * Delegation chains map to P2P
127  * JWT-compatible
128  * DID-native
129  * Designed specifically as “OAuth for decentralized systems”
130  
131  **Usage**
132  
133  * One UCAN per intent
134  * Short expiry
135  * Scoped to resources
136  
137  ---
138  
139  ## 6. Connection-local authorization *(layer)*
140  
141  ### ✅ Choice
142  
143  **Cap’n Web object-capabilities**
144  
145  **Why**
146  
147  * Eliminates permission checks
148  * Impossible to misuse
149  * Perfect fit with UCAN minting
150  
151  **Pattern**
152  
153  ```ts
154  if (ucan.allows("doc:write")) {
155    return new DocumentEditor(docId);
156  }
157  ```
158  
159  ---
160  
161  ## 7. Storage *(layer)*
162  
163  ### ✅ Choice
164  
165  **Content-addressed storage (CAS)**
166  
167  Examples:
168  
169  * IPLD blocks
170  * IPFS-compatible DAGs
171  * Hash-addressed blobs
172  
173  **Why**
174  
175  * Integrity by default
176  * Deduplication
177  * Natural fit with Merkle replication
178  
179  **Local backing**
180  
181  * IndexedDB (browser)
182  * RocksDB / SQLite (native)
183  
184  ---
185  
186  ## 8. Replication *(layer)*
187  
188  ### ✅ Choice
189  
190  **Merkle-DAG replication**
191  
192  **Why**
193  
194  * Partial sync
195  * Lazy fetch
196  * Integrity-preserving
197  * Proven at scale
198  
199  **Mechanism**
200  
201  * Exchange root CIDs
202  * Fetch missing blocks
203  * Verify hashes
204  
205  ---
206  
207  ## 9. Sync *(layer)*
208  
209  ### ✅ Choice
210  
211  **CRDTs (Automerge / Yjs)**
212  
213  **Why**
214  
215  * Offline edits
216  * No conflicts
217  * No locks
218  * Real-time collaboration
219  
220  **Storage model**
221  
222  * CRDT ops stored as blocks
223  * Addressed by hash
224  * Replicated via DAG
225  
226  ---
227  
228  ## 10. Consistency model *(cross-cutting)*
229  
230  ### ✅ Choice
231  
232  **Explicit eventual consistency**
233  
234  **Why**
235  
236  * Anything stronger breaks P2P
237  * UX can be designed around it
238  * Cap’n Web is async-first
239  
240  ---
241  
242  ## 11. State ownership & mutation authority *(layer)*
243  
244  ### ✅ Choice
245  
246  **Capability-scoped mutation**
247  
248  Rules:
249  
250  * Read = hash
251  * Write = capability
252  * Delete = lease + capability
253  
254  **Why**
255  
256  * No ACLs
257  * No roles
258  * No global policy engine
259  
260  ---
261  
262  ## 12. Delegation *(layer)*
263  
264  ### ✅ Choice
265  
266  **Dual delegation**
267  
268  * UCAN for cross-peer
269  * Cap’n Web objects for in-session
270  
271  **Why**
272  
273  * UCAN is portable
274  * Cap’n Web is ergonomic
275  
276  ---
277  
278  ## 13. Revocation *(cross-cutting)*
279  
280  ### ✅ Choice
281  
282  **Expiration + connection lifetime**
283  
284  * UCANs expire quickly
285  * Cap’n Web dies on disconnect
286  * Keys rotate rarely
287  
288  **Why**
289  
290  * Global revocation is poison in P2P
291  
292  ---
293  
294  ## 14. Versioning & history *(layer)*
295  
296  ### ✅ Choice
297  
298  **Immutable append-only history**
299  
300  * CRDT log
301  * Merkle-linked snapshots
302  
303  **Why**
304  
305  * Debuggable
306  * Auditable
307  * Undo/redo for free
308  
309  ---
310  
311  ## 15. Garbage collection *(layer)*
312  
313  ### ✅ Choice
314  
315  **Reachability-based GC**
316  
317  Rules:
318  
319  * Retain pinned roots
320  * Drop unreachable blocks
321  * Respect leases
322  
323  ---
324  
325  ## 16. Performance & flow control *(cross-cutting)*
326  
327  ### ✅ Choice
328  
329  **Async backpressure**
330  
331  * Streaming iterators
332  * Windowed replication
333  * Cap’n Web pipelining
334  
335  ---
336  
337  ## 17. Application protocol *(layer)*
338  
339  ### ✅ Choice
340  
341  **Cap’n Web RPC**
342  
343  **Why**
344  
345  * Bidirectional
346  * Object-capability native
347  * No schemas
348  * Browser-first
349  * Promise pipelining
350  
351  ---
352  
353  ## 18. UX & developer ergonomics *(layer)*
354  
355  ### ✅ Choice
356  
357  **Capability-driven APIs**
358  
359  Principle:
360  
361  > *If you can call it, you’re allowed to.*
362  
363  No:
364  
365  * auth middleware
366  * role checks
367  * headers
368  * global state
369  
370  ---
371  
372  # Final “best sense” stack (one glance)
373  
374  ```
375  UX / APIs                  → Cap’n Web
376  Application Capabilities   → Cap’n Web objects
377  Portable Authorization    → UCAN
378  Identity                  → ed25519 / did:key
379  Secure Transport           → Noise / WebRTC
380  Peer Discovery             → DHT + invites
381  Sync                       → CRDTs
382  Replication                → Merkle DAG
383  Storage                    → Content-addressed
384  ```
385  
386  ---
387  
388  # Why this stack is unusually coherent
389  
390  Because **every layer shares the same mental model**:
391  
392  * Identity = keys
393  * Authority = capabilities
394  * State = immutable history
395  * Change = mergeable ops
396  * Interaction = async objects
397  
398  There are **no impedance mismatches**.
399  
400  That’s rare.
401  
402  ---
403  
404  # If you want to go even deeper next
405  
406  We could:
407  
408  * Walk a **single write** from keystroke → CRDT op → DAG block → replication → Cap’n Web call
409  * Compare this stack to **Solid / ActivityPub / Matrix**
410  * Design a **minimal prototype**
411  * Talk about **global invariants** (the hardest part)
412  * Explore **how far Cap’n Web can go in pure P2P**
413  
414  Just tell me where you want to drill down.