@dharma-ai-labs/agent-fabric 0.2.74 → 0.2.76

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.
@@ -7,7 +7,7 @@ import { join } from 'node:path';
7
7
  import test from 'node:test';
8
8
  import { fileURLToPath, pathToFileURL } from 'node:url';
9
9
  import { promisify } from 'node:util';
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, normalizeGitRemoteIdentity, postTaskOutcome, parseCliOptions, parseSelectedProviderIds, pathExistsOrThrow, portalUrl, providerHintFromEnvironment, providerHintFromProcessArgv, probeRelayConnection, preflightBootstrapWorkspaceIdentity, rawLocalRetentionDays, 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';
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, 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
12
  import { buildTrajectoryCapsule } from '@dharma-ai-labs/agent-fabric-evidence-reduction';
13
13
  import { CLI_USAGE } from './usage.js';
@@ -1570,13 +1570,13 @@ test('relay probe opens an authenticated session without polling or leasing work
1570
1570
  },
1571
1571
  openSession: async (version) => {
1572
1572
  sessions += 1;
1573
- assert.equal(version, '0.2.74');
1573
+ assert.equal(version, '0.2.76');
1574
1574
  return { ok: true };
1575
1575
  },
1576
1576
  }));
1577
1577
  assert.equal(sessions, 1);
1578
1578
  assert.deepEqual(result, {
1579
- ok: true, connected: true, organizationId: 'org_test', deviceId: 'device_test', relayVersion: '0.2.74',
1579
+ ok: true, connected: true, organizationId: 'org_test', deviceId: 'device_test', relayVersion: '0.2.76',
1580
1580
  });
1581
1581
  });
1582
1582
  test('relay probe fails closed when the server does not acknowledge the session', async () => {
@@ -1791,6 +1791,38 @@ test('a second Codex workspace uses its repository skill without replacing the f
1791
1791
  assert.equal(await readFile(join(projectSkill, 'SKILL.md'), 'utf8'), '# Second signed workspace\n');
1792
1792
  assert.equal(await readFile(join(globalSkill, 'SKILL.md'), 'utf8'), '# First signed workspace\n');
1793
1793
  });
1794
+ test('duplicate native skill roots select the receipt pinned by protected authorization', async () => {
1795
+ const root = await mkdtemp(join(tmpdir(), 'dharma-duplicate-native-roots-'));
1796
+ const globalRoot = join(root, 'global');
1797
+ const projectRoot = join(root, 'project');
1798
+ const workspaceId = 'workspace_shared';
1799
+ const oldBundleId = '11111111-1111-4111-8111-111111111111';
1800
+ const currentBundleId = '22222222-2222-4222-8222-222222222222';
1801
+ const oldHash = `sha256:${'a'.repeat(64)}`;
1802
+ const currentHash = `sha256:${'b'.repeat(64)}`;
1803
+ const writeReceipt = async (nativeRoot, bundleId, receiptHash) => {
1804
+ const managed = join(nativeRoot, '.dharma-managed', 'workspaces', workspaceId);
1805
+ await mkdir(join(managed, 'active'), { recursive: true });
1806
+ await writeFile(join(managed, 'ACTIVE_BUNDLE'), bundleId);
1807
+ await writeFile(join(managed, 'active', 'INSTALL_RECEIPT.json'), JSON.stringify({ bundleId, receiptHash }));
1808
+ };
1809
+ await writeReceipt(globalRoot, oldBundleId, oldHash);
1810
+ await writeReceipt(projectRoot, currentBundleId, currentHash);
1811
+ const roots = [projectRoot, globalRoot];
1812
+ assert.equal(await nativeSkillRootMatchingAuthorization({
1813
+ roots, workspaceId, bundleId: currentBundleId, receiptHash: currentHash,
1814
+ }), projectRoot);
1815
+ assert.equal(await nativeSkillRootMatchingAuthorization({
1816
+ roots, workspaceId, bundleId: oldBundleId, receiptHash: oldHash,
1817
+ }), globalRoot);
1818
+ assert.equal(await nativeSkillRootMatchingAuthorization({
1819
+ roots, workspaceId, bundleId: currentBundleId, receiptHash: oldHash,
1820
+ }), null);
1821
+ await writeReceipt(projectRoot, currentBundleId, oldHash);
1822
+ assert.equal(await nativeSkillRootMatchingAuthorization({
1823
+ roots, workspaceId, bundleId: currentBundleId, receiptHash: currentHash,
1824
+ }), null);
1825
+ });
1794
1826
  test('Claude uses its project skill when another workspace owns the global skill', async () => {
1795
1827
  const root = await mkdtemp(join(tmpdir(), 'dharma-claude-multiworkspace-'));
1796
1828
  const home = join(root, 'home');