summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-common/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-common/src')
-rw-r--r--packages/meshbay-common/src/meshbay_common/__init__.py36
-rw-r--r--packages/meshbay-common/src/meshbay_common/handshake.py7
2 files changed, 40 insertions, 3 deletions
diff --git a/packages/meshbay-common/src/meshbay_common/__init__.py b/packages/meshbay-common/src/meshbay_common/__init__.py
index b64a6f2..1aaa269 100644
--- a/packages/meshbay-common/src/meshbay_common/__init__.py
+++ b/packages/meshbay-common/src/meshbay_common/__init__.py
@@ -1,6 +1,6 @@
"""MeshBay common — shared crypto primitives and protocol types."""
-__version__ = "0.12.0"
+__version__ = "0.13.0"
# 0.2: added PING/PONG, and `before`/`has_more` on chat history. Both are
# additive — an 0.1 peer sends no `before` and gets the newest page, which is
# what it wanted — so this is a MINOR bump, not a MAJOR one.
@@ -133,5 +133,37 @@ __version__ = "0.12.0"
# `index_progress` (counters only — see daemon.py `_push_index_progress`), the
# admin and configuration acks, and the media-metadata replies. The index at
# rest and file content on the operator's disk are unchanged.
-MNP_VERSION = "2.0"
+# **3.0 (2026-09-09): a transfer needs a lease, and a peer that cannot ask for
+# one is refused at the handshake.**
+#
+# `transfer_open` / `transfer_close` / `transfer_state` carry the lease a
+# download or an upload runs under; `file_req` gains an optional `tr` and
+# `file_upload` gains one beside the `upload_id` already in clear. All three are
+# in clear, like `index_progress` and for the same stated reason: `tr` is
+# opaque, `bytes` and `chunks` are numbers, and there is no filename and no path
+# anywhere in them. Putting one there to make a log line prettier is exactly the
+# trade `groupbox.py` exists to refuse.
+#
+# **The messages are additive; the requirement is not, and that is what makes
+# this MAJOR.** A 2.0 client sends no `tr`, so it is a leaseless reader — and a
+# leaseless reader is either refused as soon as it opens a third file, or it is
+# not refused and transfers outside every cap the operator set. An opt-in switch
+# ("enforce leases only for clients that speak 3.0") leaves that branch
+# reachable on every node, which is finding C6's lesson — a transport that
+# accepted a bare JWT — one feature later. It was already refused once, for chat
+# encryption, on 2026-09-07.
+#
+# Browsing is deliberately **not** leased and never will be: not the poster
+# grid, not the covers, not opening a photo to look at it. That exemption is
+# bounded rather than open (`transfers.LeaselessReads`, two files in flight per
+# session), because an exemption with no bound is the leaseless branch under
+# another name.
+#
+# **What it costs, stated plainly.** The SPA is served by the hub, so a browser
+# picks up the new client on reload. The desktop client ships its own UI, so an
+# un-updated one is locked out — which is why `GET /v1/hub/version` carries
+# `client.minimum` and the client checks it *before* connecting, and says "this
+# version can no longer connect" rather than showing a handshake refusal nobody
+# can act on.
+MNP_VERSION = "3.0"
MHP_VERSION = "0.1"
diff --git a/packages/meshbay-common/src/meshbay_common/handshake.py b/packages/meshbay-common/src/meshbay_common/handshake.py
index 188a8aa..65b4e85 100644
--- a/packages/meshbay-common/src/meshbay_common/handshake.py
+++ b/packages/meshbay-common/src/meshbay_common/handshake.py
@@ -78,7 +78,12 @@ HANDSHAKE_PREFIX = b"meshbay:mnp:handshake:v1"
# handshake and then discovering that every message it sends is rejected and
# every message it receives is unreadable. A stated refusal is a bug report; a
# chat that quietly does not work is a support case.
-MNP_MIN_SUPPORTED = "2.0"
+# 3.0 (2026-09-09): a transfer runs under a lease, and a 2.x peer cannot ask for
+# one. Admitting it would mean either refusing it later, per file, in a way it
+# has no vocabulary to understand — or serving it outside every cap the operator
+# set, which makes the caps decoration. Neither is honest, so it is refused
+# here, with a code and a sentence.
+MNP_MIN_SUPPORTED = "3.0"
ROLE_CLIENT = "client"
ROLE_NODE = "node"