@uuaid/agent-commons 0.2.0-alpha.2 → 0.2.0-alpha.4

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.
Files changed (72) hide show
  1. package/CONFORMANCE.md +1 -1
  2. package/NOTICE +4 -7
  3. package/PROVENANCE.json +12 -17
  4. package/README.md +103 -12
  5. package/bin/agent-commons.mjs +8 -3
  6. package/examples/Dockerfile +1 -1
  7. package/package.json +5 -2
  8. package/src/carrier.mjs +7 -2
  9. package/src/channels.mjs +1 -1
  10. package/src/config.mjs +2 -1
  11. package/src/continuity.mjs +14 -7
  12. package/src/governance-scope.mjs +1 -1
  13. package/src/governance.mjs +4 -2
  14. package/src/index.d.ts +3 -1
  15. package/src/pillar.mjs +2 -2
  16. package/src/profiles.mjs +2 -1
  17. package/src/relay/auth.mjs +294 -0
  18. package/src/relay/board.mjs +223 -0
  19. package/src/relay/claims.mjs +25 -0
  20. package/src/relay/cli.mjs +49 -0
  21. package/src/relay/client.mjs +437 -0
  22. package/src/relay/docs/reconnect-v1.md +27 -0
  23. package/src/relay/docs/working-rules-v1.md +42 -0
  24. package/src/relay/enroll.mjs +232 -0
  25. package/src/relay/export-cli.mjs +47 -0
  26. package/src/relay/governance.mjs +1328 -0
  27. package/src/relay/mailbox.mjs +103 -0
  28. package/src/relay/records.mjs +146 -0
  29. package/src/relay/render.mjs +38 -0
  30. package/src/relay/roster.mjs +134 -0
  31. package/src/relay/routes.mjs +87 -0
  32. package/src/relay/schema.mjs +1081 -0
  33. package/src/relay/seed.mjs +89 -0
  34. package/src/relay/serve.mjs +116 -0
  35. package/src/relay/server.mjs +633 -0
  36. package/src/relay/signing.mjs +693 -0
  37. package/src/relay/test-mode.mjs +73 -0
  38. package/src/runtime.mjs +25 -12
  39. package/src/spaces/manifest.mjs +245 -0
  40. package/src/spaces/pillar-group.mjs +12 -0
  41. package/src/spaces/policy.mjs +229 -0
  42. package/src/spaces/store.mjs +325 -0
  43. package/src/trust.mjs +44 -5
  44. package/src/uuaid-namespace.d.mts +6 -0
  45. package/src/uuaid-namespace.mjs +48 -0
  46. package/src/vendor/pillar/blob/blob.mjs +12 -14
  47. package/src/vendor/pillar/groups-v2.mjs +1108 -0
  48. package/src/vendor/pillar/groups.mjs +175 -0
  49. package/src/vendor/pillar/identity/jcs.mjs +4 -5
  50. package/src/vendor/pillar/identity/keychain.mjs +51 -2
  51. package/src/vendor/pillar/net/carrier-client.mjs +29 -7
  52. package/src/vendor/pillar/net/refusals.mjs +4 -2
  53. package/test/channels.test.mjs +0 -268
  54. package/test/cohort.test.mjs +0 -36
  55. package/test/collaboration.test.mjs +0 -459
  56. package/test/continuity.test.mjs +0 -229
  57. package/test/custody.negative.test.mjs +0 -165
  58. package/test/derivation-parity.test.mjs +0 -19
  59. package/test/fixtures/derivation-vectors.json +0 -26
  60. package/test/fixtures/ed25519-small-order.vectors.json +0 -15
  61. package/test/governance-expected-red.expected-red.mjs +0 -241
  62. package/test/governance-scope.test.mjs +0 -142
  63. package/test/governance-t1-t10.test.mjs +0 -477
  64. package/test/governance.test.mjs +0 -514
  65. package/test/hold-admission.test.mjs +0 -1185
  66. package/test/keychain-strict-ed25519.test.mjs +0 -240
  67. package/test/offline.test.mjs +0 -152
  68. package/test/runtime-channels.test.mjs +0 -1140
  69. package/test/runtime.test.mjs +0 -201
  70. package/test/security-runtime.test.mjs +0 -104
  71. package/test/strict-ed25519-consumers.test.mjs +0 -234
  72. package/test/transport.test.mjs +0 -353
