summaryrefslogtreecommitdiffstats
path: root/tmp-decisions.md
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-01 16:05:16 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-01 16:05:16 +0200
commit8a6294b0412a86f378c6e2e937c28de64a903c91 (patch)
tree20d1977d9148a2c86c62925c5be7e571815c9057 /tmp-decisions.md
parent854a9441ccb734c7fbb1e0ff8570b9ef659c09b0 (diff)
downloadmeshbay-8a6294b0412a86f378c6e2e937c28de64a903c91.tar.gz
docs: move root docs into docs/ and archive superseded drafts
Move the remaining root-level .md files (except CLAUDE.md) into docs/: devel-phases.md, devel-phases-next.md, first-review.md, second-review.md, tmp-decisions.md. Update all inbound references in CLAUDE.md (now docs/-prefixed) and strip the now-redundant docs/ prefix from links inside the moved files. Consolidate the superseded material into docs/old-draft.md: architecture drafts v1-v4, POC v1, and the Phase 1-12 development log, each under an ARCHIVED banner with a preamble pointing at the current specs. Delete the merged originals plus the unreferenced French translations (v1-fr, v2-fr, poc-v1-fr). Repoint the surviving file-links in first-review.md, second-review.md and meshbay-draft-v5.md at old-draft.md; prose "draft-v3 §x" mentions are left as-is since the content now lives in the archive. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J74kj44q6REczub8XR3DRy
Diffstat (limited to 'tmp-decisions.md')
-rw-r--r--tmp-decisions.md181
1 files changed, 0 insertions, 181 deletions
diff --git a/tmp-decisions.md b/tmp-decisions.md
deleted file mode 100644
index 76d33d2..0000000
--- a/tmp-decisions.md
+++ /dev/null
@@ -1,181 +0,0 @@
-# Client architecture — decisions
-
-> Created 2026-08-13 after the second security review. D1/D2/D3 decided the same day;
-> D4 (hub minimization) deferred. Fold into `docs/meshbay-draft-v5.md`.
-> The analysis below is kept as the rationale behind the decisions, not as open questions.
-
----
-
-## Status
-
-| # | Decision | State |
-|---|---|---|
-| D1 | Does the hub keep serving the web UI? | ✅ **DECIDED 2026-08-13 — yes** |
-| D2 | Browser extension, native desktop client, or both? | ✅ **DECIDED 2026-08-13 — native client, offered alongside the hub-served SPA.** Shell revised 2026-08-17: **Electron**, see `docs/desktop-client-v1.md` |
-| D3 | Transport: aiortc primary, QUIC at parity, TCP+HTTP removed | ✅ Decided 2026-08-13. Unchanged for the **node**; the desktop client uses Chromium's WebRTC rather than aiortc, and QUIC via a Python sidecar |
-| D4 | Hub minimization (old Phase 12) | ⏸️ **Deferred, may be dropped** |
-
-> **2026-08-17 — the browser-extension options are no longer live.** 12.2 (signed digest
-> of the served bundle) is what Option A needed, and it remains scheduled; nothing else
-> from A or B is planned. The desktop client is the answer to T3 for users who want one.
-
-**What was decided.** The hub keeps serving the web UI — that is the zero-install path
-and it stays. A native desktop client is offered *in addition*, not as a replacement.
-Hub minimization is off the critical path and may be dropped entirely.
-
-**What that means, stated once and then respected.** Keeping the hub in the trusted path
-is a legitimate product call, and this project is not obliged to defend against its own
-operator. But two consequences should be carried deliberately rather than by accident:
-
-1. **T3 is accepted permanently for browser users.** A hub that serves the code can
- exfiltrate keys from the page regardless of what the protocol does. The native client
- gives users who care an alternative; browser users are trusting meshbay.org, and the
- docs should say so plainly rather than claiming end-to-end integrity.
-2. **H3 was the last open High finding and its only fix lived in the dropped phase.**
- The hub is the public key directory: substituting a key during an invite hands it the
- group key, silently, with no forgery and no code injection. So key transparency and
- safety numbers were kept and are now Phase 12.1 — everything else from hub
- minimization is dropped. If Phase 12 is later dropped too, H3 stays open by choice,
- and "unreadable by other parties, even the hub" stops being a claim the project can
- make about an adversarial hub.
-
-The honest framing that survives all of this: **the hub cannot read your content unless
-it actively attacks you.** That is still a strong property, and it is defensible.
-
-## Rationale — why the native client is not a T3 fix
-
-The second review recommended a native client and claimed *"T3 disappears — code integrity
-stops depending on the hub."* **That claim was wrong and has been corrected** in
-`second-review.md` §9.
-
-If the hub operator is the adversary, a native client downloaded from `meshbay.org` and
-signed with a key that operator holds does not remove the trust — it relocates it from "the
-JS they serve" to "the binary they serve." What actually changes is **detectability**:
-
-- **Browser:** an attack is one HTTP response, targeted at one user, leaving no artifact.
- Undetectable in principle.
-- **Native:** an attack requires shipping a build. That build is an artifact — hashable,
- archivable, comparable between users, reversible. Targeting one user means giving them a
- different binary, which reproducible builds and published hashes make detectable.
-
-That is a real improvement, but **the value lives in the verification machinery
-(reproducible builds, published hashes, independent rebuilds — Phase 18.7), not in the
-packaging format.** Without it, a native client from meshbay.org is only marginally more
-trustworthy than the SPA from meshbay.org.
-
-Native also has real costs that were under-weighted: loss of the browser sandbox (a Python
-process with full user privileges vs a seccomp-confined renderer), ownership of patch
-velocity for WebKitGTK and every bundled dependency, and new attack surface (loopback media
-server, IPC bridge, update client).
-
-**Conclusion recorded:** the native client is justified on *product* grounds — durable keys,
-no browser tab, background connectivity, better video, hub-less `group://` access over QUIC.
-It should not be justified as the fix for T3 unless 18.7 ships with it.
-
----
-
-## D1 rationale — hub keeps serving the UI ✅
-
-Keeping it is defensible. It is how anyone tries the platform without installing anything,
-and it stays the fallback when a device has no client installed.
-
-What must be true now that it stays (Phase 12.2/12.3):
-
-- strict CSP and Subresource Integrity on the bundle
-- the hub publishes a **signed digest** of the served bundle, so any third party — an
- extension, a native client, a curious user — can verify it
-- `/app/` carries an explicit, visible "reduced trust: this hub serves this code" notice
-- the docs never claim end-to-end integrity for the hub-served SPA path
-
-The honest framing: hub-served SPA is a **convenience tier**, not the secure tier.
-
----
-
-## D2 rationale — native chosen; extension not taken up
-
-Three shapes, cheapest first:
-
-**Option A — Extension as a verifier (hub still serves the UI)**
-The extension does not ship the UI. It hashes the bundle the hub served and compares it
-against a digest signed by the project. Mismatch → visible alarm, optionally block.
-Converts a silent targeted injection into a loud one. Small effort, keeps today's
-architecture, compatible with D1 = yes.
-
-**Option B — Extension ships the UI (hub serves the API only)**
-The UI lives in the extension, distributed and signed by Mozilla/Chrome — a channel **the
-hub operator does not control**. Manifest V3 forbids remote code, which works in our favour:
-the structure enforces exactly what we want. Keys live in extension storage, isolated from
-page JS. Moderate effort.
-
-**Option C — Native desktop client** ← **CHOSEN**
-Phase 13. Full control, durable keys in an OS keystore, QUIC, hub-less access, best UX.
-Highest effort, and the security argument depends on 18.7.
-
-> **Shell revised 2026-08-17: Electron, not pywebview** (+ an optional Python sidecar for
-> `group://` over QUIC). See `docs/desktop-client-v1.md` §2. The comparison table below
-> was written against pywebview and **two of its rows are wrong for the chosen shell**:
->
-> - *Browser sandbox* — Electron with `sandbox` and `contextIsolation` **keeps** the
-> Chromium renderer sandbox. The row reads "❌ None (partial under Flatpak)"; that was
-> WebKitGTK's property, not native's.
-> - *Crypto available* — the client keeps WebCrypto **and** gains local Argon2id/ChaCha20
-> in the main process; the row implied WebCrypto is lost with the browser engine.
->
-> The row that gets *worse*: **patch velocity**. "You own it" is more true of Chromium
-> than of a distro-maintained WebKitGTK, and the renderer parses attacker-controlled
-> content from nodes. That is the real cost and it is accepted deliberately.
-
-### Comparison
-
-| | Hub-served SPA (today) | A: extension verifies | B: extension ships UI | C: native desktop |
-|---|---|---|---|---|
-| Code distribution channel | Hub (the adversary) | Hub, but **verified** | Store (independent) | Hub download + own signing key |
-| Silent targeted injection | Undetectable | **Detected** | Not possible | Detectable *if* 18.7 |
-| Browser sandbox | ✅ Full | ✅ Full | ✅ Full | ❌ None (partial under Flatpak) |
-| Patch velocity | Browser auto-updates | Browser auto-updates | Browser + store review latency | **You own it** (WebKitGTK, Python deps) |
-| Key storage | IndexedDB, page-reachable | unchanged | Extension storage, page-isolated | **OS keystore** |
-| Crypto available | WebCrypto only (no ChaCha20/Argon2id) | unchanged | unchanged | **Full** (ChaCha20, Argon2id 256 MB) |
-| Transport | WebRTC | WebRTC | WebRTC | WebRTC **+ QUIC** |
-| Large file → disk | Chrome only (FS Access API) | unchanged | unchanged | **Native, unlimited** |
-| Hub-less `group://` | ❌ | ❌ | ❌ | ✅ |
-| New attack surface | — | negligible | negligible | loopback server, IPC, updater |
-| Platforms to maintain | 0 | 2 stores | 2 stores | 3 OSes |
-| Effort | 0 | Low | Moderate | High |
-
-### Observations for the decision
-
-- **A and B are not exclusive with C.** A/B protect browser users; C serves users who want a
- real application. "Both" is coherent — just sequence them.
-- **B gives most of C's security benefit at a fraction of the cost**, because the win was
- never the packaging format — it was getting the code off the adversary's distribution
- channel — and the extension keeps the browser sandbox while doing it.
-- **Store review latency is the one place B is worse than C**: a critical fix waits on
- Mozilla/Google. Mitigate with a version-pinned kill switch.
-- **For node operators specifically, Phase 14 (CLI) beats all three.** The operator is the
- highest-value target — holds the GEK, is the content authority — and today must use
- hub-served JS to initialize GEKs and invite members. The CLI removes that dependency at a
- fraction of any client's cost. If only one thing gets built for T3, it should be the CLI.
-- If **D1 = yes** (hub keeps serving the UI), Option A is the natural companion and is nearly
- free once 12.6 publishes the signed digest.
-
-### Not yet investigated
-
-- Whether AMO/Chrome Web Store policy accepts an extension whose purpose is P2P file sharing
-- Whether MV3 service-worker lifetimes can hold a long-lived WebRTC DataChannel (may need an
- offscreen document — worth a spike before committing to B)
-- Safari/iOS: no extension route comparable to AMO; likely out of scope either way
-
----
-
-## Impact on the roadmap
-
-| Decision | If yes | If no |
-|---|---|---|
-| D1 hub serves UI | Phase 12.6 as written (CSP, SRI, signed digest, reduced-trust notice) | 12.6 shrinks to removing `/app/`; hub becomes API-only |
-| D2 = A | Small new phase; 12.6 is a prerequisite | — |
-| D2 = B | New phase, ~Phase 13-sized; 13.1 platform split is reused directly | — |
-| D2 = C | Phase 13 as written (13.2–13.11), + 18.7 for the security claim to hold | Phase 13 reduces to 13.1 only |
-
-**13.1 (platform adapter split) is worth doing regardless of D2.** It is pure refactoring
-whose acceptance criterion is "the browser SPA behaves identically," and it is the
-prerequisite for A, B and C alike.