@dharma-ai-labs/agent-fabric 0.2.152 → 0.2.154
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/bootstrapGitScope.test.d.ts +2 -0
- package/dist/bootstrapGitScope.test.d.ts.map +1 -0
- package/dist/bootstrapGitScope.test.js +115 -0
- package/dist/bootstrapGitScope.test.js.map +1 -0
- package/dist/bootstrapHostFiles.d.ts +5 -0
- package/dist/bootstrapHostFiles.d.ts.map +1 -0
- package/dist/bootstrapHostFiles.js +150 -0
- package/dist/bootstrapHostFiles.js.map +1 -0
- package/dist/bootstrapHostFiles.test.d.ts +2 -0
- package/dist/bootstrapHostFiles.test.d.ts.map +1 -0
- package/dist/bootstrapHostFiles.test.js +127 -0
- package/dist/bootstrapHostFiles.test.js.map +1 -0
- package/dist/bootstrapHostScope.d.ts +42 -0
- package/dist/bootstrapHostScope.d.ts.map +1 -0
- package/dist/bootstrapHostScope.js +224 -0
- package/dist/bootstrapHostScope.js.map +1 -0
- package/dist/bootstrapHostScope.test.d.ts +2 -0
- package/dist/bootstrapHostScope.test.d.ts.map +1 -0
- package/dist/bootstrapHostScope.test.js +577 -0
- package/dist/bootstrapHostScope.test.js.map +1 -0
- package/dist/bootstrapInstallationScope.test.d.ts +2 -0
- package/dist/bootstrapInstallationScope.test.d.ts.map +1 -0
- package/dist/bootstrapInstallationScope.test.js +68 -0
- package/dist/bootstrapInstallationScope.test.js.map +1 -0
- package/dist/bootstrapLauncherCaller.test.d.ts +2 -0
- package/dist/bootstrapLauncherCaller.test.d.ts.map +1 -0
- package/dist/bootstrapLauncherCaller.test.js +91 -0
- package/dist/bootstrapLauncherCaller.test.js.map +1 -0
- package/dist/bootstrapOwnedChildren.test.d.ts +2 -0
- package/dist/bootstrapOwnedChildren.test.d.ts.map +1 -0
- package/dist/bootstrapOwnedChildren.test.js +93 -0
- package/dist/bootstrapOwnedChildren.test.js.map +1 -0
- package/dist/bootstrapPolicyScope.test.d.ts +2 -0
- package/dist/bootstrapPolicyScope.test.d.ts.map +1 -0
- package/dist/bootstrapPolicyScope.test.js +261 -0
- package/dist/bootstrapPolicyScope.test.js.map +1 -0
- package/dist/bootstrapProcessCaller.test.d.ts +2 -0
- package/dist/bootstrapProcessCaller.test.d.ts.map +1 -0
- package/dist/bootstrapProcessCaller.test.js +262 -0
- package/dist/bootstrapProcessCaller.test.js.map +1 -0
- package/dist/bootstrapRegistryCaller.test.d.ts +2 -0
- package/dist/bootstrapRegistryCaller.test.d.ts.map +1 -0
- package/dist/bootstrapRegistryCaller.test.js +128 -0
- package/dist/bootstrapRegistryCaller.test.js.map +1 -0
- package/dist/bootstrapVaultScope.test.d.ts +2 -0
- package/dist/bootstrapVaultScope.test.d.ts.map +1 -0
- package/dist/bootstrapVaultScope.test.js +105 -0
- package/dist/bootstrapVaultScope.test.js.map +1 -0
- package/dist/codexBootstrapCompletion.test.d.ts +2 -0
- package/dist/codexBootstrapCompletion.test.d.ts.map +1 -0
- package/dist/codexBootstrapCompletion.test.js +630 -0
- package/dist/codexBootstrapCompletion.test.js.map +1 -0
- package/dist/codexBoundSession.d.ts +2 -2
- package/dist/codexBoundSession.d.ts.map +1 -1
- package/dist/codexBoundSession.js +23 -17
- package/dist/codexBoundSession.js.map +1 -1
- package/dist/codexBoundSession.test.js +3 -0
- package/dist/codexBoundSession.test.js.map +1 -1
- package/dist/codexInboxSession.d.ts.map +1 -1
- package/dist/codexInboxSession.js +3 -3
- package/dist/codexInboxSession.js.map +1 -1
- package/dist/codexScopedDispatch.test.d.ts +2 -0
- package/dist/codexScopedDispatch.test.d.ts.map +1 -0
- package/dist/codexScopedDispatch.test.js +56 -0
- package/dist/codexScopedDispatch.test.js.map +1 -0
- package/dist/codexSetupAdmission.d.ts +108 -0
- package/dist/codexSetupAdmission.d.ts.map +1 -0
- package/dist/codexSetupAdmission.js +214 -0
- package/dist/codexSetupAdmission.js.map +1 -0
- package/dist/codexSetupAdmission.test.d.ts +2 -0
- package/dist/codexSetupAdmission.test.d.ts.map +1 -0
- package/dist/codexSetupAdmission.test.js +578 -0
- package/dist/codexSetupAdmission.test.js.map +1 -0
- package/dist/codexSetupChildProvider.test.d.ts +2 -0
- package/dist/codexSetupChildProvider.test.d.ts.map +1 -0
- package/dist/codexSetupChildProvider.test.js +210 -0
- package/dist/codexSetupChildProvider.test.js.map +1 -0
- package/dist/codexSetupChildStartup.d.ts +38 -0
- package/dist/codexSetupChildStartup.d.ts.map +1 -0
- package/dist/codexSetupChildStartup.js +115 -0
- package/dist/codexSetupChildStartup.js.map +1 -0
- package/dist/codexSetupChildStartup.test.d.ts +2 -0
- package/dist/codexSetupChildStartup.test.d.ts.map +1 -0
- package/dist/codexSetupChildStartup.test.js +141 -0
- package/dist/codexSetupChildStartup.test.js.map +1 -0
- package/dist/codexSetupCliDispatch.test.d.ts +2 -0
- package/dist/codexSetupCliDispatch.test.d.ts.map +1 -0
- package/dist/codexSetupCliDispatch.test.js +138 -0
- package/dist/codexSetupCliDispatch.test.js.map +1 -0
- package/dist/codexSetupJournalOpen.test.d.ts +2 -0
- package/dist/codexSetupJournalOpen.test.d.ts.map +1 -0
- package/dist/codexSetupJournalOpen.test.js +101 -0
- package/dist/codexSetupJournalOpen.test.js.map +1 -0
- package/dist/codexSetupNativeHost.d.ts +31 -0
- package/dist/codexSetupNativeHost.d.ts.map +1 -0
- package/dist/codexSetupNativeHost.js +208 -0
- package/dist/codexSetupNativeHost.js.map +1 -0
- package/dist/codexSetupNativeHost.test.d.ts +2 -0
- package/dist/codexSetupNativeHost.test.d.ts.map +1 -0
- package/dist/codexSetupNativeHost.test.js +456 -0
- package/dist/codexSetupNativeHost.test.js.map +1 -0
- package/dist/codexSetupNativeWire.test.d.ts +2 -0
- package/dist/codexSetupNativeWire.test.d.ts.map +1 -0
- package/dist/codexSetupNativeWire.test.js +243 -0
- package/dist/codexSetupNativeWire.test.js.map +1 -0
- package/dist/codexSetupOwnedConnection.d.ts +14 -0
- package/dist/codexSetupOwnedConnection.d.ts.map +1 -0
- package/dist/codexSetupOwnedConnection.js +64 -0
- package/dist/codexSetupOwnedConnection.js.map +1 -0
- package/dist/codexSetupOwnedConnection.test.d.ts +2 -0
- package/dist/codexSetupOwnedConnection.test.d.ts.map +1 -0
- package/dist/codexSetupOwnedConnection.test.js +192 -0
- package/dist/codexSetupOwnedConnection.test.js.map +1 -0
- package/dist/codexSetupPortalCommand.test.d.ts +2 -0
- package/dist/codexSetupPortalCommand.test.d.ts.map +1 -0
- package/dist/codexSetupPortalCommand.test.js +146 -0
- package/dist/codexSetupPortalCommand.test.js.map +1 -0
- package/dist/codexSetupReadiness.d.ts +23 -0
- package/dist/codexSetupReadiness.d.ts.map +1 -0
- package/dist/codexSetupReadiness.js +74 -0
- package/dist/codexSetupReadiness.js.map +1 -0
- package/dist/codexSetupReadiness.test.d.ts +2 -0
- package/dist/codexSetupReadiness.test.d.ts.map +1 -0
- package/dist/codexSetupReadiness.test.js +145 -0
- package/dist/codexSetupReadiness.test.js.map +1 -0
- package/dist/codexSetupSessionCaller.test.d.ts +2 -0
- package/dist/codexSetupSessionCaller.test.d.ts.map +1 -0
- package/dist/codexSetupSessionCaller.test.js +352 -0
- package/dist/codexSetupSessionCaller.test.js.map +1 -0
- package/dist/codexSetupSessionHandoff.d.ts +48 -0
- package/dist/codexSetupSessionHandoff.d.ts.map +1 -0
- package/dist/codexSetupSessionHandoff.js +146 -0
- package/dist/codexSetupSessionHandoff.js.map +1 -0
- package/dist/codexSetupSessionHandoff.test.d.ts +2 -0
- package/dist/codexSetupSessionHandoff.test.d.ts.map +1 -0
- package/dist/codexSetupSessionHandoff.test.js +289 -0
- package/dist/codexSetupSessionHandoff.test.js.map +1 -0
- package/dist/codexSetupTransport.test.d.ts +2 -0
- package/dist/codexSetupTransport.test.d.ts.map +1 -0
- package/dist/codexSetupTransport.test.js +206 -0
- package/dist/codexSetupTransport.test.js.map +1 -0
- package/dist/codexSetupVaultJournal.d.ts +13 -0
- package/dist/codexSetupVaultJournal.d.ts.map +1 -0
- package/dist/codexSetupVaultJournal.js +28 -0
- package/dist/codexSetupVaultJournal.js.map +1 -0
- package/dist/codexSetupVaultJournal.test.d.ts +2 -0
- package/dist/codexSetupVaultJournal.test.d.ts.map +1 -0
- package/dist/codexSetupVaultJournal.test.js +104 -0
- package/dist/codexSetupVaultJournal.test.js.map +1 -0
- package/dist/containerChildCleanup.test.d.ts +2 -0
- package/dist/containerChildCleanup.test.d.ts.map +1 -0
- package/dist/containerChildCleanup.test.js +145 -0
- package/dist/containerChildCleanup.test.js.map +1 -0
- package/dist/containerRelayLifecycle.d.ts +1 -1
- package/dist/containerRelayLifecycle.d.ts.map +1 -1
- package/dist/containerRelayLifecycle.js +29 -37
- package/dist/containerRelayLifecycle.js.map +1 -1
- package/dist/containerRelayLifecycle.test.js +13 -0
- package/dist/containerRelayLifecycle.test.js.map +1 -1
- package/dist/cooperativeInboxSession.d.ts +2 -2
- package/dist/cooperativeInboxSession.d.ts.map +1 -1
- package/dist/cooperativeInboxSession.js +21 -13
- package/dist/cooperativeInboxSession.js.map +1 -1
- package/dist/cooperativeInboxSession.test.js +65 -0
- package/dist/cooperativeInboxSession.test.js.map +1 -1
- package/dist/demoWatchControl.d.ts +3 -3
- package/dist/index.d.ts +55 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1650 -557
- package/dist/index.js.map +1 -1
- package/dist/namedCodexSkillDiscovery.d.ts +15 -0
- package/dist/namedCodexSkillDiscovery.d.ts.map +1 -0
- package/dist/namedCodexSkillDiscovery.js +90 -0
- package/dist/namedCodexSkillDiscovery.js.map +1 -0
- package/dist/namedCodexSkillDiscovery.test.d.ts +2 -0
- package/dist/namedCodexSkillDiscovery.test.d.ts.map +1 -0
- package/dist/namedCodexSkillDiscovery.test.js +37 -0
- package/dist/namedCodexSkillDiscovery.test.js.map +1 -0
- package/dist/namedCodexThread.d.ts +2 -0
- package/dist/namedCodexThread.d.ts.map +1 -1
- package/dist/namedCodexThread.js +13 -4
- package/dist/namedCodexThread.js.map +1 -1
- package/dist/namedSessionChildOwner.d.ts +17 -0
- package/dist/namedSessionChildOwner.d.ts.map +1 -0
- package/dist/namedSessionChildOwner.js +122 -0
- package/dist/namedSessionChildOwner.js.map +1 -0
- package/dist/namedSessionChildOwner.test.d.ts +2 -0
- package/dist/namedSessionChildOwner.test.d.ts.map +1 -0
- package/dist/namedSessionChildOwner.test.js +203 -0
- package/dist/namedSessionChildOwner.test.js.map +1 -0
- package/dist/namedSessionEvidence.d.ts +2 -2
- package/dist/namedSessionEvidence.d.ts.map +1 -1
- package/dist/namedSessionEvidence.js +2 -2
- package/dist/namedSessionEvidence.js.map +1 -1
- package/dist/namedSessionEvidence.test.js +24 -1
- package/dist/namedSessionEvidence.test.js.map +1 -1
- package/dist/namedSessionRepositoryState.d.ts +2 -2
- package/dist/namedSessionRepositoryState.d.ts.map +1 -1
- package/dist/namedSessionService.d.ts +4 -2
- package/dist/namedSessionService.d.ts.map +1 -1
- package/dist/namedSessionService.js +18 -1
- package/dist/namedSessionService.js.map +1 -1
- package/dist/namedSessionService.test.js +31 -2
- package/dist/namedSessionService.test.js.map +1 -1
- package/dist/namedSessionTaskExportSync.d.ts +3 -3
- package/dist/namedSessionTaskExportSync.d.ts.map +1 -1
- package/dist/namedSessionTaskExportSync.js +6 -6
- package/dist/namedSessionTaskExportSync.js.map +1 -1
- package/dist/namedSessionTrust.d.ts +2 -2
- package/dist/namedSessionTrust.d.ts.map +1 -1
- package/dist/namedSessionTrust.js +3 -2
- package/dist/namedSessionTrust.js.map +1 -1
- package/dist/namedSessionTrust.test.js +2 -1
- package/dist/namedSessionTrust.test.js.map +1 -1
- package/dist/ownedChildLifecycle.d.ts +13 -0
- package/dist/ownedChildLifecycle.d.ts.map +1 -0
- package/dist/ownedChildLifecycle.js +87 -0
- package/dist/ownedChildLifecycle.js.map +1 -0
- package/dist/ownedChildLifecycle.test.d.ts +2 -0
- package/dist/ownedChildLifecycle.test.d.ts.map +1 -0
- package/dist/ownedChildLifecycle.test.js +133 -0
- package/dist/ownedChildLifecycle.test.js.map +1 -0
- package/dist/pidLock.test.js +242 -9
- package/dist/pidLock.test.js.map +1 -1
- package/dist/providerSessionChannel.d.ts +1 -1
- package/dist/providerSessionChannel.d.ts.map +1 -1
- package/dist/providerSessionChannel.js +7 -3
- package/dist/providerSessionChannel.js.map +1 -1
- package/dist/providerSessionChannel.test.js +20 -0
- package/dist/providerSessionChannel.test.js.map +1 -1
- package/dist/providerSessionReplyRecovery.d.ts +2 -2
- package/dist/providerSessionReplyRecovery.d.ts.map +1 -1
- package/dist/providerSessionReplyRecovery.js +3 -3
- package/dist/providerSessionReplyRecovery.js.map +1 -1
- package/dist/relayAutostart.d.ts.map +1 -1
- package/dist/relayAutostart.js +12 -9
- package/dist/relayAutostart.js.map +1 -1
- package/dist/relayRuntimeUpgrade.d.ts +1 -1
- package/dist/relayRuntimeUpgrade.d.ts.map +1 -1
- package/dist/relayRuntimeUpgrade.js +3 -1
- package/dist/relayRuntimeUpgrade.js.map +1 -1
- package/dist/relayRuntimeUpgrade.test.js +113 -0
- package/dist/relayRuntimeUpgrade.test.js.map +1 -1
- package/dist/relayRuntimeUpgradeCaller.test.js +12 -1
- package/dist/relayRuntimeUpgradeCaller.test.js.map +1 -1
- package/dist/relaySupervisor.d.ts.map +1 -1
- package/dist/relaySupervisor.js +19 -14
- package/dist/relaySupervisor.js.map +1 -1
- package/dist/relaySupervisor.test.js +26 -0
- package/dist/relaySupervisor.test.js.map +1 -1
- package/dist/relaySupervisorCleanup.test.d.ts +2 -0
- package/dist/relaySupervisorCleanup.test.d.ts.map +1 -0
- package/dist/relaySupervisorCleanup.test.js +69 -0
- package/dist/relaySupervisorCleanup.test.js.map +1 -0
- package/dist/repositoryInstallerFiles.d.ts +19 -1
- package/dist/repositoryInstallerFiles.d.ts.map +1 -1
- package/dist/repositoryInstallerFiles.js +205 -29
- package/dist/repositoryInstallerFiles.js.map +1 -1
- package/dist/repositoryInstallerScope.test.d.ts +2 -0
- package/dist/repositoryInstallerScope.test.d.ts.map +1 -0
- package/dist/repositoryInstallerScope.test.js +513 -0
- package/dist/repositoryInstallerScope.test.js.map +1 -0
- package/dist/repositoryKnowledge.d.ts.map +1 -1
- package/dist/repositoryKnowledge.js +177 -37
- package/dist/repositoryKnowledge.js.map +1 -1
- package/dist/repositoryKnowledgeScope.test.d.ts +2 -0
- package/dist/repositoryKnowledgeScope.test.d.ts.map +1 -0
- package/dist/repositoryKnowledgeScope.test.js +316 -0
- package/dist/repositoryKnowledgeScope.test.js.map +1 -0
- package/dist/repositoryOnboardingCaller.test.js +61 -4
- package/dist/repositoryOnboardingCaller.test.js.map +1 -1
- package/dist/repositoryPackage.d.ts.map +1 -1
- package/dist/repositoryPackage.js +340 -59
- package/dist/repositoryPackage.js.map +1 -1
- package/dist/repositoryPackageDelivery.test.js +65 -0
- package/dist/repositoryPackageDelivery.test.js.map +1 -1
- package/dist/repositoryPackageScope.test.d.ts +2 -0
- package/dist/repositoryPackageScope.test.d.ts.map +1 -0
- package/dist/repositoryPackageScope.test.js +578 -0
- package/dist/repositoryPackageScope.test.js.map +1 -0
- package/dist/schemas/codex-setup-child-start.schema.json +12 -0
- package/dist/schemas/codex-setup-intent.schema.json +27 -0
- package/dist/schemas/local-codex-setup-session.schema.json +39 -0
- package/dist/schemas/setup-claim-failure.schema.json +15 -0
- package/dist/skillInstallationScope.test.d.ts +2 -0
- package/dist/skillInstallationScope.test.d.ts.map +1 -0
- package/dist/skillInstallationScope.test.js +64 -0
- package/dist/skillInstallationScope.test.js.map +1 -0
- package/dist/skillPreparationCache.test.js +12 -4
- package/dist/skillPreparationCache.test.js.map +1 -1
- package/dist/skillPreparationCaller.test.js +31 -1
- package/dist/skillPreparationCaller.test.js.map +1 -1
- package/dist/startupCommitScope.test.d.ts +2 -0
- package/dist/startupCommitScope.test.d.ts.map +1 -0
- package/dist/startupCommitScope.test.js +172 -0
- package/dist/startupCommitScope.test.js.map +1 -0
- package/dist/workspaceRegistry.d.ts.map +1 -1
- package/dist/workspaceRegistry.js +7 -3
- package/dist/workspaceRegistry.js.map +1 -1
- package/dist/workspaceRegistry.test.js +51 -0
- package/dist/workspaceRegistry.test.js.map +1 -1
- package/dist/workspaceRegistryRecovery.d.ts.map +1 -1
- package/dist/workspaceRegistryRecovery.js +171 -64
- package/dist/workspaceRegistryRecovery.js.map +1 -1
- package/dist/workspaceRegistryRecoveryScope.test.d.ts +2 -0
- package/dist/workspaceRegistryRecoveryScope.test.d.ts.map +1 -0
- package/dist/workspaceRegistryRecoveryScope.test.js +416 -0
- package/dist/workspaceRegistryRecoveryScope.test.js.map +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { execFileSync } from 'node:child_process';
|
|
3
|
+
import { randomBytes } from 'node:crypto';
|
|
4
|
+
import { constants as fsConstants } from 'node:fs';
|
|
5
|
+
import { mkdtemp, readFile, realpath, rm } from 'node:fs/promises';
|
|
6
|
+
import { tmpdir } from 'node:os';
|
|
7
|
+
import { resolve } from 'node:path';
|
|
8
|
+
import { compileFunction } from 'node:vm';
|
|
9
|
+
import test from 'node:test';
|
|
10
|
+
import ts from 'typescript';
|
|
11
|
+
import { canonicalize, sha256 } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
12
|
+
import { LocalVault } from '@dharma-ai-labs/agent-fabric-local-vault';
|
|
13
|
+
import { parseLocalCodexSetupReadiness } from '@dharma-ai-labs/agent-fabric-local-vault/setup-readiness';
|
|
14
|
+
import { assertBootstrapHostSource, currentBootstrapHostScope, inspectCodexBootstrapHostPreparation, prepareCodexBootstrapHost, runCodexBootstrapHostScope } from './bootstrapHostScope.js';
|
|
15
|
+
import { assertCodexSetupExecutionLease, createCodexSetupAdmission } from './codexSetupAdmission.js';
|
|
16
|
+
import { createCodexSetupReadinessOwner } from './codexSetupReadiness.js';
|
|
17
|
+
import { isNamedSessionOwnerReceipt } from './namedSessionTrust.js';
|
|
18
|
+
import { parseNamedCodexSkillObservation } from './namedCodexSkillDiscovery.js';
|
|
19
|
+
import { discoverRepositoryRoleMetadata } from './repositoryRoleMetadata.js';
|
|
20
|
+
import { repositoryRelayObservationReady } from './repositoryRelaySupervisor.js';
|
|
21
|
+
import { selectDeviceWorkspace, workspaceIdForDevice } from './onboardingWorkspace.js';
|
|
22
|
+
import { startCodexSetupNativeHost } from './codexSetupNativeHost.js';
|
|
23
|
+
import { bootstrapFromCodexSetupScope, loadAgentFabricOnboardingContract, parseCliOptions } from './index.js';
|
|
24
|
+
import { originalCodexSetupSessionSender, withCodexSetupSessionSender } from './codexSetupSessionHandoff.js';
|
|
25
|
+
const id = (n) => `${String(n).padStart(8, '0')}-1111-4111-8111-111111111111`;
|
|
26
|
+
const hash = `sha256:${'a'.repeat(64)}`;
|
|
27
|
+
// Execute unchanged production declarations; only OS/server/native boundaries
|
|
28
|
+
// are fixtures. These tests do not establish Linux or production readiness.
|
|
29
|
+
async function declaration(name, dependencies) {
|
|
30
|
+
const baseline = process.env.DHARMA_COMPLETION_PARENT_TEST_BASELINE;
|
|
31
|
+
if (baseline && baseline !== 'e48fcd0798c26f9b8078f3ec2b4ea5bc782ad383')
|
|
32
|
+
throw new Error('fixture_source_unqualified');
|
|
33
|
+
const source = baseline ? execFileSync('git', ['show', `${baseline}:packages/cli/src/index.ts`], { encoding: 'utf8' })
|
|
34
|
+
: await readFile(new URL('../src/index.ts', import.meta.url), 'utf8');
|
|
35
|
+
const ast = ts.createSourceFile('index.ts', source, ts.ScriptTarget.Latest, true);
|
|
36
|
+
const matches = ast.statements.filter(node => ts.isFunctionDeclaration(node) && node.name?.text === name);
|
|
37
|
+
assert.equal(matches.length, 1);
|
|
38
|
+
const output = ts.transpileModule(matches[0].getText(ast), { compilerOptions: {
|
|
39
|
+
target: ts.ScriptTarget.ES2023, module: ts.ModuleKind.CommonJS
|
|
40
|
+
}, reportDiagnostics: true });
|
|
41
|
+
assert.equal(output.diagnostics?.filter(d => d.category === ts.DiagnosticCategory.Error).length, 0);
|
|
42
|
+
const body = output.outputText.replaceAll('import.meta.url', 'ENTRY_URL');
|
|
43
|
+
return compileFunction(`${body}\nreturn ${name};`, ['exports', ...Object.keys(dependencies)])({}, ...Object.values(dependencies));
|
|
44
|
+
}
|
|
45
|
+
async function fixture(t) {
|
|
46
|
+
const root = await realpath(await mkdtemp(resolve(tmpdir(), 'dharma-completion-'))), now = Date.now();
|
|
47
|
+
const prepared = prepareCodexBootstrapHost({ workspace: root, signal: new AbortController().signal, current: async () => true,
|
|
48
|
+
intent: { schema: 'dharma.codex-setup-intent/v1', operationId: id(1), setupReference: id(2),
|
|
49
|
+
organizationId: 'org_demo', recipientMembershipId: id(3), origin: 'https://hq.example',
|
|
50
|
+
repositoryFingerprint: hash, policyRevision: 'policy-v1', scopeDigest: hash, contractDigest: hash,
|
|
51
|
+
hostContextId: id(4), issuedAt: new Date(now - 1000).toISOString(), expiresAt: new Date(now + 600_000).toISOString() } });
|
|
52
|
+
const vault = await LocalVault.open({ root: resolve(root, 'vault'), masterKey: randomBytes(32) }, prepared.scope);
|
|
53
|
+
t.after(async () => { prepared.scope.close(); await vault.close(); await rm(root, { recursive: true, force: true }); });
|
|
54
|
+
const profile = { roleName: 'Reviewer', description: 'Bounded synthetic code review.', questionCategories: ['code-review'] };
|
|
55
|
+
const workspaceId = workspaceIdForDevice({ organizationId: 'org_demo', deviceId: id(5), path: root });
|
|
56
|
+
const identity = { organizationId: 'org_demo', membershipId: id(3), deviceId: id(5), workspaceId,
|
|
57
|
+
repositoryBindingId: id(7), endpointId: id(9), provider: 'codex' };
|
|
58
|
+
const roleScope = { organizationId: 'org_demo', workspaceId, repositoryBindingId: id(7),
|
|
59
|
+
repositoryAgentId: id(8), endpointId: id(9), sourceFingerprint: hash };
|
|
60
|
+
const row = { ...identity, path: root, routeHash: sha256(root), repositoryRemoteHash: hash, status: 'active', repositoryAgentId: id(8),
|
|
61
|
+
repositoryRole: { revision: 1, profileHash: sha256(canonicalize(profile)) } };
|
|
62
|
+
const name = `codex-${workspaceId.slice(0, 8)}`, home = resolve(root, 'home'), entry = resolve(root, 'index.js');
|
|
63
|
+
const policyPath = resolve(root, '.dharma', 'approved-policy.json');
|
|
64
|
+
const policy = { revision: 'policy-v1', serverAuthorization: { workspaceId, expiresAt: prepared.intent.expiresAt } };
|
|
65
|
+
const content = { bundleId: id(11), bundleHash: hash, manifestHash: hash, catalogHash: hash, skillsHash: hash };
|
|
66
|
+
const binding = { ...identity, owner: 'dharma_bridge', workspaceRoot: root, bindingId: id(10),
|
|
67
|
+
sessionId: 'synthetic_session', expiresAt: prepared.intent.expiresAt };
|
|
68
|
+
const native = { ok: true, ...identity, name, bindingId: id(10), sessionId: binding.sessionId,
|
|
69
|
+
nativeSkill: { ...content, schema: 'dharma.named-codex-skill-observation/v1', nativeDiscovered: true,
|
|
70
|
+
observedAt: new Date(now).toISOString() } };
|
|
71
|
+
const { organizationId, ...remoteIdentity } = identity;
|
|
72
|
+
const remote = { ok: true, organizationId, correlationId: id(90), registration: { ...remoteIdentity,
|
|
73
|
+
bindingId: id(10), mode: 'bridge_owned', revision: 1, state: 'attached', replay: false,
|
|
74
|
+
leaseUntil: new Date(now + 60_000).toISOString() } };
|
|
75
|
+
const startup = { backend: 'container-entrypoint', version: '0.2.153', workspace: root, policy: policyPath,
|
|
76
|
+
launcher: resolve(root, '.dharma', 'bin', 'dharma') };
|
|
77
|
+
const startupState = { state: 'enabled', backend: startup.backend, version: startup.version, lifecycle: 'running' };
|
|
78
|
+
const poll = { at: new Date(now).toISOString(), workspaceId, version: '0.2.153', pid: 102 };
|
|
79
|
+
const supervisor = { pid: 101, organizationId: 'org_demo', deviceId: id(5), policyPath,
|
|
80
|
+
version: '0.2.153', standardRepositories: true };
|
|
81
|
+
const processes = [
|
|
82
|
+
{ pid: 101, uid: 1000, parentPid: 1, processGroupId: 101, sessionId: 101, startTicks: '10',
|
|
83
|
+
argv: ['synthetic-node', entry, 'relay', 'supervise', '--policy', policyPath] },
|
|
84
|
+
{ pid: 102, uid: 1000, parentPid: 101, processGroupId: 101, sessionId: 101, startTicks: '20',
|
|
85
|
+
argv: ['synthetic-node', entry, 'relay', 'start', '--policy', policyPath] },
|
|
86
|
+
{ pid: 103, uid: 1000, parentPid: 101, processGroupId: 101, sessionId: 101, startTicks: '30',
|
|
87
|
+
argv: ['synthetic-node', entry, 'sessions', 'serve', '--name', name, '--workspace-id', workspaceId, '--apply'] },
|
|
88
|
+
];
|
|
89
|
+
const paths = new Map([
|
|
90
|
+
[resolve(home, 'relay', 'supervisor.pid'), 101], [resolve(home, 'relay', 'relay.pid'), 102],
|
|
91
|
+
[resolve(home, 'sessions', name, 'service.lock'), 103],
|
|
92
|
+
[resolve(home, 'relay', 'supervisor-workspace.json'), supervisor],
|
|
93
|
+
[resolve(home, 'relay', 'repositories', workspaceId, 'last-successful-poll.json'), poll],
|
|
94
|
+
]);
|
|
95
|
+
const calls = [], mutations = {};
|
|
96
|
+
const dependencies = {
|
|
97
|
+
resolve, Date, canonicalize, sha256, selectDeviceWorkspace, parseLocalCodexSetupReadiness, parseNamedCodexSkillObservation,
|
|
98
|
+
isNamedSessionOwnerReceipt, repositoryRelayObservationReady, discoverRepositoryRoleMetadata,
|
|
99
|
+
ENTRY_URL: 'file:///synthetic/index.js', fileURLToPath: () => entry, VERSION: '0.2.153',
|
|
100
|
+
process: { platform: 'linux', execPath: 'synthetic-node', getuid: () => 1000 },
|
|
101
|
+
preflightBootstrapWorkspaceIdentity: async () => ({ fingerprint: hash }), assertBootstrapHostSource: async () => { },
|
|
102
|
+
loadAgentFabricOnboardingContract: async () => ({ sha256: 'a'.repeat(64) }),
|
|
103
|
+
readDeviceConfig: async () => ({ ...identity, hqUrl: 'https://hq.example' }), normalizeHqUrl: (s) => s,
|
|
104
|
+
loadDeviceEnrollmentAnchor: async () => ({ devicePublicKeyEd25519: 'synthetic-public-key' }),
|
|
105
|
+
enrolledDeviceIdentity: async () => ({ publicKeyEd25519: 'synthetic-public-key' }), registry: async () => [row],
|
|
106
|
+
repositoryRoleScope: () => roleScope, loadVerifiedWorkspacePolicy: async () => policy,
|
|
107
|
+
verifyServerAuthorizedPolicy: () => { calls.push('verified-policy'); mutations.policy?.(); },
|
|
108
|
+
assertWorkspaceAuthorizationCurrent: async () => { calls.push('current-policy'); mutations.authorization?.(); },
|
|
109
|
+
activeSkillAuthorization: async () => ({ ...content, expiresAt: prepared.intent.expiresAt }),
|
|
110
|
+
loadActiveSkillAuthorizationAnchor: async () => ({ bundleId: id(11), receiptHash: hash }),
|
|
111
|
+
verifyAgentFabricSkillInstallation: async () => { calls.push('installation'); mutations.installation?.(); return { ready: true }; },
|
|
112
|
+
readNamedSessionPackageContent: async () => ({ ...content }),
|
|
113
|
+
client: async () => ({ signedGet: async () => ({ ok: true, organizationId: 'org_demo', correlationId: 'synthetic',
|
|
114
|
+
discovery: { organizationId: roleScope.organizationId, workspaceId: roleScope.workspaceId,
|
|
115
|
+
repositoryBindingId: roleScope.repositoryBindingId, repositoryAgentId: roleScope.repositoryAgentId,
|
|
116
|
+
peers: [{ endpointId: id(9), workspaceId, provider: 'codex', ...profile, revision: 1 }],
|
|
117
|
+
limit: 50, possiblyTruncated: false } }),
|
|
118
|
+
signedPost: async () => remote }),
|
|
119
|
+
dharmaHome: () => home, readNamedSession: async () => ({ enabled: true, identity, bindingId: id(10) }),
|
|
120
|
+
namedSessionCommand: async () => native, inspectOwnedRelayAutostart: async () => startup,
|
|
121
|
+
relayAutostartStatus: async () => startupState,
|
|
122
|
+
namedSessionPaths: () => ({ root: resolve(home, 'sessions', name) }),
|
|
123
|
+
readContainerProcessIdentity: async (pid) => {
|
|
124
|
+
calls.push(`process-${pid}`);
|
|
125
|
+
mutations.process?.();
|
|
126
|
+
return structuredClone(processes.find(p => p.pid === pid));
|
|
127
|
+
},
|
|
128
|
+
readBootstrapRuntimeJson: async (path, scope) => scope.step(async () => {
|
|
129
|
+
calls.push('owned-state');
|
|
130
|
+
if (!paths.has(path))
|
|
131
|
+
throw new Error('fixture_path_unknown');
|
|
132
|
+
return structuredClone(paths.get(path));
|
|
133
|
+
}),
|
|
134
|
+
};
|
|
135
|
+
const observe = await declaration('observeCodexBootstrapRuntime', dependencies);
|
|
136
|
+
let handoffEnabled = false;
|
|
137
|
+
const handoff = { state: 'accepted', request: { ...identity, setupReference: prepared.intent.setupReference,
|
|
138
|
+
workspaceRoot: root, name, repositoryFingerprint: hash, policyRevision: policy.revision,
|
|
139
|
+
scopeDigest: hash, contractDigest: hash }, result: { state: 'started', bindingId: binding.bindingId,
|
|
140
|
+
sessionId: binding.sessionId, sessionPid: 103, supervisorPid: 101, sessionStartTicks: '30', supervisorStartTicks: '10' } };
|
|
141
|
+
const providerVault = { getProviderSessionBinding: async () => binding,
|
|
142
|
+
readCodexSetupSession: async (operation, digest) => {
|
|
143
|
+
assert.equal(operation, prepared.intent.operationId);
|
|
144
|
+
assert.equal(digest, hash);
|
|
145
|
+
return handoffEnabled ? handoff : null;
|
|
146
|
+
} };
|
|
147
|
+
return { prepared, vault, observe, providerVault, calls, paths, mutations, row, profile, binding, native, remote,
|
|
148
|
+
content, startup, startupState, policy, supervisor, poll, processes, dependencies, handoff,
|
|
149
|
+
enableHandoff: () => { handoffEnabled = true; processes[2].argv.push('--setup-handoff'); } };
|
|
150
|
+
}
|
|
151
|
+
test('actual CLI producer joins the IPC-started child to its exact encrypted handoff result', async (t) => {
|
|
152
|
+
const f = await fixture(t);
|
|
153
|
+
f.enableHandoff();
|
|
154
|
+
assert.equal((await f.observe(f.prepared, f.providerVault, 'no_eligible_history', hash)).sessionId, f.binding.sessionId);
|
|
155
|
+
});
|
|
156
|
+
for (const change of ['absent', 'digest', 'member', 'device', 'repository', 'endpoint', 'source', 'scope', 'contract',
|
|
157
|
+
'binding', 'session', 'child', 'child-creation', 'supervisor', 'supervisor-creation', 'result', 'args']) {
|
|
158
|
+
test(`actual CLI producer rejects IPC handoff ${change}`, async (t) => {
|
|
159
|
+
const f = await fixture(t);
|
|
160
|
+
if (change !== 'absent')
|
|
161
|
+
f.enableHandoff();
|
|
162
|
+
if (change === 'member')
|
|
163
|
+
f.handoff.request.membershipId = id(99);
|
|
164
|
+
if (change === 'device')
|
|
165
|
+
f.handoff.request.deviceId = id(99);
|
|
166
|
+
if (change === 'repository')
|
|
167
|
+
f.handoff.request.repositoryBindingId = id(99);
|
|
168
|
+
if (change === 'endpoint')
|
|
169
|
+
f.handoff.request.endpointId = id(99);
|
|
170
|
+
if (change === 'source')
|
|
171
|
+
f.handoff.request.repositoryFingerprint = `sha256:${'b'.repeat(64)}`;
|
|
172
|
+
if (change === 'scope')
|
|
173
|
+
f.handoff.request.scopeDigest = `sha256:${'b'.repeat(64)}`;
|
|
174
|
+
if (change === 'contract')
|
|
175
|
+
f.handoff.request.contractDigest = `sha256:${'b'.repeat(64)}`;
|
|
176
|
+
if (change === 'binding')
|
|
177
|
+
f.handoff.result.bindingId = id(99);
|
|
178
|
+
if (change === 'session')
|
|
179
|
+
f.handoff.result.sessionId = 'foreign-session';
|
|
180
|
+
if (change === 'child')
|
|
181
|
+
f.handoff.result.sessionPid = 999;
|
|
182
|
+
if (change === 'child-creation')
|
|
183
|
+
f.handoff.result.sessionStartTicks = '31';
|
|
184
|
+
if (change === 'supervisor')
|
|
185
|
+
f.handoff.result.supervisorPid = 999;
|
|
186
|
+
if (change === 'supervisor-creation')
|
|
187
|
+
f.handoff.result.supervisorStartTicks = '11';
|
|
188
|
+
if (change === 'result')
|
|
189
|
+
f.handoff.result.state = 'unconfirmed';
|
|
190
|
+
if (change === 'args')
|
|
191
|
+
f.processes[2].argv.push('--arbitrary');
|
|
192
|
+
await assert.rejects(f.observe(f.prepared, f.providerVault, 'no_eligible_history', change === 'digest' ? undefined : hash), /setup_runtime_(?:session|process)_unconfirmed/);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
async function siblingAnchor(f) {
|
|
196
|
+
const path = resolve(f.row.path, 'sibling');
|
|
197
|
+
const workspaceId = workspaceIdForDevice({ organizationId: f.row.organizationId, deviceId: f.row.deviceId, path });
|
|
198
|
+
const row = { ...f.row, path, workspaceId, routeHash: sha256(path), repositoryRemoteHash: `sha256:${'b'.repeat(64)}` };
|
|
199
|
+
const policy = { ...f.policy, revision: 'sibling-policy', serverAuthorization: { ...f.policy.serverAuthorization, workspaceId } };
|
|
200
|
+
f.startup.workspace = path;
|
|
201
|
+
f.startup.policy = resolve(path, '.dharma', 'approved-policy.json');
|
|
202
|
+
f.startup.launcher = resolve(path, '.dharma', 'bin', 'dharma');
|
|
203
|
+
f.supervisor.policyPath = f.startup.policy;
|
|
204
|
+
f.processes[0].argv[5] = f.startup.policy;
|
|
205
|
+
f.processes[1].argv[5] = f.startup.policy;
|
|
206
|
+
f.dependencies.registry = async () => [f.row, row];
|
|
207
|
+
f.dependencies.loadVerifiedWorkspacePolicy = async (path) => path === f.startup.policy ? policy : f.policy;
|
|
208
|
+
const observe = await declaration('observeCodexBootstrapRuntime', f.dependencies);
|
|
209
|
+
return { row, policy, observe };
|
|
210
|
+
}
|
|
211
|
+
test('actual CLI producer accepts a verified same-device sibling startup anchor without retargeting it', async (t) => {
|
|
212
|
+
const f = await fixture(t), sibling = await siblingAnchor(f);
|
|
213
|
+
const before = structuredClone(f.startup);
|
|
214
|
+
const result = await sibling.observe(f.prepared, f.providerVault, 'no_eligible_history');
|
|
215
|
+
assert.equal(result.workspaceId, f.row.workspaceId);
|
|
216
|
+
assert.equal(result.policyRevision, f.policy.revision);
|
|
217
|
+
assert.deepEqual(f.startup, before);
|
|
218
|
+
});
|
|
219
|
+
for (const change of ['foreign-device', 'foreign-org', 'route', 'inactive', 'unregistered', 'policy',
|
|
220
|
+
'supervisor', 'startup-change', 'state-change', 'route-change', 'policy-change', 'config-change', 'authorization']) {
|
|
221
|
+
test(`actual CLI producer rejects a sibling startup anchor with ${change}`, async (t) => {
|
|
222
|
+
const f = await fixture(t), sibling = await siblingAnchor(f);
|
|
223
|
+
if (change === 'foreign-device')
|
|
224
|
+
sibling.row.workspaceId = workspaceIdForDevice({ organizationId: 'org_demo', deviceId: id(99), path: sibling.row.path });
|
|
225
|
+
if (change === 'foreign-org')
|
|
226
|
+
sibling.row.organizationId = 'org_foreign';
|
|
227
|
+
if (change === 'route')
|
|
228
|
+
sibling.row.routeHash = `sha256:${'f'.repeat(64)}`;
|
|
229
|
+
if (change === 'inactive')
|
|
230
|
+
sibling.row.status = 'revoked';
|
|
231
|
+
if (change === 'unregistered')
|
|
232
|
+
f.dependencies.registry = async () => [f.row];
|
|
233
|
+
if (change === 'policy')
|
|
234
|
+
f.dependencies.verifyServerAuthorizedPolicy = ({ workspaceId }) => {
|
|
235
|
+
if (workspaceId === sibling.row.workspaceId)
|
|
236
|
+
throw new Error('fixture_invalid_anchor_signature');
|
|
237
|
+
};
|
|
238
|
+
if (change === 'supervisor')
|
|
239
|
+
f.supervisor.deviceId = id(99);
|
|
240
|
+
if (change === 'authorization')
|
|
241
|
+
f.dependencies.assertWorkspaceAuthorizationCurrent = async (workspaceId) => {
|
|
242
|
+
if (workspaceId === sibling.row.workspaceId)
|
|
243
|
+
throw new Error('fixture_anchor_authority_revoked');
|
|
244
|
+
};
|
|
245
|
+
let reads = 0;
|
|
246
|
+
f.mutations.process = () => {
|
|
247
|
+
if (++reads !== 4)
|
|
248
|
+
return;
|
|
249
|
+
if (change === 'startup-change')
|
|
250
|
+
f.startup.launcher = resolve(f.row.path, 'foreign-launcher');
|
|
251
|
+
if (change === 'state-change')
|
|
252
|
+
f.startupState.lifecycle = 'stopped';
|
|
253
|
+
if (change === 'route-change')
|
|
254
|
+
sibling.row.repositoryRemoteHash = `sha256:${'f'.repeat(64)}`;
|
|
255
|
+
if (change === 'policy-change')
|
|
256
|
+
sibling.policy.revision = 'withdrawn';
|
|
257
|
+
};
|
|
258
|
+
if (change === 'config-change')
|
|
259
|
+
f.dependencies.readDeviceConfig = async () => ({ organizationId: 'org_demo',
|
|
260
|
+
deviceId: reads >= 4 ? id(99) : id(5), hqUrl: 'https://hq.example' });
|
|
261
|
+
const observe = await declaration('observeCodexBootstrapRuntime', f.dependencies);
|
|
262
|
+
const expected = change === 'policy' ? /fixture_invalid_anchor_signature/
|
|
263
|
+
: change === 'authorization' ? /fixture_anchor_authority_revoked/
|
|
264
|
+
: change === 'supervisor' ? /setup_runtime_process_unconfirmed/
|
|
265
|
+
: change.endsWith('-change') ? /setup_runtime_startup_changed/ : /setup_runtime_startup_unconfirmed/;
|
|
266
|
+
await assert.rejects(observe(f.prepared, f.providerVault, 'no_eligible_history'), expected);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
test('actual CLI producer joins scoped identity, server role, native package and creation-identity observations', async (t) => {
|
|
270
|
+
const f = await fixture(t);
|
|
271
|
+
const observation = await f.observe(f.prepared, f.providerVault, 'no_eligible_history');
|
|
272
|
+
assert.equal(Object.isFrozen(observation), true);
|
|
273
|
+
assert.equal(observation.endpointId, id(9));
|
|
274
|
+
assert.equal(observation.catalogHash, hash);
|
|
275
|
+
assert.equal(observation.firstLearning, 'no_eligible_history');
|
|
276
|
+
assert.equal(f.calls.filter(c => c === 'current-policy').length, 4);
|
|
277
|
+
assert.equal(f.calls.filter(c => c === 'process-102').length, 2);
|
|
278
|
+
const claim = await f.vault.claimCodexSetupOperation(id(1), hash);
|
|
279
|
+
assert.equal(claim.state, 'acquired');
|
|
280
|
+
if (claim.state !== 'acquired')
|
|
281
|
+
throw new Error('fixture_claim_missing');
|
|
282
|
+
const owner = createCodexSetupReadinessOwner({ intent: f.prepared.intent, workspace: f.row.path,
|
|
283
|
+
scope: f.prepared.scope, vault: f.vault, observe: () => f.observe(f.prepared, f.providerVault, 'no_eligible_history') });
|
|
284
|
+
const receipt = await owner.record({ leaseId: claim.leaseId, intentDigest: hash });
|
|
285
|
+
assert.equal(await owner.verify(receipt.readinessReceiptId, f.prepared.intent, hash), true);
|
|
286
|
+
f.native.sessionId = 'different_session';
|
|
287
|
+
assert.equal(await owner.verify(receipt.readinessReceiptId, f.prepared.intent, hash), false);
|
|
288
|
+
});
|
|
289
|
+
test('actual CLI producer rejects a named worker not owned by the verified standing supervisor', async (t) => {
|
|
290
|
+
const f = await fixture(t);
|
|
291
|
+
f.processes[2].parentPid = 1;
|
|
292
|
+
await assert.rejects(f.observe(f.prepared, f.providerVault, 'no_eligible_history'), { message: 'setup_runtime_process_unconfirmed' });
|
|
293
|
+
});
|
|
294
|
+
for (const change of ['source', 'recipient', 'role', 'package', 'native', 'lease', 'startup', 'poll', 'process', 'withdrawn']) {
|
|
295
|
+
test(`actual CLI producer withholds readiness for ${change} mismatch`, async (t) => {
|
|
296
|
+
const f = await fixture(t);
|
|
297
|
+
if (change === 'source')
|
|
298
|
+
f.row.repositoryRemoteHash = `sha256:${'b'.repeat(64)}`;
|
|
299
|
+
if (change === 'recipient')
|
|
300
|
+
f.binding.membershipId = id(99);
|
|
301
|
+
if (change === 'role')
|
|
302
|
+
f.row.repositoryRole.revision = 2;
|
|
303
|
+
if (change === 'package')
|
|
304
|
+
f.content.catalogHash = `sha256:${'b'.repeat(64)}`;
|
|
305
|
+
if (change === 'native')
|
|
306
|
+
f.native.nativeSkill.observedAt = new Date(Date.now() - 90_000).toISOString();
|
|
307
|
+
if (change === 'lease')
|
|
308
|
+
f.remote.registration.leaseUntil = new Date(Date.now() - 1).toISOString();
|
|
309
|
+
if (change === 'startup')
|
|
310
|
+
f.startupState.lifecycle = 'stopped';
|
|
311
|
+
if (change === 'poll')
|
|
312
|
+
f.poll.pid = 104;
|
|
313
|
+
if (change === 'process')
|
|
314
|
+
f.processes[1].parentPid = 999;
|
|
315
|
+
if (change === 'withdrawn')
|
|
316
|
+
f.prepared.scope.close();
|
|
317
|
+
const expected = { source: 'setup_runtime_repository_unconfirmed', recipient: 'setup_runtime_session_unconfirmed',
|
|
318
|
+
role: 'setup_runtime_role_unconfirmed', package: 'setup_runtime_session_unconfirmed', native: 'named_session_native_skill_invalid',
|
|
319
|
+
lease: 'setup_runtime_session_unconfirmed', startup: 'setup_runtime_startup_unconfirmed', poll: 'setup_runtime_poll_unconfirmed',
|
|
320
|
+
process: 'setup_runtime_process_unconfirmed', withdrawn: 'codex_setup_host_scope_unavailable' };
|
|
321
|
+
await assert.rejects(f.observe(f.prepared, f.providerVault, 'no_eligible_history'), { message: expected[change] });
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
test('actual CLI producer denies process reuse and policy withdrawal during readback', async (t) => {
|
|
325
|
+
const f = await fixture(t);
|
|
326
|
+
let processReads = 0;
|
|
327
|
+
f.mutations.process = () => { if (++processReads === 4)
|
|
328
|
+
f.processes[1].startTicks = '999'; };
|
|
329
|
+
await assert.rejects(f.observe(f.prepared, f.providerVault, 'no_eligible_history'), /process_changed/);
|
|
330
|
+
delete f.mutations.process;
|
|
331
|
+
f.mutations.authorization = () => { f.prepared.scope.close(); };
|
|
332
|
+
await assert.rejects(f.observe(f.prepared, f.providerVault, 'no_eligible_history'), /scope_unavailable/);
|
|
333
|
+
});
|
|
334
|
+
test('actual completion composition denies copied leases and retains the incomplete-execution guard', async (t) => {
|
|
335
|
+
const f = await fixture(t);
|
|
336
|
+
let executions = 0;
|
|
337
|
+
const compose = await declaration('createCodexBootstrapCompletionOwner', { ...f.dependencies,
|
|
338
|
+
runCodexBootstrapHostScope, createCodexSetupReadinessOwner, assertCodexSetupExecutionLease, withCodexSetupSessionSender,
|
|
339
|
+
observeCodexBootstrapRuntime: f.observe,
|
|
340
|
+
bootstrapFromCodexSetupScope: async () => {
|
|
341
|
+
executions++;
|
|
342
|
+
return { ok: false, stage: 'host_setup_unavailable',
|
|
343
|
+
code: 'codex_setup_host_execution_unqualified', effects: false, grantRedeemed: false };
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
const completion = await compose(f.prepared.scope, f.vault);
|
|
347
|
+
await assert.rejects(completion.execute({ leaseId: id(99), intentDigest: hash }), /execution_lease_unavailable/);
|
|
348
|
+
assert.equal(executions, 0);
|
|
349
|
+
const active = { connectionId: id(20), threadId: 'synthetic_thread', turnId: 'synthetic_turn', hostContextId: id(4) };
|
|
350
|
+
const owner = createCodexSetupAdmission({ ...active, intent: f.prepared.intent,
|
|
351
|
+
current: async () => ({ ...active, mode: 'setup' }), qualifyHost: async () => true,
|
|
352
|
+
journal: { claim: async (operation, digest) => f.vault.claimCodexSetupOperation(operation, digest),
|
|
353
|
+
read: async (operation, digest) => f.vault.readCodexSetupOperation(operation, digest),
|
|
354
|
+
finish: async (lease, digest, result) => f.vault.finishCodexSetupOperation(lease, digest, result) },
|
|
355
|
+
execute: (_intent, _signal, _current, lease) => completion.execute(lease), verifyReadiness: completion.verify });
|
|
356
|
+
try {
|
|
357
|
+
const result = await owner.handler({ threadId: active.threadId, turnId: active.turnId,
|
|
358
|
+
callId: 'synthetic_call', tool: 'dharma_setup_reference', namespace: null,
|
|
359
|
+
arguments: { operationId: id(1), setupReference: id(2) } }, { signal: new AbortController().signal });
|
|
360
|
+
assert.equal(result.success, false);
|
|
361
|
+
assert.equal(executions, 1);
|
|
362
|
+
assert.equal(JSON.stringify(result).includes('readinessReceiptId'), false);
|
|
363
|
+
assert.equal(f.calls.length, 0);
|
|
364
|
+
}
|
|
365
|
+
finally {
|
|
366
|
+
owner.close();
|
|
367
|
+
await owner.settled;
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
for (const disposition of ['complete', 'package-pending', 'foreign-recipient',
|
|
371
|
+
...['source', 'device-config', 'claim', 'credentials', 'onboard', 'launcher', 'startup', 'skill', 'relay', 'api', 'named']
|
|
372
|
+
.map(stage => `withdrawn-${stage}`)]) {
|
|
373
|
+
test(`actual bootstrap composition admits only the original lease (${disposition})`, async (t) => {
|
|
374
|
+
const f = await fixture(t);
|
|
375
|
+
f.enableHandoff();
|
|
376
|
+
let claims = 0, onboards = 0, starts = 0, completionDigest = '';
|
|
377
|
+
const effects = [];
|
|
378
|
+
const effect = (stage, value) => {
|
|
379
|
+
effects.push(stage);
|
|
380
|
+
if (disposition === `withdrawn-${stage}`)
|
|
381
|
+
f.prepared.scope.close();
|
|
382
|
+
return value;
|
|
383
|
+
};
|
|
384
|
+
const config = { organizationId: f.row.organizationId, deviceId: f.row.deviceId,
|
|
385
|
+
hqUrl: f.prepared.intent.origin, installationId: id(80), setupClaimReference: id(2) };
|
|
386
|
+
const source = { fingerprint: f.prepared.intent.repositoryFingerprint };
|
|
387
|
+
const bootstrap = await declaration('bootstrap', {
|
|
388
|
+
...f.dependencies, originalCodexSetupSessionSender, assertBootstrapHostSource,
|
|
389
|
+
currentBootstrapHostScope, UUID_PATTERN: /^[0-9a-f-]{36}$/,
|
|
390
|
+
portalUrl: (flags) => flags.get('portal-url'),
|
|
391
|
+
required: (flags, key) => {
|
|
392
|
+
const value = flags.get(key);
|
|
393
|
+
assert.equal(typeof value, 'string');
|
|
394
|
+
return value;
|
|
395
|
+
},
|
|
396
|
+
bootstrapGrantMode: () => 'reference', realpath: async (path) => path,
|
|
397
|
+
readDeviceConfig: async () => effect('device-config', config),
|
|
398
|
+
preflightBootstrapWorkspaceIdentity: async () => effect('source', source),
|
|
399
|
+
isLocalProviderId: (provider) => provider === 'codex',
|
|
400
|
+
process: { platform: 'linux', env: {}, stderr: { write() { throw new Error('fixture_unexpected_output'); } } },
|
|
401
|
+
configPath: () => 'synthetic-config', platform: async () => 'linux',
|
|
402
|
+
claimSetupReference: async (input) => {
|
|
403
|
+
claims++;
|
|
404
|
+
assert.equal(input.hostScope, f.prepared.scope);
|
|
405
|
+
assert.equal(input.recipientMembershipId, f.prepared.intent.recipientMembershipId);
|
|
406
|
+
assert.equal(input.repositoryFingerprint, source.fingerprint);
|
|
407
|
+
assert.equal(input.setupReference, f.prepared.intent.setupReference);
|
|
408
|
+
return effect('claim', { config, scopes: ['fabric:tasks'] });
|
|
409
|
+
},
|
|
410
|
+
loadOrganizationApiToken: async () => effect('credentials', 'synthetic-not-a-real-credential'),
|
|
411
|
+
retryBootstrapOnboarding: async (operation) => operation(),
|
|
412
|
+
onboard: async (flags) => {
|
|
413
|
+
onboards++;
|
|
414
|
+
assert.equal(currentBootstrapHostScope(), f.prepared.scope);
|
|
415
|
+
for (const key of ['grant', 'grant-prompt', 'setup-reference', 'setup-recipient-membership-id']) {
|
|
416
|
+
assert.equal(flags.has(key), false);
|
|
417
|
+
}
|
|
418
|
+
return effect('onboard', { ok: true, stage: 'complete', workspaceId: f.row.workspaceId,
|
|
419
|
+
sharedRepositoryReady: disposition !== 'package-pending', repositoryRole: f.profile,
|
|
420
|
+
firstLearningEvidence: { state: 'synchronized', discovered: 0, disclosureReady: true } });
|
|
421
|
+
},
|
|
422
|
+
installStableRepositoryLauncher: async () => effect('launcher', { shell: '.dharma/bin/dharma', windows: '.dharma/bin/dharma.cmd' }),
|
|
423
|
+
withOnboardingStage: async (_stage, _workspace, _command, operation) => operation(),
|
|
424
|
+
withRelayStartupMutation: async (operation) => operation(),
|
|
425
|
+
relayAutostartStatus: async () => ({ state: 'disabled', backend: null }),
|
|
426
|
+
enableRelayAutostart: async () => effect('startup', { state: 'enabled', backend: 'systemd-user' }),
|
|
427
|
+
verifyAgentFabricSkillInstallation: async () => effect('skill', { ready: true }),
|
|
428
|
+
startRelayDaemon: async () => effect('relay', { state: 'running', probe: { connected: true } }),
|
|
429
|
+
waitForRepositoryReadiness: async () => ({ outcome: 'blocked' }),
|
|
430
|
+
runOrganizationCommand: async () => effect('api', { organizationId: f.row.organizationId }),
|
|
431
|
+
summarizeBootstrapOrganizationApi: () => ({ ready: true }),
|
|
432
|
+
namedSessionCommand: async (action) => {
|
|
433
|
+
if (action === 'start')
|
|
434
|
+
starts++;
|
|
435
|
+
return effect('named', { ...f.native, state: 'running' });
|
|
436
|
+
},
|
|
437
|
+
});
|
|
438
|
+
const run = await declaration('run', { parseCliOptions, currentBootstrapHostScope,
|
|
439
|
+
inspectCodexBootstrapHostPreparation, originalCodexSetupSessionSender, bootstrap });
|
|
440
|
+
const continueFromScope = await declaration('bootstrapFromCodexSetupScope', { runCodexBootstrapHostScope, run });
|
|
441
|
+
const vault = { ...f.vault, ...f.providerVault,
|
|
442
|
+
readCodexSetupSession: async (operation, digest) => {
|
|
443
|
+
assert.equal(operation, f.prepared.intent.operationId);
|
|
444
|
+
assert.equal(digest, completionDigest);
|
|
445
|
+
return f.handoff;
|
|
446
|
+
} };
|
|
447
|
+
if (disposition === 'foreign-recipient')
|
|
448
|
+
f.binding.membershipId = id(99);
|
|
449
|
+
const compose = await declaration('createCodexBootstrapCompletionOwner', { ...f.dependencies,
|
|
450
|
+
runCodexBootstrapHostScope, createCodexSetupReadinessOwner, assertCodexSetupExecutionLease, withCodexSetupSessionSender,
|
|
451
|
+
observeCodexBootstrapRuntime: f.observe,
|
|
452
|
+
bootstrapFromCodexSetupScope: continueFromScope,
|
|
453
|
+
});
|
|
454
|
+
const completion = await compose(f.prepared.scope, vault);
|
|
455
|
+
const active = { connectionId: id(20), threadId: 'synthetic_thread', turnId: 'synthetic_turn', hostContextId: id(4) };
|
|
456
|
+
const admission = createCodexSetupAdmission({ ...active, intent: f.prepared.intent,
|
|
457
|
+
current: async () => ({ ...active, mode: 'setup' }), qualifyHost: async () => true,
|
|
458
|
+
journal: { claim: async (operation, digest) => f.vault.claimCodexSetupOperation(operation, digest),
|
|
459
|
+
read: async (operation, digest) => f.vault.readCodexSetupOperation(operation, digest),
|
|
460
|
+
finish: async (lease, digest, result) => f.vault.finishCodexSetupOperation(lease, digest, result) },
|
|
461
|
+
execute: (_intent, _signal, _current, lease) => {
|
|
462
|
+
completionDigest = lease.intentDigest;
|
|
463
|
+
return completion.execute(lease);
|
|
464
|
+
}, verifyReadiness: completion.verify });
|
|
465
|
+
try {
|
|
466
|
+
const response = await admission.handler({ threadId: active.threadId, turnId: active.turnId,
|
|
467
|
+
callId: 'original_bootstrap', tool: 'dharma_setup_reference', namespace: null,
|
|
468
|
+
arguments: { operationId: id(1), setupReference: id(2) } }, { signal: new AbortController().signal });
|
|
469
|
+
await admission.settled;
|
|
470
|
+
assert.equal(claims, ['withdrawn-source', 'withdrawn-device-config'].includes(disposition) ? 0 : 1, 'the actual bootstrap must reach only a still-admitted bound claim');
|
|
471
|
+
assert.equal(onboards, effects.filter(stage => stage === 'onboard').length);
|
|
472
|
+
if (disposition === 'package-pending')
|
|
473
|
+
assert.equal(starts, 0);
|
|
474
|
+
if (disposition.startsWith('withdrawn-')) {
|
|
475
|
+
const withdrawn = disposition.slice('withdrawn-'.length);
|
|
476
|
+
assert.equal(effects.at(-1), withdrawn, 'no later boundary may run after withdrawal');
|
|
477
|
+
assert.equal(await f.prepared.scope.current(), false);
|
|
478
|
+
await assert.rejects(f.vault.readCodexSetupOperation(id(1), completionDigest), /vault_scope_unavailable/);
|
|
479
|
+
}
|
|
480
|
+
assert.equal(response.success, disposition === 'complete');
|
|
481
|
+
if (disposition === 'complete') {
|
|
482
|
+
const saved = await f.vault.readCodexSetupOperation(id(1), completionDigest);
|
|
483
|
+
assert.equal(saved?.state, 'terminal');
|
|
484
|
+
if (saved?.state !== 'terminal')
|
|
485
|
+
throw new Error('fixture_terminal_missing');
|
|
486
|
+
assert.equal(saved.result.state, 'completed');
|
|
487
|
+
assert.equal(JSON.parse(response.contentItems[0].text).readinessReceiptId, saved.result.readinessReceiptId);
|
|
488
|
+
const reconciled = await admission.handler({ threadId: active.threadId, turnId: active.turnId,
|
|
489
|
+
callId: 'reconcile_bootstrap', tool: 'dharma_setup_reference', namespace: null,
|
|
490
|
+
arguments: { operationId: id(1), setupReference: id(2) } }, { signal: new AbortController().signal });
|
|
491
|
+
await admission.settled;
|
|
492
|
+
assert.equal(reconciled.success, true);
|
|
493
|
+
assert.equal(claims, 1);
|
|
494
|
+
assert.equal(onboards, 1);
|
|
495
|
+
assert.equal(starts, 1);
|
|
496
|
+
assert.equal(JSON.parse(reconciled.contentItems[0].text).readinessReceiptId, saved.result.readinessReceiptId);
|
|
497
|
+
}
|
|
498
|
+
else
|
|
499
|
+
assert.equal(JSON.stringify(response).includes('readinessReceiptId'), false);
|
|
500
|
+
}
|
|
501
|
+
finally {
|
|
502
|
+
admission.close();
|
|
503
|
+
await admission.settled;
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
test('actual runtime-state reader enforces ownership, private mode, bounds and unchanged descriptor identity', async (t) => {
|
|
508
|
+
const f = await fixture(t), bytes = Buffer.from('{"pid":102}\n');
|
|
509
|
+
let opens = 0, closes = 0, changed = false, short = false;
|
|
510
|
+
const stat = { dev: 1n, ino: 2n, nlink: 1n, size: BigInt(bytes.length), mtimeNs: 1n, ctimeNs: 1n,
|
|
511
|
+
mode: 33152n, uid: 1000n, gid: 1000n, isFile: () => true, isSymbolicLink: () => false };
|
|
512
|
+
const read = await declaration('readBootstrapRuntimeJson', { Buffer, JSON, fsConstants,
|
|
513
|
+
process: { getuid: () => 1000 },
|
|
514
|
+
lstat: async () => ({ ...stat }),
|
|
515
|
+
open: async (_path, flags) => {
|
|
516
|
+
opens++;
|
|
517
|
+
assert.equal(flags, fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW | fsConstants.O_NONBLOCK);
|
|
518
|
+
return { stat: async () => ({ ...stat, ino: changed ? 3n : stat.ino }),
|
|
519
|
+
read: async (target) => { bytes.copy(target); return { bytesRead: short ? bytes.length - 1 : bytes.length }; },
|
|
520
|
+
close: async () => { closes++; } };
|
|
521
|
+
} });
|
|
522
|
+
assert.deepEqual(await read('synthetic-owned-state', f.prepared.scope), { pid: 102 });
|
|
523
|
+
assert.equal(opens, 1);
|
|
524
|
+
assert.equal(closes, 1);
|
|
525
|
+
for (const change of [{ uid: 999n }, { mode: 33184n }, { nlink: 2n }, { size: 32769n }]) {
|
|
526
|
+
const old = { ...stat };
|
|
527
|
+
Object.assign(stat, change);
|
|
528
|
+
await assert.rejects(read('synthetic-owned-state', f.prepared.scope), /state_unconfirmed/);
|
|
529
|
+
assert.equal(opens, 1);
|
|
530
|
+
Object.assign(stat, old);
|
|
531
|
+
}
|
|
532
|
+
changed = true;
|
|
533
|
+
await assert.rejects(read('synthetic-owned-state', f.prepared.scope), /state_unconfirmed/);
|
|
534
|
+
assert.equal(closes, 2);
|
|
535
|
+
changed = false;
|
|
536
|
+
short = true;
|
|
537
|
+
await assert.rejects(read('synthetic-owned-state', f.prepared.scope), /state_unconfirmed/);
|
|
538
|
+
assert.equal(closes, 3);
|
|
539
|
+
f.prepared.scope.close();
|
|
540
|
+
await assert.rejects(read('synthetic-owned-state', f.prepared.scope), /scope_unavailable/);
|
|
541
|
+
assert.equal(opens, 3);
|
|
542
|
+
});
|
|
543
|
+
for (const withdrawAfterOpen of [false, true]) {
|
|
544
|
+
test(`official composition owns the same protected vault and closes a denied opening (withdraw=${withdrawAfterOpen})`, async (t) => {
|
|
545
|
+
const f = await fixture(t), key = randomBytes(32), home = resolve(f.row.path, 'native-home');
|
|
546
|
+
let allowed = true, opens = 0, closes = 0, vault;
|
|
547
|
+
let originalScope, handler;
|
|
548
|
+
const listeners = new Set(), lifetime = new AbortController();
|
|
549
|
+
t.after(() => { key.fill(0); });
|
|
550
|
+
const transport = {
|
|
551
|
+
signal: lifetime.signal, close: async () => { lifetime.abort(); },
|
|
552
|
+
onNotification: listener => { listeners.add(listener); return () => { listeners.delete(listener); }; },
|
|
553
|
+
onToolCall: callback => { handler = callback; return () => { handler = undefined; }; },
|
|
554
|
+
request: async (method) => {
|
|
555
|
+
if (method === 'permissionProfile/list')
|
|
556
|
+
return { data: [{ id: 'dharma_bridge', allowed: true }] };
|
|
557
|
+
if (method === 'config/read')
|
|
558
|
+
return { config: { permissions: { dharma_bridge: {
|
|
559
|
+
filesystem: { ':minimal': 'read', ':workspace_roots': { '.': 'read' } }, network: { enabled: false }
|
|
560
|
+
} } } };
|
|
561
|
+
if (method === 'thread/start' || method === 'thread/read')
|
|
562
|
+
return { thread: {
|
|
563
|
+
id: 'synthetic_thread', cwd: f.row.path, name: 'reviewer', status: { type: 'idle' }
|
|
564
|
+
} };
|
|
565
|
+
if (method === 'thread/name/set' || method === 'turn/interrupt')
|
|
566
|
+
return {};
|
|
567
|
+
if (method === 'turn/start')
|
|
568
|
+
return { turn: { id: 'synthetic_turn', status: 'inProgress' } };
|
|
569
|
+
throw new Error('fixture_native_method_unexpected');
|
|
570
|
+
},
|
|
571
|
+
};
|
|
572
|
+
const compose = await declaration('createCodexBootstrapCompletionOwner', { ...f.dependencies,
|
|
573
|
+
runCodexBootstrapHostScope, createCodexSetupReadinessOwner, assertCodexSetupExecutionLease, withCodexSetupSessionSender,
|
|
574
|
+
observeCodexBootstrapRuntime: f.observe, bootstrapFromCodexSetupScope,
|
|
575
|
+
});
|
|
576
|
+
const start = await declaration('startCodexBootstrapNativeHost', { resolve, dharmaHome: () => home,
|
|
577
|
+
runCodexBootstrapHostScope, startCodexSetupNativeHost, createCodexBootstrapCompletionOwner: compose,
|
|
578
|
+
openBootstrapVault: async (options) => {
|
|
579
|
+
opens++;
|
|
580
|
+
assert.equal(options.root, resolve(home, 'vault'));
|
|
581
|
+
const scope = currentBootstrapHostScope();
|
|
582
|
+
assert.ok(scope);
|
|
583
|
+
originalScope = scope;
|
|
584
|
+
vault = await LocalVault.open({ ...options, masterKey: key }, scope);
|
|
585
|
+
if (withdrawAfterOpen)
|
|
586
|
+
allowed = false;
|
|
587
|
+
const owned = vault;
|
|
588
|
+
return { ...owned, close: async () => { closes++; await owned.close(); } };
|
|
589
|
+
},
|
|
590
|
+
});
|
|
591
|
+
const contract = await loadAgentFabricOnboardingContract();
|
|
592
|
+
const input = { transport, workspace: f.row.path, name: 'reviewer',
|
|
593
|
+
intent: { ...f.prepared.intent, contractDigest: `sha256:${contract.sha256}` },
|
|
594
|
+
signal: new AbortController().signal, current: async () => allowed,
|
|
595
|
+
maximumProviderCostCents: 25, reserve: async () => true };
|
|
596
|
+
if (withdrawAfterOpen) {
|
|
597
|
+
await assert.rejects(start(input), { message: 'codex_setup_host_scope_unavailable' });
|
|
598
|
+
assert.equal(opens, 1);
|
|
599
|
+
assert.equal(closes, 1);
|
|
600
|
+
assert.equal(handler, undefined);
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
const host = await start(input);
|
|
604
|
+
try {
|
|
605
|
+
assert.ok(handler);
|
|
606
|
+
assert.ok(originalScope);
|
|
607
|
+
assert.equal(await originalScope.current(), true);
|
|
608
|
+
const response = await handler({ threadId: 'synthetic_thread', turnId: 'synthetic_turn', callId: 'setup_call',
|
|
609
|
+
tool: 'dharma_setup_reference', namespace: null, arguments: { operationId: id(1), setupReference: id(2) } }, { signal: transport.signal });
|
|
610
|
+
assert.equal(response.success, false);
|
|
611
|
+
assert.equal(JSON.parse(response.contentItems[0].text).code, 'codex_setup_execution_unconfirmed');
|
|
612
|
+
assert.equal(f.calls.length, 0, 'the guarded actual bootstrap cannot synthesize live readiness');
|
|
613
|
+
assert.equal(opens, 1);
|
|
614
|
+
assert.equal(closes, 0);
|
|
615
|
+
for (const listener of listeners)
|
|
616
|
+
listener({ method: 'turn/completed',
|
|
617
|
+
params: { threadId: 'synthetic_thread', turn: { id: 'synthetic_turn', status: 'completed' } } });
|
|
618
|
+
await host.settled;
|
|
619
|
+
assert.equal(closes, 1);
|
|
620
|
+
assert.equal(await originalScope.current(), false);
|
|
621
|
+
assert.equal(handler, undefined);
|
|
622
|
+
assert.equal(listeners.size, 0);
|
|
623
|
+
}
|
|
624
|
+
finally {
|
|
625
|
+
await host.close();
|
|
626
|
+
}
|
|
627
|
+
assert.equal(closes, 1);
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
//# sourceMappingURL=codexBootstrapCompletion.test.js.map
|