<feed xmlns='http://www.w3.org/2005/Atom'>
<title>meshbay.git/packages/meshbay-hub/src/meshbay_hub/static, branch 0.15</title>
<subtitle>MeshBay — read-only public mirror</subtitle>
<id>https://git.meshbay.org/meshbay.git/atom?h=0.15</id>
<link rel='self' href='https://git.meshbay.org/meshbay.git/atom?h=0.15'/>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/'/>
<updated>2026-09-23T22:10:41Z</updated>
<entry>
<title>fix(hub): Search reaches each group with one offer, and a busy hub is not a dead node</title>
<updated>2026-09-23T22:10:41Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-23T22:10:41Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=059eb0318daf27d98bd1c9532705ff406c0a10f8'/>
<id>urn:sha1:059eb0318daf27d98bd1c9532705ff406c0a10f8</id>
<content type='text'>
The other half of the 4G failure. The page negotiated every group twice: the
sweep opened a connection, read the index and closed it, then the warm-up
opened the same group again. The sweep, the warm-up and the tiles each had a
concurrency ceiling of their own, and together they went past what the hub
admits per account. Whatever the hub refused was then reported as "node
unreachable" and remembered as down, which put that group last next time.

- Every connection goes through ConnectionPool, which holds the page's one
  ceiling (six at once, sized for twenty groups on a phone) and keeps what
  the sweep opened for the tiles. A visit costs one offer per group. A
  refresh costs none for a connection that answers a four-second ping, and
  a connection that died while the phone slept is replaced, not waited on.
- A connection whose index is being read is held against eviction. With
  more groups than the pool keeps, it was otherwise the least recently used
  one.
- Negotiations still under way when the page closes close what they get,
  and a sweep cut short that way remembers nobody as down.
- transport.js sends an offer again on 429, 502 or 503, honouring
  Retry-After, with jittered waits of about twenty seconds at worst. Search
  counts each retry as progress. A 404, 403 or 504 still fails at once, so
  a dead node costs no time.

The fan-out tests assumed a ceiling of three and were re-measured: four dead
groups of twelve now hold nothing back, even on a first visit. The pool and
the retry run as shipped code, lifted as text, against a fake clock. Each
guard was checked by removing it and seeing its test fail.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(hub): a redeemed invitation link leaves the owner's list</title>
<updated>2026-09-23T17:30:47Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-23T17:30:47Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=95cec0e0bbc28e930f297f44bbd3dbf4d63f0bc2'/>
<id>urn:sha1:95cec0e0bbc28e930f297f44bbd3dbf4d63f0bc2</id>
<content type='text'>
The list under "Invite by link" answered every ticket the group had ever
minted, so a link that somebody had already used sat there saying "used by
&lt;name&gt;" for the thirty days of KEEP_REDEEMED — beside the member row it had
just produced, and above the links that still wait for somebody, which are
the only ones there is anything to do about. The node's own `member list`
had never shown them: it selects `used_at IS NULL`.

The listing now selects `redeemed_by IS NULL`, and drops the `redeemed`
status and the `redeemed_by` field with it. The row itself still lives for
KEEP_REDEEMED, which is what lets a reload or a second tab of the invitation
page be answered rather than refused; its comment says that now instead of
naming a list it is no longer in.

