aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-17 10:11:07 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-17 10:11:07 +0200
commit7e61d16f0ca6aeca6adb1dd909a7e7b0376719f9 (patch)
tree08466d6c6879efd1f2c21a118919cb99835fb31f /docs
parent6329beaca34e31749ff0343d02e27db2826157e7 (diff)
downloadmeshbay-7e61d16f0ca6aeca6adb1dd909a7e7b0376719f9.tar.gz
fix(spa): follow the device to another network
Moving between mobile data and the node's Wi-Fi left the connection on the network it had left until ICE gave up, and a group that had failed was never tried again: the Android application had to be killed. A change of network or an ICE disconnection now pings the session and reconnects one that does not answer, wakes a reconnect backing off, and retries a group page left on an error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'docs')
-rw-r--r--docs/MESHBAY_DESIGN.md10
1 files changed, 9 insertions, 1 deletions
diff --git a/docs/MESHBAY_DESIGN.md b/docs/MESHBAY_DESIGN.md
index 4db06c40..6fe0722e 100644
--- a/docs/MESHBAY_DESIGN.md
+++ b/docs/MESHBAY_DESIGN.md
@@ -1561,6 +1561,15 @@ refusal and not a dropped connection, so a chunk let through while a reconnect's
handshake runs ends the download the reconnect is for. The close event of a
channel a reconnect has replaced concerns nothing on the new one.
+**A connection follows the device to another network.** A phone moving between
+mobile data and the Wi-Fi the node is on keeps a candidate pair over the
+network it left, and ICE says so only once its consent checks lapse, about
+thirty seconds. So a change of network (`online`, the connection's `type`, the
+Android application's `meshbay-default-network`) and an ICE `disconnected` each
+ask the session for a ping, and a session that does not answer within five
+seconds is reconnected; a reconnect backing off tries again at once; a group
+page left on an error tries again (`transport.js` `onNetworkChange`).
+
The lease module is free of asyncio and of the transport: it decides, and the
caller does the I/O. A queue that reveals itself only through a DataChannel is a
queue nobody can prove things about.
@@ -4781,7 +4790,6 @@ process runs it — `systemctl --user` on Linux, Task Scheduler on Windows.
| Metadata at the hub | Membership, and who posted in which group and when. A known leak, not a solved problem (§7.1) |
| **QUIC** | Off by default, and **not at parity**: it serves the index and file chunks with no transfer lease, no leaseless ceiling, no root-availability check and no content blocklist, does its file I/O on the event loop, and returns exception text to the peer (**L3**). No client speaks it. Either it comes to parity or it goes; until then §5.1's "chat is the only gap" is the one sentence here that overstates the code |
| **A very high bitrate wedges the player against a small buffer ceiling** | Where even the *floor* read-ahead does not fit — ninety seconds plus the minute kept behind, at the file's bitrate, above what the engine will hold — the film stalls: measured on the harness at 9.3 Mbit/s against a 100 MB ceiling, 100.8 s of film played in 900 s of wall clock. **Predates the byte budget and is unchanged by it**, to the tenth of a second; what the budget did change there is the refusal count, 1560 → 2. The fix is not a bound at all, it is a second stage of buffer outside the SourceBuffer, which means gating the append path — the riskiest change in this area and not one to make alongside another |
-| **The reconnect backoff only wakes on `visibilitychange`** | So a tab that stays visible through an outage — which is what a screen wake lock guarantees while a film is playing — waits out the full backoff, up to 30 s, after the network is already back. Nothing listens for `online` |
| **Per-device revocation has no CLI** | A device is revoked over MNP (`roster.revoke_device`), from a device the node has already pinned. On a headless node the operator's only lever is `member unpin`, which removes **every** device of that account — so the per-device control the roster is built around is reachable from an interface and from nowhere else. §6.7 listed a `meshbay-node member device list\|revoke` verb that was never written, and that listing is how this was found: `USERGUIDE.md` was the first document written by reading the CLI rather than this specification, and the verb it copied out did not run |
| **Migrations run on SQLite only** | The chain reaches head and agrees with the models there (§12), which is not where it ships. **The exposure is one revision deep, not the whole chain**: every revision behind the first packaged release was development that no installation ever ran, so nothing replays them on PostgreSQL. What is unguarded is the *next* migration — a default, an index type or a constraint PostgreSQL refuses reaches a deploy without the suite saying so |
| **The Create group wizard calls two hooks after an early return** | `CreateGroupWizard` (`create-group-page.js`) returns during node detection, before its `useRef`/`useEffect` for provisioning, so the hook count changes between renders. Preact tolerates a list that grows, and nothing is known to break; `test_hook_ordering.py` checks declaration order, not this. Found while tracing the frozen-fields report, which had another cause (`ask.js`) |