aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-10 17:23:40 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-10 17:23:40 +0200
commit1dcedc77083b908b7b3b431bad679a4813884355 (patch)
treedb6ae06c05e5f337aeb42dde5c7bd2a7fe9444b5 /packages/meshbay-node/src/meshbay_node
parent6964ff112fec47498ed778a491cf2a1490392c79 (diff)
downloadmeshbay-1dcedc77083b908b7b3b431bad679a4813884355.tar.gz
refactor(mnp)!: one answer to "may this member write", and it is the root
The group-wide `member_upload` switch is gone: the message, the signed operation, the field on the handshake ack, the `upload` alias on every root in the index payload, and the client's fallback path to it. Whether a member may write has been a property of each root for a while, and that is the model that survives: a single flag over the group cannot express "this library is published read-only and that folder is a drop box", which is the ordinary arrangement. What was left of the switch was a handler that logged a deprecation and acted on nothing, and a client that read `ack.member_upload` whenever the roots carried no `writable` — a second source for one question, with whichever the code consulted first deciding it. `roots.describe()` drops `upload` for the same reason: it was `writable` under an older name, and two names for one boolean is one too many. The paperclip now says "nowhere to write" rather than picking a root, in a group that has none writable. That is the honest answer; the fallback picked whatever came first and failed at send time. Node suite 1215 passed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AsoWC3GmhNdwVFomW3QjH3
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node')
-rw-r--r--packages/meshbay-node/src/meshbay_node/roots.py4
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py22
2 files changed, 1 insertions, 25 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/roots.py b/packages/meshbay-node/src/meshbay_node/roots.py
index d288231..410fe68 100644
--- a/packages/meshbay-node/src/meshbay_node/roots.py
+++ b/packages/meshbay-node/src/meshbay_node/roots.py
@@ -371,9 +371,7 @@ class RootSet:
"available": r.available,
"writable": r.writable,
"removable": r.removable,
- "ejected": r.ejected,
- # Backward compat for MNP 1.0 clients
- "upload": r.writable}
+ "ejected": r.ejected}
# `with_paths` is for the operator's *own* channels only — the
# loopback API and the CLI reading it, both of which already
# require being on this machine with the run token. A member is
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 11412bf..ec7ef5d 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
@@ -67,7 +67,6 @@ from meshbay_common.adminop import (
OP_MEMBER_REVOKE,
OP_GEK_ROTATE,
OP_MEMBER_UNPIN,
- OP_MEMBER_UPLOAD,
OP_APPS_ENABLED,
OP_SET_SCAN_SETTINGS,
OP_TRANSFER_LIMITS,
@@ -570,8 +569,6 @@ class WebRTCPeerSession:
self._spawn(self._do_device_revoke(msg))
elif mtype == MNP.DEVICE_HELLO and self._nonce_node:
self._spawn(self._do_device_hello(msg))
- elif mtype == MNP.MEMBER_UPLOAD:
- self._do_member_upload(msg)
elif mtype == MNP.APPS_ENABLED:
self._do_apps_enabled(msg)
elif mtype == MNP.TRANSFER_LIMITS:
@@ -879,12 +876,6 @@ class WebRTCPeerSession:
# channel and nothing else.
config = {
"is_node_admin": self._is_node_admin(),
- # Backward compat for MNP 1.0 clients: computed from writable roots.
- # New clients read per-root writable from the index payload instead.
- "member_upload": any(
- r.get("writable") for r in
- (self._group_ctx().get("roots").describe()
- if self._group_ctx().get("roots") else [])),
# Which group "applications" to show. Absent/empty falls back to
# every registered one client-side, so a node that predates this
# setting (or one whose context has not loaded it yet) hides
@@ -2075,14 +2066,6 @@ class WebRTCPeerSession:
self._send({"type": MNP.MEMBER_UNPIN_ACK, "v": MNP_VERSION,
"user_id": user_id})
- def _do_member_upload(self, msg: dict) -> None:
- # Deprecated: upload control is now per-root via writable flag.
- # Old clients may still send this — acknowledge without acting.
- log.warning("Deprecated member_upload message received — use root "
- "writable/read-only instead")
- self._send({"type": MNP.MEMBER_UPLOAD_ACK, "v": MNP_VERSION,
- "allowed": True, "deprecated": True})
-
# Every "application" a group can show. Photos joins this set (and
# apps.js's registry, client-side) when it lands; nothing else about
# this handler changes. DEFAULT_APPS (roster.py) deliberately does not
@@ -5321,11 +5304,6 @@ class WebRTCPeerSession:
elif pending["op"] == OP_MEMBER_UNPIN:
self._spawn(
self._admin_exec_member_unpin(pending, transcript, sig_bytes))
- elif pending["op"] == OP_MEMBER_UPLOAD:
- log.warning("Deprecated OP_MEMBER_UPLOAD signed op — use root "
- "writable/read-only instead")
- self._send({"type": MNP.MEMBER_UPLOAD_ACK, "v": MNP_VERSION,
- "allowed": True, "deprecated": True})
elif pending["op"] == OP_APPS_ENABLED:
self._spawn(
self._admin_exec_apps_enabled(pending, transcript, sig_bytes))