1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
"""MeshBay common — shared crypto primitives and protocol types."""
__version__ = "0.11.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.
# 0.4: added `apps_enabled`/`apps_enabled_ack`, and `enabled_apps` on the
# handshake ack, for the group-applications registry. Additive — a node that
# predates it is never sent the op, and a client that predates it never looks
# for the field — so this is a MINOR bump too.
# 0.5: added `width`/`height`/`display_title`/`season`/`episode` to
# `IndexEntry`, started populating the already-declared `duration`/
# `thumb_hash`, and added `media_meta_req`/`media_meta_resp`, for the Videos
# group app. Additive — an older client simply doesn't render the new
# fields — so this is a MINOR bump too.
# 0.6: added `season_meta_req`/`season_meta_resp` (per-season TMDB overview,
# rather than one static show-level summary applied to every season alike)
# and `tmdb_search_req`/`tmdb_search_resp` + `tmdb_override`/`tmdb_override_ack`
# (an operator correcting a wrong automatic TMDB match, found live against a
# real show fragmented across TMDB entries per season). All additive.
# 0.7: added `tmdb_enabled`/`tmdb_enabled_ack` — whether TMDB is used moved
# from a node-wide setting to per-group (an operator running a real media
# library alongside test/demo groups on one node wants outbound TMDB traffic
# for one, not all of them). `tmdb_config`/`tmdb_config_ack` keep their name
# but now only cover the token/language, which stay node-wide. Additive: an
# older client simply never sends/handles the new pair.
# 0.8: added `artist`/`album`/`track_no` to `IndexEntry`, and
# `musicbrainz_config`/`_ack`, `musicbrainz_enabled`/`_ack`,
# `music_meta_req`/`_resp`, for the Music group app (docs/musicbay.md).
# Same shape as 0.5-0.7's Videos additions, and reuses `duration`/
# `thumb_hash`/`display_title` rather than declaring new ones. Additive:
# an older client simply doesn't render the new fields or send the new
# messages.
# 0.9: added `audio_transcode_req`/`_resp` — WMA and Musepack tag/cover
# fine but decode in no mainstream browser's <audio> element at all, so
# the node transcodes to AAC/M4A on request and caches the result the same
# way a TMDB poster or MusicBrainz cover is cached. Additive: an older
# client never sends the request, and simply can't play those two formats,
# same as before this existed.
# 0.10: added `audio_root`/`_ack` — the Music app's own entry point, same
# shape as `video_root`/`_ack`. Reverses musicbay.md's original "no root,
# whole shared tree" call: a real messy library showed that call was
# wrong, and Music now requires one before showing/enriching anything,
# exactly like Videos. Additive at the protocol level: an older client
# never sends the op and never expects the field.
# 0.11: added `taken_at`/`camera` to `IndexEntry` (best-effort, from a photo's
# own EXIF block) and `photo_roots`/`photo_roots_ack`, for the Photos group
# app (docs/photos.md). Unlike `video_root`/`audio_root`, `photo_roots` is a
# *set*, replaced whole in one signed op — a photo library is routinely
# scattered across several folders, not one. Additive: an older client
# never sends the op and never expects either field.
# 0.12: added `link_preview_req`/`link_preview_resp` — the node unfurls a URL
# pasted in chat into an OpenGraph card. Additive: an older node logs "unknown
# type" and the client just shows the bare link, as it always did.
# 0.13: added `tmdb_rematch`/`tmdb_rematch_ack` — an operator dropping one
# file's cached TMDB match so it re-resolves with the current matcher
# (§10.1/V13). Additive: an older node logs "unknown type", the client's
# button just does nothing.
# 0.14: added an optional `bundle_enc_recovery` field on `keypair_bundle_store`
# and `keypair_bundle_resp` — a second copy of the identity bundle wrapped
# under the account's recovery key, so a forgotten passphrase does not strand
# the identity (docs/auth-confirm.md §4.3). Additive: an older node ignores the
# field on store and never returns one; an older client never sends it.
# 0.15: `file_chunk` and `index_sync` had forked between the transports — WebRTC
# sent binary, unsigned chunks and plain index entries, QUIC sent base64 chunks
# with a per-chunk Ed25519 signature and a `GroupIndex.serialize()` envelope. One
# type, two shapes, a single consumer each and no test that they agreed. Both now
# come from one encoder (`protocol.file_chunk_wire`, `transport/wire.py`), which is
# QUIC adopting what WebRTC already sent. **Breaking on the QUIC wire**, and only
# there: the WebRTC shape — the one every deployed client speaks — is byte for byte
# what it was, and no QUIC client ships. Recorded as a MINOR bump for that reason;
# a deployed QUIC peer would have made it a MAJOR one.
# 1.0: `index_sync`, `index_delta` and the `handshake_ack` configuration
# fields now travel **sealed under a GEK-derived subkey**
# (`meshbay_common.groupbox`), and the handshake negotiates a supported
# version range instead of writing a `v` nobody reads.
#
# **Breaking, on the wire every deployed client speaks**, and there is no way
# to describe it as additive: an old client sends `index_sync` and gets a
# message with no `entries`; it reads `ack.enabled_apps`, finds nothing, and
# applies its documented fallback — "show every app" — rather than reporting
# an error; a new client against an old node finds `entries` it does not
# expect and no `ct`. 0.15 stayed MINOR because only the QUIC wire changed and
# no QUIC client ships; that argument is not available here, and MAJOR is what
# the project's own rule says. Hub and every node deploy together; the SPA is
# served by the hub, so a browser picks up the new client on reload.
#
# Version negotiation ships in the same flag day rather than after it (phase
# 15.6): the coordinated deployment is already being paid for, and it is what
# makes the *next* breaking change cost a refusal message instead of a second
# flag day. `MNP_MIN_SUPPORTED` in `handshake.py` is the other half.
#
# The index at rest, `index_progress` (counters only, never a path — see
# `groupbox.py` and daemon.py `_push_index_progress`), chat, and file content
# on the operator's disk are all deliberately unchanged.
MNP_VERSION = "1.0"
MHP_VERSION = "0.1"
|