@dharma-ai-labs/agent-fabric 0.2.120 → 0.2.121

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,167 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { lstat, mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises';
3
+ import { dirname, resolve } from 'node:path';
4
+ function object(value) {
5
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : null;
6
+ }
7
+ function unique(rows, predicate, code) {
8
+ const matching = rows.map(object).filter((row) => Boolean(row && predicate(row)));
9
+ if (matching.length !== 1)
10
+ throw new Error(code);
11
+ return matching[0];
12
+ }
13
+ export function resolveRegistryRecoveryProjection(input) {
14
+ const workspaces = object(input.workspaces);
15
+ const agents = object(input.repositoryAgents);
16
+ if (workspaces?.ok !== true || workspaces.organizationId !== input.organizationId
17
+ || !Array.isArray(workspaces.workspaces)
18
+ || agents?.ok !== true || agents.organizationId !== input.organizationId
19
+ || !Array.isArray(agents.repositoryAgents)) {
20
+ throw new Error('registry_recovery_server_scope_mismatch');
21
+ }
22
+ const workspace = unique(workspaces.workspaces, row => row.id === input.workspaceId, 'registry_recovery_workspace_missing_or_ambiguous');
23
+ if (workspace.device_id !== input.deviceId || workspace.status !== 'active'
24
+ || workspace.policy_revision !== input.policyRevision
25
+ || typeof workspace.repository_binding_id !== 'string') {
26
+ throw new Error('registry_recovery_workspace_authority_mismatch');
27
+ }
28
+ const binding = unique(agents.repositoryAgents, row => row.id === workspace.repository_binding_id, 'registry_recovery_binding_missing_or_ambiguous');
29
+ if (binding.status !== 'active'
30
+ || binding.source_repository_fingerprint !== input.repositoryFingerprint
31
+ || typeof binding.organization_agent_id !== 'string'
32
+ || typeof binding.control_branch !== 'string' || !binding.control_branch) {
33
+ throw new Error('registry_recovery_repository_mismatch');
34
+ }
35
+ const agent = object(binding.agent);
36
+ if (!agent || agent.id !== binding.organization_agent_id
37
+ || typeof agent.agent_key !== 'string' || !agent.agent_key) {
38
+ throw new Error('registry_recovery_agent_mismatch');
39
+ }
40
+ if (!Array.isArray(binding.workspaces)
41
+ || !binding.workspaces.some(value => {
42
+ const row = object(value);
43
+ return row?.id === input.workspaceId && row.device_id === input.deviceId
44
+ && row.repository_binding_id === binding.id && row.status === 'active';
45
+ })) {
46
+ throw new Error('registry_recovery_binding_workspace_mismatch');
47
+ }
48
+ const endpoints = Array.isArray(binding.endpoints) ? binding.endpoints : [];
49
+ const matchingEndpoints = endpoints.map(object).filter((row) => Boolean(row
50
+ && row.workspace_id === input.workspaceId && row.device_id === input.deviceId
51
+ && row.organization_agent_id === binding.organization_agent_id && row.status === 'active'));
52
+ if (matchingEndpoints.length > 1)
53
+ throw new Error('registry_recovery_endpoint_ambiguous');
54
+ return {
55
+ repositoryBindingId: binding.id,
56
+ repositoryAgentId: binding.organization_agent_id,
57
+ repositoryAgentKey: agent.agent_key,
58
+ controlBranch: binding.control_branch,
59
+ endpointId: typeof matchingEndpoints[0]?.id === 'string' ? matchingEndpoints[0].id : null,
60
+ name: typeof workspace.name === 'string' && workspace.name ? workspace.name : null,
61
+ defaultBranch: typeof workspace.default_branch === 'string' ? workspace.default_branch : null,
62
+ };
63
+ }
64
+ export function appendRecoveredWorkspace(records, recovered) {
65
+ if (records.some(row => !row || typeof row.workspaceId !== 'string'
66
+ || typeof row.organizationId !== 'string' || typeof row.path !== 'string')) {
67
+ throw new Error('registry_recovery_existing_rows_invalid');
68
+ }
69
+ if (records.some(row => row.organizationId !== recovered.organizationId)) {
70
+ throw new Error('registry_recovery_foreign_organization');
71
+ }
72
+ const matches = records.filter(row => row.workspaceId === recovered.workspaceId || row.path === recovered.path);
73
+ if (matches.length > 1)
74
+ throw new Error('registry_recovery_existing_rows_ambiguous');
75
+ if (matches.length === 1) {
76
+ const row = matches[0];
77
+ if (row.workspaceId !== recovered.workspaceId || row.path !== recovered.path
78
+ || row.organizationId !== recovered.organizationId
79
+ || row.repositoryRemoteHash !== recovered.repositoryRemoteHash) {
80
+ throw new Error('registry_recovery_existing_row_conflict');
81
+ }
82
+ return { records: [...records], alreadyPresent: true };
83
+ }
84
+ return { records: [...records, recovered], alreadyPresent: false };
85
+ }
86
+ export async function inspectRegistryRecoveryFile(path) {
87
+ let bytes = null;
88
+ try {
89
+ const metadata = await lstat(path);
90
+ if (!metadata.isFile() || metadata.isSymbolicLink() || metadata.nlink !== 1) {
91
+ throw new Error('registry_recovery_registry_file_unsafe');
92
+ }
93
+ bytes = await readFile(path);
94
+ }
95
+ catch (error) {
96
+ if (error.code !== 'ENOENT')
97
+ throw error;
98
+ }
99
+ let records = [];
100
+ if (bytes && bytes.length > 0) {
101
+ let parsed;
102
+ try {
103
+ parsed = JSON.parse(bytes.toString('utf8'));
104
+ }
105
+ catch {
106
+ throw new Error('registry_recovery_nonempty_registry_invalid');
107
+ }
108
+ if (!Array.isArray(parsed))
109
+ throw new Error('registry_recovery_nonempty_registry_invalid');
110
+ records = parsed;
111
+ }
112
+ return {
113
+ kind: bytes === null ? 'absent' : bytes.length === 0 ? 'corrupt_zero' : 'valid',
114
+ bytes, records,
115
+ hash: bytes === null ? null : `sha256:${createHash('sha256').update(bytes).digest('hex')}`,
116
+ };
117
+ }
118
+ export async function backupRegistryRecoveryFile(input) {
119
+ if (input.expectedBytes === null)
120
+ return null;
121
+ const directory = resolve(input.home, 'registry', 'recovery-backups');
122
+ await mkdir(directory, { recursive: true, mode: 0o700 });
123
+ if (!(await lstat(directory)).isDirectory())
124
+ throw new Error('registry_recovery_backup_directory_unsafe');
125
+ const backup = resolve(directory, `workspaces-${Date.now()}-${randomUUID()}.bin`);
126
+ await writeFile(backup, input.expectedBytes, { flag: 'wx', mode: 0o600 });
127
+ const current = await readFile(input.path);
128
+ if (!current.equals(input.expectedBytes))
129
+ throw new Error('registry_recovery_registry_changed');
130
+ return backup;
131
+ }
132
+ export async function applyRegistryRecoveryFile(input) {
133
+ const current = await inspectRegistryRecoveryFile(input.path);
134
+ if (current.kind !== input.expectedKind || current.hash !== input.expectedHash) {
135
+ throw new Error('registry_recovery_registry_changed');
136
+ }
137
+ const final = appendRecoveredWorkspace(current.records, input.entry);
138
+ if (final.alreadyPresent)
139
+ return { state: 'already_present', backup: null,
140
+ previousHash: current.hash, restoredCount: final.records.length };
141
+ const backup = await backupRegistryRecoveryFile({ home: input.home, path: input.path,
142
+ expectedBytes: current.bytes });
143
+ const temporary = `${input.path}.${process.pid}.${randomUUID()}.tmp`;
144
+ await mkdir(dirname(input.path), { recursive: true, mode: 0o700 });
145
+ try {
146
+ await writeFile(temporary, `${JSON.stringify(final.records, null, 2)}\n`, { flag: 'wx', mode: 0o600 });
147
+ const beforeReplace = await inspectRegistryRecoveryFile(input.path);
148
+ if (beforeReplace.kind !== current.kind || beforeReplace.hash !== current.hash) {
149
+ throw new Error('registry_recovery_registry_changed');
150
+ }
151
+ await rename(temporary, input.path);
152
+ }
153
+ finally {
154
+ await unlink(temporary).catch(error => {
155
+ if (error.code !== 'ENOENT')
156
+ throw error;
157
+ });
158
+ }
159
+ const confirmed = await inspectRegistryRecoveryFile(input.path);
160
+ if (confirmed.kind !== 'valid' || confirmed.records.length !== final.records.length
161
+ || !confirmed.records.some(row => row.workspaceId === input.entry.workspaceId && row.path === input.entry.path)) {
162
+ throw new Error('registry_recovery_write_unconfirmed');
163
+ }
164
+ return { state: 'recovered', backup, previousHash: current.hash,
165
+ restoredCount: confirmed.records.length };
166
+ }
167
+ //# sourceMappingURL=workspaceRegistryRecovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceRegistryRecovery.js","sourceRoot":"","sources":["../src/workspaceRegistryRecovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=workspaceRegistryRecovery.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceRegistryRecovery.test.d.ts","sourceRoot":"","sources":["../src/workspaceRegistryRecovery.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,111 @@
1
+ import assert from 'node:assert/strict';
2
+ import { link, mkdtemp, mkdir, readFile, symlink, writeFile } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import test from 'node:test';
6
+ import { appendRecoveredWorkspace, applyRegistryRecoveryFile, backupRegistryRecoveryFile, inspectRegistryRecoveryFile, resolveRegistryRecoveryProjection } from './workspaceRegistryRecovery.js';
7
+ const scope = { organizationId: 'org_test', deviceId: 'device_test', workspaceId: 'workspace_test',
8
+ policyRevision: 'policy_test', repositoryFingerprint: 'sha256:source' };
9
+ const workspaces = { ok: true, organizationId: scope.organizationId, workspaces: [{
10
+ id: scope.workspaceId, device_id: scope.deviceId, status: 'active', repository_binding_id: 'binding_test',
11
+ name: 'repo', default_branch: 'main', policy_revision: scope.policyRevision,
12
+ }] };
13
+ const repositoryAgents = { ok: true, organizationId: scope.organizationId, repositoryAgents: [{
14
+ id: 'binding_test', status: 'active', source_repository_fingerprint: scope.repositoryFingerprint,
15
+ organization_agent_id: 'agent_test', control_branch: 'agent-fabric/control',
16
+ agent: { id: 'agent_test', agent_key: 'repo-key' },
17
+ workspaces: [{ id: scope.workspaceId, device_id: scope.deviceId, repository_binding_id: 'binding_test', status: 'active' }],
18
+ endpoints: [{ id: 'endpoint_test', workspace_id: scope.workspaceId, device_id: scope.deviceId,
19
+ organization_agent_id: 'agent_test', status: 'active' }],
20
+ }] };
21
+ test('registry recovery accepts only one current-device canonical binding', () => {
22
+ assert.deepEqual(resolveRegistryRecoveryProjection({ ...scope, workspaces, repositoryAgents }), {
23
+ repositoryBindingId: 'binding_test', repositoryAgentId: 'agent_test', repositoryAgentKey: 'repo-key',
24
+ controlBranch: 'agent-fabric/control', endpointId: 'endpoint_test', name: 'repo', defaultBranch: 'main',
25
+ });
26
+ });
27
+ test('registry recovery rejects foreign, revoked, duplicate and mismatched projections', () => {
28
+ const resolve = (workspaceRows, agentRows) => resolveRegistryRecoveryProjection({ ...scope, workspaces: workspaceRows, repositoryAgents: agentRows });
29
+ assert.throws(() => resolve({ ...workspaces, organizationId: 'org_other' }, repositoryAgents), /scope_mismatch/);
30
+ assert.throws(() => resolve({ ...workspaces, workspaces: [workspaces.workspaces[0], workspaces.workspaces[0]] }, repositoryAgents), /workspace_missing_or_ambiguous/);
31
+ assert.throws(() => resolve({ ...workspaces, workspaces: [{ ...workspaces.workspaces[0], device_id: 'foreign' }] }, repositoryAgents), /workspace_authority_mismatch/);
32
+ assert.throws(() => resolve({ ...workspaces, workspaces: [{ ...workspaces.workspaces[0], status: 'revoked' }] }, repositoryAgents), /workspace_authority_mismatch/);
33
+ assert.throws(() => resolve({ ...workspaces, workspaces: [{ ...workspaces.workspaces[0], policy_revision: 'newer' }] }, repositoryAgents), /workspace_authority_mismatch/);
34
+ const binding = repositoryAgents.repositoryAgents[0];
35
+ assert.throws(() => resolve(workspaces, { ...repositoryAgents, repositoryAgents: [{ ...binding,
36
+ source_repository_fingerprint: 'sha256:other' }] }), /repository_mismatch/);
37
+ assert.throws(() => resolve(workspaces, { ...repositoryAgents, repositoryAgents: [{ ...binding,
38
+ workspaces: [] }] }), /binding_workspace_mismatch/);
39
+ assert.throws(() => resolve(workspaces, { ...repositoryAgents, repositoryAgents: [{ ...binding,
40
+ endpoints: [binding.endpoints[0], binding.endpoints[0]] }] }), /endpoint_ambiguous/);
41
+ });
42
+ test('registry recovery appends without overwriting another workspace or foreign state', () => {
43
+ const first = { workspaceId: 'first', organizationId: 'org_test', path: '/first', repositoryRemoteHash: 'sha256:first' };
44
+ const second = { workspaceId: 'second', organizationId: 'org_test', path: '/second', repositoryRemoteHash: 'sha256:second' };
45
+ assert.deepEqual(appendRecoveredWorkspace([first], second), { records: [first, second], alreadyPresent: false });
46
+ assert.deepEqual(appendRecoveredWorkspace([first], first), { records: [first], alreadyPresent: true });
47
+ assert.throws(() => appendRecoveredWorkspace([first], { ...second, path: '/first' }), /existing_row_conflict/);
48
+ assert.throws(() => appendRecoveredWorkspace([first, first], first), /existing_rows_ambiguous/);
49
+ assert.throws(() => appendRecoveredWorkspace([{ ...first, organizationId: 'foreign' }], second), /foreign_organization/);
50
+ });
51
+ test('registry recovery preserves zero-byte evidence and rejects changed files', async () => {
52
+ const home = await mkdtemp(join(tmpdir(), 'registry-recovery-'));
53
+ const directory = join(home, 'registry');
54
+ await mkdir(directory);
55
+ const path = join(directory, 'workspaces.json');
56
+ await writeFile(path, '');
57
+ const snapshot = await inspectRegistryRecoveryFile(path);
58
+ assert.equal(snapshot.kind, 'corrupt_zero');
59
+ assert.equal(snapshot.hash, 'sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
60
+ const backup = await backupRegistryRecoveryFile({ home, path, expectedBytes: snapshot.bytes });
61
+ assert.ok(backup);
62
+ assert.equal((await readFile(backup)).length, 0);
63
+ assert.equal((await readFile(path)).length, 0);
64
+ await writeFile(path, '[]');
65
+ await assert.rejects(backupRegistryRecoveryFile({ home, path, expectedBytes: snapshot.bytes }), /registry_recovery_registry_changed/);
66
+ assert.equal((await inspectRegistryRecoveryFile(path)).kind, 'valid');
67
+ await writeFile(path, '{');
68
+ await assert.rejects(inspectRegistryRecoveryFile(path), /registry_recovery_nonempty_registry_invalid/);
69
+ assert.equal((await readFile(path, 'utf8')), '{');
70
+ });
71
+ test('registry recovery refuses symlinked registry and does not follow its target', async () => {
72
+ const home = await mkdtemp(join(tmpdir(), 'registry-recovery-link-'));
73
+ const target = join(home, 'target.json');
74
+ await writeFile(target, '[]');
75
+ await mkdir(join(home, 'registry'));
76
+ await symlink(target, join(home, 'registry', 'workspaces.json'));
77
+ await assert.rejects(inspectRegistryRecoveryFile(join(home, 'registry', 'workspaces.json')), /registry_recovery_registry_file_unsafe/);
78
+ assert.equal(await readFile(target, 'utf8'), '[]');
79
+ });
80
+ test('registry recovery refuses a hardlinked registry file', async () => {
81
+ const home = await mkdtemp(join(tmpdir(), 'registry-recovery-hardlink-'));
82
+ const target = join(home, 'target.json');
83
+ await writeFile(target, '[]');
84
+ await mkdir(join(home, 'registry'));
85
+ await link(target, join(home, 'registry', 'workspaces.json'));
86
+ await assert.rejects(inspectRegistryRecoveryFile(join(home, 'registry', 'workspaces.json')), /registry_recovery_registry_file_unsafe/);
87
+ assert.equal(await readFile(target, 'utf8'), '[]');
88
+ });
89
+ test('registry recovery applies one row atomically and preserves the corrupt file', async () => {
90
+ const home = await mkdtemp(join(tmpdir(), 'registry-recovery-apply-'));
91
+ const directory = join(home, 'registry');
92
+ await mkdir(directory);
93
+ const path = join(directory, 'workspaces.json');
94
+ await writeFile(path, '');
95
+ const entry = { workspaceId: 'anchor', organizationId: 'org_test', path: '/anchor',
96
+ repositoryRemoteHash: 'sha256:source' };
97
+ const expectedHash = (await inspectRegistryRecoveryFile(path)).hash;
98
+ const applied = await applyRegistryRecoveryFile({ home, path, expectedKind: 'corrupt_zero', expectedHash, entry });
99
+ assert.equal(applied.state, 'recovered');
100
+ assert.ok(applied.backup);
101
+ assert.equal((await readFile(applied.backup)).length, 0);
102
+ assert.deepEqual(JSON.parse(await readFile(path, 'utf8')), [entry]);
103
+ await assert.rejects(applyRegistryRecoveryFile({ home, path, expectedKind: 'corrupt_zero', expectedHash, entry }), /registry_recovery_registry_changed/);
104
+ const second = { ...entry, workspaceId: 'second', path: '/second' };
105
+ const currentHash = (await inspectRegistryRecoveryFile(path)).hash;
106
+ const added = await applyRegistryRecoveryFile({ home, path, expectedKind: 'valid', expectedHash: currentHash,
107
+ entry: second });
108
+ assert.equal(added.restoredCount, 2);
109
+ assert.deepEqual(JSON.parse(await readFile(path, 'utf8')), [entry, second]);
110
+ });
111
+ //# sourceMappingURL=workspaceRegistryRecovery.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceRegistryRecovery.test.js","sourceRoot":"","sources":["../src/workspaceRegistryRecovery.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dharma-ai-labs/agent-fabric",
3
- "version": "0.2.120",
3
+ "version": "0.2.121",
4
4
  "description": "Local-first CLI for connecting coding agents to Dharma evaluation, orchestration, and signed Skill delivery",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/dharma-ai-labs/dharma-agent-fabric/tree/main/packages/cli#readme",