Skip to content

feat(core): verify and deliver a directed room.send - #76

Merged
Mearman merged 6 commits into
mainfrom
feat/room-send-directed
Sep 12, 2026
Merged

feat(core): verify and deliver a directed room.send#76
Mearman merged 6 commits into
mainfrom
feat/room-send-directed

Conversation

@Mearman

@Mearman Mearman commented Sep 12, 2026

Copy link
Copy Markdown
Member

P3.4/P3.5 groundwork for #48: real room.send admission and directed delivery.

handleRoomSend verifies a presented room:member token against all six of core/room's obligations (room-token-verification.ts), then delivers the message locally once -- the manage-response itself is the delivery receipt. sendRoomMessageDirected is the client-side counterpart: loads the sender's own persisted token for the room and sends a real wire-authenticated room.send via sendRoomRequest.

Blocked on ExaDev/wire-mesh#89 landing and publishing: building this surfaced a real bug in wire-mesh-core where a capability token received over a genuine TCP/TLS connection fails signature verification, even though its bytes cross the wire perfectly intact (cbor2 mis-encodes a Buffer-typed byte string it just decoded). Fixed in ExaDev/wire-mesh#88. This PR's own new integration test (room-send-directed.integration.test.ts) is the first thing in either codebase to actually exercise a real, cryptographically-signed CapabilityToken sent over a real wire connection and verified on the receiving end, which is how the bug surfaced. CI here will fail against the currently-published wire-mesh-core until that fix ships; this stays draft until the dependency bumps to a version carrying it.

Also includes a mechanical rename (token-id.ts -> random-id.ts, since core/room's message-id needs the identical randomness token-id already provided) and a genuine fix to the smoke test's generated child-process script, which never passed roomVerbHandlers to WireMeshTransport and so could never dispatch a room verb over the wire at all.

core/room's own fields (token-id, message-id) are both defined as an
arbitrary-length bstr needing the same unguessable-identifier
randomness, so the helper is renamed to reflect that it now backs
both, not just token minting.
handleRoomSend verifies the presented room:member token against all
six of core/room's obligations, then delivers the message locally
once -- the manage-response itself is the delivery receipt, so there
is no separate "delivered" event to emit the way the legacy
broadcastPatch path needs.

sendRoomMessageDirected is the client-side counterpart: loads the
sender's own persisted token for the room, throwing NOT_A_MEMBER if
absent, and sends it as a real wire-authenticated room.send via
sendRoomRequest.

MeshStoreIdentity grows a revocation: RevocationCheck field so
verifyRoomToken has a real revocation view to consult, threaded
through every setIdentity() call site.
The generated child-process script never passed store.roomVerbHandlers
to WireMeshTransport's constructor, so the smoke test's own peers could
never dispatch any room verb over the wire -- missed until now since
it's a dynamically-generated string tsc never checks. Also threads the
revocation view MeshStoreIdentity now requires.
Three real, two-peer integration tests: a directed send from the
owner delivers to the member's own onDelivery, the same works in
reverse from a member back to the owner, and sendRoomMessageDirected
throws when this store holds no persisted token for the room.

Membership is set up by minting and persisting the member's own token
directly rather than driving a real room.join round trip: MeshStore's
legacy full-state-sync makes two mesh-connected peers instantly aware
of any room the moment it's created, so a genuine join round trip
always takes the already-known-locally branch here, irrelevant to
what this file actually exercises.
Every capability token received over a genuine TCP/TLS connection
failed signature verification despite its bytes crossing the wire
perfectly intact -- a cbor2 Buffer-vs-Uint8Array mismatch, fixed
upstream in ExaDev/wire-mesh#88. This dependency's own project-level
.npmrc gains a matching minimum-release-age exclusion, since it's a
first-party package this repo depends on.
@Mearman
Mearman marked this pull request as ready for review September 12, 2026 08:52
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 12, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review Completed 2026-09-12T09:02:44.619933Z 02a0ba2 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Mearman
Mearman merged commit 3cb441e into main Sep 12, 2026
5 checks passed
@Mearman
Mearman deleted the feat/room-send-directed branch September 12, 2026 09:03
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.9.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant