diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-12 13:48:09 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-12 16:36:54 +0200 |
| commit | ef4842644a207c3d1b6d6f06c1ad1055270ae283 (patch) | |
| tree | 965b3a5f5d27a10c25186b70c108fdcaf126fe1f /docs | |
| parent | e16be41ce2862f78d98efc6b44f957dc98e96280 (diff) | |
| download | meshbay-ef4842644a207c3d1b6d6f06c1ad1055270ae283.tar.gz | |
docs: AV16–AV17, and why node --check is not the check
AV16 the allowance that survives a restart and that an operator can see and
change; AV17 the single worker.
And a lesson that cost a full suite run: `node --check` reports success on a
module-syntax error. An unclosed `.map(` inside a tagged template came back
clean four times. `test_spa_syntax.py` says exactly this in its own docstring
— copying to `.mjs` is what forces the module parser — and the reflex still
reached for `node --check`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T4YmK41VsEURWFdop4EEeT
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/MESHBAY_DESIGN.md | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/docs/MESHBAY_DESIGN.md b/docs/MESHBAY_DESIGN.md index 8da4552..be74e64 100644 --- a/docs/MESHBAY_DESIGN.md +++ b/docs/MESHBAY_DESIGN.md @@ -2530,6 +2530,8 @@ had already been asked. | **AV13** | **The mail server is not a relay, and `mail.py` is where that is decided.** Every message passes one function; `purpose` is keyword-required and checked against a closed list, so a helper that names anything else does not send and one that names nothing is a TypeError. Under it sit a bound per **recipient** — the thing a person being mail-bombed actually experiences, unmoved by which account, address or endpoint asks — and an instance-wide hourly ceiling, because registration is open and "per account" is a bound an attacker buys more of | | **AV11** | **A namespace a client writes into is closed, and its rows are capped.** The preference key space is an allow-list plus `default_tab:<group_id>` checked as a group id, the value is length-bounded, and the row count per account is bounded | | **AV12** | **Every list has an upper bound on `limit` and a floor under `offset`.** Including the ones that take no authentication at all — the public group directory and the content blocklist | +| **AV16** | **A bound the operator can see and change, and that a restart does not forget.** The mail allowance lives in `mail_quota`, not in a module dict — a deploy used to hand out a fresh budget, and the hub is deployed often. The values are settings with defaults in `hub.toml` and a block in the admin panel, because the hour a budget runs out is not when anyone wants to edit a file and restart; `/v1/admin/mail` says how much of the hour is left, which was previously visible only as an absence of mail | +| **AV17** | **The hub runs on exactly one worker, and says so at startup.** `_connected_nodes`, `_node_groups`, `_webrtc_answers` and the relay registry are per-process: a second worker makes a node intermittently unreachable for half its members, which is a symptom that describes something else entirely | | **AV14** | **MHP binds its audience, and the hub reads its own identity at call time.** A token is minted for one peer and accepted by that peer only. `federation.py` bound `_hub_id` and `_hub_sk_pem` at import, which is before `load_hub_keypair` runs, so it signed with `None` and called itself `meshbay.org` whatever the instance was named — and the verifier named no audience for the `aud` the issuer sets, which PyJWT refuses outright. MHP could not complete one authenticated request between two hubs | | **AV15** | **A hash is checked for shape before it is a key lookup**, on the unauthenticated blocklist endpoints a node consults | |