fix(broker+cli): multi-session DM routing + broadcast self-loopback (v0.3.2)
Two related bugs surfaced in multi-session production use of 1.8.0: 1. Replies via `claudemesh send <from_id>` rejected with "no connected peer for target" when the original sender's session had rotated (Claude Code restart, /resume). Root cause: from_id carried the ephemeral session pubkey, which disappears the moment the session ends. Fix: handleSend pre-flight now also resolves the target pubkey against the persistent meshMember table and routes to the owning member's live session(s); MCP push channel now sets from_id to the stable member pubkey and exposes the ephemeral one under from_session_pubkey. 2. Broadcast/* and @group sends loopback'd to the sender's *sibling* sessions (same member, different session keypair), surfacing a spurious "tampered or wrong keypair" decrypt warning on the sender's own inboxes. Fix: broadcast/group fan-out now skips by memberPubkey, not just by presence_id, so the entire sender member is excluded — direct sends keep per-presence skip so a member can still DM their own sibling session intentionally. Push envelope now also carries senderMemberPubkey alongside senderPubkey so any other client of the WS channel can choose the right one.
This commit is contained in:
@@ -100,7 +100,12 @@ export interface PeerInfo {
|
||||
export interface InboundPush {
|
||||
messageId: string;
|
||||
meshId: string;
|
||||
/** Sender's *session* pubkey — ephemeral. Rotates on session restart.
|
||||
* Used by crypto_box_open to verify the seal. Prefer the member
|
||||
* pubkey for replies. */
|
||||
senderPubkey: string;
|
||||
/** Sender's *member* pubkey — stable. Use as the reply target. */
|
||||
senderMemberPubkey?: string;
|
||||
/** Stable mesh.member id of the sender — preferred id for replies. */
|
||||
senderMemberId?: string;
|
||||
/** Sender's current display name (a join from the broker). */
|
||||
@@ -2036,6 +2041,7 @@ export class BrokerClient {
|
||||
messageId: String(msg.messageId ?? ""),
|
||||
meshId: String(msg.meshId ?? ""),
|
||||
senderPubkey,
|
||||
...(msg.senderMemberPubkey ? { senderMemberPubkey: String(msg.senderMemberPubkey) } : {}),
|
||||
...(msg.senderMemberId ? { senderMemberId: String(msg.senderMemberId) } : {}),
|
||||
...(msg.senderName ? { senderName: String(msg.senderName) } : {}),
|
||||
...(msg.topic ? { topic: String(msg.topic) } : {}),
|
||||
|
||||
Reference in New Issue
Block a user