summaryrefslogtreecommitdiffstats
path: root/CLAUDE.md
diff options
context:
space:
mode:
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md56
1 files changed, 55 insertions, 1 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index d5b66c7..6845b5f 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -26,7 +26,7 @@ readily as what is (§15.2, §15.3); a feature that lands deletes its line there
```
meshbay/
├── packages/
-│ ├── meshbay-common/ # Shared crypto + protocol — python3-meshbay-common RPM
+│ ├── meshbay-common/ # Shared crypto + protocol — python3-meshbay-common RPM (LGPL; rest AGPL)
│ ├── meshbay-hub/ # Hub server (FastAPI + PostgreSQL) — meshbay-hub RPM
│ ├── meshbay-node/ # Node daemon + local UI — meshbay-node RPM
│ ├── meshbay-client/ # Desktop client (Electron)
@@ -132,6 +132,60 @@ Scope: `hub`, `node`, `common`, or omitted for cross-cutting
- **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
+## Licensing
+
+**The protocol layer is LGPL-3.0-or-later, in every language; everything else is
+AGPL-3.0-or-later.** The protocol layer is `meshbay-common` (`COPYING.LESSER` +
+`COPYING` in its package) and, in the clients, the files whose first line is
+`// SPDX-License-Identifier: LGPL-3.0-or-later`: `keyderive.js`, `crypto.js`,
+`playlist-crypto.js`, `transport.js`, `transport-*.js`; `meshbay-client/src/`
+`keyring.js`, `transcripts.js`, `argon2-wasm.js`; Android `keys/Kdf.kt`,
+`Keyring.kt`, `Transcripts.kt`. A file without that line has its package's
+licence: the AGPL (`LICENSE` at the root, copied into `meshbay-hub/` and
+`meshbay-node/` because a wheel's `license-files` cannot reach outside its
+package; into `static/licenses/` with the LGPL and GPL, so that every client
+carries all three).
+
+- **An LGPL file depends only on LGPL files, permissive vendored code or the
+ platform.** One import of an AGPL module and a client using the layer is under
+ the AGPL after all. What a host must supply (`window.MeshBayPlatform`,
+ `window.meshbay`, a `Secrets` store) is reached as an injected interface, never
+ imported. `test_licensing.py` checks the closure.
+- **The same piece has the same licence on every platform.** A port is LGPL when
+ its original is (Keyring.kt ↔ keyring.js ↔ keyderive.js), and stays on the AGPL
+ side when its original is part of a shell (DeviceKey.kt ↔ the device key in
+ `main.js`). A new protocol file is added to the list here, to the README, and
+ to `LGPL_FILES` in the test, with its SPDX line. The Android application adds a §7 permission for
+Google Play services (`meshbay-android/LICENSE-EXCEPTION.txt`).
+
+- **A new dependency must be compatible with GPLv3.** Apache-2.0 already is
+ everywhere (watchdog, asyncpg, msgpack, okhttp), so nothing GPLv2-*only* can
+ come in. GPL dependencies exist and are fine for the AGPL packages (mutagen in
+ the node; PyAV's wheel grafts in libx264/libx265) — **but not for
+ `meshbay-common`**, whose point is to be usable under the LGPL: it imports
+ only permissive packages, and keeps doing so. The same goes for the LGPL files
+ in the clients.
+- **Group applications may be under any licence** —
+ `static/licenses/APPLICATION-EXCEPTION.txt`, an AGPL §7 permission over a
+ named surface: the props and registry fields of §9.2–9.4, the exports of
+ `i18n.js`, `icon.js`, `file-utils.js`, `settings-ui.js`, `folder-tree.js`,
+ `style.css`'s classes and the catalogues' keys. **That list is a commitment to
+ third-party authors**: renaming or removing an export of those modules, or a
+ prop, breaks applications nobody here can see. Adding a module to it is a
+ decision, made in the exception file (the test reads the list from there). The
+ reference application (`helloworld-app*.js`) is 0BSD and imports nothing
+ outside that surface, so copying it never brings AGPL code along.
+- **A proprietary dependency is a licensing change, not a dependency.** Play
+ services needed an exception; another one needs its own, and keeps the
+ Android application out of F-Droid until a flavour without it exists.
+- **A vendored file** gets its entry in `static/vendor/PROVENANCE.md` and its
+ licence text in `static/vendor/LICENSES.txt`, in the same commit.
+- **Notices are generated, not listed.** `packaging/third_party_notices.py`
+ writes `THIRD-PARTY-NOTICES.txt` from the metadata of the environment a build
+ ships (the deb/rpm venv, the frozen Windows node); a hand-kept list would be
+ wrong by the next upgrade. The ffmpeg the Windows build fetches is not a
+ Python package and keeps its own `packaging/win/LICENSE-ffmpeg.txt`.
+
## Design, security findings and protocol — one document
**`docs/MESHBAY_DESIGN.md` is the specification.** Everything that used to be