@@ -1,1185 +0,0 @@
1
- // L11: Hold Before Admission in Agent Commons Engine (T1-T16 Two-Pole Suite)
2
- // Code mutants for these properties: the project design
3
- import test from "node:test";
4
- import assert from "node:assert/strict";
5
- import { randomUUID } from "node:crypto";
6
- import {
7
- AgentCommons,
8
- CommonsStore,
9
- Keychain,
10
- createProfile,
11
- MemoryLoopbackTransport,
12
- } from "../src/index.mjs";
13
- import { seal, envelopeSha } from "../src/pillar.mjs";
14
- import { encode, digest } from "../src/profiles.mjs";
15
-
16
- function makeKey() {
17
- const k = new Keychain("test-key");
18
- k._identity = Keychain.generate();
19
- return k;
20
- }
21
-
22
- function makeTestEnv({ holdBeforeAdmission = true } = {}) {
23
- const atlasKey = makeKey();
24
- const lyraKey = makeKey();
25
- const atlasId = atlasKey._identity.uuaid;
26
- const lyraId = lyraKey._identity.uuaid;
27
- const channelUri = "channel://local/community/general";
28
-
29
- const policy = {
30
- mode: "local",
31
- offline: true,
32
- channelsEnabled: true,
33
- holdBeforeAdmission,
34
- channels: {
35
- [channelUri]: {
36
- members: [lyraId], // atlasId intentionally omitted from channel members
37
- allowForwarding: false,
38
- },
39
- },
40
- agents: {
41
- [atlasId]: {
42
- kind: "agent",
43
- publicKey: atlasKey._identity.publicKeyHex,
44
- capabilities: ["commons:message", "commons:evolve"],
45
- },
46
- [lyraId]: {
47
- kind: "agent",
48
- publicKey: lyraKey._identity.publicKeyHex,
49
- capabilities: ["commons:message", "commons:evolve"],
50
- },
51
- },
52
- };
53
-
54
- const profile = createProfile({
55
- namespace: "local/test",
56
- name: "Test Profile",
57
- scope: "local",
58
- fixtures: ["fixture one", "fixture two"],
59
- });
60
-
61
- const lyraStore = new CommonsStore(":memory:");
62
- const transport = new MemoryLoopbackTransport();
63
-
64
- const lyraRuntime = new AgentCommons({
65
- keychain: lyraKey,
66
- store: lyraStore,
67
- policy,
68
- transport,
69
- });
70
- lyraRuntime.addProfile(profile);
71
-
72
- return {
73
- atlasKey,
74
- lyraKey,
75
- atlasId,
76
- lyraId,
77
- channelUri,
78
- policy,
79
- profile,
80
- lyraStore,
81
- transport,
82
- lyraRuntime,
83
- };
84
- }
85
-
86
- function makeSealedMessage(senderKey, recipientKey, profile, {
87
- thread = "channel://local/community/general",
88
- body = "test-message",
89
- kind = "message",
90
- expiresAt = new Date(Date.now() + 3600000).toISOString(),
91
- id = randomUUID(),
92
- } = {}) {
93
- const payload = {
94
- v: "agent-commons/1",
95
- id,
96
- kind,
97
- thread,
98
- profileId: profile.id,
99
- wire: encode(body, profile.lexicon),
100
- bodyHash: digest(body),
101
- expiresAt,
102
- };
103
- return {
104
- payload,
105
- envelope: seal(senderKey, {
106
- recipient: recipientKey._identity.uuaid,
107
- recipientPublicKey: recipientKey._identity.publicKeyHex,
108
- kind: "agent-commons/1",
109
- payload,
110
- }),
111
- };
112
- }
113
-
114
- // =========================================================================
115
- // T1: Hold before admission for invited sender, released after policy update
116
- // =========================================================================
117
- test("T1: CONTROL - Invited sender message is held, then accepted on releaseHeld after admission manifest", async () => {
118
- const env = makeTestEnv({ holdBeforeAdmission: true });
119
- const { payload, envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "hello-hold" });
120
-
121
- const res = await env.lyraRuntime.receive(envelope);
122
- assert.equal(res.held, true);
123
- assert.equal(res.id, envelope.id);
124
- assert.equal(res.sender, env.atlasId);
125
- assert.equal(res.channel, env.channelUri);
126
-
127
- // Stored in held table, not yet processed/delivered
128
- assert.equal(env.lyraStore.allHeld().length, 1);
129
- assert.equal(env.lyraStore.seen(`msg:${env.atlasId}:${payload.id}`), false);
130
-
131
- // Update policy to admit sender to channel
132
- env.policy.channels[env.channelUri].members.push(env.atlasId);
133
-
134
- const released = await env.lyraRuntime.releaseHeld();
135
- assert.equal(released.length, 1);
136
- assert.equal(released[0].accepted, true);
137
- assert.equal(released[0].body, "hello-hold");
138
- assert.equal(released[0].id, payload.id);
139
-
140
- // Now leaves hold and is marked processed
141
- assert.equal(env.lyraStore.allHeld().length, 0);
142
- assert.equal(env.lyraStore.seen(`msg:${env.atlasId}:${payload.id}`), true);
143
-
144
- const auditKinds = env.lyraStore.audit().map(r => JSON.parse(r.body).kind);
145
- assert.ok(auditKinds.includes("hold-added"));
146
- assert.ok(auditKinds.includes("hold-released"));
147
- assert.ok(auditKinds.includes("message-received"));
148
- });
149
-
150
- test("T1: CONTROL (inverse) - When hold is disabled, unauthorized sender is refused and lost, releaseHeld finds 0", async () => {
151
- const env = makeTestEnv({ holdBeforeAdmission: false });
152
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "hello-mutant" });
153
-
154
- await assert.rejects(
155
- () => env.lyraRuntime.receive(envelope),
156
- (err) => err.code === "UNAUTHORIZED_CHANNEL_SENDER"
157
- );
158
- assert.equal(env.lyraStore.allHeld().length, 0);
159
- const released = await env.lyraRuntime.releaseHeld();
160
- assert.equal(released.length, 0);
161
- });
162
-
163
- // =========================================================================
164
- // T2: Stranger (not in policy.agents) is never held
165
- // =========================================================================
166
- test("T2: CONTROL - Stranger not in policy.agents is refused with NOT_ADMITTED and never held", async () => {
167
- const env = makeTestEnv({ holdBeforeAdmission: true });
168
- const strangerKey = makeKey();
169
- const { envelope } = makeSealedMessage(strangerKey, env.lyraKey, env.profile, { thread: env.channelUri });
170
-
171
- await assert.rejects(
172
- () => env.lyraRuntime.receive(envelope),
173
- (err) => err.code === "NOT_ADMITTED" || /NOT_ADMITTED/.test(err.message)
174
- );
175
- assert.equal(env.lyraStore.allHeld().length, 0);
176
- });
177
-
178
- test("T2: CONTROL (inverse) - Stranger envelope does not enter hold even if channel admits stranger ID", async () => {
179
- const env = makeTestEnv({ holdBeforeAdmission: true });
180
- const strangerKey = makeKey();
181
- const strangerId = strangerKey._identity.uuaid;
182
- env.policy.channels[env.channelUri].members.push(strangerId); // In channel, but NOT in policy.agents
183
- const { envelope } = makeSealedMessage(strangerKey, env.lyraKey, env.profile, { thread: env.channelUri });
184
-
185
- await assert.rejects(
186
- () => env.lyraRuntime.receive(envelope),
187
- (err) => err.code === "NOT_ADMITTED" || /NOT_ADMITTED/.test(err.message)
188
- );
189
- assert.equal(env.lyraStore.allHeld().length, 0);
190
- });
191
-
192
- // =========================================================================
193
- // T3 (C1): Injected permissive trust plus stranger: direct check fails closed
194
- // =========================================================================
195
- test("T3: CONTROL (C1) - Injected permissive trust authorizing strangers is overridden by direct policy check", async () => {
196
- const strangerKey = makeKey();
197
- const env = makeTestEnv({ holdBeforeAdmission: true });
198
- // Injected permissive trust that authorizes everything
199
- const mockTrust = {
200
- authorize: async () => ({ tier: "permissive-mock" }),
201
- standards: async () => [],
202
- publishedProfilePin: async () => {},
203
- };
204
- env.lyraRuntime.trust = mockTrust;
205
-
206
- const { envelope } = makeSealedMessage(strangerKey, env.lyraKey, env.profile, { thread: env.channelUri });
207
-
208
- // Stranger passes mock trust.authorize, but fails channel admission AND direct policy.agents check
209
- await assert.rejects(
210
- () => env.lyraRuntime.receive(envelope),
211
- (err) => err.code === "UNAUTHORIZED_CHANNEL_SENDER"
212
- );
213
- assert.equal(env.lyraStore.allHeld().length, 0);
214
- });
215
-
216
- test("T3: CONTROL (inverse) (C1) - Simulated trust-trusting hold check would have held stranger; direct check prevents it", async () => {
217
- const strangerKey = makeKey();
218
- const env = makeTestEnv({ holdBeforeAdmission: true });
219
- const mockTrust = {
220
- authorize: async () => ({ tier: "permissive-mock" }),
221
- standards: async () => [],
222
- publishedProfilePin: async () => {},
223
- };
224
- env.lyraRuntime.trust = mockTrust;
225
- const { envelope } = makeSealedMessage(strangerKey, env.lyraKey, env.profile, { thread: env.channelUri });
226
-
227
- // Verify that stranger is NOT in policy.agents directly
228
- assert.equal(env.policy.agents[strangerKey._identity.uuaid], undefined);
229
- await assert.rejects(() => env.lyraRuntime.receive(envelope));
230
- assert.equal(env.lyraStore.allHeld().length, 0);
231
- });
232
-
233
- // =========================================================================
234
- // T4 (C1): Admitted UUAID whose transport key differs from policy key
235
- // =========================================================================
236
- test("T4: CONTROL (C1) - Admitted sender UUAID signed with wrong transport key is rejected and never held", async () => {
237
- const env = makeTestEnv({ holdBeforeAdmission: true });
238
- const otherKey = makeKey();
239
- // Set policy.agents to have a different public key than Atlas's real key
240
- env.policy.agents[env.atlasId].publicKey = otherKey._identity.publicKeyHex;
241
-
242
- // Permissive trust to test hold path's direct check
243
- const mockTrust = {
244
- authorize: async () => ({ tier: "mock" }),
245
- standards: async () => [],
246
- publishedProfilePin: async () => {},
247
- };
248
- env.lyraRuntime.trust = mockTrust;
249
-
250
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri });
251
-
252
- // Direct hold check fails key comparison (agent.publicKey !== envelope.transportSignature.publicKey)
253
- await assert.rejects(
254
- () => env.lyraRuntime.receive(envelope),
255
- (err) => err.code === "UNAUTHORIZED_CHANNEL_SENDER"
256
- );
257
- assert.equal(env.lyraStore.allHeld().length, 0);
258
- });
259
-
260
- test("T4: CONTROL (inverse) (C1) - When transport key matches policy key, envelope IS eligible for hold", async () => {
261
- const env = makeTestEnv({ holdBeforeAdmission: true });
262
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri });
263
-
264
- // Key matches policy
265
- assert.equal(envelope.transportSignature.publicKey, env.policy.agents[env.atlasId].publicKey);
266
- const res = await env.lyraRuntime.receive(envelope);
267
- assert.equal(res.held, true);
268
- assert.equal(env.lyraStore.allHeld().length, 1);
269
- });
270
-
271
- // =========================================================================
272
- // T5 (C2): UNAUTHORIZED_CHANNEL_SENDER thrown from inside apply(): not held
273
- // =========================================================================
274
- test("T5: CONTROL (C2) - Error thrown from apply() escapes receiveInternal and is never held", async () => {
275
- const env = makeTestEnv({ holdBeforeAdmission: true });
276
- // Add Atlas to channel so channel admission check passes
277
- env.policy.channels[env.channelUri].members.push(env.atlasId);
278
-
279
- // Monkey-patch apply to simulate a throw with UNAUTHORIZED_CHANNEL_SENDER
280
- env.lyraRuntime.apply = async () => {
281
- const err = new Error("Simulated apply error");
282
- err.code = "UNAUTHORIZED_CHANNEL_SENDER";
283
- throw err;
284
- };
285
-
286
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, {
287
- thread: env.channelUri,
288
- kind: "profile-control",
289
- body: JSON.stringify({ kind: "profile-proposal", id: randomUUID(), createdAt: new Date().toISOString(), issuer: env.atlasId, publicKey: env.atlasKey._identity.publicKeyHex, payload: {} }),
290
- });
291
-
292
- await assert.rejects(
293
- () => env.lyraRuntime.receive(envelope),
294
- (err) => err.code === "UNAUTHORIZED_CHANNEL_SENDER" && err.message === "Simulated apply error"
295
- );
296
- assert.equal(env.lyraStore.allHeld().length, 0);
297
- });
298
-
299
- test("T5: CONTROL (inverse) (C2) - Only assertChannelReceiveAdmission throw is held, not downstream errors", async () => {
300
- const env = makeTestEnv({ holdBeforeAdmission: true });
301
- // Channel admission fails -> held
302
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri });
303
- const res = await env.lyraRuntime.receive(envelope);
304
- assert.equal(res.held, true);
305
- assert.equal(env.lyraStore.allHeld().length, 1);
306
- });
307
-
308
- // =========================================================================
309
- // T6 (C2): UNCONFIGURED_CHANNEL: dropped, not held
310
- // =========================================================================
311
- test("T6: CONTROL (C2) - Message to unconfigured channel throws UNCONFIGURED_CHANNEL and is not held", async () => {
312
- const env = makeTestEnv({ holdBeforeAdmission: true });
313
- const unconfiguredUri = "channel://local/unconfigured/channel";
314
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: unconfiguredUri });
315
-
316
- await assert.rejects(
317
- () => env.lyraRuntime.receive(envelope),
318
- (err) => err.code === "UNCONFIGURED_CHANNEL"
319
- );
320
- assert.equal(env.lyraStore.allHeld().length, 0);
321
- });
322
-
323
- test("T6: CONTROL (inverse) (C2) - Configuring the channel allows hold to activate instead of dropping", async () => {
324
- const env = makeTestEnv({ holdBeforeAdmission: true });
325
- const newUri = "channel://local/new/channel";
326
- env.policy.channels[newUri] = { members: [env.lyraId], allowForwarding: false };
327
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: newUri });
328
-
329
- const res = await env.lyraRuntime.receive(envelope);
330
- assert.equal(res.held, true);
331
- assert.equal(env.lyraStore.allHeld().length, 1);
332
- });
333
-
334
- // =========================================================================
335
- // T7 (C3): profile-control from invited sender: refused, not held
336
- // =========================================================================
337
- test("T7: CONTROL (C3) - profile-control envelope is refused immediately and not held", async () => {
338
- const env = makeTestEnv({ holdBeforeAdmission: true });
339
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, {
340
- thread: env.channelUri,
341
- kind: "profile-control",
342
- body: JSON.stringify({ kind: "profile-proposal", id: randomUUID(), createdAt: new Date().toISOString(), issuer: env.atlasId, publicKey: env.atlasKey._identity.publicKeyHex, payload: {} }),
343
- });
344
-
345
- await assert.rejects(
346
- () => env.lyraRuntime.receive(envelope),
347
- (err) => err.code === "UNAUTHORIZED_CHANNEL_SENDER"
348
- );
349
- assert.equal(env.lyraStore.allHeld().length, 0);
350
- });
351
-
352
- test("T7: CONTROL (inverse) (C3) - kind === 'message' from same sender IS held", async () => {
353
- const env = makeTestEnv({ holdBeforeAdmission: true });
354
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, {
355
- thread: env.channelUri,
356
- kind: "message",
357
- });
358
- const res = await env.lyraRuntime.receive(envelope);
359
- assert.equal(res.held, true);
360
- assert.equal(env.lyraStore.allHeld().length, 1);
361
- });
362
-
363
- // =========================================================================
364
- // T8 (C4): Deduplication of carrier duplicates & re-held envelopes
365
- // =========================================================================
366
- test("T8: CONTROL (C4) - Carrier duplicate and re-held envelope store 1 entry and count once against bounds", async () => {
367
- const env = makeTestEnv({ holdBeforeAdmission: true });
368
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "dedupe-test" });
369
-
370
- // First receipt -> held
371
- const r1 = await env.lyraRuntime.receive(envelope);
372
- assert.equal(r1.held, true);
373
- assert.equal(env.lyraStore.allHeld().length, 1);
374
-
375
- // Duplicate receipt of identical envelope -> returned as held, not stored twice
376
- const r2 = await env.lyraRuntime.receive(envelope);
377
- assert.equal(r2.held, true);
378
- assert.equal(env.lyraStore.allHeld().length, 1);
379
-
380
- // Attempt release while still unadmitted -> stays held, 1 entry
381
- const released = await env.lyraRuntime.releaseHeld();
382
- assert.equal(released.length, 0);
383
- assert.equal(env.lyraStore.allHeld().length, 1);
384
-
385
- const counts = env.lyraStore.holdCounts(env.channelUri, env.atlasId);
386
- assert.equal(counts.channelSender, 1);
387
- assert.equal(counts.total, 1);
388
- });
389
-
390
- test("T8: CONTROL (inverse) (C4) - Distinct envelopes with different message IDs create distinct held rows", async () => {
391
- const env = makeTestEnv({ holdBeforeAdmission: true });
392
- const { envelope: env1 } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "msg-1" });
393
- const { envelope: env2 } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "msg-2" });
394
-
395
- await env.lyraRuntime.receive(env1);
396
- await env.lyraRuntime.receive(env2);
397
- assert.equal(env.lyraStore.allHeld().length, 2);
398
- const counts = env.lyraStore.holdCounts(env.channelUri, env.atlasId);
399
- assert.equal(counts.channelSender, 2);
400
- });
401
-
402
- // =========================================================================
403
- // T9a (R5): Bounds: 20 per (channel, sender), 100 per channel, 500 total
404
- // =========================================================================
405
- test("T9a: CONTROL (R5) - Bounds 20 per (channel, sender), 100 per channel, 500 total refuse with exact reason", async () => {
406
- const env = makeTestEnv({ holdBeforeAdmission: true });
407
-
408
- // 1. Channel-sender bound: 20 envelopes from Atlas into channelUri
409
- for (let i = 0; i < 20; i++) {
410
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: `cs-${i}` });
411
- const r = await env.lyraRuntime.receive(envelope);
412
- assert.equal(r.held, true);
413
- }
414
- assert.equal(env.lyraStore.holdCounts(env.channelUri, env.atlasId).channelSender, 20);
415
-
416
- // 21st envelope from Atlas to same channel is refused with 'channel-sender'
417
- const { envelope: cs21 } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "cs-21" });
418
- await assert.rejects(
419
- () => env.lyraRuntime.receive(cs21),
420
- (err) => err.code === "UNAUTHORIZED_CHANNEL_SENDER"
421
- );
422
- let audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
423
- let refused = audit.find(e => e.kind === "hold-refused" && e.id === cs21.id);
424
- assert.ok(refused);
425
- assert.equal(refused.reason, "channel-sender");
426
-
427
- // 2. Channel bound: 100 per channel
428
- // We already have 20 from Atlas. We add 4 more senders with 20 envelopes each (= 100 total for channelUri).
429
- const extraSenders = [];
430
- for (let s = 0; s < 4; s++) {
431
- const k = makeKey();
432
- const id = k._identity.uuaid;
433
- env.policy.agents[id] = { kind: "agent", publicKey: k._identity.publicKeyHex, capabilities: ["commons:message"] };
434
- extraSenders.push(k);
435
- for (let i = 0; i < 20; i++) {
436
- const { envelope } = makeSealedMessage(k, env.lyraKey, env.profile, { thread: env.channelUri, body: `ch-${s}-${i}` });
437
- const r = await env.lyraRuntime.receive(envelope);
438
- assert.equal(r.held, true);
439
- }
440
- }
441
- assert.equal(env.lyraStore.holdCounts(env.channelUri, env.atlasId).channel, 100);
442
-
443
- // 101st envelope for channelUri from a fresh 6th sender: channel-sender is 0, sender is 0, but channel is 100 -> refused with 'channel'
444
- const sender6 = makeKey();
445
- env.policy.agents[sender6._identity.uuaid] = { kind: "agent", publicKey: sender6._identity.publicKeyHex, capabilities: ["commons:message"] };
446
- const { envelope: ch101 } = makeSealedMessage(sender6, env.lyraKey, env.profile, { thread: env.channelUri, body: "ch-101" });
447
- await assert.rejects(
448
- () => env.lyraRuntime.receive(ch101),
449
- (err) => err.code === "UNAUTHORIZED_CHANNEL_SENDER"
450
- );
451
- audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
452
- refused = audit.find(e => e.kind === "hold-refused" && e.id === ch101.id);
453
- assert.ok(refused);
454
- assert.equal(refused.reason, "channel");
455
-
456
- // 3. Total bound: 500 across engine
457
- // Channel 1 has 100. We populate channels 2, 3, 4, 5 with 100 each -> 500 total.
458
- for (let c = 2; c <= 5; c++) {
459
- const cUri = `channel://local/c${c}/general`;
460
- env.policy.channels[cUri] = { members: [env.lyraId], allowForwarding: false };
461
- for (let s = 0; s < 5; s++) {
462
- const k = makeKey();
463
- env.policy.agents[k._identity.uuaid] = { kind: "agent", publicKey: k._identity.publicKeyHex, capabilities: ["commons:message"] };
464
- for (let i = 0; i < 20; i++) {
465
- const { envelope } = makeSealedMessage(k, env.lyraKey, env.profile, { thread: cUri, body: `tot-${c}-${s}-${i}` });
466
- const r = await env.lyraRuntime.receive(envelope);
467
- assert.equal(r.held, true);
468
- }
469
- }
470
- }
471
- assert.equal(env.lyraStore.holdCounts(env.channelUri, env.atlasId).total, 500);
472
-
473
- // 501st envelope into channel 6 from a fresh sender: refused with 'total'
474
- const c6Uri = "channel://local/c6/general";
475
- env.policy.channels[c6Uri] = { members: [env.lyraId], allowForwarding: false };
476
- const freshSender = makeKey();
477
- env.policy.agents[freshSender._identity.uuaid] = { kind: "agent", publicKey: freshSender._identity.publicKeyHex, capabilities: ["commons:message"] };
478
- const { envelope: tot501 } = makeSealedMessage(freshSender, env.lyraKey, env.profile, { thread: c6Uri, body: "tot-501" });
479
- await assert.rejects(
480
- () => env.lyraRuntime.receive(tot501),
481
- (err) => err.code === "UNAUTHORIZED_CHANNEL_SENDER"
482
- );
483
- audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
484
- refused = audit.find(e => e.kind === "hold-refused" && e.id === tot501.id);
485
- assert.ok(refused);
486
- assert.equal(refused.reason, "total");
487
- });
488
-
489
- test("T9a: CONTROL (inverse) (R5) - Below bounds, envelopes are held without refusal", async () => {
490
- const env = makeTestEnv({ holdBeforeAdmission: true });
491
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "under-bound" });
492
- const res = await env.lyraRuntime.receive(envelope);
493
- assert.equal(res.held, true);
494
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
495
- assert.equal(audit.some(e => e.kind === "hold-refused"), false);
496
- });
497
-
498
- // =========================================================================
499
- // T9b (R5): 10-minute expiry and payload expiresAt
500
- // =========================================================================
501
- test("T9b: CONTROL (R5) - Expired held entry is purged on release with hold-expired", async () => {
502
- const env = makeTestEnv({ holdBeforeAdmission: true });
503
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, {
504
- thread: env.channelUri,
505
- body: "will-expire",
506
- // 5 seconds from now
507
- expiresAt: new Date(Date.now() + 5000).toISOString(),
508
- });
509
-
510
- const res = await env.lyraRuntime.receive(envelope);
511
- assert.equal(res.held, true);
512
- assert.equal(env.lyraStore.allHeld().length, 1);
513
-
514
- // Directly set expires_at in database to simulated past time
515
- env.lyraStore.db.prepare("UPDATE held SET expires_at=? WHERE id=?").run(Date.now() - 1000, envelope.id);
516
-
517
- // Admit Atlas and release
518
- env.policy.channels[env.channelUri].members.push(env.atlasId);
519
- const released = await env.lyraRuntime.releaseHeld();
520
- assert.equal(released.length, 0); // Not delivered because expired
521
- assert.equal(env.lyraStore.allHeld().length, 0); // Removed from hold
522
-
523
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
524
- const expiredEvent = audit.find(e => e.kind === "hold-expired" && e.id === envelope.id);
525
- assert.ok(expiredEvent);
526
- assert.equal(expiredEvent.reason, "expired");
527
- });
528
-
529
- test("T9b: CONTROL (inverse) (R5) - Non-expired held entry is released and accepted", async () => {
530
- const env = makeTestEnv({ holdBeforeAdmission: true });
531
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "unexpired" });
532
- await env.lyraRuntime.receive(envelope);
533
-
534
- env.policy.channels[env.channelUri].members.push(env.atlasId);
535
- const released = await env.lyraRuntime.releaseHeld();
536
- assert.equal(released.length, 1);
537
- assert.equal(released[0].accepted, true);
538
- });
539
-
540
- // =========================================================================
541
- // T9c (R5): Held body is never returned before acceptance
542
- // =========================================================================
543
- test("T9c: CONTROL (R5) - Held return value contains no body, wire, or payload content", async () => {
544
- const env = makeTestEnv({ holdBeforeAdmission: true });
545
- const secretBody = "ultra-secret-body-content";
546
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: secretBody });
547
-
548
- const res = await env.lyraRuntime.receive(envelope);
549
- assert.equal(res.held, true);
550
- assert.equal(res.body, undefined);
551
- assert.equal(res.wire, undefined);
552
- assert.equal(res.payload, undefined);
553
- assert.equal(Object.keys(res).sort().join(","), "channel,held,id,sender");
554
- });
555
-
556
- test("T9c: CONTROL (inverse) (R5) - Upon acceptance, body is properly returned to caller", async () => {
557
- const env = makeTestEnv({ holdBeforeAdmission: true });
558
- const bodyText = "accepted-body-content";
559
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: bodyText });
560
- await env.lyraRuntime.receive(envelope);
561
-
562
- env.policy.channels[env.channelUri].members.push(env.atlasId);
563
- const released = await env.lyraRuntime.releaseHeld();
564
- assert.equal(released.length, 1);
565
- assert.equal(released[0].body, bodyText);
566
- });
567
-
568
- // =========================================================================
569
- // T13 (R1): Admitted sender flooding 5 channels caps at 20 across all channels
570
- // =========================================================================
571
- test("T13: CONTROL (R1) - Admitted sender flooding 5 channels stops at 20 across channels; 6th channel sender succeeds", async () => {
572
- const env = makeTestEnv({ holdBeforeAdmission: true });
573
-
574
- // Create 5 channels
575
- const channels = [];
576
- for (let i = 1; i <= 5; i++) {
577
- const cUri = `channel://local/flood-${i}/general`;
578
- env.policy.channels[cUri] = { members: [env.lyraId], allowForwarding: false };
579
- channels.push(cUri);
580
- }
581
-
582
- // Atlas sends 4 messages to each of the 5 channels = 20 total
583
- for (const cUri of channels) {
584
- for (let m = 0; m < 4; m++) {
585
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: cUri, body: `flood-${m}` });
586
- const r = await env.lyraRuntime.receive(envelope);
587
- assert.equal(r.held, true);
588
- }
589
- }
590
-
591
- const countsAtlas = env.lyraStore.holdCounts(channels[0], env.atlasId);
592
- assert.equal(countsAtlas.sender, 20);
593
- assert.equal(countsAtlas.channelSender, 4);
594
-
595
- // 21st message from Atlas to channel 1: channelSender is 4 (< 20), but sender count is 20 -> refused with 'sender'
596
- const { envelope: flood21 } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: channels[0], body: "flood-21" });
597
- await assert.rejects(
598
- () => env.lyraRuntime.receive(flood21),
599
- (err) => err.code === "UNAUTHORIZED_CHANNEL_SENDER"
600
- );
601
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
602
- const refused = audit.find(e => e.kind === "hold-refused" && e.id === flood21.id);
603
- assert.ok(refused);
604
- assert.equal(refused.reason, "sender");
605
-
606
- // An independent sender in channel 6 succeeds in being held
607
- const c6Uri = "channel://local/flood-6/general";
608
- env.policy.channels[c6Uri] = { members: [env.lyraId], allowForwarding: false };
609
- const independentKey = makeKey();
610
- env.policy.agents[independentKey._identity.uuaid] = { kind: "agent", publicKey: independentKey._identity.publicKeyHex, capabilities: ["commons:message"] };
611
- const { envelope: indEnv } = makeSealedMessage(independentKey, env.lyraKey, env.profile, { thread: c6Uri, body: "ind-1" });
612
- const indRes = await env.lyraRuntime.receive(indEnv);
613
- assert.equal(indRes.held, true);
614
- });
615
-
616
- test("T13: CONTROL (inverse) (R1) - A sender with < 20 messages across channels is not refused by sender cap", async () => {
617
- const env = makeTestEnv({ holdBeforeAdmission: true });
618
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "single-send" });
619
- const r = await env.lyraRuntime.receive(envelope);
620
- assert.equal(r.held, true);
621
- });
622
-
623
- // =========================================================================
624
- // T14 (R2): Sender removed during hold is dropped on releaseHeld
625
- // =========================================================================
626
- test("T14: CONTROL (R2) - Sender removed from policy.agents during hold is dropped on release with hold-dropped", async () => {
627
- const env = makeTestEnv({ holdBeforeAdmission: true });
628
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "will-be-dropped" });
629
-
630
- await env.lyraRuntime.receive(envelope);
631
- assert.equal(env.lyraStore.allHeld().length, 1);
632
-
633
- // Remove Atlas from policy.agents while envelope is held
634
- delete env.policy.agents[env.atlasId];
635
-
636
- // Also admit Atlas in channel (to prove channel admission isn't what drops it)
637
- env.policy.channels[env.channelUri].members.push(env.atlasId);
638
-
639
- const released = await env.lyraRuntime.releaseHeld();
640
- assert.equal(released.length, 0); // Dropped, not delivered
641
- assert.equal(env.lyraStore.allHeld().length, 0); // Removed from hold
642
-
643
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
644
- const dropped = audit.find(e => e.kind === "hold-dropped" && e.id === envelope.id);
645
- assert.ok(dropped);
646
- assert.equal(dropped.reason, "sender-not-admitted");
647
- });
648
-
649
- test("T14: CONTROL (inverse) (R2) - When sender remains in policy.agents, releaseHeld accepts message", async () => {
650
- const env = makeTestEnv({ holdBeforeAdmission: true });
651
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "remains-admitted" });
652
- await env.lyraRuntime.receive(envelope);
653
-
654
- env.policy.channels[env.channelUri].members.push(env.atlasId);
655
- const released = await env.lyraRuntime.releaseHeld();
656
- assert.equal(released.length, 1);
657
- assert.equal(released[0].accepted, true);
658
- });
659
-
660
- // =========================================================================
661
- // T15 (R3): Message accepted directly while copy is held -> duplicate: true on release
662
- // =========================================================================
663
- test("T15: CONTROL (R3) - Message accepted directly while copy is held returns duplicate: true on release with 1 delivery", async () => {
664
- const env = makeTestEnv({ holdBeforeAdmission: true });
665
- const { payload, envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "seen-race" });
666
-
667
- // 1. Envelope arrives and is held
668
- await env.lyraRuntime.receive(envelope);
669
- assert.equal(env.lyraStore.allHeld().length, 1);
670
-
671
- // 2. Channel policy updated to admit Atlas
672
- env.policy.channels[env.channelUri].members.push(env.atlasId);
673
-
674
- // 3. Same envelope is received directly via receive() and accepted
675
- const directRes = await env.lyraRuntime.receive(envelope);
676
- assert.equal(directRes.accepted, true);
677
- assert.equal(directRes.id, payload.id);
678
- assert.equal(env.lyraStore.seen(`msg:${env.atlasId}:${payload.id}`), true);
679
-
680
- // 4. releaseHeld() runs: seen check catches it -> leaves hold, returns duplicate: true
681
- const releaseRes = await env.lyraRuntime.releaseHeld();
682
- assert.equal(releaseRes.length, 1);
683
- assert.equal(releaseRes[0].duplicate, true);
684
- assert.equal(env.lyraStore.allHeld().length, 0);
685
-
686
- // Audit has exactly 1 message-received event (1 delivery)
687
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
688
- const messageReceived = audit.filter(e => e.kind === "message-received" && e.envelopeId === envelope.id);
689
- assert.equal(messageReceived.length, 1);
690
- });
691
-
692
- test("T15: CONTROL (inverse) (R3) - Without prior direct delivery, release delivers normally", async () => {
693
- const env = makeTestEnv({ holdBeforeAdmission: true });
694
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "no-race" });
695
- await env.lyraRuntime.receive(envelope);
696
-
697
- env.policy.channels[env.channelUri].members.push(env.atlasId);
698
- const releaseRes = await env.lyraRuntime.releaseHeld();
699
- assert.equal(releaseRes.length, 1);
700
- assert.equal(releaseRes[0].accepted, true);
701
- });
702
-
703
- // =========================================================================
704
- // T16 (R6): poll() suppresses quarantined-inbound row for held envelopes
705
- // =========================================================================
706
- test("T16: CONTROL (R6) - poll() advances carrier cursor and writes hold-added with zero quarantined-inbound rows", async () => {
707
- const env = makeTestEnv({ holdBeforeAdmission: true });
708
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "poll-hold" });
709
-
710
- await env.transport.deliver(envelope);
711
- const polled = await env.lyraRuntime.poll();
712
-
713
- assert.equal(polled.length, 1);
714
- assert.equal(polled[0].held, true);
715
- assert.equal(polled[0].id, envelope.id);
716
-
717
- // Check audit: hold-added present, quarantined-inbound absent
718
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
719
- assert.ok(audit.some(e => e.kind === "hold-added" && e.id === envelope.id));
720
- assert.equal(audit.some(e => e.kind === "quarantined-inbound"), false);
721
-
722
- // Carrier cursor advanced
723
- const cursors = env.lyraStore.get("cursors");
724
- assert.ok(cursors);
725
- assert.ok(Object.values(cursors).some(seq => seq > 0));
726
- });
727
-
728
- test("T16: CONTROL (inverse) (R6) - When hold is disabled, poll() writes quarantined-inbound", async () => {
729
- const env = makeTestEnv({ holdBeforeAdmission: false });
730
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "poll-refused" });
731
-
732
- await env.transport.deliver(envelope);
733
- const polled = await env.lyraRuntime.poll();
734
-
735
- assert.equal(polled.length, 1);
736
- assert.equal(polled[0].rejected, true);
737
-
738
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
739
- assert.ok(audit.some(e => e.kind === "quarantined-inbound" && e.id === envelope.id));
740
- assert.equal(audit.some(e => e.kind === "hold-added"), false);
741
- });
742
-
743
- // =========================================================================
744
- // T10 (C6): Audit rows never contain body, wire, or plaintext
745
- // =========================================================================
746
- test("T10: CONTROL (C6) - Audit rows for hold-added, hold-released, hold-dropped, hold-refused contain zero body or wire data", async () => {
747
- const env = makeTestEnv({ holdBeforeAdmission: true });
748
- const secretText = "confidential-payload-cannot-leak";
749
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: secretText });
750
-
751
- await env.lyraRuntime.receive(envelope);
752
- env.policy.channels[env.channelUri].members.push(env.atlasId);
753
- await env.lyraRuntime.releaseHeld();
754
-
755
- const holdRows = env.lyraStore.audit().filter(r => JSON.parse(r.body).kind?.startsWith("hold-"));
756
- assert.ok(holdRows.length >= 2);
757
- for (const row of holdRows) {
758
- const raw = row.body;
759
- assert.equal(raw.includes(secretText), false);
760
- assert.equal(raw.includes("wire"), false);
761
- assert.equal(raw.includes("payload"), false);
762
- }
763
- });
764
-
765
- test("T10: CONTROL (inverse) (C6) - Audit events contain required metadata fields", async () => {
766
- const env = makeTestEnv({ holdBeforeAdmission: true });
767
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "metadata-check" });
768
- await env.lyraRuntime.receive(envelope);
769
-
770
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
771
- const holdEvent = audit.find(e => e.kind === "hold-added");
772
- assert.ok(holdEvent);
773
- assert.equal(holdEvent.id, envelope.id);
774
- assert.equal(holdEvent.sender, env.atlasId);
775
- assert.equal(holdEvent.channel, env.channelUri);
776
- assert.equal(holdEvent.sha, envelopeSha(envelope));
777
- });
778
-
779
- // =========================================================================
780
- // T11: Default policy behavior unchanged (holdBeforeAdmission defaults to false)
781
- // =========================================================================
782
- test("T11: CONTROL - Without holdBeforeAdmission flag, behavior matches f4aeab9 baseline", async () => {
783
- const env = makeTestEnv();
784
- delete env.policy.holdBeforeAdmission; // unset flag
785
-
786
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri });
787
- await assert.rejects(
788
- () => env.lyraRuntime.receive(envelope),
789
- (err) => err.code === "UNAUTHORIZED_CHANNEL_SENDER"
790
- );
791
- assert.equal(env.lyraStore.allHeld().length, 0);
792
- });
793
-
794
- test("T11: CONTROL (inverse) - Explicit holdBeforeAdmission: true enables hold", async () => {
795
- const env = makeTestEnv({ holdBeforeAdmission: true });
796
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri });
797
- const res = await env.lyraRuntime.receive(envelope);
798
- assert.equal(res.held, true);
799
- assert.equal(env.lyraStore.allHeld().length, 1);
800
- });
801
-
802
- // =========================================================================
803
- // T12 (C5): Multi-page bounded flush in flushInternal
804
- // =========================================================================
805
- test("T12: CONTROL (C5) - 120 pending outbox rows all flush in 1 call; 1,100 rows stops at 1,000", async () => {
806
- const k1 = makeKey();
807
- const k2 = makeKey();
808
- const policy = {
809
- mode: "local",
810
- offline: true,
811
- channelsEnabled: false,
812
- agents: {
813
- [k1._identity.uuaid]: { kind: "agent", publicKey: k1._identity.publicKeyHex, capabilities: ["commons:message"] },
814
- [k2._identity.uuaid]: { kind: "agent", publicKey: k2._identity.publicKeyHex, capabilities: ["commons:message"] },
815
- },
816
- };
817
- const profile = createProfile({ namespace: "local/test", name: "Test", scope: "local", fixtures: ["f1", "f2"] });
818
- const transport = new MemoryLoopbackTransport();
819
-
820
- // Test part 1: 120 queued rows all flush in 1 call (3 pages: 50, 50, 20)
821
- const runtime1 = new AgentCommons({ keychain: k1, policy, transport });
822
- runtime1.addProfile(profile);
823
-
824
- for (let i = 0; i < 120; i++) {
825
- await runtime1.send({ recipient: k2._identity.uuaid, profileId: profile.id, body: `msg-${i}`, deferFlush: true });
826
- }
827
- assert.equal(runtime1.store.db.prepare("SELECT COUNT(*) as n FROM outbox WHERE state='pending'").get().n, 120);
828
-
829
- const res1 = await runtime1.flush();
830
- assert.equal(res1.length, 120);
831
- assert.equal(runtime1.store.db.prepare("SELECT COUNT(*) as n FROM outbox WHERE state='pending'").get().n, 0);
832
-
833
- // Test part 2: 1,100 queued rows stops at hard cap of 20 pages = 1,000 rows
834
- const runtime2 = new AgentCommons({ keychain: k1, policy, transport });
835
- runtime2.addProfile(profile);
836
-
837
- for (let i = 0; i < 1100; i++) {
838
- await runtime2.send({ recipient: k2._identity.uuaid, profileId: profile.id, body: `msg-${i}`, deferFlush: true });
839
- }
840
- assert.equal(runtime2.store.db.prepare("SELECT COUNT(*) as n FROM outbox WHERE state='pending'").get().n, 1100);
841
-
842
- const res2 = await runtime2.flush();
843
- assert.equal(res2.length, 1000);
844
- assert.equal(runtime2.store.db.prepare("SELECT COUNT(*) as n FROM outbox WHERE state='pending'").get().n, 100);
845
- });
846
-
847
- test("T12: CONTROL (inverse) (C5) - Flush with zero pending rows returns empty results without infinite loop", async () => {
848
- const k1 = makeKey();
849
- const runtime = new AgentCommons({ keychain: k1, policy: { mode: "local" }, transport: new MemoryLoopbackTransport() });
850
- const res = await runtime.flush();
851
- assert.deepEqual(res, []);
852
- });
853
-
854
- // =========================================================================
855
- // Concurrency & Interleaving Proof: 50-Cycle Stress with Fixed Seed
856
- // =========================================================================
857
- test("Concurrency & Interleaving: 50-cycle interleaving stress proof between poll() and releaseHeld()", async () => {
858
- const FIXED_SEED = 0x11062026;
859
- console.log(`[L11 Interleaving Test] PRNG Fixed Seed: 0x${FIXED_SEED.toString(16)} (${FIXED_SEED})`);
860
-
861
- function makePrng(seed) {
862
- let s = seed >>> 0;
863
- return () => {
864
- s = (Math.imul(s, 1664525) + 1013904223) >>> 0;
865
- return s / 4294967296;
866
- };
867
- }
868
- const rand = makePrng(FIXED_SEED);
869
-
870
- const receiverKey = makeKey();
871
- const receiverId = receiverKey._identity.uuaid;
872
- const channelUri = "channel://local/c/stress";
873
- const profile = createProfile({ namespace: "local/test", name: "Test", scope: "local", fixtures: ["f1", "f2"] });
874
-
875
- const senderKeys = [];
876
- const senderIds = [];
877
- for (let i = 0; i < 4; i++) {
878
- const k = makeKey();
879
- senderKeys.push(k);
880
- senderIds.push(k._identity.uuaid);
881
- }
882
-
883
- const policy = {
884
- mode: "local",
885
- offline: true,
886
- channelsEnabled: true,
887
- holdBeforeAdmission: true,
888
- channels: {
889
- [channelUri]: { members: [receiverId], allowForwarding: false },
890
- },
891
- agents: {
892
- [receiverId]: { kind: "agent", publicKey: receiverKey._identity.publicKeyHex, capabilities: ["commons:message"] },
893
- },
894
- };
895
- for (const k of senderKeys) {
896
- policy.agents[k._identity.uuaid] = { kind: "agent", publicKey: k._identity.publicKeyHex, capabilities: ["commons:message"] };
897
- }
898
-
899
- const transport = new MemoryLoopbackTransport();
900
- const store = new CommonsStore(":memory:");
901
- const runtime = new AgentCommons({ keychain: receiverKey, store, policy, transport });
902
- runtime.addProfile(profile);
903
-
904
- const deliveredMessages = new Map();
905
-
906
- for (let cycle = 0; cycle < 50; cycle++) {
907
- const senderIdx = Math.floor(rand() * senderKeys.length);
908
- const senderKey = senderKeys[senderIdx];
909
- const sId = senderIds[senderIdx];
910
- const msgId = randomUUID();
911
-
912
- const { envelope } = makeSealedMessage(senderKey, receiverKey, profile, {
913
- thread: channelUri,
914
- body: `stress-msg-${cycle}`,
915
- id: msgId,
916
- });
917
-
918
- await transport.deliver(envelope);
919
-
920
- // Dynamically admit sender with 50% probability
921
- if (rand() > 0.5) {
922
- if (!policy.channels[channelUri].members.includes(sId)) {
923
- policy.channels[channelUri].members.push(sId);
924
- }
925
- }
926
-
927
- // Concurrently trigger poll() and releaseHeld()
928
- const [pollRes, releaseRes] = await Promise.all([
929
- runtime.poll(),
930
- runtime.releaseHeld(),
931
- ]);
932
-
933
- for (const r of pollRes) {
934
- if (r?.accepted) {
935
- assert.equal(deliveredMessages.has(r.id), false, `Duplicate delivery via poll for ${r.id}`);
936
- deliveredMessages.set(r.id, r);
937
- }
938
- }
939
- for (const r of releaseRes) {
940
- if (r?.accepted) {
941
- assert.equal(deliveredMessages.has(r.id), false, `Duplicate delivery via releaseHeld for ${r.id}`);
942
- deliveredMessages.set(r.id, r);
943
- }
944
- }
945
- }
946
-
947
- // Final phase: admit all senders and release any remaining held messages
948
- for (const sId of senderIds) {
949
- if (!policy.channels[channelUri].members.includes(sId)) {
950
- policy.channels[channelUri].members.push(sId);
951
- }
952
- }
953
- const finalRelease = await runtime.releaseHeld();
954
- for (const r of finalRelease) {
955
- if (r?.accepted) {
956
- assert.equal(deliveredMessages.has(r.id), false, `Duplicate delivery in final release for ${r.id}`);
957
- deliveredMessages.set(r.id, r);
958
- }
959
- }
960
-
961
- // Invariants:
962
- // 1. Every message sent was delivered exactly once
963
- assert.equal(deliveredMessages.size, 50);
964
-
965
- // 2. Zero quarantined-inbound rows in audit log
966
- const audit = store.audit().map(r => JSON.parse(r.body));
967
- const quarantined = audit.filter(e => e.kind === "quarantined-inbound");
968
- assert.equal(quarantined.length, 0);
969
-
970
- // 3. Store audit integrity is intact
971
- assert.equal(store.verify(), true);
972
-
973
- // 4. Zero held messages remain
974
- assert.equal(store.allHeld().length, 0);
975
- });
976
-
977
- // =========================================================================
978
- // Rework 1 F1: Expired held row pruning before bounds and deduplication
979
- // =========================================================================
980
- test("Rework 1 F1 (a): CONTROL - 20 expired rows for (channel, sender) are pruned so fresh eligible message is held", async () => {
981
- const env = makeTestEnv({ holdBeforeAdmission: true });
982
- for (let i = 0; i < 20; i++) {
983
- const { envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: `old-${i}` });
984
- env.lyraStore.hold(envelope, `msg:${env.atlasId}:${randomUUID()}`, env.channelUri, env.atlasId, envelopeSha(envelope), Date.now() - 1000);
985
- }
986
- assert.equal(env.lyraStore.holdCounts(env.channelUri, env.atlasId).channelSender, 20);
987
-
988
- const { envelope: freshEnv } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "fresh-msg" });
989
- const res = await env.lyraRuntime.receive(freshEnv);
990
- assert.equal(res.held, true);
991
- assert.equal(env.lyraStore.holdCounts(env.channelUri, env.atlasId).channelSender, 1);
992
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
993
- const expiredEvents = audit.filter(e => e.kind === "hold-expired");
994
- assert.equal(expiredEvents.length, 20);
995
- });
996
-
997
- test("Rework 1 F1 (b): CONTROL - Expired row with id X is pruned so same envelope X arriving again is held as live", async () => {
998
- const env = makeTestEnv({ holdBeforeAdmission: true });
999
- const { payload, envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "replay-after-expiry" });
1000
- const msgKey = `msg:${env.atlasId}:${payload.id}`;
1001
- env.lyraStore.hold(envelope, msgKey, env.channelUri, env.atlasId, envelopeSha(envelope), Date.now() - 1000);
1002
- assert.equal(env.lyraStore.allHeld().length, 1);
1003
-
1004
- const res = await env.lyraRuntime.receive(envelope);
1005
- assert.equal(res.held, true);
1006
- const live = env.lyraStore.allHeld();
1007
- assert.equal(live.length, 1);
1008
- assert.ok(live[0].expires_at > Date.now());
1009
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
1010
- assert.ok(audit.some(e => e.kind === "hold-expired" && e.id === envelope.id));
1011
- assert.ok(audit.some(e => e.kind === "hold-added" && e.id === envelope.id));
1012
- });
1013
-
1014
- // =========================================================================
1015
- // Rework 1 F2: Transient error handling in releaseHeldInternal
1016
- // =========================================================================
1017
- test("Rework 1 F2 (c): CONTROL - Injected trust throwing transient error keeps entry held with hold-deferred, accepted on later release", async () => {
1018
- const env = makeTestEnv({ holdBeforeAdmission: true });
1019
- const { payload, envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "transient-retry" });
1020
-
1021
- await env.lyraRuntime.receive(envelope);
1022
- assert.equal(env.lyraStore.allHeld().length, 1);
1023
-
1024
- env.policy.channels[env.channelUri].members.push(env.atlasId);
1025
-
1026
- let callCount = 0;
1027
- const originalTrust = env.lyraRuntime.trust;
1028
- env.lyraRuntime.trust = {
1029
- ...originalTrust,
1030
- authorize: async (uuaid, key, cap) => {
1031
- if (callCount++ === 0) {
1032
- const err = new Error("Registry temporarily offline");
1033
- err.transient = true;
1034
- err.code = "REGISTRY_UNAVAILABLE";
1035
- throw err;
1036
- }
1037
- return originalTrust.authorize(uuaid, key, cap);
1038
- },
1039
- };
1040
-
1041
- const res1 = await env.lyraRuntime.releaseHeld();
1042
- assert.equal(res1.length, 0);
1043
- assert.equal(env.lyraStore.allHeld().length, 1);
1044
-
1045
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
1046
- const deferred = audit.find(e => e.kind === "hold-deferred" && e.id === envelope.id);
1047
- assert.ok(deferred);
1048
- assert.equal(deferred.reason, "REGISTRY_UNAVAILABLE");
1049
- assert.equal(audit.some(e => e.kind === "hold-dropped"), false);
1050
-
1051
- const res2 = await env.lyraRuntime.releaseHeld();
1052
- assert.equal(res2.length, 1);
1053
- assert.equal(res2[0].accepted, true);
1054
- assert.equal(res2[0].id, payload.id);
1055
- assert.equal(env.lyraStore.allHeld().length, 0);
1056
- });
1057
-
1058
- test("Rework 1 F2 (d): CONTROL - Two held entries where first defers halts release pass so second is not released ahead", async () => {
1059
- const env = makeTestEnv({ holdBeforeAdmission: true });
1060
- const { payload: p1, envelope: env1 } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "msg-1" });
1061
- const { payload: p2, envelope: env2 } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "msg-2" });
1062
-
1063
- await env.lyraRuntime.receive(env1);
1064
- await env.lyraRuntime.receive(env2);
1065
- assert.equal(env.lyraStore.allHeld().length, 2);
1066
-
1067
- env.policy.channels[env.channelUri].members.push(env.atlasId);
1068
-
1069
- let calls = 0;
1070
- const originalTrust = env.lyraRuntime.trust;
1071
- env.lyraRuntime.trust = {
1072
- ...originalTrust,
1073
- authorize: async (uuaid, key, cap) => {
1074
- calls++;
1075
- if (calls === 1) {
1076
- const err = new Error("Backend timeout");
1077
- err.transient = true;
1078
- err.code = "BACKEND_TIMEOUT";
1079
- throw err;
1080
- }
1081
- return originalTrust.authorize(uuaid, key, cap);
1082
- },
1083
- };
1084
-
1085
- const res1 = await env.lyraRuntime.releaseHeld();
1086
- assert.equal(res1.length, 0);
1087
- assert.equal(env.lyraStore.allHeld().length, 2);
1088
- assert.equal(calls, 1);
1089
-
1090
- env.lyraRuntime.trust = originalTrust;
1091
- const res2 = await env.lyraRuntime.releaseHeld();
1092
- assert.equal(res2.length, 2);
1093
- assert.equal(res2[0].id, p1.id);
1094
- assert.equal(res2[1].id, p2.id);
1095
- assert.equal(env.lyraStore.allHeld().length, 0);
1096
- });
1097
-
1098
- // =========================================================================
1099
- // L13 Item A: Duplicate release appends hold-released audit row
1100
- // =========================================================================
1101
- test("L13 Item A: CONTROL - Duplicate release appends hold-released audit row with reason duplicate-of-accepted", async () => {
1102
- const env = makeTestEnv({ holdBeforeAdmission: true });
1103
- const { payload, envelope } = makeSealedMessage(env.atlasKey, env.lyraKey, env.profile, { thread: env.channelUri, body: "audit-duplicate-release" });
1104
-
1105
- // 1. Envelope arrives and is held
1106
- const heldRes = await env.lyraRuntime.receive(envelope);
1107
- assert.equal(heldRes.held, true);
1108
- assert.equal(env.lyraStore.allHeld().length, 1);
1109
-
1110
- // 2. Channel policy updated to admit Atlas
1111
- env.policy.channels[env.channelUri].members.push(env.atlasId);
1112
-
1113
- // 3. Same envelope accepted directly
1114
- const directRes = await env.lyraRuntime.receive(envelope);
1115
- assert.equal(directRes.accepted, true);
1116
-
1117
- // 4. Release held copy
1118
- const releaseRes = await env.lyraRuntime.releaseHeld();
1119
- assert.equal(releaseRes.length, 1);
1120
- assert.equal(releaseRes[0].duplicate, true);
1121
-
1122
- // Held row is gone
1123
- assert.equal(env.lyraStore.allHeld().length, 0);
1124
-
1125
- // Exactly one hold-released row with reason "duplicate-of-accepted" exists
1126
- const audit = env.lyraStore.audit().map(r => JSON.parse(r.body));
1127
- const duplicateReleased = audit.filter(e => e.kind === "hold-released" && e.reason === "duplicate-of-accepted");
1128
- assert.equal(duplicateReleased.length, 1);
1129
- assert.equal(duplicateReleased[0].id, envelope.id);
1130
- assert.equal(duplicateReleased[0].sender, env.atlasId);
1131
- assert.equal(duplicateReleased[0].channel, env.channelUri);
1132
- assert.equal(duplicateReleased[0].sha, envelopeSha(envelope));
1133
- });
1134
-
1135
- // =========================================================================
1136
- // L13 Item B: pruneExpiredHeld in transaction deletes strictly by key
1137
- // =========================================================================
1138
- test("L13 Item B: CONTROL - pruneExpiredHeld deletes strictly by key inside transaction and preserves interleaved row", () => {
1139
- const store = new CommonsStore(":memory:");
1140
- const now = 10000;
1141
- // Hold initial row that is expired at `now`
1142
- store.hold({ id: "h1" }, "k1", "chan1", "sender1", "sha1", now - 1000);
1143
-
1144
- // Wrap store.db.prepare for the SELECT call
1145
- const originalPrepare = store.db.prepare.bind(store.db);
1146
- let injected = false;
1147
- store.db.prepare = (sql) => {
1148
- const stmt = originalPrepare(sql);
1149
- if (sql.includes("FROM held WHERE expires_at<=?") && !injected) {
1150
- const origAll = stmt.all.bind(stmt);
1151
- stmt.all = (...args) => {
1152
- const result = origAll(...args);
1153
- // Simulate interleaved write of an expired row right after SELECT
1154
- originalPrepare("INSERT INTO held(id,msg_key,channel,sender,envelope,sha,expires_at,created_at) VALUES(?,?,?,?,?,?,?,?)").run(
1155
- "injected-id", "injected-key", "chan1", "sender1", JSON.stringify({ id: "injected-id" }), "sha-inj", now - 500, now - 500
1156
- );
1157
- injected = true;
1158
- return result;
1159
- };
1160
- }
1161
- return stmt;
1162
- };
1163
-
1164
- const returned = store.pruneExpiredHeld(now);
1165
- store.db.prepare = originalPrepare;
1166
-
1167
- // 1. Every row the prune removed is in its return value
1168
- assert.equal(returned.length, 1);
1169
- assert.equal(returned[0].id, "h1");
1170
- assert.equal(store.isHeld("h1", "k1"), false);
1171
-
1172
- // 2. The injected row is either returned or still present
1173
- const returnedIds = new Set(returned.map(r => r.id));
1174
- assert.equal(returnedIds.has("injected-id"), false);
1175
- assert.equal(store.isHeld("injected-id", "injected-key"), true, "injected row must still be present if not returned by prune");
1176
-
1177
- const allRemaining = store.allHeld();
1178
- assert.equal(allRemaining.length, 1);
1179
- assert.equal(allRemaining[0].id, "injected-id");
1180
-
1181
- store.close();
1182
- });
1183
-
1184
-
1185
-