feat(core): verify and deliver a directed room.send - #76
Merged
Conversation
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
marked this pull request as ready for review
September 12, 2026 08:52
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
🎉 This PR is included in version 2.9.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.