summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/MESHBAY_DESIGN.md24
1 files changed, 18 insertions, 6 deletions
diff --git a/docs/MESHBAY_DESIGN.md b/docs/MESHBAY_DESIGN.md
index f1c0a67..33ab6fa 100644
--- a/docs/MESHBAY_DESIGN.md
+++ b/docs/MESHBAY_DESIGN.md
@@ -2363,6 +2363,14 @@ extension-gated: two container formats tag perfectly and decode in no mainstream
engine, so for those the node performs a **one-shot whole-file conversion**, cached
under its own content hash and served through the ordinary chunk path.
+**That conversion has a size ceiling, and it is the cache's rather than
+memory's.** The result is one row in a 512 MB least-recently-used store sized for
+thumbnails, posters and subtitle tracks; a source hours long would be a single row
+that evicts most of the cache to fit and is evicted again by the next few
+thumbnails. Whole-file is the right shape for the few-megabyte sources this
+exists for, and the wrong one past that — serving audio of that length means
+streaming the conversion, which is a different feature and not this one.
+
**The player is persistent across tabs**, at shell level: closing the tab must not
stop the music. The next queued track is prefetched while one plays — client-side
only, a small in-memory cache evicted as the queue moves.
@@ -2890,7 +2898,7 @@ had already been asked.
| **AV6** | **A relay proves possession of its approved key.** A public key is not a password, and the register call is unauthenticated by design — it is not a user — so the proof is the only thing standing between a stranger and where nodes send relayed traffic |
| **AV7** | **A node bounds how many peers it holds and how long an unproven one lasts.** The hub's cap is per calling account, which is a limit on each member and not on the machine, so without this an operator's exposure grew with the size of their groups |
| **AV8** | **One account cannot make the hub mail another at will.** The invitation email's subject comes from the group row, never from the request, and the endpoint is metered |
-| **AV9** | **No mail is sent from the event loop.** `smtplib` is synchronous and waits up to ten seconds; called from an async handler that wait is the whole instance's, not one request's. Every send goes through `mail.send_off_loop`. **Argon2 is held to the same rule**: every derivation runs on one dedicated worker thread (`auth.*_off_loop`), never on the loop and never two at a time, because two concurrent `lanes=4` derivations deadlock in OpenSSL. **So is the node's disk**: every filesystem call on a group's content — the stat as much as the read, since a stat is what wakes a sleeping disk — goes through `roots.off_disk`, onto one worker thread per root set. A spun-down or network-mounted root answers its first syscall in seconds, and on the loop that is every group, every stream and the hub socket waiting for a platter |
+| **AV9** | **No mail is sent from the event loop.** `smtplib` is synchronous and waits up to ten seconds; called from an async handler that wait is the whole instance's, not one request's. Every send goes through `mail.send_off_loop`. **Argon2 is held to the same rule**: every derivation runs on one dedicated worker thread (`auth.*_off_loop`), never on the loop and never two at a time, because two concurrent `lanes=4` derivations deadlock in OpenSSL. **So is the node's disk**: every filesystem call on a group's content — the stat as much as the read, since a stat is what wakes a sleeping disk — goes through `roots.off_disk`, onto one worker thread per root set. A spun-down or network-mounted root answers its first syscall in seconds, and on the loop that is every group, every stream and the hub socket waiting for a platter. **ffmpeg's own output too**, through `asyncio.to_thread` rather than that per-root thread: a temp file is not a group root and has no platter to serialise against, but a whole transcode read inline is still tens of megabytes of blocking read |
| **AV10** | **Every path that makes the hub send mail is metered, per account.** A rate limit that counts by IP bounds a caller, not an inbox. Changing one's address mails an arbitrary stranger, so it carries a cooldown *and* a daily ceiling; a reset request and a registration resend carry cooldowns |
| **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 |
@@ -3085,12 +3093,16 @@ process runs it — `systemctl --user` on Linux, Task Scheduler on Windows.
## 16. Concordance
-Code comments, tests and older documents cite sections of the documents this one
-replaces. **Those documents are no longer in the tree** — they were removed on
-2026-09-11, once their content was here and this table could resolve every
-reference they left behind. `git log -- docs/` recovers any of them.
+Older documents, notes outside this repository and every earlier revision in
+git cite sections of the documents this one replaces. **Those documents are no
+longer in the tree** — they were removed on 2026-09-11, once their content was here and
+this table could resolve every reference they left behind. `git log -- docs/`
+recovers any of them.
-Nothing needs editing to follow a reference: look the citation up here.
+The code does not need this table: since 2026-09-19 every comment and test cites
+`MESHBAY_DESIGN.md` and a section directly, and a new one must. What this
+resolves is what cannot be rewritten — a commit message, a `git blame`, a
+superseded document kept under `docs/`, a note somebody holds elsewhere.
| Cited as | Read |
|---|---|