<feed xmlns='http://www.w3.org/2005/Atom'>
<title>meshbay.git/packages/meshbay-node/tests, branch 0.20</title>
<subtitle>MeshBay — read-only public mirror</subtitle>
<id>https://git.meshbay.org/meshbay.git/atom?h=0.20</id>
<link rel='self' href='https://git.meshbay.org/meshbay.git/atom?h=0.20'/>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/'/>
<updated>2026-10-15T15:45:41Z</updated>
<entry>
<title>build: ignore the Windows build's work directories; a Linux mode check off Windows</title>
<updated>2026-10-15T15:45:41Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-15T15:42:30Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=23cb42e97b6fdff85fad3c3d4b9c9dd8e8d0a0ce'/>
<id>urn:sha1:23cb42e97b6fdff85fad3c3d4b9c9dd8e8d0a0ce</id>
<content type='text'>
packages/meshbay-client/build/_pip-audit (and its siblings) is made by the
Windows build and was untracked noise. test_packaging_default_env checked a
POSIX file mode that Git's bash on Windows cannot set.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(packaging): setup ends a command-line client run from its install</title>
<updated>2026-10-15T15:45:41Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-15T15:42:30Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=0d082ab4d19412079516b281aff76e8c3f70d9ba'/>
<id>urn:sha1:0d082ab4d19412079516b281aff76e8c3f70d9ba</id>
<content type='text'>
A `meshbay-cli chat --follow` left open holds node-runtime's DLLs, so the
previous version's uninstaller failed ("Failed to uninstall old application
files"), a silent update included, and left the node it had stopped not
running. stop-node.ps1 now ends a meshbay-cli.exe run from this install
(-InstallDir, setup's $INSTDIR), and no other copy.

Found through CIM, not Get-Process: setup runs the 32-bit PowerShell, which
reads no path for a 64-bit process, and the first version of the stop matched
nothing. The test runs the script in that PowerShell. Checked live: an update
over a running follower now ends it, replaces every file and restarts the node.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>build: audit the shipped Python dependencies with pip-audit</title>
<updated>2026-10-15T12:56:35Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-15T12:56:35Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=7fc2fa04d7d88a1cdf0d290ddd2de3815a7d52a5'/>
<id>urn:sha1:7fc2fa04d7d88a1cdf0d290ddd2de3815a7d52a5</id>
<content type='text'>
No lock file pins the dependencies, so each build installs the newest
releases and what ships is only known once it has. packaging/audit_deps.py
runs pip-audit then: build-common.sh on the venv before stripping it,
build-node-runtime.ps1 on the environment before PyInstaller freezes it.

A known vulnerability stops the build, unless its id is listed in
packaging/pip-audit-ignore.txt with why it does not apply. No network only
skips the audit with a warning, as does a pip-audit that cannot be installed
or writes no report. pip-audit runs from a venv of its own, never from the
one that ships. Our packages are not audited (not on PyPI), nor pip,
setuptools and wheel, which do not ship.

Checked with the real build-common.sh (79 packages, none known), with
PyJWT 2.14 (the build stops on its two advisories, and goes on once they are
listed) and offline (a warning, the build goes on). The PowerShell step was
not run here.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>test(node): the event-loop disk guard watches os.stat again</title>
<updated>2026-10-15T12:37:45Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-15T12:37:45Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=9dd6d1003cf92c0e4e7f23414565314691aa5516'/>
<id>urn:sha1:9dd6d1003cf92c0e4e7f23414565314691aa5516</id>
<content type='text'>
test_a_scan_asks_the_disk_nothing_from_the_event_loop patched Path.stat,
and since the indexer learned Windows' long paths it calls
os.stat(long_path(p)) and os.scandir instead: the guard saw no call at all,
and asserting that the calls ran on the indexer's thread failed on an empty
set. It watches os.stat and os.scandir now (Path.stat goes through os.stat
too), counting what the root holds and not the root, whose availability
check runs on the roots' I/O thread. Nothing runs on the loop; a stat added
there makes it fail again.

The node CLI's parser names itself: under `python -m pytest`, Python 3.14
named the program after the module, so test_cli_golden saw "python -m
pytest" in the help. The installed meshbay-node was not affected.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(node): a removal made at the machine is in audit.db</title>
<updated>2026-10-15T12:24:44Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-15T12:24:44Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=283771ff468bd9e1a60a4902a5ada4319c063073'/>
<id>urn:sha1:283771ff468bd9e1a60a4902a5ada4319c063073</id>
<content type='text'>
The Node page and the CLI remove access through the loopback API, and
revoke and unpin there wrote nothing to audit.db; only the signed MNP door
did. A removed person's next connection then showed an auth_failed with
nothing before it to explain it. Both routes now record member_revoke and
member_unpin once the operation has succeeded, with the node's own account
as the actor and 127.0.0.1 as the address, which tells the two doors apart.
A refusal changes nothing and records nothing.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(packaging): ship only the TMDB token line of QE/default.env</title>
<updated>2026-10-15T12:24:25Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-15T12:24:25Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=5949532e6450d1aebc681caa8db2192a43b11f12'/>
<id>urn:sha1:5949532e6450d1aebc681caa8db2192a43b11f12</id>
<content type='text'>
build-node.sh and build-node-runtime.ps1 copied QE/default.env whole into
every deb, rpm and Windows build after checking only its first 30 bytes. The
file is unversioned and sits beside other QE notes, so any line added to it
later would have gone out publicly. Only its first line ships now, and only
once it is exactly MESHBAY_TMDB_DEFAULT_TOKEN=&lt;JWT&gt;; a missing file, a BOM,
a token not on the first line or an empty one still stop the build.

The Linux step is run by a test against a scratch repo; the PowerShell one
has the same rule and was not run here.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor(chat): no thread_id — chat has no threads</title>
<updated>2026-10-15T10:57:51Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-15T10:57:51Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=a86bced1640ac1a695b95ac68b95e3fc581e687d'/>
<id>urn:sha1:a86bced1640ac1a695b95ac68b95e3fc581e687d</id>
<content type='text'>
Nothing ever set it (the page and the CLI sent null) and nothing read it
(the node's get_thread had no caller). It is no longer sent by the page or
the CLI, in clear or in the sealed payload, nor relayed or served by the
node; get_thread and its index are gone, and the protocol and design docs
no longer name it.

The node still accepts a chat_msg carrying one, from the desktop apps and
CLIs already installed, and drops it. The column stays, empty, in chat.db:
a node downgraded to an older version names it in every query.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(node): an operator who was a member first holds the authority at once</title>
<updated>2026-10-15T10:32:24Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-15T10:32:24Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=e0a1036e0fee15b3c6c83f3e935d50f472a2e776'/>
<id>urn:sha1:e0a1036e0fee15b3c6c83f3e935d50f472a2e776</id>
<content type='text'>
A member pinned on the node who then redeems the operator pairing code was
written down as the operator but the node kept its "nobody can authorize"
flag until it restarted: every admin operation — removing a folder, inviting,
the apps' settings — was refused meanwhile. Only a key paired fresh set it.

The join result now names `operator` for an account holding the node-wide
operator row, whatever its row in the group says. The page and the CLI read
that role to know what to offer, and refused before asking deletions the node
would have accepted. Nothing is granted by it: every admin operation is still
checked against the operators' keys.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(hub): one account, several linked nodes</title>
<updated>2026-10-15T07:33:28Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-15T07:33:28Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=1e8eae1f3de765fcd8163716de6e5fe5aab5a034'/>
<id>urn:sha1:1e8eae1f3de765fcd8163716de6e5fe5aab5a034</id>
<content type='text'>
An account links up to MAX_NODES_PER_ACCOUNT node keys (node_keys table)
instead of the one users.pk_node_ed25519; the migration carries each
account's key over and the downgrade keeps the last one linked.
/v1/nodes/auth accepts any linked key, and its token names the key that
won it (nk). PUT /me/node_key adds a key, idempotently, 409 past the
limit; DELETE /me/node_key names the key: a browser session any of its
own, a node only its own. Unlinking a key closes that node's socket and
refuses its tokens at once, on REST and on the socket; the account's other
nodes are untouched. /pubkeys no longer gives a node key to other accounts,
and gives the caller its last linked one, which installed desktop apps read.

The node reports waiting_for_node_key while its key is unlinked and signs
in again as soon as the hub says so, so a key linked again is back within
seconds; unlinking itself signs in first to hold a token naming its key.

Profile -&gt; Linked nodes lists each node (connected, last seen, IP, linked
since, This machine in the desktop app) with Copy and Unlink, and adds a
key by hand. The Node page banner, Create group and the desktop app add
this machine's key instead of replacing another's. Messages that pointed
at Settings -&gt; Link Node point at Profile -&gt; Linked nodes.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(node): a chat-epoch notice answers no request, not even the asker's</title>
<updated>2026-10-14T22:56:04Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-14T22:56:04Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=16d92c96bde3a65fc54a93b4662df30cafc831e4'/>
<id>urn:sha1:16d92c96bde3a65fc54a93b4662df30cafc831e4</id>
<content type='text'>
Revoking a device or removing a member opens a chat epoch, announced to
everyone connected to the group, the asker included. Sent inside the
handler, the asker's copy was stamped with its request's id and arrived as
the answer to device_revoke, before the real one. It now leaves outside the
reply context.

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