@dharma-ai-labs/agent-fabric 0.2.81 → 0.2.83

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.
@@ -0,0 +1,329 @@
1
+ import { createHash, randomBytes, randomUUID, sign } from 'node:crypto';
2
+ import { chmod, mkdir, open, readFile, rename, stat, unlink, writeFile } from 'node:fs/promises';
3
+ import { dirname } from 'node:path';
4
+ import { loadOrCreateDeviceIdentity, normalizeHqUrl } from '@dharma-ai-labs/agent-fabric-relay-client';
5
+ import { scopePath, verifyDemoDevice } from './demoEnrollment.js';
6
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
7
+ const MAX_PENDING_AGE_MS = 4 * 60_000;
8
+ function assertAction(action) {
9
+ if (!['role', 'peers', 'ask', 'reply', 'inbox', 'ack'].includes(action.kind)) {
10
+ throw new Error('Demo peer action is invalid.');
11
+ }
12
+ if (action.kind === 'role') {
13
+ if (typeof action.role !== 'string' || !Array.isArray(action.categories)
14
+ || action.role.length < 2 || action.role.length > 80 || action.categories.length > 12
15
+ || action.categories.some((category) => typeof category !== 'string'
16
+ || category.length < 2 || category.length > 80)) {
17
+ throw new Error('Demo peer role and categories must be bounded strings.');
18
+ }
19
+ }
20
+ else if (action.kind === 'ask' || action.kind === 'reply') {
21
+ if (typeof action.recipientDeviceId !== 'string' || typeof action.content !== 'string'
22
+ || !UUID.test(action.recipientDeviceId) || action.content.length < 1
23
+ || action.content.length > 4000 || (action.kind === 'reply' && !UUID.test(action.questionId))) {
24
+ throw new Error('Demo peer target or question content is invalid.');
25
+ }
26
+ }
27
+ else if (action.kind === 'ack' && !UUID.test(action.messageId)) {
28
+ throw new Error('Demo peer message ID is invalid.');
29
+ }
30
+ }
31
+ async function privateWrite(path, value) {
32
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
33
+ const temporary = `${path}.${randomUUID()}.tmp`;
34
+ await writeFile(temporary, `${JSON.stringify(value)}\n`, { mode: 0o600, flag: 'wx' });
35
+ await rename(temporary, path);
36
+ if (process.platform !== 'win32')
37
+ await chmod(path, 0o600);
38
+ }
39
+ async function device(input, deps) {
40
+ const origin = normalizeHqUrl(input.hqUrl);
41
+ const configPath = scopePath(input, origin);
42
+ let config;
43
+ try {
44
+ config = JSON.parse(await readFile(configPath, 'utf8'));
45
+ }
46
+ catch {
47
+ throw new Error('Demo device is not enrolled. Run the recipient-bound demo connect prompt first.');
48
+ }
49
+ if (config.schema !== 'dharma.demo-device/v1' || config.hqUrl !== origin
50
+ || config.organizationId !== input.organizationId || config.repositoryId !== input.repositoryId
51
+ || config.normalizedRepository !== input.normalizedRepository
52
+ || config.installationId !== input.installationId || !UUID.test(config.deviceId)
53
+ || !Number.isSafeInteger(config.nextSequence) || config.nextSequence < 1) {
54
+ throw new Error('Demo device state does not match this repository and installation.');
55
+ }
56
+ const identity = await loadOrCreateDeviceIdentity({ hqUrl: origin,
57
+ organizationId: `${input.organizationId}:${input.repositoryId}`,
58
+ installationId: input.installationId, store: deps.store });
59
+ if (config.publicKeyEd25519 !== identity.publicKeyEd25519) {
60
+ throw new Error('Demo device key does not match its protected identity.');
61
+ }
62
+ return { origin, configPath, config, privateJwk: identity.privateJwk };
63
+ }
64
+ function endpoint(origin, input, action) {
65
+ const root = `/api/demo/fabric/repositories/${input.repositoryId}`;
66
+ const pathname = action.kind === 'role' || action.kind === 'peers' ? `${root}/peers`
67
+ : action.kind === 'ack' ? `${root}/messages/${action.messageId}/ack`
68
+ : `${root}/messages`;
69
+ const url = new URL(pathname, origin);
70
+ url.searchParams.set('orgId', input.organizationId);
71
+ const method = action.kind === 'role' || action.kind === 'ask'
72
+ || action.kind === 'reply' || action.kind === 'ack' ? 'POST' : 'GET';
73
+ return { url, method };
74
+ }
75
+ function bodyFor(action, operationId) {
76
+ if (action.kind === 'role')
77
+ return JSON.stringify({ role: action.role, categories: action.categories });
78
+ if (action.kind === 'ask' || action.kind === 'reply')
79
+ return JSON.stringify({
80
+ operationId, recipientDeviceId: action.recipientDeviceId,
81
+ kind: action.kind === 'ask' ? 'question' : 'answer',
82
+ inReplyTo: action.kind === 'reply' ? action.questionId : null,
83
+ content: action.content,
84
+ });
85
+ return '';
86
+ }
87
+ function signedOperation(origin, input, action, operationId, config, privateJwk) {
88
+ const { url, method } = endpoint(origin, input, action);
89
+ const body = bodyFor(action, operationId);
90
+ const sessionId = randomUUID();
91
+ const messageId = randomUUID();
92
+ const timestamp = new Date().toISOString();
93
+ const nonce = randomBytes(24).toString('base64url');
94
+ const sequence = config.nextSequence;
95
+ const payload = Buffer.from(JSON.stringify({
96
+ bodyHash: `sha256:${createHash('sha256').update(body).digest('hex')}`,
97
+ deviceId: config.deviceId, messageId, method, nonce,
98
+ organizationId: input.organizationId,
99
+ pathname: `${url.pathname}${url.search}`, sequence, sessionId, timestamp,
100
+ }));
101
+ const signature = sign(null, payload, { key: privateJwk, format: 'jwk' }).toString('base64url');
102
+ return { method, url: url.toString(), body, sequence, createdAt: timestamp,
103
+ headers: {
104
+ 'x-dharma-device-id': config.deviceId, 'x-dharma-session-id': sessionId,
105
+ 'x-dharma-message-id': messageId, 'x-dharma-timestamp': timestamp,
106
+ 'x-dharma-nonce': nonce, 'x-dharma-sequence': String(sequence),
107
+ 'x-dharma-signature': signature,
108
+ } };
109
+ }
110
+ function responseError(body, status) {
111
+ const item = body && typeof body === 'object' ? body : {};
112
+ const nested = item.error && typeof item.error === 'object' && !Array.isArray(item.error)
113
+ ? item.error : null;
114
+ const code = typeof nested?.code === 'string' ? nested.code
115
+ : typeof item.error === 'string' ? item.error : `http_${status}`;
116
+ const message = typeof nested?.message === 'string' ? nested.message
117
+ : typeof item.message === 'string' ? item.message : 'Demo peer request failed.';
118
+ return Object.assign(new Error(`${code}: ${message}`), { code });
119
+ }
120
+ function assertReceipt(body, action) {
121
+ const object = (value) => Boolean(value) && typeof value === 'object' && !Array.isArray(value);
122
+ const items = action.kind === 'peers' ? body.peers
123
+ : action.kind === 'inbox' ? body.messages : null;
124
+ const valid = action.kind === 'role' ? object(body.role)
125
+ && UUID.test(String(body.role.deviceId)) && body.role.role === action.role
126
+ : action.kind === 'peers' ? Array.isArray(items)
127
+ && items.every((item) => object(item) && UUID.test(String(item.deviceId))
128
+ && typeof item.role === 'string' && Array.isArray(item.categories))
129
+ : action.kind === 'inbox' ? Array.isArray(items)
130
+ && items.every((item) => object(item) && UUID.test(String(item.id))
131
+ && UUID.test(String(item.senderDeviceId)) && typeof item.content === 'string')
132
+ : action.kind === 'ack' ? object(body.acknowledgement)
133
+ && body.acknowledgement.id === action.messageId
134
+ && typeof body.acknowledgement.acknowledgedAt === 'string'
135
+ : object(body.message) && UUID.test(String(body.message.id))
136
+ && typeof body.message.duplicate === 'boolean';
137
+ if (!valid)
138
+ throw new Error('Demo peer response does not match the expected command receipt.');
139
+ }
140
+ async function dispatch(request, action, fetcher) {
141
+ const response = await fetcher(request.url, {
142
+ method: request.method, headers: request.headers,
143
+ body: request.method === 'POST' && request.body ? request.body : undefined,
144
+ });
145
+ const body = await response.json().catch(() => null);
146
+ if (!response.ok)
147
+ throw responseError(body, response.status);
148
+ if (!body || typeof body !== 'object' || Array.isArray(body)
149
+ || body.ok !== true) {
150
+ throw new Error('Demo peer response is not a verified JSON receipt.');
151
+ }
152
+ const receipt = body;
153
+ assertReceipt(receipt, action);
154
+ return receipt;
155
+ }
156
+ async function complete(path, configPath, config, pending, result) {
157
+ config.nextSequence = pending.request.sequence + 1;
158
+ await privateWrite(configPath, config);
159
+ await unlink(path).catch(() => { });
160
+ return { ...result, stage: 'demo_peer_operation', action: pending.action.kind,
161
+ deviceId: config.deviceId, repositoryId: config.repositoryId };
162
+ }
163
+ export async function performDemoPeerAction(input, requested, deps = {}) {
164
+ if (requested)
165
+ assertAction(requested);
166
+ const initial = await device(input, deps);
167
+ if (!initial.config.signedReady)
168
+ throw new Error('Demo device has not completed signed readiness. Run demo status.');
169
+ const pendingPath = `${initial.configPath}.pending-peer.json`;
170
+ let pending = null;
171
+ try {
172
+ pending = JSON.parse(await readFile(pendingPath, 'utf8'));
173
+ }
174
+ catch (error) {
175
+ if (error.code !== 'ENOENT') {
176
+ throw new Error('Pending Demo peer request is invalid; preserve it for recovery.', { cause: error });
177
+ }
178
+ }
179
+ if (pending) {
180
+ if (pending.schema !== 'dharma.demo-peer-pending/v1' || !pending.action
181
+ || (pending.operationId !== null && !UUID.test(pending.operationId))
182
+ || (['ask', 'reply'].includes(pending.action.kind) && pending.operationId === null)
183
+ || !Number.isSafeInteger(pending.request?.sequence)
184
+ || pending.request.sequence < 1 || !Number.isFinite(Date.parse(pending.request.createdAt))
185
+ || !pending.request.headers || typeof pending.request.headers !== 'object'
186
+ || Object.keys(pending.request.headers).sort().join(',') !== [
187
+ 'x-dharma-device-id', 'x-dharma-message-id', 'x-dharma-nonce',
188
+ 'x-dharma-sequence', 'x-dharma-session-id', 'x-dharma-signature',
189
+ 'x-dharma-timestamp',
190
+ ].sort().join(',')
191
+ || pending.request.headers['x-dharma-device-id'] !== initial.config.deviceId
192
+ || pending.request.headers['x-dharma-sequence'] !== String(pending.request.sequence)
193
+ || pending.request.url !== endpoint(initial.origin, input, pending.action).url.toString()
194
+ || pending.request.body !== bodyFor(pending.action, pending.operationId)
195
+ || pending.request.method !== endpoint(initial.origin, input, pending.action).method) {
196
+ throw new Error('Pending Demo peer request does not match this signed repository.');
197
+ }
198
+ assertAction(pending.action);
199
+ const sameAction = requested !== null
200
+ && JSON.stringify(requested) === JSON.stringify(pending.action);
201
+ if (initial.config.nextSequence === pending.request.sequence
202
+ && Date.now() - Date.parse(pending.request.createdAt) < MAX_PENDING_AGE_MS) {
203
+ const pendingSequence = pending.request.sequence;
204
+ try {
205
+ const result = await dispatch(pending.request, pending.action, deps.fetcher || fetch);
206
+ const receipt = await complete(pendingPath, initial.configPath, initial.config, pending, result);
207
+ if (sameAction || !requested)
208
+ return { ...receipt, resumed: true };
209
+ pending = null;
210
+ }
211
+ catch (error) {
212
+ const code = error.code;
213
+ if (code && code !== 'demo_fabric_sequence_out_of_order') {
214
+ await verifyDemoDevice(input, { ...deps,
215
+ expectedAcceptedSequence: pendingSequence });
216
+ await unlink(pendingPath).catch(() => { });
217
+ }
218
+ if (code !== 'demo_fabric_sequence_out_of_order')
219
+ throw error;
220
+ }
221
+ }
222
+ if (pending) {
223
+ await verifyDemoDevice(input, { ...deps,
224
+ expectedAcceptedSequence: pending.request.sequence });
225
+ const resumed = await device(input, deps);
226
+ pending.request = signedOperation(resumed.origin, input, pending.action, pending.operationId, resumed.config, resumed.privateJwk);
227
+ await privateWrite(pendingPath, pending);
228
+ try {
229
+ const result = await dispatch(pending.request, pending.action, deps.fetcher || fetch);
230
+ const receipt = await complete(pendingPath, resumed.configPath, resumed.config, pending, result);
231
+ if (sameAction || !requested)
232
+ return { ...receipt, resumed: true };
233
+ }
234
+ catch (error) {
235
+ if (error.code) {
236
+ await verifyDemoDevice(input, { ...deps,
237
+ expectedAcceptedSequence: pending.request.sequence });
238
+ await unlink(pendingPath).catch(() => { });
239
+ }
240
+ throw error;
241
+ }
242
+ }
243
+ }
244
+ if (!requested)
245
+ return { ok: true, stage: 'demo_peer_no_pending' };
246
+ await verifyDemoDevice(input, deps);
247
+ const ready = await device(input, deps);
248
+ const operationId = requested.kind === 'ask' || requested.kind === 'reply' ? randomUUID() : null;
249
+ const fresh = { schema: 'dharma.demo-peer-pending/v1',
250
+ action: requested, operationId,
251
+ request: signedOperation(ready.origin, input, requested, operationId, ready.config, ready.privateJwk) };
252
+ await privateWrite(pendingPath, fresh);
253
+ try {
254
+ const result = await dispatch(fresh.request, requested, deps.fetcher || fetch);
255
+ return complete(pendingPath, ready.configPath, ready.config, fresh, result);
256
+ }
257
+ catch (error) {
258
+ if (error.code === 'demo_fabric_sequence_out_of_order') {
259
+ await verifyDemoDevice(input, { ...deps,
260
+ expectedAcceptedSequence: fresh.request.sequence });
261
+ const retry = await device(input, deps);
262
+ fresh.request = signedOperation(retry.origin, input, requested, operationId, retry.config, retry.privateJwk);
263
+ await privateWrite(pendingPath, fresh);
264
+ const result = await dispatch(fresh.request, requested, deps.fetcher || fetch);
265
+ return complete(pendingPath, retry.configPath, retry.config, fresh, result);
266
+ }
267
+ if (error.code) {
268
+ await verifyDemoDevice(input, { ...deps,
269
+ expectedAcceptedSequence: fresh.request.sequence });
270
+ await unlink(pendingPath).catch(() => { });
271
+ }
272
+ throw error;
273
+ }
274
+ }
275
+ export async function withDemoDeviceLock(input, work) {
276
+ const path = `${scopePath(input, normalizeHqUrl(input.hqUrl))}.lock`;
277
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
278
+ const token = randomUUID();
279
+ for (let attempt = 0; attempt < 2; attempt += 1) {
280
+ let handle;
281
+ try {
282
+ handle = await open(path, 'wx', 0o600);
283
+ }
284
+ catch (error) {
285
+ if (error.code !== 'EEXIST')
286
+ throw error;
287
+ const age = Date.now() - (await stat(path)).mtimeMs;
288
+ let owner = 0;
289
+ try {
290
+ owner = JSON.parse(await readFile(path, 'utf8')).pid || 0;
291
+ }
292
+ catch { /* An incomplete new lock is treated as busy. */ }
293
+ let alive = owner > 0;
294
+ if (alive) {
295
+ try {
296
+ process.kill(owner, 0);
297
+ }
298
+ catch (processError) {
299
+ alive = processError.code !== 'ESRCH';
300
+ }
301
+ }
302
+ if (age < 2_000 || alive) {
303
+ throw new Error('Demo device is busy on this machine. Retry after its current operation ends.');
304
+ }
305
+ await unlink(path);
306
+ continue;
307
+ }
308
+ try {
309
+ await handle.writeFile(JSON.stringify({ pid: process.pid, token }));
310
+ }
311
+ catch (error) {
312
+ await unlink(path).catch(() => { });
313
+ throw error;
314
+ }
315
+ finally {
316
+ await handle.close();
317
+ }
318
+ try {
319
+ return await work();
320
+ }
321
+ finally {
322
+ const current = JSON.parse(await readFile(path, 'utf8'));
323
+ if (current.token === token)
324
+ await unlink(path);
325
+ }
326
+ }
327
+ throw new Error('Demo device lock could not be recovered.');
328
+ }
329
+ //# sourceMappingURL=demoPeer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demoPeer.js","sourceRoot":"","sources":["../src/demoPeer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=demoPeer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demoPeer.test.d.ts","sourceRoot":"","sources":["../src/demoPeer.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,191 @@
1
+ import assert from 'node:assert/strict';
2
+ import { createHash, createPublicKey, verify } from 'node:crypto';
3
+ import { mkdtemp, readFile, stat, writeFile } from 'node:fs/promises';
4
+ import { tmpdir } from 'node:os';
5
+ import { resolve } from 'node:path';
6
+ import test from 'node:test';
7
+ import { connectDemoDevice, scopePath } from './demoEnrollment.js';
8
+ import { performDemoPeerAction, withDemoDeviceLock } from './demoPeer.js';
9
+ const orgId = 'org_fixture';
10
+ const repositoryId = '10000000-0000-4000-8000-000000000001';
11
+ const recipientDeviceId = '30000000-0000-4000-8000-000000000002';
12
+ const deviceId = '30000000-0000-4000-8000-000000000001';
13
+ const normalizedRepository = 'github.com/example/private';
14
+ const hqUrl = 'https://dharma.example';
15
+ function memoryStore() {
16
+ const values = new Map();
17
+ return { backend: 'linux-secret-service',
18
+ async get(account) { return values.get(account) || null; },
19
+ async put(account, value) { values.set(account, value); },
20
+ async delete(account) { values.delete(account); } };
21
+ }
22
+ function scope(stateRoot) {
23
+ return { hqUrl, organizationId: orgId, repositoryId, normalizedRepository,
24
+ installationId: '40000000-0000-4000-8000-000000000001', stateRoot };
25
+ }
26
+ function server(options = {}) {
27
+ let publicKey = '';
28
+ let sequence = 0;
29
+ let loseNextSend = !options.failNextSendWithCode && !options.invalidNextSend;
30
+ let failNextSendWithCode = options.failNextSendWithCode;
31
+ let invalidNextSend = options.invalidNextSend;
32
+ const receipts = new Map();
33
+ const operations = new Map();
34
+ const sendHeaders = [];
35
+ const fetcher = async (resource, init) => {
36
+ const url = new URL(String(resource));
37
+ if (url.pathname.endsWith('/enrollments')) {
38
+ publicKey = JSON.parse(String(init?.body)).publicKeyEd25519;
39
+ return new Response(JSON.stringify({ ok: true, status: 'pending',
40
+ organizationId: orgId, repositoryId, deviceCode: 'B'.repeat(43),
41
+ expiresAt: new Date(Date.now() + 60_000).toISOString(),
42
+ verificationUri: `${hqUrl}/demo/fabric/approve?orgId=${orgId}&repositoryId=${repositoryId}&code=ABCDEF0123456789ABCD` }), { status: 202 });
43
+ }
44
+ if (url.pathname.endsWith('/poll')) {
45
+ return new Response(JSON.stringify({ ok: true, status: 'approved', deviceId, repositoryId }), { status: 200 });
46
+ }
47
+ const headers = new Headers(init?.headers);
48
+ const method = init?.method || 'GET';
49
+ const rawBody = String(init?.body || '');
50
+ const messageId = headers.get('x-dharma-message-id');
51
+ const requestSequence = Number(headers.get('x-dharma-sequence'));
52
+ const signedPayload = Buffer.from(JSON.stringify({
53
+ bodyHash: `sha256:${createHash('sha256').update(rawBody).digest('hex')}`,
54
+ deviceId, messageId, method, nonce: headers.get('x-dharma-nonce'),
55
+ organizationId: orgId, pathname: `${url.pathname}${url.search}`,
56
+ sequence: requestSequence, sessionId: headers.get('x-dharma-session-id'),
57
+ timestamp: headers.get('x-dharma-timestamp'),
58
+ }));
59
+ assert.equal(verify(null, signedPayload, createPublicKey({ key: { kty: 'OKP', crv: 'Ed25519', x: publicKey }, format: 'jwk' }), Buffer.from(headers.get('x-dharma-signature'), 'base64url')), true);
60
+ if (receipts.has(messageId)) {
61
+ const previous = receipts.get(messageId);
62
+ return new Response(JSON.stringify(previous), { status: 200 });
63
+ }
64
+ if (requestSequence !== sequence + 1) {
65
+ return new Response(JSON.stringify({ ok: false, error: {
66
+ code: 'demo_fabric_sequence_out_of_order', message: 'Device sequence is out of order.',
67
+ } }), { status: 409 });
68
+ }
69
+ sequence = requestSequence;
70
+ if (url.pathname.endsWith('/status')) {
71
+ const result = { ok: true, organizationId: orgId, repositoryId,
72
+ deviceId, normalizedRepository };
73
+ receipts.set(messageId, result);
74
+ return new Response(JSON.stringify(result), { status: 200 });
75
+ }
76
+ assert.equal(url.pathname, `/api/demo/fabric/repositories/${repositoryId}/messages`);
77
+ if (failNextSendWithCode) {
78
+ const code = failNextSendWithCode;
79
+ failNextSendWithCode = undefined;
80
+ return new Response(JSON.stringify({ ok: false, error: { code, message: 'Peer operation rejected.' } }), { status: 400 });
81
+ }
82
+ if (invalidNextSend) {
83
+ invalidNextSend = false;
84
+ return new Response(JSON.stringify({ ok: true }), { status: 200 });
85
+ }
86
+ const body = JSON.parse(rawBody);
87
+ assert.equal(body.kind, 'question');
88
+ sendHeaders.push(headers);
89
+ const prior = operations.get(body.operationId);
90
+ const id = prior || '50000000-0000-4000-8000-000000000001';
91
+ operations.set(body.operationId, id);
92
+ const result = { ok: true, message: { id, duplicate: Boolean(prior) } };
93
+ receipts.set(messageId, result);
94
+ if (loseNextSend) {
95
+ loseNextSend = false;
96
+ throw new Error('connection lost after send');
97
+ }
98
+ return new Response(JSON.stringify(result), { status: 200 });
99
+ };
100
+ return { fetcher, operations, sendHeaders, get sequence() { return sequence; } };
101
+ }
102
+ async function enrolled(options = {}) {
103
+ const stateRoot = await mkdtemp(resolve(tmpdir(), 'dharma-demo-peer-'));
104
+ const store = memoryStore();
105
+ const fixture = server(options);
106
+ const input = scope(stateRoot);
107
+ const connected = await connectDemoDevice({ ...input, grant: 'A'.repeat(43),
108
+ deviceName: 'Fixture device', platform: 'linux' }, { store, fetcher: fixture.fetcher, sleep: async () => { } });
109
+ assert.equal(connected.stage, 'device_signed_ready');
110
+ return { fixture, input, store, configPath: connected.configPath };
111
+ }
112
+ test('a lost peer response replays the exact signed request without creating another question', async () => {
113
+ const { fixture, input, store, configPath } = await enrolled();
114
+ const action = { kind: 'ask', recipientDeviceId, content: 'Which approved mapping?' };
115
+ await assert.rejects(performDemoPeerAction(input, action, { store, fetcher: fixture.fetcher }), /connection lost after send/);
116
+ const recovered = await performDemoPeerAction(input, action, { store, fetcher: fixture.fetcher });
117
+ assert.equal(recovered.stage, 'demo_peer_operation');
118
+ assert.equal(recovered.resumed, true);
119
+ assert.equal(fixture.operations.size, 1);
120
+ assert.equal(fixture.sendHeaders.length, 1);
121
+ assert.equal(fixture.sequence, 3);
122
+ assert.equal(JSON.parse(await readFile(configPath, 'utf8')).nextSequence, 4);
123
+ });
124
+ test('an expired signed peer request recovers sequence and reissues one logical operation', async () => {
125
+ const { fixture, input, store, configPath } = await enrolled();
126
+ const action = { kind: 'ask', recipientDeviceId, content: 'Which approved mapping?' };
127
+ await assert.rejects(performDemoPeerAction(input, action, { store, fetcher: fixture.fetcher }), /connection lost after send/);
128
+ const pendingPath = `${configPath}.pending-peer.json`;
129
+ const pending = JSON.parse(await readFile(pendingPath, 'utf8'));
130
+ pending.request.createdAt = new Date(Date.now() - 5 * 60_000).toISOString();
131
+ await writeFile(pendingPath, JSON.stringify(pending));
132
+ const recovered = await performDemoPeerAction(input, action, { store, fetcher: fixture.fetcher });
133
+ assert.equal(recovered.stage, 'demo_peer_operation');
134
+ assert.equal(recovered.resumed, true);
135
+ assert.equal(recovered.message.duplicate, true);
136
+ assert.equal(fixture.operations.size, 1);
137
+ assert.equal(fixture.sendHeaders.length, 2);
138
+ assert.notEqual(fixture.sendHeaders[0].get('x-dharma-message-id'), fixture.sendHeaders[1].get('x-dharma-message-id'));
139
+ assert.equal(fixture.sequence, 5);
140
+ assert.equal(JSON.parse(await readFile(configPath, 'utf8')).nextSequence, 6);
141
+ });
142
+ test('a typed post-acceptance rejection reconciles sequence and clears the failed operation', async () => {
143
+ const { fixture, input, store, configPath } = await enrolled({
144
+ failNextSendWithCode: 'demo_fabric_peer_invalid',
145
+ });
146
+ await assert.rejects(performDemoPeerAction(input, { kind: 'ask',
147
+ recipientDeviceId, content: 'Invalid on server' }, { store, fetcher: fixture.fetcher }), /demo_fabric_peer_invalid/);
148
+ assert.equal(fixture.sequence, 4);
149
+ assert.equal(JSON.parse(await readFile(configPath, 'utf8')).nextSequence, 5);
150
+ await assert.rejects(stat(`${configPath}.pending-peer.json`), { code: 'ENOENT' });
151
+ });
152
+ test('an incomplete 200 response cannot be reported as a completed peer operation', async () => {
153
+ const { fixture, input, store, configPath } = await enrolled({ invalidNextSend: true });
154
+ await assert.rejects(performDemoPeerAction(input, { kind: 'ask',
155
+ recipientDeviceId, content: 'Which approved mapping?' }, { store, fetcher: fixture.fetcher }), /expected command receipt/);
156
+ assert.equal(fixture.operations.size, 0);
157
+ assert.equal(fixture.sequence, 3);
158
+ await stat(`${configPath}.pending-peer.json`);
159
+ });
160
+ test('a tampered pending URL cannot receive signed device headers', async () => {
161
+ const { fixture, input, store, configPath } = await enrolled();
162
+ const action = { kind: 'ask', recipientDeviceId, content: 'Which mapping?' };
163
+ await assert.rejects(performDemoPeerAction(input, action, { store, fetcher: fixture.fetcher }), /connection lost after send/);
164
+ const pendingPath = `${configPath}.pending-peer.json`;
165
+ const pending = JSON.parse(await readFile(pendingPath, 'utf8'));
166
+ pending.request.url = 'https://attacker.example/collect';
167
+ await writeFile(pendingPath, JSON.stringify(pending));
168
+ await assert.rejects(performDemoPeerAction(input, action, { store, fetcher: fixture.fetcher }), /does not match this signed repository/);
169
+ assert.equal(fixture.sequence, 3);
170
+ });
171
+ test('the CLI lock rejects overlapping Demo operations on one local device', async () => {
172
+ const stateRoot = await mkdtemp(resolve(tmpdir(), 'dharma-demo-peer-lock-'));
173
+ const input = scope(stateRoot);
174
+ let release;
175
+ const first = withDemoDeviceLock(input, () => new Promise((done) => { release = done; }));
176
+ const lockPath = `${scopePath(input, hqUrl)}.lock`;
177
+ for (let attempts = 0; attempts < 20; attempts += 1) {
178
+ try {
179
+ await stat(lockPath);
180
+ break;
181
+ }
182
+ catch {
183
+ await new Promise((done) => setTimeout(done, 10));
184
+ }
185
+ }
186
+ await assert.rejects(withDemoDeviceLock(input, async () => 'overlap'), /busy/);
187
+ release?.();
188
+ await first;
189
+ assert.equal(await withDemoDeviceLock(input, async () => 'available'), 'available');
190
+ });
191
+ //# sourceMappingURL=demoPeer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demoPeer.test.js","sourceRoot":"","sources":["../src/demoPeer.test.ts"],"names":[],"mappings":"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"}