# MeshBay — Project Conventions ## What this project is MeshBay is a decentralized peer-to-peer platform for file sharing, video streaming, and group messaging. See `docs/meshbay-draft-v3.md` for the architecture specification. ## Repository structure ``` meshbay/ ├── packages/ │ ├── meshbay-common/ # Shared crypto + protocol — python3-meshbay-common RPM │ ├── meshbay-hub/ # Hub server (FastAPI + PostgreSQL) — meshbay-hub RPM │ └── meshbay-node/ # Node daemon + local UI — meshbay-node RPM ├── poc/ # POC spike scripts (reference, not production) ├── docs/ # Architecture drafts and POC plans ├── packaging/ # RPM spec files, DEB control files, systemd units └── QE/ # NOT versioned (.gitignore) — test artefacts, credentials, demos ├── demo-v1/ # Scripts démo opérationnels (setup_demo.py, run_node.py, download.py) ├── spikes/ # Expérimentations futures (remplace ~/draft/) └── server-state/ # Inventaire de ce qui tourne sur meshbay.org ``` **Règle QE/** : tout test sur meshbay.org doit ouvrir le port UFW, tester, et fermer le port + tuer les processus dans le MÊME bloc de commandes. Jamais de processus orphelins ni de ports ouverts après un test. ## Python environment - **Minimum Python:** 3.12 - **Build backend:** hatchling (per package `pyproject.toml`) ```bash # Créer le venv (--clear si recréation sur une autre machine/OS) python3 -m venv .venv --clear source .venv/bin/activate # Toutes les dépendances sont déclarées dans les pyproject.toml — un seul pip install suffit pip install -e packages/meshbay-common -e packages/meshbay-hub -e packages/meshbay-node pip install pytest pytest-asyncio aiosqlite # extras dev ``` Les deps clés (aioquic, watchdog, fastapi, blake3, etc.) sont dans les `pyproject.toml` et installées automatiquement. Ne pas ajouter manuellement des packages sans les déclarer dans le bon `pyproject.toml`. > **Ne jamais copier `.venv/` entre machines d'OS différents.** Si rsync depuis Fedora vers Ubuntu, > exclure `.venv/` et recréer sur la cible avec `python3 -m venv .venv --clear`. > Sans `--clear`, `certifi.where()` pointe vers un chemin Fedora inexistant sur Ubuntu → `FileNotFoundError`. ```bash # Lancer les tests .venv/bin/pytest ``` ## Code conventions - **Linter/formatter:** ruff (`uv run ruff check .` / `uv run ruff format .`) - **Line length:** 100 - **Type hints:** required on all public functions - **Comments:** only when the WHY is non-obvious; no docstrings restating the function name - **No prints in library code** — use `logging` module ## Versioning ### Package versions (SemVer) - Format: `MAJOR.MINOR.PATCH` - Pre-1.0: breaking changes bump MINOR, not MAJOR - All three packages share the same version number (released together) ### Protocol versions (independent) - MNP: `0.1` → bumped independently of package version - MHP: `0.1` → bumped independently of package version - Every wire message carries a `v` field - Breaking change → MAJOR bump; backward-compatible → MINOR bump - N-2 MINOR backward compatibility guaranteed ## Commit messages (Conventional Commits) ``` feat(node): add directory watcher with watchdog fix(hub): include jti in all JWT tokens chore(common): add Argon2id calibration to crypto.py docs: update draft v3 with POC findings test(common): add wrap/unwrap GEK round-trip test ``` Types: `feat`, `fix`, `chore`, `docs`, `test`, `refactor`, `perf` Scope: `hub`, `node`, `common`, or omitted for cross-cutting ## Security rules - **Never commit private keys** (hub_private.pem, *.key, unlock.key, keystore.enc) - **Never commit QE/** — credentials, test keys, demo data go there - **Never log GEK, private keys, or plaintext passwords** — even at DEBUG level - **meshbay.org is internet-facing** — open port → test → close port + kill processes in same block ## Known calibration TODOs - Argon2id `memory_cost`: currently 65536 (64 MB, 78ms) — increase to 262144 (256 MB) before prod to target ~500ms on typical home server hardware. Implement a `calibrate` CLI command. ## NAT traversal — résultats empiriques (demo-v2) SFR résidentiel Fedora 44 → meshbay.org OVH VPS : - **IPv6** : adresse publique présente MAIS entrant bloqué par la box → skippé - **NAT type** : **Port-Restricted Cone** (pas Address-Restricted comme supposé en Spike 4) - **Mécanisme validé** : `QuicChunkServer.punch_nat(peer_ip, peer_port)` envoie la probe depuis le socket QUIC interne (`_transport.sendto()`). Le client DOIT se connecter depuis le même port (local_port=QUIC_PORT dans QuicChunkClient). - **UPnP** : désactivé sur box SFR → skippé - **Handshake QUIC** : 12.7s (demo) → < 500ms attendu en prod (gap probe↔connect réduit + 0-RTT) - **Scripts** : `QE/demo-v2/` — run_node.py / download.py / nat.py / setup_demo.py ## Key modules — où trouver quoi | Besoin | Module | Fichier | |---|---|---| | Chiffrement chunks (prod) | `meshbay_common.crypto` | `crypto.py` | | Dérivation clés depuis password | `meshbay_common.keyderive` | `keyderive.py` | | Bundle clés (web) | `meshbay_common.keyderive` | `keyderive.py` + `static/keyderive.js` | | GEK wrap/unwrap (ECIES) | `meshbay_common.crypto` | `crypto.py` | | Double Ratchet (chat) | `meshbay_common.ratchet` | `ratchet.py` | | AES-GCM (navigateur) | `meshbay_common.webcrypto` | `webcrypto.py` + `static/crypto.js` | | Keystore node | `meshbay_node.keystore` | `keystore.py` | | NAT traversal | `QE/demo-v2/nat.py` | non versionné — résultats dans devel-phases.md | | QUIC NAT punch | `meshbay_node.transport.quic_server` | `QuicChunkServer.punch_nat()` | | Scripts de démo opérationnels | — | `QE/demo-v1/*.py` (non versionné) | ## meshbay.org server (état cible) - OS: Ubuntu 26.04 LTS, Python 3.14.4 - SSH: `ssh cbesson@meshbay.org` - Caddy : reverse proxy HTTPS sur 80/443 - UFW rules: **22/tcp, 80/tcp, 443/tcp uniquement** - Services légitimes : `meshbay-hub.service`, Caddy, PostgreSQL (local) - Inventaire détaillé : `QE/server-state/meshbay.org.md` - Deploy hub : voir `QE/server-state/meshbay.org.md`