| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
| |
A user revocation closed nothing: the denylist stopped the next connection and
left the live ones streaming and chatting. Revocations now go through one
method that closes the account's or the group's sessions (F-21).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Transitional. The Argon2 run that makes M makes A, the key MBK2 bundles were
sealed under; a session keeps it as a decrypt-only key (IndexedDB in a browser,
the key storage in the desktop app). A client meeting an MBK2 bundle opens it —
or its recovery copy — and stores the same identity as MBK3 once connected; the
desktop app reseals or withdraws it as browser access says. A session without
A asks for the passphrase once. Older formats stay refused by name. Replaces
the unpin-and-reinvite step the 0.17 flag day required on every node.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
a disk
unlock.key sits beside keystore.enc by default, so a whole disk, an image or a
home-directory backup opens the stored chat. The claims table, §4.5 and the
user guide say so and name what protects those: disk encryption, or the unlock
key on other storage (F-20).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
The desktop app writes the Mark-of-the-Web on each file it saves on Windows, as
a browser does. Bidirectional controls are reserved characters in a saved name
(portable-name.js and paths.sanitize_for_download, and again in the main
process), so a name cannot display one extension and carry another. The node
refuses uploads of files Windows Explorer acts on by itself: desktop.ini,
.lnk, .url, .scf, .library-ms, .searchConnector-ms (F-19).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
A sign-in from a browser that presented no token is answered with one
(known_browser, kept hashed, twenty per account); a later sign-in presenting it
counts failures on its own row, which nobody else can spend. Passphrase checks
inside an open session (change, e-mail, deletion, device, pepper) count on the
account's own row, so a locked name no longer stops its owner there either; /me
reports that row. Reset and erasure forget the browsers (F-15).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
128 peer sessions on the node, at most 64 per account (the hub names the
account with each offer; the node's own account is not counted). One account
plays at most half the stream slots, rounded up, and runs two subtitle
extractions at once. Frames after the handshake are 8 MiB (was 64), decoded
with per-container bounds, and a frame refused for either ends the session
instead of jamming its buffer (F-16).
Sized for the heaviest real member: twenty groups on one node, three devices
and a tab, up to 52 sessions. Measured: ~0.15 MiB and one fd per idle session.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
Over 128 characters was a 500 on PostgreSQL; line breaks, C0/C1 controls and
bidi overrides are refused (joiners stay, for emoji). The creation form caps
the field at 128 (F-13, what remains of it).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
A name an upload in flight will take is reserved; each upload writes its own
`name.<tag>.part`; the finished file is published by a hard link, which
refuses an existing target, and takes the next free name if one appeared
meanwhile — the last ack names it. Two members sending one name at once wrote
one part and published it twice; a file copied in during an upload was
replaced (F-09).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
probe_video waits 30 s at most and kills ffprobe on a timeout or when its
caller gives up — a cancelled wait left the process running. The seek probe
kills what it timed out on. Stream, subtitle and enrichment requests no longer
hang on a file that keeps ffprobe busy (F-18, timeouts; the protocol
whitelist was dropped: ffmpeg already confines nested protocols of a local
input, measured on 8.0 against HLS and concat inputs).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
| |
The name is resolved off the event loop and every answer checked; the socket
is then opened to that IP literal through a pinned httpcore backend, TLS still
verifying the certificate for the name, and no proxy from the environment.
A name that answers clean and then with a LAN address no longer gets a
request sent there, and a slow name no longer stalls the node (F-12).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
attach_group no longer copies join_policy and visibility from the hub's
answer: they come with the operator's request (the desktop creation form,
`group add --open`) and default to invite/private; the CLI says when the hub
lists the group otherwise. Every string written into node.toml is escaped
(toml_string) and read back through tomllib, so a group or folder name cannot
write lines of its own (F-17).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
| |
they are
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
The desktop main process builds every transcript itself from fields
(transcripts.js) and signs no raw bytes; the page's identity has the same
contract (crypto.js transcriptFor). The keyring seals no bundle while browser
access is off. On the node, device_add must redeem a pending request filed by
the same keys, and device_revoke is signed under its own prefix
(meshbay:device_revoke:v1), so a retirement signature admits nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
POST /me/bundle-pepper (was GET) and POST /users/devices require auth_key.
A refreshed or lifted token could otherwise fetch the pepper, or register a
device whose every sign-in carries it. Both callers have just been given the
passphrase.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
| |
Design §2.2-§3.7, §4, §5.6, §7.7, §8, §9.10 and the registers; protocol §7,
§7.1, §7.1a and §13; the user guide; CLAUDE.md's parity rule.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
Off for an account made there: its identities stay on the device and nothing is
left on nodes. Turned on from the Profile page behind a native confirmation;
each node is settled when its group next opens. The hub keeps a mirror a
browser reads to say why a group will not open; it grants nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
main process
keyring.js derives, opens, mints, seals, signs and agrees there; the page gets
public keys and a handle. Argon2 comes from the page's own WebAssembly build
(Electron's crypto has none). Without OS key storage the page keeps its keys as
a browser does. A node's bundle is settled after connecting, re-sealed when the
key changed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
Two public keys, sign() and shared(); the apps take transport.signFn. What
holds the keys (this page, or the desktop main process) is the identity's
business alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
The session key is M = HKDF(Argon2(passphrase) || pepper, account id); each
node's bundle key and the playlist key derive from it. Bundles are MBK3, bound
to account and node; MBK1/MBK2 are refused by name, never replaced silently.
Playlists move to key v2 and are re-sealed over unreadable node copies.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
Sealed at rest and bound to the account; returned by sign-in, device sign-in,
a passphrase change and GET /me/bundle-pepper, never by a refresh, to a node
token, in a token or in a log. Erasure clears it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
| |
Open is offered for PDFs, raster images, audio, video and plain text, typed
from the name; HTML, SVG and the rest are not opened in the hub's origin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
connect-src drops https: and wss: in both policies. Checked against Google's
reCAPTCHA test keys: in Chrome widget, token and registration unchanged; in
Firefox the widget loads; no violation reported in either.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
widens the node
node:call is replaced by named operations with checked arguments; hosting a
group, sharing an unpicked folder, key rotation, denylist clearing and a change
of node account are confirmed by a native dialog. Every channel checks its
sender, secrets:get/set/clear are gone, node:start writes the app's own hub.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
| |
Each name in admin_usernames is pinned to the first active account seen
holding it (admin_pins), so a name freed by a deletion grants nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
Present-tense statements of what holds, in place of before/after phrasing:
host designation (§7.2, AV32), invitations (§3.4, §7.3, AV33), the roster
check at the handshake (§5.2, protocol §6.3), the wrong-code lock (protocol
§8.3), and what the link-preview gate does and does not refuse (§6.5).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The handshake opened a session for anyone holding the group key with a hub
token naming the group; the roster was consulted only when wrapping the key
in a join. A member revoked or unpinned on the node but still a member on
the hub kept a full session with the key they already held — and was handed
the chat epoch their removal had just opened, since chat keys go to any
session. An honest client never met this (it asks for the key through
join_request every time); one that kept the key did not have to.
- After the proof, the node asks the roster and refuses with
`not_authorized_for_group` unless the account is an active member of the
group or the node's operator.
- A removal from any door — MNP, the node page, the CLI — now opens a new
chat epoch in each group the person could read, broadcasts it, and closes
every connection they hold (`ops.members._after_removal`). The CLI and the
node page did neither.
- Design §5.2, protocol §6.1, §6.3, §14.2.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
unasked
- hub: a node may host a group only if its account owns it or the owner
approved that node (new `group_hosts`). Membership was the ceiling, and
every member holds the group key, so any member's node could register as a
host and be the one clients kept. A node claiming a group it may not host
is recorded as a request; the owner is notified once and approves or
refuses it (GET/POST/DELETE /v1/groups/{id}/hosts[/{node_id}]), which
takes effect on a connected node at once.
- hub: an owner adding a username creates an invitation (new
`group_invitations`), accepted or declined by the invitee
(/v1/groups/invitations, /{id}/invitation/accept|decline). Until then the
group is not listed, not dialled, not searched and not in any token.
Invitation links, open joins and group creation still make members
directly: they are the account's own act.
- hub: the MNP token names only the group it is minted for (group_id is now
required), so a node operator no longer learns a member's other groups.
- SPA: invitations on the home page; invited people and host requests in
the group's settings; the transport sends group_id. Ten catalogues.
- Browser probes for both screens, run in Chrome and Firefox.
- Design §5.2, §7.2, §7.3, AV32, AV33; protocol §6.3; user guide.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
cleanup
- node: only a wrong code counts towards the join lock, now per account
(5) as well as node-wide (20), and it is consulted only when a code is
tried. Every member reconnecting gets the group key through join_request,
so a lock checked before recognition let one member refuse it to everyone.
- node: link previews read the body as a stream and stop at the cap,
counted on decoded bytes; a declared oversized image is not read; 15 s
total deadline; image decoding off the loop. `client.get` had buffered
the whole (decompressed) response before the caps looked at it.
- hub: the daily purge of never-verified accounts detaches their IP-log
rows (keeping the name) and clears every other reference first, and each
cleanup step runs on its own. On PostgreSQL the bare DELETE violated the
ip_logs foreign key and stopped every purge behind it for good.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
A descriptive <title>, a two-line meta description apart from the
short one messengers get, "/" canonical for every shell path, and a
<noscript> pitch with the download and doc links for crawlers that
do not run app.js.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
| |
Home, downloads, and the repository's about page and docs on
git.meshbay.org, spelled as the welcome page links them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
| |
Every /v1/relays route answered 503 and nothing called them; no TURN
relay is needed. The proof-of-possession rule it carried stays as AV6.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
The group-setting routes for app directories, chat directory, link
previews, Search listing and scan settings had no caller and no test;
those settings are signed MNP operations only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
| |
The node honours it and no interface sends it; offered alone it would
strand the next browser that signs in. Stated in both documents.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
| |
The interface reads a member's cap from transfer_state and never read the
copy on the ack. The transfer probe reads it from transfer_state too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
A node serves the name its disk gave a file; the client now makes it
portable at save time (single file, zip entries, zip name) and says so
on the transfer row. Same rule as paths.sanitize_for_download, held by a
parity test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
| |
A report needs a person's account at least a day old, membership of the
public group, and fits a daily allowance per account. Past the threshold
a hash is queued and administrators are notified; blocking without
review is an instance setting, off by default. Report menu item in
public groups, Reports tab and settings in the admin panel.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
A node hosting a public group syncs the hub's blocklist on every
connection (paged, node token only) and applies pushed changes. A
blocked file leaves the index and is refused (content_blocked); private
groups are untouched. The unused per-hash check route is gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
Nodes registered the hashes of their public groups on the hub and nothing
ever read them back. Routes, model and node registration removed; a
migration drops swarm_sources. No node sends the hub a content hash now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
| |
Any member could make a node hold unbounded challenge requests; a
connection now keeps at most 8, 64 KiB each. root_add, group_attach,
invite_create and tmdb_config signed less than they did; their subjects
are now canonical JSON of every value (the TMDB token by SHA-256).
MNP 5.0, floor kept at 4.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
Unused modules, functions, constants and client helpers with no caller,
the unreachable hub:probe IPC handler, and the CSAM hash matching.
Behaviour unchanged; the dispatch golden loses only the two removed
message types.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
| |
serialize/deserialize had no production caller, and took with them the
per-chunk signature, the ChaCha20 cipher variant and the zstandard
dependency. Key derivations are unchanged. Docs corrected, including
design §4.3's claim that chunks are compressed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
Every node the 4.0 floor admits signs its challenge, and one without a
channel binding could not complete the proof anyway, so a missing
signature is refused like a wrong one (browser and QUIC client).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
MNP 4.0 and the node-bound token, signaling limits, file_delete and
operator-control authority, error codes, lease semantics of tr, chat
bounds, revocation's single door, e-mail opt-in defaults.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
A tab opened before a hub deploy got 404 for every module it had not
loaded yet, and lazy.js kept its spinner for good. It now shows a notice
with a Reload button and logs the failure.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
| |
Closing the player lands back on the season being watched, with the
episode just started marked. A film's modal still closes on Play.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
| |
_pid_alive only ran tasklist, so request_graceful_stop raised
FileNotFoundError off Windows and two real-daemon tests failed on Linux.
Read /proc there, counting a zombie as gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- MESHBAY_DESIGN.md §11.2: the node runs only while the app is open, at
sign-in, or as a boot-time service; starting and stopping have one
implementation, the CLI's; a second instance refuses before it writes
anything the running one depends on.
- packaging/win/README.md: the three modes, switching between them, upgrading
a running node, where the log is, the service task's settings.
- docs/windows-build.md: the build's smoke start of the frozen daemon, the log
location, and what an upgrade does to a running node.
- CLAUDE.md: four engineering lessons -- an upgrade that cannot stop the node
installs around it; on Windows the CLI is the process it is stopping; a
second instance must fail before it touches anything shared; a test that
redirects HOME isolates nothing on Windows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Most of these failed on Windows for reasons that had nothing to do with the
code under test, which is how real Windows defects hid among them:
- Read and write files as UTF-8, and talk to Node in UTF-8. read_text(),
write_text() and subprocess text=True use the locale codepage, cp1252 on
Windows: "é", "—" and "→" arrived as "?" or crashed, some sixty tests.
Calls to PowerShell and schtasks are left alone -- they answer in the
console codepage.
- Import ESM harness modules by file URL (as_uri): a raw "C:\..." path is not
a module specifier.
- test_cli_golden: mask the tmp path in its JSON-escaped form, spell it the
POSIX way, record on Linux, mask the protocol version (the recording had
failed everywhere since the MNP 4.0 bump) and argparse's version-dependent
quoting; point USERPROFILE at the tmp home, or `member invite` and
`operator pair` wrote their codes into the developer's profile.
- test_disk_io_off_loop: expect what a free loop can reach on the platform's
timer, 15.6 ms on Windows, not an assumed 5 ms.
- test_root_paths_are_operator_only: expect the OS's spelling of the path.
- test_audio_meta_cache: find ffprobe with shutil.which.
Node suite on Windows: 1489 passed, none failed. Hub suite: 3 failures left,
all older than this change (two SQLite concurrency tests, one transfer resume).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|