The SPA filters too, because the desktop client's copy of this interface can
be newer than the hub it is signed into.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(hub): open, create and join invitation links in the interface</title>
<updated>2026-09-23T16:05:14Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-23T16:05:14Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=35a7764db3f58a93c32206cb3ce74bb2f03967e7'/>
<id>urn:sha1:35a7764db3f58a93c32206cb3ce74bb2f03967e7</id>
<content type='text'>
#/invite takes the link out of the address on load and keeps it in the
tab through registration and sign-in; joining is one click, only the
ticket goes to the hub, and the code goes only to the node the link
names once it has signed its challenge. Members tab gains "Invite by
link" (shared e-mail box, pending list, cancel both halves); home page
takes a pasted link. Browser probe drives the real app, signed out and in.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(hub): invitation-link tickets bound to a verified address</title>
<updated>2026-09-23T15:46:48Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-23T15:46:48Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=998f9c69308ee88fac36cfb77dfb6d07c6fa926a'/>
<id>urn:sha1:998f9c69308ee88fac36cfb77dfb6d07c6fa926a</id>
<content type='text'>
group_invite_links holds sha256(ticket) and the invitee's address blind
index; redeeming grants membership to that account only. Owner-only
create/list/cancel (a node token may create, never mail), 20 outstanding
per group, optional mail written by the hub itself and capped at 10 per
sender per day (mail.invite_link_daily_cap). MESHBAY_DESIGN.md §3.4 now
carries the whole link design.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat: the node signs its handshake challenge (MNP 3.4)</title>
<updated>2026-09-23T15:14:26Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-23T15:14:26Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=339cb427f886a0177014126bb684335837eff067'/>
<id>urn:sha1:339cb427f886a0177014126bb684335837eff067</id>
<content type='text'>
node_pk in handshake_challenge is now signed over the channel binding
and both nonces, so a client can check the node key before a join
rather than only at the ack. Both transports; the browser and the QUIC
client refuse a wrong signature and treat an absent one as an older node.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(hub): make mailing an invitation a remembered choice</title>
<updated>2026-09-23T15:01:07Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-23T15:01:07Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=cd85808c13926c89a97987d320ac26391eae3267'/>
<id>urn:sha1:cd85808c13926c89a97987d320ac26391eae3267</id>
<content type='text'>
A "Send the invitation by e-mail" box under the Invite member field,
checked by default and stored as the invite_email preference. Unchecked,
invite-notify is never called and the hub never sees the code.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(hub): right-click menu in the Files tab</title>
<updated>2026-09-23T13:21:30Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-23T13:21:30Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=3d8c1acf785ff7389a68cc515a5c9324dee8de41'/>
<id>urn:sha1:3d8c1acf785ff7389a68cc515a5c9324dee8de41</id>
<content type='text'>
The toolbar's actions on the row under the pointer, sharing one action list
with the toolbar — which keeps showing what does not apply, disabled, while
the menu leaves it out. A count only where more than one item is concerned.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix: ask in the page instead of native confirm/alert</title>
<updated>2026-09-21T17:53:33Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-21T17:53:33Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=9f3445d03f106ee3ebd8b4b1bd546a08d9169af7'/>
<id>urn:sha1:9f3445d03f106ee3ebd8b4b1bd546a08d9169af7</id>
<content type='text'>
A native confirm() or alert() leaves the desktop client unable to type
until the window is refocused. ask.js draws both in the page; the SPA
test now bans all three browser dialogs.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(hub): removing from a group no longer unpins the account</title>
<updated>2026-09-20T23:35:13Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-20T23:35:13Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=03bcfcdef2ff9a3d6ed0776f7580a45a5401ef37'/>
<id>urn:sha1:03bcfcdef2ff9a3d6ed0776f7580a45a5401ef37</id>
<content type='text'>
The node half called `unpin` after `revoke`, and an unpin takes no group:
it deletes the identity and every member row the account holds on this
node, and drops the stored keypair bundle with them. Taking somebody out
of one group took them out of all of them, silently. `revoke` is
group-scoped and is what withdraws the key.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(hub): keep the video read-ahead across a reconnection</title>
<updated>2026-09-20T22:43:14Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-20T22:43:14Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=90e26beff212e4994b8e4f18c8260f2aa8a9b40c'/>
<id>urn:sha1:90e26beff212e4994b8e4f18c8260f2aa8a9b40c</id>
<content type='text'>
A reconnection restarted the stream at the playhead, and that empties the
source buffer — spending the whole read-ahead at the one moment it was the
thing carrying the film. It carries on from the end of the buffer instead,
except where the buffer is short, the stream already ended, or a cast is
active: the receiver is fed from the wire and never had that buffer, so
resuming there would skip it forward by the lot.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
