aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-10 17:30:40 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-10 17:30:40 +0200
commitd5442e3a335327b445d27d0f7e8798726ba20973 (patch)
treef83e276a210fe36e1371bcc6a15bf5023c758056
parent803e654086ac63e2d01fa4eb9cca50a4ebebcb73 (diff)
downloadmeshbay-d5442e3a335327b445d27d0f7e8798726ba20973.tar.gz
docs(code): drop the references to a plan file that no longer exists
Seven comments pointed at sections of `~/next/improve-downloads.md`, which is not in the tree and not anywhere a reader of this repository can follow. Each now states the thing it was citing: why a paused transfer holds nothing, why the lease is taken after the save target and not before, why a chunk request marks a lease alive, where the leaseless bound's number comes from. The leaseless comment also said "two files at a time" three paragraphs under `MAX_LEASELESS_IN_FLIGHT = 12`, left behind when the bound was raised. A comment that contradicts the constant beside it is worse than no comment: one of them is wrong and the reader cannot tell which. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AsoWC3GmhNdwVFomW3QjH3
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/downloads.js5
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/file-utils.js6
-rw-r--r--packages/meshbay-hub/tests/test_client_version_gate.py6
-rw-r--r--packages/meshbay-hub/tests/test_transfers.py2
-rw-r--r--packages/meshbay-node/src/meshbay_node/transfers.py45
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py6
-rw-r--r--packages/meshbay-node/tests/test_leaseless_reads.py6
7 files changed, 36 insertions, 40 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/downloads.js b/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
index c790394..9c23d3c 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
@@ -649,8 +649,9 @@ async function _attemptStreamedDownload(filename, size, attempt,
// writing to the stream stalls that download where we cannot see it or
// resume it, and an idle worker is terminated within seconds, taking the
// stream with it. A pause button here would restart from zero, which is
- // worse than not offering one. §6.5 of ~/next/improve-downloads.md records
- // what giving Firefox and Safari a resumable target would cost.
+ // worse than not offering one. Offering Firefox and Safari a resumable
+ // target means a resumable sink of our own, which is a larger piece of work
+ // than the button it would enable.
pausable: false,
writable: {
write: (bytes) => { lastWrite = Date.now(); return writer.write(bytes); },
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/file-utils.js b/packages/meshbay-hub/src/meshbay_hub/static/file-utils.js
index 99d9f9a..b732734 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/file-utils.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/file-utils.js
@@ -451,9 +451,9 @@ async function downloadEntry(transfers, transport, gek, entry) {
},
// After the target, never before: a granted slot has to be taken up within
- // the node's deadline, and opening a target can outlast it. See §8.1 of
- // ~/next/improve-downloads.md — the other order was tried and cost two of
- // three downloads.
+ // the node's deadline, and opening a target can outlast it — a Save As
+ // dialog waits for a person. Asking for the slot first loses it to the
+ // grant deadline while the dialog is open.
makeLease: () => transport.openTransfer({
kind: 'download', bytes: entry.size, chunks: totalChunks }),
diff --git a/packages/meshbay-hub/tests/test_client_version_gate.py b/packages/meshbay-hub/tests/test_client_version_gate.py
index 69ca062..4dc9b98 100644
--- a/packages/meshbay-hub/tests/test_client_version_gate.py
+++ b/packages/meshbay-hub/tests/test_client_version_gate.py
@@ -5,9 +5,9 @@ The SPA is served by the hub, so a browser picks up a new client on reload. The
desktop application **ships its own interface**, so on a flag day an un-updated
one can still sign in, still list groups, and then fail every connection with
`version_too_old` — a refusal in a protocol vocabulary, surfacing as a node that
-will not talk, with nothing anyone can act on. §12.3 of
-~/next/improve-downloads.md named this as the thing that had to exist before
-MNP 3.0 could ship.
+will not talk, with nothing anyone can act on. Refusing at the handshake is only
+honest if something tells the person *before* they get there, and this is that
+something.
`compareVersions` and `refuseIfTooOld` are lifted out of `main.js` **as text**
and executed against a modelled environment, on the rule this repo follows
diff --git a/packages/meshbay-hub/tests/test_transfers.py b/packages/meshbay-hub/tests/test_transfers.py
index d93cf80..a776b50 100644
--- a/packages/meshbay-hub/tests/test_transfers.py
+++ b/packages/meshbay-hub/tests/test_transfers.py
@@ -560,7 +560,7 @@ def test_a_transport_is_not_closed_under_a_preparing_transfer(tmp_path):
# The rule the whole design turns on: **a paused transfer holds nothing.** Its
# slot goes back to the node the moment it stops, and resuming rejoins the queue
# at the tail. Anything else lets one member close a node by pausing four
-# downloads and going to lunch (§6.2 of ~/next/improve-downloads.md).
+# downloads and going to lunch.
def _pausable_run():
diff --git a/packages/meshbay-node/src/meshbay_node/transfers.py b/packages/meshbay-node/src/meshbay_node/transfers.py
index dd382b4..cef817a 100644
--- a/packages/meshbay-node/src/meshbay_node/transfers.py
+++ b/packages/meshbay-node/src/meshbay_node/transfers.py
@@ -28,9 +28,8 @@ properties are load-bearing, and each one is a decision:
This module is deliberately free of asyncio and of the transport: it decides,
and the caller does the I/O. `sweep()` is called on a clock the caller owns, and
every method returns what changed so the caller can push it. That is what makes
-the failure modes in §5 of ~/next/improve-downloads.md testable at all — a
-queue that only reveals itself through a DataChannel is a queue nobody can
-prove things about.
+the failure modes testable at all — a queue that only reveals itself through a
+DataChannel is a queue nobody can prove things about.
"""
from __future__ import annotations
@@ -412,28 +411,24 @@ class TransferSlots:
# Browsing a group is never subject to a transfer slot — not the poster grid,
# not the covers, not opening a photo or a PDF to look at it. A member must be
# able to browse a group that is at capacity exactly as they browse an idle one.
-# That is a requirement, and §3.4 of ~/next/improve-downloads.md satisfies it
-# structurally: a transfer is what the transfers widget shows, and nothing else
-# takes a slot.
+# That requirement is met structurally rather than by judgement: a transfer is
+# what the transfers widget shows, and nothing else takes a slot.
#
# But "not leased" cannot mean "unbounded", or a client that simply omits `tr`
# transfers outside every cap and the caps are decoration.
#
-# **The number comes from what the shipped client legitimately does, and it was
-# wrong once already.** §3.4.1 of ~/next/improve-downloads.md argued for two,
-# reasoning about *viewers*: a photo viewer shows one photo, a preview modal one
-# document, and the second is for prefetching the next photo. That reasoning
-# forgot the music player, which warms a read-ahead window — `prefetchDepth()`
-# in music-player.js returns 5 on Wi-Fi, 3 otherwise — so playing an album has
-# six files in flight and the fourth was refused with `transfer_required`.
-# Reported the day MNP 3.0 shipped, as "I try to play a track and it tells me to
-# download it instead".
+# **The number comes from what the client legitimately does**, and reasoning
+# about *viewers* alone gets it wrong: a photo viewer shows one photo and a
+# preview modal one document, but the music player warms a read-ahead window —
+# `prefetchDepth()` in music-player.js returns 5 on Wi-Fi, 3 otherwise — so
+# playing an album has six files in flight before anyone has done anything
+# unusual, and a bound of two refuses a member trying to play a track.
#
-# Twelve: six for the music read-ahead at its widest, two for a photo viewer
-# and its own prefetch running at the same time in the same session, and the
-# rest as headroom for the next app that reads ahead. `test_leaseless_reads.py`
-# derives the floor from music-player.js itself, so raising the client's
-# prefetch without raising this fails rather than reaching a person.
+# Twelve: six for that read-ahead at its widest, two for a photo viewer and its
+# own prefetch running at the same time in the same session, and the rest as
+# headroom for the next app that reads ahead. `test_leaseless_reads.py` derives
+# the floor from music-player.js itself, so raising the client's prefetch
+# without raising this fails rather than reaching a person.
#
# Generosity is cheap here and refusal is not. This is a fairness control among
# cooperating clients, not a security boundary — a client that lies gets twelve
@@ -445,11 +440,11 @@ class TransferSlots:
# size threshold separates them. What separates them is which function asked.
#
# What it costs, stated plainly: a client that lies — labelling a bulk download
-# as a view — gets two files at a time instead of its member cap. That is the
-# residual, it is bounded, it is audited, and it is the same kind of statement
-# as the cap itself. **This is a fairness control among cooperating clients**,
-# not a defence against a member determined to saturate a node's disk. The
-# answer to that member is `member revoke`.
+# as a view — gets this many files at a time instead of its member cap. That is
+# the residual, it is bounded, it is audited, and it is the same kind of
+# statement as the cap itself. **This is a fairness control among cooperating
+# clients**, not a defence against a member determined to saturate a node's
+# disk. The answer to that member is `member revoke`.
MAX_LEASELESS_IN_FLIGHT = 12
# A leaseless read has no "close" message, so it ends when the last chunk goes
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
index 46fbba3..b3618b5 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
@@ -4822,9 +4822,9 @@ class WebRTCPeerSession:
# 11:54:19 reclaimed 919ebf54 (abandoned)
# 11:55:48 Upload complete: ... (3 522 297 517 bytes)
#
- # The download twin of this was fixed on 2026-09-08 (§12.1 of
- # ~/next/improve-downloads.md); the same omission was still here,
- # invisible until uploads started taking a real lease.
+ # `_do_file_request` marks a lease alive for exactly the same reason;
+ # both sides of a transfer have to say they are still moving, or the
+ # sweeper reclaims whichever one forgot.
tr = msg.get("tr")
if tr:
slots = self._ctx.get("_transfer_slots")
diff --git a/packages/meshbay-node/tests/test_leaseless_reads.py b/packages/meshbay-node/tests/test_leaseless_reads.py
index 64aed3d..6bd7f1f 100644
--- a/packages/meshbay-node/tests/test_leaseless_reads.py
+++ b/packages/meshbay-node/tests/test_leaseless_reads.py
@@ -3,9 +3,9 @@ Browsing is never subject to a transfer slot — and is not unbounded either.
**Operator decision, 2026-09-08:** a member must be able to browse a group that
is at capacity exactly as they browse an idle one. Not the poster grid, not the
-covers, not opening a photo or a PDF to look at it. §3.4 of
-~/next/improve-downloads.md satisfies that structurally: a transfer is what the
-transfers widget shows, and nothing else takes a slot.
+covers, not opening a photo or a PDF to look at it. That is met structurally
+rather than by judgement: a transfer is what the transfers widget shows, and
+nothing else takes a slot.
But "not leased" cannot mean "unbounded". With MNP 3.0 making leases
compulsory, a client that simply omits `tr` would otherwise transfer outside