From c2c49182e6d4f1f1ef3ed3ba5e8699912f9a27bd Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Sat, 19 Sep 2026 01:02:05 +0200 Subject: feat(node): per-file upload ceiling is an operator setting, default 8 GB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was a 4 GB constant in webrtc_server.py, the same on a small board and on a machine holding a library. Now max_upload_gb in node.toml, on the Node page and via `meshbay-node transfers max-size`, read from the transport context per chunk so a change reaches an upload already running. MESHBAY_DESIGN.md §6.4; §15.3 records a defect found beside it. Co-Authored-By: Claude Opus 5 --- docs/MESHBAY_DESIGN.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'docs/MESHBAY_DESIGN.md') diff --git a/docs/MESHBAY_DESIGN.md b/docs/MESHBAY_DESIGN.md index 03ae77e..dcfc77b 100644 --- a/docs/MESHBAY_DESIGN.md +++ b/docs/MESHBAY_DESIGN.md @@ -1326,9 +1326,15 @@ Five protections, and they are the substance: and `stat()` is itself case-insensitive on NTFS and exFAT, so this already holds there; - **strict chunk ordering**; -- a **size cap** — 4 GB per file. There is deliberately no aggregate quota yet, and - that gap is named in §15.3 rather than left to be discovered: a member can still - fill the operator's disk one capped file at a time; +- a **size cap** — 8 GB per file by default, and **the operator's to set** + (`max_upload_gb` in node.toml, on the Node page, or `meshbay-node transfers + max-size`), because the disk that fills is theirs and a Pi and a film server + are not the same machine. It is read from the transport context on every + chunk, so a change applies to an upload already running. A file past the + ceiling is refused at the chunk that crosses it and its `.part` is deleted. + There is deliberately no aggregate quota yet, and that gap is named in §15.3 + rather than left to be discovered: a member can still fill the operator's + disk one capped file at a time; - the target root must be **writable and available**, enforced by the node. **There is no quarantine subdirectory.** A folder appearing beside the operator's @@ -3062,7 +3068,8 @@ process runs it — `systemctl --user` on Linux, Task Scheduler on Windows. | **C4** for browser-using accounts | Open until the signed bundle opt-out ships (O3) | | **T3** for browser users | **Accepted permanently.** Removed for native clients, and that removal's value depends on reproducible builds | | **Hub identity pinning** (O13) | Nothing pins the hub's key. Bounded, because a substituted hub can neither read content nor ship code to a native client | -| **Aggregate upload quota** | Per-file caps exist; a per-user or per-group total does not | +| **Aggregate upload quota** | Per-file caps exist and the operator sets theirs (§6.4); a per-user or per-group total does not | +| **`max_concurrent_downloads` / `max_concurrent_uploads` are lost at startup** | The daemon builds the `defaults` dict it hands `roster.node_settings` without those two keys, so a node that has never had them set from the panel resolves both to `None`, assigns that back onto the config, and builds the transport with it — the pools then come up at `transfers.py`'s defaults and **what node.toml says about them is read and ignored**. The Node page and the CLI still work, because writing the setting is what creates the roster row the startup path then finds. Found while adding the per-file ceiling beside them, which is in that dict | | **A signed upload transcript** | Ownership is recorded by the node and verifiable by nobody else (§5.4). Making it provable is a transcript the uploader signs, stored with the entry — designed in outline, not built | | Forward secrecy in group chat | **Given up deliberately and on the record** (§4.5). If it becomes a requirement it belongs in 1:1 DM | | Metadata at the hub | Membership, and who posted in which group and when. A known leak, not a solved problem (§7.1) | -- cgit v1.2.3