@dharma-ai-labs/agent-fabric 0.2.87 → 0.2.88
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.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -7
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +71 -3
- package/dist/index.test.js.map +1 -1
- package/package.json +2 -2
package/dist/index.test.js
CHANGED
|
@@ -9,7 +9,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
9
9
|
import { promisify } from 'node:util';
|
|
10
10
|
import { acceptedTrajectoryHead, activateAgyPlugin, attestAgySkillActivation, attestHermesSkillBundleActivation, actionDecisionCapabilityFreshUntil, canonicalFilesystemPath, controlAgentDecisionUrl, installAvailableNativeAgentFabricBootstraps, assertCapsuleAuthorizedByCurrentPolicy, assertRecoveredTaskWorkspacePolicy, assertTaskWorkspacePolicy, assertTaskSkillPin, installNativeAgentFabricBootstrap, installClaudeReadOnlyProjectPermissions, installRepositoryAgentFabricSkill, isDirectExecution, isTransientBootstrapError, loadAgentFabricOnboardingContract, loadOrCreateInstallationId, materializeWorkspacePolicy, applyServerEvidencePolicy, materializeInlineSkillFiles, validateSkillBundleSources, nativeSkillDirectory, nativeSkillDirectoryForWorkspace, nativeSkillRootMatchingAuthorization, normalizeGitRemoteIdentity, postTaskOutcome, parseCliOptions, parseSelectedProviderIds, pathExistsOrThrow, portalUrl, providerHintFromEnvironment, providerHintFromProcessArgv, probeRelayConnection, preflightBootstrapWorkspaceIdentity, rawLocalRetentionDays, syncPendingRetentionCapsules, requireCompletedBootstrapEvidence, retryBootstrapOnboarding, synchronizeBootstrapEvidence, deferUnavailableRelayRetention, recoverLegacySkillBundleIdAfterAuthorizationFailure, installedBundleIdForSkillPollAfterAuthorizationFailure, recoveredTaskPolicyWasSuperseded, relayProcessState, releaseDailyContentUpload, reserveDailyContentUpload, run, runAssistantCommand, sourceRepositoryFingerprint, stableRepositoryLauncherContents, summarizeBootstrapOrganizationApi, ensureAgyReadOnlyAttestationPermission, attestAgySkillBundleActivation, responseTextFromEvent, taskResponsePreview, taskReceiptSession, taskSkillPinFailureCode, verifyAgentFabricSkillInstallation, waitForRelayReadiness, withWorkspacePolicyRefreshLock, withWorkspaceSkillActivationLock, } from './index.js';
|
|
11
11
|
import { canonicalize, signCanonicalObject } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
12
|
-
import { buildTrajectoryCapsule } from '@dharma-ai-labs/agent-fabric-evidence-reduction';
|
|
12
|
+
import { buildTrajectoryCapsule, trajectoryCapsuleHash } from '@dharma-ai-labs/agent-fabric-evidence-reduction';
|
|
13
13
|
import { CLI_USAGE } from './usage.js';
|
|
14
14
|
import { isSupportedNodeVersion, launchWithRuntime, nodeRuntimeCandidates, runtimeBootstrapHint, } from './runtime-bootstrap.js';
|
|
15
15
|
test('installation identity is durable per DHARMA_HOME and rejects corrupt state', async () => {
|
|
@@ -1404,6 +1404,74 @@ test('oversized queued current-device revision is retired only after checking th
|
|
|
1404
1404
|
await assert.rejects(() => syncPendingRetentionCapsules(vault, fabric, policyWithSmallerCap, 'workspace-northstar'), /conflicts with the accepted server head/);
|
|
1405
1405
|
assert.equal(pending.length, 1);
|
|
1406
1406
|
});
|
|
1407
|
+
test('queued native recipient paths retire only an unsent revision without uploading it', async () => {
|
|
1408
|
+
const workspace = await mkdtemp(join(tmpdir(), 'dharma-recipient-path-capsule-'));
|
|
1409
|
+
const signed = signedPolicyAuthorization({
|
|
1410
|
+
revision: 'content-v1', evidence: {
|
|
1411
|
+
automaticDisclosure: { mode: 'customer_authorized_content', consentReceiptId: 'consent-recipient', allowedContentClasses: ['native_provider_payload'] },
|
|
1412
|
+
maximumCapsuleBytes: 500_000, maximumDailyUploadBytes: 50_000_000,
|
|
1413
|
+
},
|
|
1414
|
+
});
|
|
1415
|
+
const base = await materializeWorkspacePolicy({
|
|
1416
|
+
workspace, organizationId: 'org_northstar', revision: 'portal-bootstrap',
|
|
1417
|
+
serverPolicyAuthorization: signed.envelope, serverPublicKeyEd25519: signed.publicKeyEd25519,
|
|
1418
|
+
workspaceId: 'workspace-northstar', secureStore: memorySecureStore(),
|
|
1419
|
+
});
|
|
1420
|
+
const capsule = buildTrajectoryCapsule({
|
|
1421
|
+
organizationId: 'org_northstar', deviceId: '22222222-2222-4222-8222-222222222222',
|
|
1422
|
+
workspaceId: 'workspace-northstar', policy: base.policy,
|
|
1423
|
+
session: {
|
|
1424
|
+
provider: 'codex', sessionId: 'recipient-path-pending', sourcePath: '/private/codex.jsonl',
|
|
1425
|
+
workspace: '/repo', coverage: 'observed', startedAt: '2026-09-24T00:00:00.000Z',
|
|
1426
|
+
endedAt: '2026-09-24T00:00:01.000Z',
|
|
1427
|
+
records: [{ native: { type: 'tool_call', payload: { recipient: 'peer' } }, sourcePath: '/private/codex.jsonl',
|
|
1428
|
+
line: 1, workspace: '/repo', timestamp: '2026-09-24T00:00:00.000Z', kind: 'tool_call' }],
|
|
1429
|
+
},
|
|
1430
|
+
rawContentId: `sha256:${'b'.repeat(64)}`, rawBytes: 32,
|
|
1431
|
+
});
|
|
1432
|
+
const native = capsule.events[0].payload.nativeProviderPayload;
|
|
1433
|
+
native.payload.recipient = '/home';
|
|
1434
|
+
capsule.capsuleHash = trajectoryCapsuleHash(capsule);
|
|
1435
|
+
const pending = [{ trajectoryId: capsule.trajectoryId, revision: 1, capsule }];
|
|
1436
|
+
const discarded = [];
|
|
1437
|
+
let synced = 0;
|
|
1438
|
+
let head = null;
|
|
1439
|
+
let unavailable = false;
|
|
1440
|
+
const vault = {
|
|
1441
|
+
listPendingCapsuleSyncs: async () => [...pending],
|
|
1442
|
+
markCapsuleSynced: () => { synced += 1; pending.length = 0; },
|
|
1443
|
+
discardPendingCapsuleSync: (_trajectoryId, _revision, reason) => {
|
|
1444
|
+
discarded.push(reason);
|
|
1445
|
+
pending.length = 0;
|
|
1446
|
+
},
|
|
1447
|
+
};
|
|
1448
|
+
const fabric = {
|
|
1449
|
+
config: { organizationId: 'org_northstar', deviceId: capsule.deviceId },
|
|
1450
|
+
getTrajectoryHead: async () => {
|
|
1451
|
+
if (unavailable)
|
|
1452
|
+
throw new Error('provider unavailable');
|
|
1453
|
+
return { trajectoryId: capsule.trajectoryId, head };
|
|
1454
|
+
},
|
|
1455
|
+
syncTrajectory: async () => { throw new Error('path-bearing capsule must not be uploaded'); },
|
|
1456
|
+
};
|
|
1457
|
+
assert.equal(await syncPendingRetentionCapsules(vault, fabric, base.policy, 'workspace-northstar'), 0);
|
|
1458
|
+
assert.deepEqual(discarded, ['local_path_disclosure_superseded']);
|
|
1459
|
+
assert.equal(synced, 0);
|
|
1460
|
+
assert.equal(native.payload.recipient, '/home');
|
|
1461
|
+
pending.push({ trajectoryId: capsule.trajectoryId, revision: 1, capsule });
|
|
1462
|
+
head = { revision: 1, capsuleHash: capsule.capsuleHash };
|
|
1463
|
+
assert.equal(await syncPendingRetentionCapsules(vault, fabric, base.policy, 'workspace-northstar'), 1);
|
|
1464
|
+
assert.equal(synced, 1);
|
|
1465
|
+
assert.deepEqual(discarded, ['local_path_disclosure_superseded']);
|
|
1466
|
+
pending.push({ trajectoryId: capsule.trajectoryId, revision: 1, capsule });
|
|
1467
|
+
head = { revision: 2, capsuleHash: capsule.capsuleHash };
|
|
1468
|
+
await assert.rejects(() => syncPendingRetentionCapsules(vault, fabric, base.policy, 'workspace-northstar'), /conflicts with the accepted server head/);
|
|
1469
|
+
assert.equal(pending.length, 1);
|
|
1470
|
+
head = null;
|
|
1471
|
+
unavailable = true;
|
|
1472
|
+
await assert.rejects(() => syncPendingRetentionCapsules(vault, fabric, base.policy, 'workspace-northstar'), /provider unavailable/);
|
|
1473
|
+
assert.equal(pending.length, 1);
|
|
1474
|
+
});
|
|
1407
1475
|
test('recovered task evidence distinguishes a superseded policy from the current revision', () => {
|
|
1408
1476
|
const capsule = { redactionReceipt: { policyRevision: 'policy-v1' } };
|
|
1409
1477
|
assert.equal(recoveredTaskPolicyWasSuperseded(capsule, { revision: 'policy-v2' }), true);
|
|
@@ -1684,13 +1752,13 @@ test('relay probe opens an authenticated session without polling or leasing work
|
|
|
1684
1752
|
},
|
|
1685
1753
|
openSession: async (version) => {
|
|
1686
1754
|
sessions += 1;
|
|
1687
|
-
assert.equal(version, '0.2.
|
|
1755
|
+
assert.equal(version, '0.2.88');
|
|
1688
1756
|
return { ok: true };
|
|
1689
1757
|
},
|
|
1690
1758
|
}));
|
|
1691
1759
|
assert.equal(sessions, 1);
|
|
1692
1760
|
assert.deepEqual(result, {
|
|
1693
|
-
ok: true, connected: true, organizationId: 'org_test', deviceId: 'device_test', relayVersion: '0.2.
|
|
1761
|
+
ok: true, connected: true, organizationId: 'org_test', deviceId: 'device_test', relayVersion: '0.2.88',
|
|
1694
1762
|
});
|
|
1695
1763
|
});
|
|
1696
1764
|
test('relay probe fails closed when the server does not acknowledge the session', async () => {
|