diff options
Diffstat (limited to 'docs/MESHBAY_DESIGN.md')
| -rw-r--r-- | docs/MESHBAY_DESIGN.md | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/docs/MESHBAY_DESIGN.md b/docs/MESHBAY_DESIGN.md index a079e50..e7d4a76 100644 --- a/docs/MESHBAY_DESIGN.md +++ b/docs/MESHBAY_DESIGN.md @@ -1102,19 +1102,30 @@ client on reload; the desktop client ships its own UI, which is why connecting and says "this version can no longer connect" rather than showing a handshake refusal nobody can act on. -**The floor being the current version is what keeps capability branches out of the -client.** `MNP_MIN_SUPPORTED` equals `MNP_VERSION`, so `check_version` refuses -every older peer at the handshake — which means **every capability is true of every -peer the client can reach**, and there is nothing to test for. An upload is sealed -or it is not sent; a transfer has a real lease or it does not run; there is one -app-directories op and no wrappers behind it. The client records the version its -peer declared, for diagnostics, and **branches on none of it**. +**Every *requirement* is true of every peer the client can reach.** The floor moves +with each MAJOR, so `check_version` refuses at the handshake any peer that cannot +meet one: an upload is sealed or it is not sent; a transfer has a real lease or it +does not run; there is one app-directories op and no wrappers behind it. The client +records the version its peer declared, for diagnostics, and **branches on none of +it**. > A capability flag on a peer whose floor already guarantees the capability is a > branch that can only ever take one path — until somebody lowers the floor, at > which point it silently takes the other. **A field kept "just in case" is how > the branches come back.** +**The floor is not the current version, and MINOR additions are why.** It is +`MNP_MIN_SUPPORTED` in `handshake.py`, it equals the last MAJOR, and 3.1 and 3.2 +have both been added above it without moving it. So a peer can be reachable and +still not do something the current version can, and the client has to cope with +that — **by reading the peer's own answer, never by comparing version numbers**. +3.2's audio tracks are the worked example: the node lists them in `stream_init`, +the client draws its selector from that list, and a node that sends no list gets no +selector. That is not the branch the box above refuses. The branch it refuses is a +flag the client sets from a version it parsed; this is the node stating what it +has, in the same message the feature already needed, and it takes exactly one path +per peer because the peer said which. + Where a break leaves data behind, a migration runs with the node stopped, backs the database up first and is idempotent. But **a migration that has to be remembered is a migration that does not happen**, so anything that *can* be a @@ -2020,6 +2031,14 @@ MSE string) fed to a source buffer, with the node holding one slot per viewer. - **Seeking restarts the source with an index seek before the input**, clamped away from the end and echoed back; the client supplies the timestamp offset, because copying timestamps does not preserve position. +- **The viewer picks the audio track, and picking one is a seek.** One ffmpeg + carries one audio track, so there is nothing to switch inside a running stream: + the node is asked again at the current position and the source buffer is reset + the way any seek resets it. It costs nothing extra — audio is transcoded on every + stream anyway — and mapping the first track unconditionally, which is what this + replaced, made a dubbed library playable in one language only. The node reports + the tracks it found and the one it used; **the client draws its selector from + that list and from no version number**, which is what keeps the addition MINOR. - **Losing a peer must stop its work, not merely forget it** — anything holding a resource is shut down on the way out, or a closed tab transcodes for the length of the credit timeout. |