summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-common/src
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-02 10:20:09 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-02 10:20:09 +0200
commite4f61771131be635b9e81a19203a00707b4b19df (patch)
treed80e4edafbeade3c27137e6753140e6585a26b9b /packages/meshbay-common/src
parente941cc4c39c38a12220153ea572bd4c7bb92fde0 (diff)
downloadmeshbay-e4f61771131be635b9e81a19203a00707b4b19df.tar.gz
feat(mnp): sharing a folder is decided on the node's machine only (MNP 6.0)
root_add, root_update and group_attach leave MNP: adding a directory and switching writable/removable go through the loopback API (native dialog in the desktop app) or the CLI. The operator's Settings tab still lists the roots from any browser, read-only. The desktop app refuses to sign those ops; a loopback flag change now reaches open pages (publish_roots). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-common/src')
-rw-r--r--packages/meshbay-common/src/meshbay_common/__init__.py9
-rw-r--r--packages/meshbay-common/src/meshbay_common/adminop.py21
-rw-r--r--packages/meshbay-common/src/meshbay_common/protocol.py6
3 files changed, 15 insertions, 21 deletions
diff --git a/packages/meshbay-common/src/meshbay_common/__init__.py b/packages/meshbay-common/src/meshbay_common/__init__.py
index b68e828..c5c04a5 100644
--- a/packages/meshbay-common/src/meshbay_common/__init__.py
+++ b/packages/meshbay-common/src/meshbay_common/__init__.py
@@ -260,5 +260,12 @@ __version__ = "0.17.0"
# a refusal, across the break. The break is confined to them, so the floor stays
# at 4.0: everything else a 4.x peer does still works, and nothing is left
# unsigned on either side — no node accepts the old subjects.
-MNP_VERSION = "5.0"
+#
+# 6.0 (2026-10-02) is a MAJOR — three signed operations are removed: `root_add`,
+# `root_update` and `group_attach`. What of the operator's disk is shared, and
+# whether members may write there, is decided on the node's own machine (the
+# desktop application over loopback, behind a native dialog, or the CLI), never
+# over the wire. A 5.x client that sends one gets no answer, as for any unknown
+# type; everything else it does still works, so the floor stays at 4.0.
+MNP_VERSION = "6.0"
MHP_VERSION = "0.1"
diff --git a/packages/meshbay-common/src/meshbay_common/adminop.py b/packages/meshbay-common/src/meshbay_common/adminop.py
index 4379519..11100b5 100644
--- a/packages/meshbay-common/src/meshbay_common/adminop.py
+++ b/packages/meshbay-common/src/meshbay_common/adminop.py
@@ -101,7 +101,6 @@ OP_TMDB_REMATCH = "tmdb_rematch"
# the lesson was already learned once). Signed for the same reason as
# tmdb_enabled.
OP_MUSICBRAINZ_ENABLED = "musicbrainz_enabled"
-OP_ROOT_ADD = "root_add"
OP_ROOT_REMOVE = "root_remove"
# One op for every application's directories. The subject is
# "<app>:<comma-joined sorted paths>" so what the operator is shown before
@@ -122,11 +121,16 @@ OP_SEARCH_LISTED = "search_listed"
# There is no op for *enabling* chat encryption. It is not a setting — MNP 2.0
# has no plaintext chat to fall back to.
OP_CHAT_EPOCH = "chat_epoch"
-OP_ROOT_UPDATE = "root_update"
OP_ROOT_EJECT = "root_eject"
OP_ROOT_PLUG = "root_plug"
-OP_GROUP_ATTACH = "group_attach"
OP_GROUP_DETACH = "group_detach"
+# OP_ROOT_ADD, OP_ROOT_UPDATE and OP_GROUP_ATTACH are gone (MNP 6.0). Each one
+# chose what of the operator's disk is shared and who may write there, and a
+# signature proves only that the operator's key signed — in a browser, through
+# code the hub serves; on the desktop, through a renderer that parses content
+# from nodes. Sharing a folder, hosting a group and opening a folder to writes
+# are done on the node's own machine (loopback, behind a native dialog) or with
+# the CLI, and a message that does not exist cannot be mis-authorized.
# OP_GEK_BUNDLE_STORE is gone. Members no longer hand the node key material at
# all: the node holds the GEK and wraps it itself, for a key the recipient proved
# they hold (see `join.py` and docs/MESHBAY_DESIGN.md §3.4). The operation existed
@@ -159,17 +163,6 @@ def secret_digest(value: str | None) -> str | None:
return "sha256:" + hashlib.sha256(value.encode()).hexdigest()
-def root_add_subject(path: str, name: str, kind: str, writable: bool,
- removable: bool) -> str:
- return structured_subject({"path": path, "name": name, "kind": kind,
- "writable": writable, "removable": removable})
-
-
-def group_attach_subject(name: str, shared_dir: str, writable: bool) -> str:
- return structured_subject({"name": name, "shared_dir": shared_dir,
- "writable": writable})
-
-
def invite_create_subject(user_id: str, username: str) -> str:
return structured_subject({"user_id": user_id, "username": username})
diff --git a/packages/meshbay-common/src/meshbay_common/protocol.py b/packages/meshbay-common/src/meshbay_common/protocol.py
index af2d93b..2c7e301 100644
--- a/packages/meshbay-common/src/meshbay_common/protocol.py
+++ b/packages/meshbay-common/src/meshbay_common/protocol.py
@@ -224,8 +224,6 @@ class MNP:
INVITE_LINK_RESULT = "invite_link_result" # node → operator: link code + handle, once
NODE_STATUS = "node_status" # operator → node: list all groups + roots
NODE_STATUS_ACK = "node_status_ack" # node → operator: full status
- ROOT_ADD = "root_add" # operator → node: add a directory to a group
- ROOT_ADD_ACK = "root_add_ack" # node → operator: confirmed
ROOT_REMOVE = "root_remove" # operator → node: remove a root from a group
ROOT_REMOVE_ACK = "root_remove_ack" # node → operator: confirmed
# One message for every application's directories, keyed by the app's own
@@ -256,8 +254,6 @@ class MNP:
# key without having to reconnect.
CHAT_EPOCH = "chat_epoch"
CHAT_EPOCH_ACK = "chat_epoch_ack"
- ROOT_UPDATE = "root_update" # operator → node: a root's flags
- ROOT_UPDATE_ACK = "root_update_ack"
ROOT_EJECT = "root_eject" # operator → node: mark removable root as ejected
ROOT_EJECT_ACK = "root_eject_ack"
ROOT_PLUG = "root_plug" # operator → node: re-enable an ejected root
@@ -276,8 +272,6 @@ class MNP:
DENYLIST_READ_ACK = "denylist_read_ack"
DENYLIST_CLEAR = "denylist_clear" # operator → node: remove denylist entry(ies)
DENYLIST_CLEAR_ACK = "denylist_clear_ack"
- GROUP_ATTACH = "group_attach" # operator → node: host a new group
- GROUP_ATTACH_ACK = "group_attach_ack"
GROUP_DETACH = "group_detach" # operator → node: stop hosting a group
GROUP_DETACH_ACK = "group_detach_ack"
NODE_SETTINGS_SET = "node_settings_set" # operator → node: change daemon settings