agent-comms 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,7 @@
15
15
  "url": "https://github.com/ExaDev/agent-comms.git"
16
16
  },
17
17
  "description": "Cross-harness LLM agent communication mesh — rooms, DMs, and presence",
18
- "version": "2.2.0"
18
+ "version": "2.3.1"
19
19
  }
20
20
  ]
21
21
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-comms",
3
3
  "description": "Cross-harness LLM agent communication mesh — rooms, DMs, and presence",
4
- "version": "2.2.0",
4
+ "version": "2.3.1",
5
5
  "author": {
6
6
  "name": "ExaDev"
7
7
  },
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github&logoColor=white)](https://github.com/ExaDev/agent-comms)
4
4
  [![npm](https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white)](https://www.npmjs.com/package/agent-comms)
5
- [![version](https://img.shields.io/badge/version-2.2.0-blue)](https://github.com/ExaDev/agent-comms/releases/tag/v2.2.0)
5
+ [![version](https://img.shields.io/badge/version-2.3.1-blue)](https://github.com/ExaDev/agent-comms/releases/tag/v2.3.1)
6
6
  [![CI](https://img.shields.io/github/actions/workflow/status/ExaDev/agent-comms/ci.yml?branch=main)](https://github.com/ExaDev/agent-comms/actions)
7
7
 
8
8
  Cross-harness communication mesh for LLM agents: rooms, DMs, presence, and visibility over TCP with zero filesystem dependencies.
@@ -1,10 +1,11 @@
1
1
  /**
2
- * Persistent bridge identity: load-or-create the TLS key material for a (harness, cwd) slot so the certificate fingerprint and therefore the peer and agent ID survives restarts.
2
+ * Persistent bridge identity: load-or-create the TLS key material for a (harness, cwd) slot so the device-id -- and therefore the peer and agent ID -- survives restarts. Also persists a per-room capability token set in the same slot, so a room membership grant survives a restart the same way the identity it was minted against does.
3
3
  *
4
- * Mesh state stays in memory and on the wire; the only thing on disk is this local credential, the same trust model as an SSH key. A lock file holding a PID keeps two live bridges in one slot from sharing an identity, which would put duplicate peer IDs on the mesh; the second bridge runs with an ephemeral identity (the behaviour before persistence) instead. Bridges without a graceful shutdown hook can skip releasing the lock: a stale lock is detected by probing the recorded PID, the same way the coordinator probes for stale agents.
4
+ * Mesh state stays in memory and on the wire; the only thing on disk is this local credential (plus, now, the tokens minted against it), the same trust model as an SSH key. A lock file holding a PID keeps two live bridges in one slot from sharing an identity, which would put duplicate peer IDs on the mesh; the second bridge runs with an ephemeral identity (the behaviour before persistence) instead. Bridges without a graceful shutdown hook can skip releasing the lock: a stale lock is detected by probing the recorded PID, the same way the coordinator probes for stale agents.
5
5
  *
6
- * Persisting the key material rather than a bare agent ID is what makes restarts work: delivery routing fires when agentId === peerId, and peerId is the live certificate fingerprint, so an ID without its key can never match the running peer.
6
+ * Persisting the key material rather than a bare agent ID is what makes restarts work: delivery routing fires when agentId === peerId, and peerId is deviceIdToHex(identity.deviceId), so an ID without its key can never match the running peer. Renewal near certificate expiry currently generates an entirely fresh key pair rather than re-certifying the existing one, which silently rotates the device-id (and so invalidates any persisted room tokens bound to it) -- a real, separately tracked gap (#68), not addressed here.
7
7
  */
8
+ import type { CapabilityToken } from "wire-mesh-core/generated/protocol";
8
9
  import type { PeerIdentity } from "./identity.js";
9
10
  /** A bridge's identity slot: one persisted identity per harness and cwd. */
10
11
  export interface IdentitySlot {
@@ -21,4 +22,14 @@ export declare function loadOrCreateIdentity(slot: IdentitySlot): PeerIdentity;
21
22
  * Release the slot lock on graceful shutdown. A lock held by another PID (taken over after this process crashed and restarted) is left alone.
22
23
  */
23
24
  export declare function releaseIdentityLock(slot: IdentitySlot): void;
25
+ /**
26
+ * Every room-membership capability token persisted for this slot, keyed by room path. Empty if the slot has never had one saved (or the identity file doesn't exist yet -- call loadOrCreateIdentity first).
27
+ */
28
+ export declare function loadRoomTokens(slot: IdentitySlot): Record<string, CapabilityToken>;
29
+ /**
30
+ * Persists a capability token for the given room path, surviving a restart the same way the identity it was minted against does. Overwrites any token already saved for that room; leaves every other room's token and the identity's own key material untouched.
31
+ */
32
+ export declare function saveRoomToken(slot: IdentitySlot, roomPath: string, token: CapabilityToken): void;
33
+ /** Removes the persisted token for one room path, if any. A no-op if none was saved for that path. */
34
+ export declare function deleteRoomToken(slot: IdentitySlot, roomPath: string): void;
24
35
  //# sourceMappingURL=identity-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identity-store.d.ts","sourceRoot":"","sources":["../../src/core/identity-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAkFD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAgBrE;AAsCD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAK5D"}
1
+ {"version":3,"file":"identity-store.d.ts","sourceRoot":"","sources":["../../src/core/identity-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAOzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAuJD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAgBrE;AAsCD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAK5D;AAuBD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,GACjB,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CASjC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,eAAe,GACrB,IAAI,CAaN;AAED,sGAAsG;AACtG,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ1E"}
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Persistent bridge identity: load-or-create the TLS key material for a (harness, cwd) slot so the certificate fingerprint and therefore the peer and agent ID survives restarts.
2
+ * Persistent bridge identity: load-or-create the TLS key material for a (harness, cwd) slot so the device-id -- and therefore the peer and agent ID -- survives restarts. Also persists a per-room capability token set in the same slot, so a room membership grant survives a restart the same way the identity it was minted against does.
3
3
  *
4
- * Mesh state stays in memory and on the wire; the only thing on disk is this local credential, the same trust model as an SSH key. A lock file holding a PID keeps two live bridges in one slot from sharing an identity, which would put duplicate peer IDs on the mesh; the second bridge runs with an ephemeral identity (the behaviour before persistence) instead. Bridges without a graceful shutdown hook can skip releasing the lock: a stale lock is detected by probing the recorded PID, the same way the coordinator probes for stale agents.
4
+ * Mesh state stays in memory and on the wire; the only thing on disk is this local credential (plus, now, the tokens minted against it), the same trust model as an SSH key. A lock file holding a PID keeps two live bridges in one slot from sharing an identity, which would put duplicate peer IDs on the mesh; the second bridge runs with an ephemeral identity (the behaviour before persistence) instead. Bridges without a graceful shutdown hook can skip releasing the lock: a stale lock is detected by probing the recorded PID, the same way the coordinator probes for stale agents.
5
5
  *
6
- * Persisting the key material rather than a bare agent ID is what makes restarts work: delivery routing fires when agentId === peerId, and peerId is the live certificate fingerprint, so an ID without its key can never match the running peer.
6
+ * Persisting the key material rather than a bare agent ID is what makes restarts work: delivery routing fires when agentId === peerId, and peerId is deviceIdToHex(identity.deviceId), so an ID without its key can never match the running peer. Renewal near certificate expiry currently generates an entirely fresh key pair rather than re-certifying the existing one, which silently rotates the device-id (and so invalidates any persisted room tokens bound to it) -- a real, separately tracked gap (#68), not addressed here.
7
7
  */
8
8
  import * as fs from "node:fs";
9
9
  import * as os from "node:os";
@@ -11,6 +11,21 @@ import * as path from "node:path";
11
11
  import { generateIdentity, getCertificateFingerprint, deriveDeviceId, CERTIFICATE_VALIDITY_MS, } from "./identity.js";
12
12
  /** Renew during the final twelfth of the certificate's validity. */
13
13
  const RENEWAL_MARGIN_MS = CERTIFICATE_VALIDITY_MS / 12;
14
+ function isSerializedCapabilityToken(value) {
15
+ if (!Array.isArray(value) || value.length !== 4)
16
+ return false;
17
+ const protectedHeader = value[0];
18
+ const unprotectedHeader = value[1];
19
+ const payload = value[2];
20
+ const signature = value[3];
21
+ if (typeof protectedHeader !== "string")
22
+ return false;
23
+ if (typeof unprotectedHeader !== "object" || unprotectedHeader === null)
24
+ return false;
25
+ if (payload !== null && typeof payload !== "string")
26
+ return false;
27
+ return typeof signature === "string";
28
+ }
14
29
  function isStoredIdentity(value) {
15
30
  if (typeof value !== "object" || value === null)
16
31
  return false;
@@ -18,9 +33,52 @@ function isStoredIdentity(value) {
18
33
  !("certificate" in value) ||
19
34
  !("expiresAt" in value))
20
35
  return false;
21
- return (typeof value.privateKey === "string" &&
22
- typeof value.certificate === "string" &&
23
- typeof value.expiresAt === "string");
36
+ if (typeof value.privateKey !== "string" ||
37
+ typeof value.certificate !== "string" ||
38
+ typeof value.expiresAt !== "string")
39
+ return false;
40
+ if (!("roomTokens" in value))
41
+ return true;
42
+ const { roomTokens } = value;
43
+ if (typeof roomTokens !== "object" || roomTokens === null)
44
+ return false;
45
+ return Object.values(roomTokens).every(isSerializedCapabilityToken);
46
+ }
47
+ function serializeToken(token) {
48
+ const [protectedHeader, unprotectedHeader, payload, signature] = token;
49
+ const serializedUnprotected = {
50
+ ...(unprotectedHeader["1"] !== undefined
51
+ ? { "1": unprotectedHeader["1"] }
52
+ : {}),
53
+ ...(unprotectedHeader["4"] !== undefined
54
+ ? { "4": Buffer.from(unprotectedHeader["4"]).toString("base64") }
55
+ : {}),
56
+ };
57
+ return [
58
+ Buffer.from(protectedHeader).toString("base64"),
59
+ serializedUnprotected,
60
+ payload === null ? null : Buffer.from(payload).toString("base64"),
61
+ Buffer.from(signature).toString("base64"),
62
+ ];
63
+ }
64
+ function deserializeToken(serialized) {
65
+ const [protectedHeader, unprotectedHeader, payload, signature] = serialized;
66
+ const deserializedUnprotected = {
67
+ ...(unprotectedHeader["1"] !== undefined
68
+ ? { "1": unprotectedHeader["1"] }
69
+ : {}),
70
+ ...(unprotectedHeader["4"] !== undefined
71
+ ? {
72
+ "4": Uint8Array.from(Buffer.from(unprotectedHeader["4"], "base64")),
73
+ }
74
+ : {}),
75
+ };
76
+ return [
77
+ Uint8Array.from(Buffer.from(protectedHeader, "base64")),
78
+ deserializedUnprotected,
79
+ payload === null ? null : Uint8Array.from(Buffer.from(payload, "base64")),
80
+ Uint8Array.from(Buffer.from(signature, "base64")),
81
+ ];
24
82
  }
25
83
  /** Replace path separators and other filesystem-hostile characters. */
26
84
  function slugifyCwd(cwd) {
@@ -127,4 +185,58 @@ export function releaseIdentityLock(slot) {
127
185
  fs.rmSync(lockFile, { force: true });
128
186
  }
129
187
  }
188
+ /** Reads the slot's raw stored identity record, or undefined if the file is missing or unparseable. Used by the room-token functions below to read-modify-write only the roomTokens field, leaving the persisted key material exactly as it is. */
189
+ function readStoredIdentity(identityFile) {
190
+ let parsed;
191
+ try {
192
+ parsed = JSON.parse(fs.readFileSync(identityFile, "utf-8"));
193
+ }
194
+ catch {
195
+ return undefined;
196
+ }
197
+ return isStoredIdentity(parsed) ? parsed : undefined;
198
+ }
199
+ function writeStoredIdentity(identityFile, stored) {
200
+ fs.writeFileSync(identityFile, `${JSON.stringify(stored, null, 2)}\n`, {
201
+ encoding: "utf-8",
202
+ mode: 0o600,
203
+ });
204
+ }
205
+ /**
206
+ * Every room-membership capability token persisted for this slot, keyed by room path. Empty if the slot has never had one saved (or the identity file doesn't exist yet -- call loadOrCreateIdentity first).
207
+ */
208
+ export function loadRoomTokens(slot) {
209
+ const { identityFile } = slotPaths(slot);
210
+ const stored = readStoredIdentity(identityFile);
211
+ const serialized = stored?.roomTokens ?? {};
212
+ const tokens = {};
213
+ for (const [roomPath, token] of Object.entries(serialized)) {
214
+ tokens[roomPath] = deserializeToken(token);
215
+ }
216
+ return tokens;
217
+ }
218
+ /**
219
+ * Persists a capability token for the given room path, surviving a restart the same way the identity it was minted against does. Overwrites any token already saved for that room; leaves every other room's token and the identity's own key material untouched.
220
+ */
221
+ export function saveRoomToken(slot, roomPath, token) {
222
+ const { identityFile } = slotPaths(slot);
223
+ const stored = readStoredIdentity(identityFile);
224
+ if (stored === undefined) {
225
+ throw new Error(`no identity persisted for this slot yet -- call loadOrCreateIdentity first (${identityFile})`);
226
+ }
227
+ const roomTokens = {
228
+ ...stored.roomTokens,
229
+ [roomPath]: serializeToken(token),
230
+ };
231
+ writeStoredIdentity(identityFile, { ...stored, roomTokens });
232
+ }
233
+ /** Removes the persisted token for one room path, if any. A no-op if none was saved for that path. */
234
+ export function deleteRoomToken(slot, roomPath) {
235
+ const { identityFile } = slotPaths(slot);
236
+ const stored = readStoredIdentity(identityFile);
237
+ if (stored?.roomTokens === undefined)
238
+ return;
239
+ const roomTokens = Object.fromEntries(Object.entries(stored.roomTokens).filter(([path]) => path !== roomPath));
240
+ writeStoredIdentity(identityFile, { ...stored, roomTokens });
241
+ }
130
242
  //# sourceMappingURL=identity-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"identity-store.js","sourceRoot":"","sources":["../../src/core/identity-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAWvB,oEAAoE;AACpE,MAAM,iBAAiB,GAAG,uBAAuB,GAAG,EAAE,CAAC;AAQvD,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,IACE,CAAC,CAAC,YAAY,IAAI,KAAK,CAAC;QACxB,CAAC,CAAC,aAAa,IAAI,KAAK,CAAC;QACzB,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC;QAEvB,OAAO,KAAK,CAAC;IACf,OAAO,CACL,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ;QACrC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CACpC,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,SAAS,CAAC,IAAkB;IAKnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,YAAY,IAAI,CAAC,OAAO,KAAK,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACjE,OAAO;QACL,GAAG;QACH,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,OAAO,CAAC;QAC5C,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,OAAO,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,SAAS,WAAW,CAAC,QAAgB;IACnC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5C,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB;IACjC,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,eAAe,CAAC,YAAoB,EAAE,QAAsB;IACnE,MAAM,MAAM,GAAmB;QAC7B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,uBAAuB,CAAC,CAAC,WAAW,EAAE;KACxE,CAAC;IACF,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QACrE,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAkB;IACrD,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACxD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEpD,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACzE,OAAO,CAAC,KAAK,CACX,8BAA8B,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,GAAG,yBAAyB,MAAM,CAAC,MAAM,CAAC,sCAAsC,CACrI,CAAC;QACF,OAAO,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAED,MAAM,QAAQ,GACZ,kBAAkB,CAAC,YAAY,CAAC,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;IACnE,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,mFAAmF;AACnF,SAAS,kBAAkB,CAAC,YAAoB;IAC9C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAEhD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,iBAAiB,EAAE,CAAC;QAC1E,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,OAAO;YACL,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,WAAW,EAAE,yBAAyB,CAAC,MAAM,CAAC,WAAW,CAAC;YAC1D,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,UAAU,CAAC;SAC5C,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,mCAAmC,YAAY,mBAAmB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,gCAAgC,CACnJ,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,YAAoB;IAC1C,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IACpC,eAAe,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACxC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAkB;IACpD,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1C,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"identity-store.js","sourceRoot":"","sources":["../../src/core/identity-store.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  /**
2
- * core/room's six verifier obligations (spec/room.cddl), layered on top of verifyCapabilityToken (obligations 2, 4, and 5 -- bearer match, ordinary token-claims checks, and delegations-remaining narrowing -- already live there). This module adds the two obligations specific to room-shaped scopes: the chain must terminate at the correct root for the path's own shape (1), and the token's own scope must actually name the room the request claims to act on (3). Obligation 6 (refuse an unrecognised content-type/kind) is a message-handling concern, not a token-verification one, and belongs to the room verb router instead.
2
+ * core/room's six verifier obligations (spec/room.cddl), layered on top of verifyCapabilityToken (obligations 2, 4, and 5 -- bearer match, ordinary token-claims checks, and delegations-remaining narrowing -- already live there). This module adds the checks specific to room-shaped scopes: the token must actually carry the room:member capability the six obligations presuppose (room.cddl's own obligation 1 opens with "a room:member token's delegation chain..." -- a token minted for some other capability that happens to be scoped to a room path must not pass just because scope.kind/path line up), the chain must terminate at the correct root for the path's own shape (1), and the token's own scope must actually name the room the request claims to act on (3). Obligation 6 (refuse an unrecognised content-type/kind) is a message-handling concern, not a token-verification one, and belongs to the room verb router instead.
3
3
  */
4
4
  import { type TokenVerdictReason, type VerifyCapabilityTokenOptions } from "wire-mesh-core/domain/tokens";
5
5
  import type { CapabilityToken, DeviceId, TokenClaims } from "wire-mesh-core/generated/protocol";
6
- export type RoomTokenVerdictReason = TokenVerdictReason | "wrong_scope_kind" | "wrong_scope_path" | "wrong_chain_root";
6
+ export type RoomTokenVerdictReason = TokenVerdictReason | "wrong_capability" | "wrong_scope_kind" | "wrong_scope_path" | "wrong_chain_root";
7
7
  export type RoomTokenVerdict = {
8
8
  ok: true;
9
9
  claims: TokenClaims;
@@ -1 +1 @@
1
- {"version":3,"file":"room-token-verification.d.ts","sourceRoot":"","sources":["../../src/core/room-token-verification.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,EAClC,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,WAAW,EACZ,MAAM,mCAAmC,CAAC;AAG3C,MAAM,MAAM,sBAAsB,GAC9B,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,CAAC;AAEvB,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GACjC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAElD,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAClD,4BAA4B,EAC5B,gBAAgB,CACjB;IACC,6UAA6U;IAC7U,cAAc,EAAE,QAAQ,CAAC;IACzB,8KAA8K;IAC9K,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CA4B3B"}
1
+ {"version":3,"file":"room-token-verification.d.ts","sourceRoot":"","sources":["../../src/core/room-token-verification.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,EAClC,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,WAAW,EACZ,MAAM,mCAAmC,CAAC;AAM3C,MAAM,MAAM,sBAAsB,GAC9B,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,CAAC;AAEvB,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GACjC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAElD,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAClD,4BAA4B,EAC5B,gBAAgB,CACjB;IACC,6UAA6U;IAC7U,cAAc,EAAE,QAAQ,CAAC;IACzB,8KAA8K;IAC9K,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CA+B3B"}
@@ -1,9 +1,11 @@
1
1
  /**
2
- * core/room's six verifier obligations (spec/room.cddl), layered on top of verifyCapabilityToken (obligations 2, 4, and 5 -- bearer match, ordinary token-claims checks, and delegations-remaining narrowing -- already live there). This module adds the two obligations specific to room-shaped scopes: the chain must terminate at the correct root for the path's own shape (1), and the token's own scope must actually name the room the request claims to act on (3). Obligation 6 (refuse an unrecognised content-type/kind) is a message-handling concern, not a token-verification one, and belongs to the room verb router instead.
2
+ * core/room's six verifier obligations (spec/room.cddl), layered on top of verifyCapabilityToken (obligations 2, 4, and 5 -- bearer match, ordinary token-claims checks, and delegations-remaining narrowing -- already live there). This module adds the checks specific to room-shaped scopes: the token must actually carry the room:member capability the six obligations presuppose (room.cddl's own obligation 1 opens with "a room:member token's delegation chain..." -- a token minted for some other capability that happens to be scoped to a room path must not pass just because scope.kind/path line up), the chain must terminate at the correct root for the path's own shape (1), and the token's own scope must actually name the room the request claims to act on (3). Obligation 6 (refuse an unrecognised content-type/kind) is a message-handling concern, not a token-verification one, and belongs to the room verb router instead.
3
3
  */
4
4
  import { verifyCapabilityToken, } from "wire-mesh-core/domain/tokens";
5
5
  import { deviceIdToHex } from "wire-mesh-core/domain/device-id";
6
6
  import { parseRoomPath } from "./room-path.js";
7
+ /** The one capability that authorises every ordinary room-membership verb (room.send/read/leave/members) -- "one resource, not several", the same pattern exec:pty already uses for its own four inner verbs. room.join/room.invite are deliberately ungated and never reach this check at all. */
8
+ const ROOM_MEMBER_CAPABILITY = "room:member";
7
9
  /**
8
10
  * Verifies a `room:member` capability token against all six of core/room's verifier obligations. Delegates obligations 2/4/5 to verifyCapabilityToken directly; adds obligation 3 (scope.kind/scope.path must match the room being acted on) and obligation 1 (the chain's root must be the room's own owner for a named room, or the verifying identity itself for a DM -- never either named participant directly, since a DM token minted by anyone other than the verifier would let a sender self-issue authority to message a stranger unsolicited).
9
11
  */
@@ -17,6 +19,9 @@ export async function verifyRoomToken(token, options) {
17
19
  if (!verdict.ok) {
18
20
  return verdict;
19
21
  }
22
+ if (verdict.claims.capability !== ROOM_MEMBER_CAPABILITY) {
23
+ return { ok: false, reason: "wrong_capability" };
24
+ }
20
25
  if (verdict.claims.scope.kind !== "room") {
21
26
  return { ok: false, reason: "wrong_scope_kind" };
22
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"room-token-verification.js","sourceRoot":"","sources":["../../src/core/room-token-verification.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,qBAAqB,GAGtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAMhE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAsB/C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAsB,EACtB,OAA+B;IAE/B,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,KAAK,EAAE;QACjD,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACnD,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;QACnD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACnD,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,eAAe,GACnB,MAAM,CAAC,IAAI,KAAK,aAAa;QAC3B,CAAC,CAAC,MAAM,CAAC,KAAK;QACd,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,eAAe,EAAE,CAAC;QAC1D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACnD,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;AAC9C,CAAC"}
1
+ {"version":3,"file":"room-token-verification.js","sourceRoot":"","sources":["../../src/core/room-token-verification.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,qBAAqB,GAGtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAMhE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,mSAAmS;AACnS,MAAM,sBAAsB,GAAG,aAAa,CAAC;AAuB7C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAsB,EACtB,OAA+B;IAE/B,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,KAAK,EAAE;QACjD,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,KAAK,sBAAsB,EAAE,CAAC;QACzD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACnD,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACnD,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;QACnD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACnD,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,eAAe,GACnB,MAAM,CAAC,IAAI,KAAK,aAAa;QAC3B,CAAC,CAAC,MAAM,CAAC,KAAK;QACd,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,eAAe,EAAE,CAAC;QAC1D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACnD,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Unit tests for per-room capability token persistence (core/identity-store).
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=room-token-store.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room-token-store.test.d.ts","sourceRoot":"","sources":["../../src/test/room-token-store.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Unit tests for per-room capability token persistence (core/identity-store).
3
+ */
4
+ import * as assert from "node:assert/strict";
5
+ import * as fs from "node:fs";
6
+ import { tmpdir } from "node:os";
7
+ import path from "node:path";
8
+ import { test } from "node:test";
9
+ import { loadOrCreateIdentity, loadRoomTokens, saveRoomToken, deleteRoomToken, releaseIdentityLock, } from "../core/identity-store.js";
10
+ function tempSlot(harness) {
11
+ const dir = fs.mkdtempSync(path.join(tmpdir(), "agent-comms-room-token-test-"));
12
+ return { slot: { harness, cwd: "/tmp/project", dir }, dir };
13
+ }
14
+ function buf(bytes) {
15
+ return Uint8Array.from(bytes);
16
+ }
17
+ const TOKEN_A = [
18
+ buf([1, 2, 3]),
19
+ {},
20
+ buf([4, 5, 6]),
21
+ buf([7, 8, 9]),
22
+ ];
23
+ const TOKEN_B = [
24
+ buf([10, 11]),
25
+ { 1: -7 },
26
+ null,
27
+ buf([12, 13, 14]),
28
+ ];
29
+ const ROOM_A = "aa".repeat(32) + "/general";
30
+ const ROOM_B = "bb".repeat(32) + "/other-room";
31
+ void test("loadRoomTokens returns an empty map before anything is saved", () => {
32
+ const { slot } = tempSlot("pi");
33
+ loadOrCreateIdentity(slot);
34
+ assert.deepEqual(loadRoomTokens(slot), {});
35
+ releaseIdentityLock(slot);
36
+ });
37
+ void test("saveRoomToken persists a token retrievable by loadRoomTokens", () => {
38
+ const { slot } = tempSlot("claude-code");
39
+ loadOrCreateIdentity(slot);
40
+ saveRoomToken(slot, ROOM_A, TOKEN_A);
41
+ const tokens = loadRoomTokens(slot);
42
+ assert.deepEqual(tokens[ROOM_A], TOKEN_A);
43
+ releaseIdentityLock(slot);
44
+ });
45
+ void test("saveRoomToken round-trips a token whose payload is null", () => {
46
+ const { slot } = tempSlot("codex");
47
+ loadOrCreateIdentity(slot);
48
+ saveRoomToken(slot, ROOM_B, TOKEN_B);
49
+ const tokens = loadRoomTokens(slot);
50
+ assert.deepEqual(tokens[ROOM_B], TOKEN_B);
51
+ releaseIdentityLock(slot);
52
+ });
53
+ void test("saveRoomToken for a second room does not disturb the first", () => {
54
+ const { slot } = tempSlot("mcp");
55
+ loadOrCreateIdentity(slot);
56
+ saveRoomToken(slot, ROOM_A, TOKEN_A);
57
+ saveRoomToken(slot, ROOM_B, TOKEN_B);
58
+ const tokens = loadRoomTokens(slot);
59
+ assert.deepEqual(tokens[ROOM_A], TOKEN_A);
60
+ assert.deepEqual(tokens[ROOM_B], TOKEN_B);
61
+ releaseIdentityLock(slot);
62
+ });
63
+ void test("saveRoomToken overwrites an existing token for the same room", () => {
64
+ const { slot } = tempSlot("opencode");
65
+ loadOrCreateIdentity(slot);
66
+ saveRoomToken(slot, ROOM_A, TOKEN_A);
67
+ saveRoomToken(slot, ROOM_A, TOKEN_B);
68
+ const tokens = loadRoomTokens(slot);
69
+ assert.deepEqual(tokens[ROOM_A], TOKEN_B);
70
+ assert.equal(Object.keys(tokens).length, 1);
71
+ releaseIdentityLock(slot);
72
+ });
73
+ void test("deleteRoomToken removes only the named room's token", () => {
74
+ const { slot } = tempSlot("user");
75
+ loadOrCreateIdentity(slot);
76
+ saveRoomToken(slot, ROOM_A, TOKEN_A);
77
+ saveRoomToken(slot, ROOM_B, TOKEN_B);
78
+ deleteRoomToken(slot, ROOM_A);
79
+ const tokens = loadRoomTokens(slot);
80
+ assert.equal(ROOM_A in tokens, false);
81
+ assert.deepEqual(tokens[ROOM_B], TOKEN_B);
82
+ releaseIdentityLock(slot);
83
+ });
84
+ void test("room tokens survive reloading the identity file across a fresh load", () => {
85
+ const { slot } = tempSlot("pi");
86
+ loadOrCreateIdentity(slot);
87
+ saveRoomToken(slot, ROOM_A, TOKEN_A);
88
+ releaseIdentityLock(slot);
89
+ // A fresh process re-loading the same slot.
90
+ loadOrCreateIdentity(slot);
91
+ const tokens = loadRoomTokens(slot);
92
+ assert.deepEqual(tokens[ROOM_A], TOKEN_A);
93
+ releaseIdentityLock(slot);
94
+ });
95
+ void test("saving a room token does not disturb the persisted key material", () => {
96
+ const { slot } = tempSlot("claude-code");
97
+ const identity = loadOrCreateIdentity(slot);
98
+ saveRoomToken(slot, ROOM_A, TOKEN_A);
99
+ const reloaded = loadOrCreateIdentity(slot);
100
+ assert.equal(reloaded.privateKey, identity.privateKey);
101
+ assert.equal(reloaded.certificate, identity.certificate);
102
+ releaseIdentityLock(slot);
103
+ });
104
+ //# sourceMappingURL=room-token-store.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room-token-store.test.js","sourceRoot":"","sources":["../../src/test/room-token-store.test.ts"],"names":[],"mappings":"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"}
@@ -125,7 +125,7 @@ describe("verifyRoomToken", () => {
125
125
  if (!verdict.ok)
126
126
  assert.equal(verdict.reason, "wrong_scope_path");
127
127
  });
128
- it("refuses a token scoped to a non-room capability", async () => {
128
+ it("refuses a token with an unrelated capability and an unrelated scope kind", async () => {
129
129
  const owner = await generateEs256Identity();
130
130
  const member = await generateEs256Identity();
131
131
  const roomPath = ownerNamedRoomPath(deviceIdToHex(owner.deviceId), "general");
@@ -149,7 +149,34 @@ describe("verifyRoomToken", () => {
149
149
  });
150
150
  assert.equal(verdict.ok, false);
151
151
  if (!verdict.ok)
152
- assert.equal(verdict.reason, "wrong_scope_kind");
152
+ assert.equal(verdict.reason, "wrong_capability");
153
+ });
154
+ it("refuses a token with the wrong capability even when its scope is correctly shaped for the room", async () => {
155
+ const owner = await generateEs256Identity();
156
+ const member = await generateEs256Identity();
157
+ const roomPath = ownerNamedRoomPath(deviceIdToHex(owner.deviceId), "general");
158
+ // Nonsensical, but not structurally prevented at mint time: capability and scope disagree about what this token actually grants. Neither scope.kind nor scope.path alone can catch this -- only checking the capability itself can.
159
+ const verdict1 = await mintCapabilityToken({
160
+ identity: owner,
161
+ clock: fixedClock(NOW_MS),
162
+ tokenId: nextTokenId(),
163
+ bearer: member.deviceId,
164
+ capability: "exec:pty",
165
+ scope: { kind: "room", path: roomPath },
166
+ expires: EXPIRES_MS,
167
+ });
168
+ if (!verdict1.ok)
169
+ throw new Error(`mint failed: ${verdict1.reason}`);
170
+ const verdict = await verifyRoomToken(verdict1.token, {
171
+ identity: owner,
172
+ clock: fixedClock(NOW_MS),
173
+ revocation: createRevocationView(),
174
+ expectedBearer: member.deviceId,
175
+ roomPath,
176
+ });
177
+ assert.equal(verdict.ok, false);
178
+ if (!verdict.ok)
179
+ assert.equal(verdict.reason, "wrong_capability");
153
180
  });
154
181
  it("refuses a token bearing a different device than the authenticated connection", async () => {
155
182
  const owner = await generateEs256Identity();
@@ -1 +1 @@
1
- {"version":3,"file":"room-token-verification.test.js","sourceRoot":"","sources":["../../src/test/room-token-verification.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"room-token-verification.test.js","sourceRoot":"","sources":["../../src/test/room-token-verification.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-comms",
3
- "version": "2.2.0",
3
+ "version": "2.3.1",
4
4
  "description": "Cross-harness communication mesh for LLM agents — rooms, DMs, presence, and real-time push delivery over TCP",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.33.0",