# MeshBay — Development Phases > Reference: architecture spec in `docs/meshbay-draft-v3.md` > POC results: `poc/spike-results.md` --- ## Phase 1 — Foundations ✅ DONE **Goal:** validate all blocking concepts before writing production code. ### Deliverables | Item | Status | Notes | |---|---|---| | POC Spike 1 — Crypto primitives | ✅ | All 22 tests pass. ChaCha20 1MB in 1.1ms. | | POC Spike 2 — Hub skeleton | ✅ | 12/12 endpoints. JWT EdDSA offline verify in 884µs. | | POC Spike 3 — Node registration | ✅ | Full handshake. jti bug found and fixed. | | POC Spike 4 — NAT traversal | ✅ | Cone NAT on SFR. UDP P2P works. UPnP disabled (SFR). | | POC Spike 5 — Encrypted transfer | ✅ | 1MB P2P. 3.2ms encrypt, 3.9ms decrypt. 4.3MB/s. | | POC Spike 6 — GEK distribution | ✅ | X25519+HKDF wrap/unwrap. 0.48ms/0.59ms. Hub opaque. | | Security cleanup meshbay.org | ✅ | UFW: 22/80/443 only. No services exposed. | | Git monorepo | ✅ | 3 packages: meshbay-common, meshbay-hub, meshbay-node. | | Draft v3 | ✅ | POC findings integrated. All corrections applied. | | CLAUDE.md conventions | ✅ | Python 3.12+, uv, ruff, SemVer, commit format. | ### Key findings from POC - jti mandatory in all JWTs (Ed25519 is deterministic — same payload = same token) - Argon2id at 64MB/3iter = 78ms — increase to 256MB for production (~500ms target) - NAT order: STUN/hole-punching is priority 2, not UPnP (UPnP disabled on tested SFR box) - TCP+TLS for v1 transport; QUIC in v2 - GEK wrapping: ephemeral X25519 + HKDF(salt=pk_eph) + ChaCha20-Poly1305(aad=pk_recipient) --- ## Phase 2 — Node v1 ✅ DONE **Goal:** working Mesh Node: indexes a directory, registers with hub, serves encrypted chunks over TCP+TLS, local web UI on localhost:18000. **Transport:** TCP+TLS 1.3 (QUIC in v2). Self-signed cert per node. Node identity verified via Ed25519 PK from hub, not TLS cert chain (client uses CERT_NONE). ### Milestones | # | Component | File(s) | Tests | |---|---|---|---| | 2.1 | Keystore | `meshbay_node/keystore.py` | 10/10 | | 2.2 | Hub client | `meshbay_node/hub_client.py` | 6/6 | | 2.3 | Directory indexer | `meshbay_node/indexer/indexer.py` | 5/5 | | 2.4 | Mesh Group Index | `meshbay_node/indexer/group_index.py` | 5/5 | | 2.5 | TCP+TLS chunk server | `meshbay_node/transport/server.py` | 3/3 | | 2.6 | TCP+TLS chunk client | `meshbay_node/transport/client.py` | included above | | 2.7 | TLS cert helper | `meshbay_node/transport/tls_cert.py` | — | | 2.8 | Config (TOML + env) | `meshbay_node/config.py` | — | | 2.9 | Local web UI | `meshbay_node/ui/app.py` | — | | 2.10 | Daemon + CLI | `meshbay_node/daemon.py` | — | **Total: 29/29 tests passing** ### Python dependencies (dev venv — `/home/cbesson/meshbay/.venv`) Installed packages (freeze) as of Phase 2 completion: ``` aioice==0.10.2 # ICE/STUN for NAT traversal blake3==1.0.9 # fast content hashing cryptography==50.0.0 # Ed25519, X25519, ChaCha20, Argon2id, AES-GCM fastapi==0.141.1 # local web UI + hub POC httpx==0.28.1 # hub client HTTP meshbay-common==0.1.0 # editable install meshbay-node==0.1.0 # editable install msgpack==1.2.1 # wire serialisation PyJWT==2.13.0 # JWT EdDSA pytest==9.1.1 # test runner pytest-asyncio==1.4.0 # async test support uvicorn==0.52.1 # ASGI server (local UI) watchdog==6.0.0 # filesystem watcher zstandard==0.25.0 # zstd compression ``` Also installed transitively: pydantic 2.13.4, starlette 1.6.0, anyio 4.14.2, uvloop 0.22.1. ### meshbay_common/crypto.py — Argon2id NOTE Current params: `iterations=3, memory_cost=65536` (64MB) → ~78ms on dev laptop. **Must increase to `memory_cost=262144` (256MB) before production keystore use.** Run `meshbay-node calibrate-argon2` on target hardware to tune. ### Out of scope for Phase 2 Multiple groups, chat, QUIC, module sandbox, mobile pairing, HLS streaming. --- ## Phase 3 — Hub v1 production ✅ DONE **Goal:** replace POC in-memory hub with a production-ready service on meshbay.org. PostgreSQL persistence, HTTPS via Caddy, all endpoints hardened, legal IP logging, deploy. ### Environment - **Server:** meshbay.org — Ubuntu 26.04 LTS, Python 3.14.4, OVH VPS - **Database:** PostgreSQL 16 (to install) - **Proxy:** Caddy (to install — handles Let's Encrypt automatically) - **Service:** systemd `meshbay-hub.service` ### Python dependencies to add (Phase 3) ``` sqlalchemy>=2.0 # async ORM (SQLAlchemy 2.x) alembic>=1.13 # DB migrations asyncpg>=0.30 # PostgreSQL async driver aiosqlite>=0.20 # SQLite async driver (tests only) slowapi>=0.1 # rate limiting (FastAPI middleware) ``` ### Milestones | # | Component | File(s) | Status | |---|---|---|---| | 3.1 | DB models | `meshbay_hub/db/models.py` | ✅ | | 3.2 | DB engine + session | `meshbay_hub/db/engine.py` | ✅ | | 3.3 | Alembic migrations | `meshbay_hub/db/migrations/` | ✅ initial_schema | | 3.4 | Hub config | `meshbay_hub/config.py` | ✅ | | 3.5 | Auth (JWT + Argon2id) | `meshbay_hub/auth.py` | ✅ | | 3.6 | API deps | `meshbay_hub/api/deps.py` | ✅ | | 3.7 | Hub info router | `meshbay_hub/api/hub.py` | ✅ | | 3.8 | Users router | `meshbay_hub/api/users.py` | ✅ | | 3.9 | Nodes router | `meshbay_hub/api/nodes.py` | ✅ | | 3.10 | Groups router | `meshbay_hub/api/groups.py` | ✅ | | 3.11 | Rate limiting | `meshbay_hub/api/middleware.py` | ✅ slowapi | | 3.12 | App factory + lifespan | `meshbay_hub/app.py` | ✅ | | 3.13 | Hub daemon CLI | `meshbay_hub/daemon.py` | ✅ | | 3.14 | PostgreSQL 16 | meshbay.org | ✅ DB: meshbay_hub | | 3.15 | Caddy + Let's Encrypt | meshbay.org Caddyfile | ✅ HTTPS auto-cert | | 3.16 | Systemd service | `/etc/systemd/system/meshbay-hub.service` | ✅ | | 3.17 | Deploy + smoke test | https://meshbay.org | ✅ 11/11 endpoints | **Total: 40 local tests (SQLite) + 11/11 smoke tests HTTPS production** ### Phase 3 deployment details (meshbay.org) - PostgreSQL 16, user `meshbay`, DB `meshbay_hub` - Caddy auto-handles Let's Encrypt for `meshbay.org` and `www.meshbay.org` - `www.meshbay.org` → 301 redirect → `meshbay.org` - TLS setup documented in `docs/HTTPS.md` - Hub listens on `127.0.0.1:8000`, Caddy proxies 80/443 - Systemd service: `meshbay-hub.service` (restart-on-failure) - Hub config: `~/.config/meshbay/hub.toml` - Hub keypair: `~/.config/meshbay/hub_private.pem` (chmod 600) - Source deployed at: `~/meshbay-hub/` (common_pkg + hub_pkg) ### Additional Python dependencies added in Phase 3 ``` sqlalchemy==2.0.51 # async ORM alembic==1.19.1 # DB migrations asyncpg==0.31.0 # PostgreSQL async driver aiosqlite # SQLite async (tests only) slowapi==0.1.10 # rate limiting hatchling==1.31.0 # build backend (needed for pip install) ``` ### Notes - Initial DB schema created via `init_db()` (`create_all`) — Alembic tracks future changes - IP logging records: account_create, login, login_fail, group_create, node_announce - Rate limiting active on /v1/users/register and /v1/users/login (slowapi) - Revocation, CSAM hash matching, moderation deferred to Phase 5 ### Phase 3 scope **In scope:** - All POC endpoints from Spike 2+6, production-ready - PostgreSQL via SQLAlchemy async + Alembic migrations - IP logging (creation, login, group events) — 1-year retention, legal compliance - Access token (JWT, 1h) + refresh token (30d, stored hashed) - Rate limiting on auth endpoints - Hub config file `/etc/meshbay/hub.toml` or env vars - HTTPS via Caddy + auto Let's Encrypt on meshbay.org - Systemd service with restart-on-failure **Deferred to later:** - Revocation push (WebSocket signaling to nodes) - CSAM hash matching (NCMEC/IWF integration) - Moderation flow (blocklist + takedown) - MHP federation - RPM/DEB packaging ### Testing strategy - Unit tests with SQLite in-memory (`aiosqlite`) — no PostgreSQL needed locally - API tests via `httpx.AsyncClient` + `ASGITransport` — no network - All tests run in the existing `.venv` after adding Phase 3 deps --- ## Phase 4 — Integration & Client **Goal:** end-to-end working product: node + hub + web client. | # | Component | Notes | |---|---|---| | 4.1 | Web client (browser) | Browse Mesh Group Index, download, stream VOD | | 4.2 | End-to-end integration test | Node ↔ Hub ↔ Client full flow | | 4.3 | HLS/DASH streaming | Node segments on-the-fly, per-segment GEK-derived key | | 4.4 | Chat (Double Ratchet) | Group messaging with attachments, Signal-like | | 4.5 | Multi-group + multi-dir | Node hosts N groups across M directories | --- ## Phase 5 — QUIC, Federation, Mobile **Goal:** full decentralization, mobile support, community infrastructure. | # | Component | Notes | |---|---|---| | 5.1 | QUIC transport (MNP v2) | Replace TCP+TLS with aioquic; same application protocol | | 5.2 | MHP federation | Hub-to-hub Mesh Directory exchange, explicit peer allowlist | | 5.3 | Mesh Relay | Community TURN relay registration protocol | | 5.4 | Android client | Kotlin/Flutter, hub account, group access, node pairing | | 5.5 | Content replication | Node-to-node, admin-authorized, no hub involvement | | 5.6 | iOS client | After Android stabilizes | | 5.7 | Revocation push | WebSocket hub→node signed token broadcast | | 5.8 | CSAM hash matching | NCMEC/IWF integration on public content registration | | 5.9 | Moderation flow | blake3 blocklist, DMCA takedown, escalation | | 5.10 | RPM/DEB packaging | meshbay-hub, meshbay-node, python3-meshbay-common | --- ## Conventions - Commits: `feat(node):`, `fix(hub):`, `chore(common):`, `docs:`, `test(node):` - Branch per feature/fix, merge to `main` (when remote configured) - **Always close test UFW ports after any spike on meshbay.org** - **Never commit key material** (keystore.enc, hub_private.pem, *.key, node_state.json, unlock.key) - meshbay.org is internet-facing: only run known-safe services, close ports after tests