@dharma-ai-labs/agent-fabric 0.2.153 → 0.2.155

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.
Files changed (300) hide show
  1. package/dist/bootstrapGitScope.test.d.ts +2 -0
  2. package/dist/bootstrapGitScope.test.d.ts.map +1 -0
  3. package/dist/bootstrapGitScope.test.js +115 -0
  4. package/dist/bootstrapGitScope.test.js.map +1 -0
  5. package/dist/bootstrapHostFiles.d.ts +5 -0
  6. package/dist/bootstrapHostFiles.d.ts.map +1 -0
  7. package/dist/bootstrapHostFiles.js +150 -0
  8. package/dist/bootstrapHostFiles.js.map +1 -0
  9. package/dist/bootstrapHostFiles.test.d.ts +2 -0
  10. package/dist/bootstrapHostFiles.test.d.ts.map +1 -0
  11. package/dist/bootstrapHostFiles.test.js +127 -0
  12. package/dist/bootstrapHostFiles.test.js.map +1 -0
  13. package/dist/bootstrapHostScope.d.ts +42 -0
  14. package/dist/bootstrapHostScope.d.ts.map +1 -0
  15. package/dist/bootstrapHostScope.js +224 -0
  16. package/dist/bootstrapHostScope.js.map +1 -0
  17. package/dist/bootstrapHostScope.test.d.ts +2 -0
  18. package/dist/bootstrapHostScope.test.d.ts.map +1 -0
  19. package/dist/bootstrapHostScope.test.js +577 -0
  20. package/dist/bootstrapHostScope.test.js.map +1 -0
  21. package/dist/bootstrapInstallationScope.test.d.ts +2 -0
  22. package/dist/bootstrapInstallationScope.test.d.ts.map +1 -0
  23. package/dist/bootstrapInstallationScope.test.js +68 -0
  24. package/dist/bootstrapInstallationScope.test.js.map +1 -0
  25. package/dist/bootstrapLauncherCaller.test.d.ts +2 -0
  26. package/dist/bootstrapLauncherCaller.test.d.ts.map +1 -0
  27. package/dist/bootstrapLauncherCaller.test.js +91 -0
  28. package/dist/bootstrapLauncherCaller.test.js.map +1 -0
  29. package/dist/bootstrapOwnedChildren.test.d.ts +2 -0
  30. package/dist/bootstrapOwnedChildren.test.d.ts.map +1 -0
  31. package/dist/bootstrapOwnedChildren.test.js +93 -0
  32. package/dist/bootstrapOwnedChildren.test.js.map +1 -0
  33. package/dist/bootstrapPolicyScope.test.d.ts +2 -0
  34. package/dist/bootstrapPolicyScope.test.d.ts.map +1 -0
  35. package/dist/bootstrapPolicyScope.test.js +261 -0
  36. package/dist/bootstrapPolicyScope.test.js.map +1 -0
  37. package/dist/bootstrapProcessCaller.test.d.ts +2 -0
  38. package/dist/bootstrapProcessCaller.test.d.ts.map +1 -0
  39. package/dist/bootstrapProcessCaller.test.js +262 -0
  40. package/dist/bootstrapProcessCaller.test.js.map +1 -0
  41. package/dist/bootstrapRegistryCaller.test.d.ts +2 -0
  42. package/dist/bootstrapRegistryCaller.test.d.ts.map +1 -0
  43. package/dist/bootstrapRegistryCaller.test.js +128 -0
  44. package/dist/bootstrapRegistryCaller.test.js.map +1 -0
  45. package/dist/bootstrapVaultScope.test.d.ts +2 -0
  46. package/dist/bootstrapVaultScope.test.d.ts.map +1 -0
  47. package/dist/bootstrapVaultScope.test.js +105 -0
  48. package/dist/bootstrapVaultScope.test.js.map +1 -0
  49. package/dist/codexBootstrapCompletion.test.d.ts +2 -0
  50. package/dist/codexBootstrapCompletion.test.d.ts.map +1 -0
  51. package/dist/codexBootstrapCompletion.test.js +630 -0
  52. package/dist/codexBootstrapCompletion.test.js.map +1 -0
  53. package/dist/codexBoundSession.d.ts +2 -2
  54. package/dist/codexBoundSession.d.ts.map +1 -1
  55. package/dist/codexBoundSession.js +23 -17
  56. package/dist/codexBoundSession.js.map +1 -1
  57. package/dist/codexBoundSession.test.js +3 -0
  58. package/dist/codexBoundSession.test.js.map +1 -1
  59. package/dist/codexInboxSession.d.ts.map +1 -1
  60. package/dist/codexInboxSession.js +3 -3
  61. package/dist/codexInboxSession.js.map +1 -1
  62. package/dist/codexScopedDispatch.test.d.ts +2 -0
  63. package/dist/codexScopedDispatch.test.d.ts.map +1 -0
  64. package/dist/codexScopedDispatch.test.js +56 -0
  65. package/dist/codexScopedDispatch.test.js.map +1 -0
  66. package/dist/codexSetupAdmission.d.ts +108 -0
  67. package/dist/codexSetupAdmission.d.ts.map +1 -0
  68. package/dist/codexSetupAdmission.js +214 -0
  69. package/dist/codexSetupAdmission.js.map +1 -0
  70. package/dist/codexSetupAdmission.test.d.ts +2 -0
  71. package/dist/codexSetupAdmission.test.d.ts.map +1 -0
  72. package/dist/codexSetupAdmission.test.js +578 -0
  73. package/dist/codexSetupAdmission.test.js.map +1 -0
  74. package/dist/codexSetupChildProvider.test.d.ts +2 -0
  75. package/dist/codexSetupChildProvider.test.d.ts.map +1 -0
  76. package/dist/codexSetupChildProvider.test.js +210 -0
  77. package/dist/codexSetupChildProvider.test.js.map +1 -0
  78. package/dist/codexSetupChildStartup.d.ts +38 -0
  79. package/dist/codexSetupChildStartup.d.ts.map +1 -0
  80. package/dist/codexSetupChildStartup.js +115 -0
  81. package/dist/codexSetupChildStartup.js.map +1 -0
  82. package/dist/codexSetupChildStartup.test.d.ts +2 -0
  83. package/dist/codexSetupChildStartup.test.d.ts.map +1 -0
  84. package/dist/codexSetupChildStartup.test.js +141 -0
  85. package/dist/codexSetupChildStartup.test.js.map +1 -0
  86. package/dist/codexSetupCliDispatch.test.d.ts +2 -0
  87. package/dist/codexSetupCliDispatch.test.d.ts.map +1 -0
  88. package/dist/codexSetupCliDispatch.test.js +138 -0
  89. package/dist/codexSetupCliDispatch.test.js.map +1 -0
  90. package/dist/codexSetupJournalOpen.test.d.ts +2 -0
  91. package/dist/codexSetupJournalOpen.test.d.ts.map +1 -0
  92. package/dist/codexSetupJournalOpen.test.js +101 -0
  93. package/dist/codexSetupJournalOpen.test.js.map +1 -0
  94. package/dist/codexSetupNativeHost.d.ts +31 -0
  95. package/dist/codexSetupNativeHost.d.ts.map +1 -0
  96. package/dist/codexSetupNativeHost.js +211 -0
  97. package/dist/codexSetupNativeHost.js.map +1 -0
  98. package/dist/codexSetupNativeHost.test.d.ts +2 -0
  99. package/dist/codexSetupNativeHost.test.d.ts.map +1 -0
  100. package/dist/codexSetupNativeHost.test.js +479 -0
  101. package/dist/codexSetupNativeHost.test.js.map +1 -0
  102. package/dist/codexSetupNativeWire.test.d.ts +2 -0
  103. package/dist/codexSetupNativeWire.test.d.ts.map +1 -0
  104. package/dist/codexSetupNativeWire.test.js +243 -0
  105. package/dist/codexSetupNativeWire.test.js.map +1 -0
  106. package/dist/codexSetupOwnedConnection.d.ts +14 -0
  107. package/dist/codexSetupOwnedConnection.d.ts.map +1 -0
  108. package/dist/codexSetupOwnedConnection.js +64 -0
  109. package/dist/codexSetupOwnedConnection.js.map +1 -0
  110. package/dist/codexSetupOwnedConnection.test.d.ts +2 -0
  111. package/dist/codexSetupOwnedConnection.test.d.ts.map +1 -0
  112. package/dist/codexSetupOwnedConnection.test.js +192 -0
  113. package/dist/codexSetupOwnedConnection.test.js.map +1 -0
  114. package/dist/codexSetupPortalCommand.test.d.ts +2 -0
  115. package/dist/codexSetupPortalCommand.test.d.ts.map +1 -0
  116. package/dist/codexSetupPortalCommand.test.js +146 -0
  117. package/dist/codexSetupPortalCommand.test.js.map +1 -0
  118. package/dist/codexSetupReadiness.d.ts +23 -0
  119. package/dist/codexSetupReadiness.d.ts.map +1 -0
  120. package/dist/codexSetupReadiness.js +74 -0
  121. package/dist/codexSetupReadiness.js.map +1 -0
  122. package/dist/codexSetupReadiness.test.d.ts +2 -0
  123. package/dist/codexSetupReadiness.test.d.ts.map +1 -0
  124. package/dist/codexSetupReadiness.test.js +145 -0
  125. package/dist/codexSetupReadiness.test.js.map +1 -0
  126. package/dist/codexSetupSessionCaller.test.d.ts +2 -0
  127. package/dist/codexSetupSessionCaller.test.d.ts.map +1 -0
  128. package/dist/codexSetupSessionCaller.test.js +352 -0
  129. package/dist/codexSetupSessionCaller.test.js.map +1 -0
  130. package/dist/codexSetupSessionHandoff.d.ts +48 -0
  131. package/dist/codexSetupSessionHandoff.d.ts.map +1 -0
  132. package/dist/codexSetupSessionHandoff.js +146 -0
  133. package/dist/codexSetupSessionHandoff.js.map +1 -0
  134. package/dist/codexSetupSessionHandoff.test.d.ts +2 -0
  135. package/dist/codexSetupSessionHandoff.test.d.ts.map +1 -0
  136. package/dist/codexSetupSessionHandoff.test.js +289 -0
  137. package/dist/codexSetupSessionHandoff.test.js.map +1 -0
  138. package/dist/codexSetupTransport.test.d.ts +2 -0
  139. package/dist/codexSetupTransport.test.d.ts.map +1 -0
  140. package/dist/codexSetupTransport.test.js +206 -0
  141. package/dist/codexSetupTransport.test.js.map +1 -0
  142. package/dist/codexSetupVaultJournal.d.ts +13 -0
  143. package/dist/codexSetupVaultJournal.d.ts.map +1 -0
  144. package/dist/codexSetupVaultJournal.js +28 -0
  145. package/dist/codexSetupVaultJournal.js.map +1 -0
  146. package/dist/codexSetupVaultJournal.test.d.ts +2 -0
  147. package/dist/codexSetupVaultJournal.test.d.ts.map +1 -0
  148. package/dist/codexSetupVaultJournal.test.js +104 -0
  149. package/dist/codexSetupVaultJournal.test.js.map +1 -0
  150. package/dist/containerChildCleanup.test.d.ts +2 -0
  151. package/dist/containerChildCleanup.test.d.ts.map +1 -0
  152. package/dist/containerChildCleanup.test.js +145 -0
  153. package/dist/containerChildCleanup.test.js.map +1 -0
  154. package/dist/containerRelayLifecycle.d.ts +1 -1
  155. package/dist/containerRelayLifecycle.d.ts.map +1 -1
  156. package/dist/containerRelayLifecycle.js +29 -37
  157. package/dist/containerRelayLifecycle.js.map +1 -1
  158. package/dist/cooperativeInboxSession.d.ts +2 -2
  159. package/dist/cooperativeInboxSession.d.ts.map +1 -1
  160. package/dist/cooperativeInboxSession.js +21 -13
  161. package/dist/cooperativeInboxSession.js.map +1 -1
  162. package/dist/cooperativeInboxSession.test.js +65 -0
  163. package/dist/cooperativeInboxSession.test.js.map +1 -1
  164. package/dist/demoWatchControl.d.ts +3 -3
  165. package/dist/index.d.ts +55 -14
  166. package/dist/index.d.ts.map +1 -1
  167. package/dist/index.js +1642 -553
  168. package/dist/index.js.map +1 -1
  169. package/dist/namedCodexSkillDiscovery.d.ts +15 -0
  170. package/dist/namedCodexSkillDiscovery.d.ts.map +1 -0
  171. package/dist/namedCodexSkillDiscovery.js +90 -0
  172. package/dist/namedCodexSkillDiscovery.js.map +1 -0
  173. package/dist/namedCodexSkillDiscovery.test.d.ts +2 -0
  174. package/dist/namedCodexSkillDiscovery.test.d.ts.map +1 -0
  175. package/dist/namedCodexSkillDiscovery.test.js +37 -0
  176. package/dist/namedCodexSkillDiscovery.test.js.map +1 -0
  177. package/dist/namedCodexThread.d.ts +2 -0
  178. package/dist/namedCodexThread.d.ts.map +1 -1
  179. package/dist/namedCodexThread.js +13 -4
  180. package/dist/namedCodexThread.js.map +1 -1
  181. package/dist/namedSessionChildOwner.d.ts +17 -0
  182. package/dist/namedSessionChildOwner.d.ts.map +1 -0
  183. package/dist/namedSessionChildOwner.js +122 -0
  184. package/dist/namedSessionChildOwner.js.map +1 -0
  185. package/dist/namedSessionChildOwner.test.d.ts +2 -0
  186. package/dist/namedSessionChildOwner.test.d.ts.map +1 -0
  187. package/dist/namedSessionChildOwner.test.js +203 -0
  188. package/dist/namedSessionChildOwner.test.js.map +1 -0
  189. package/dist/namedSessionEvidence.d.ts +2 -2
  190. package/dist/namedSessionEvidence.d.ts.map +1 -1
  191. package/dist/namedSessionEvidence.js +2 -2
  192. package/dist/namedSessionEvidence.js.map +1 -1
  193. package/dist/namedSessionEvidence.test.js +24 -1
  194. package/dist/namedSessionEvidence.test.js.map +1 -1
  195. package/dist/namedSessionRepositoryState.d.ts +2 -2
  196. package/dist/namedSessionRepositoryState.d.ts.map +1 -1
  197. package/dist/namedSessionService.d.ts +4 -2
  198. package/dist/namedSessionService.d.ts.map +1 -1
  199. package/dist/namedSessionService.js +18 -1
  200. package/dist/namedSessionService.js.map +1 -1
  201. package/dist/namedSessionService.test.js +31 -2
  202. package/dist/namedSessionService.test.js.map +1 -1
  203. package/dist/namedSessionTaskExportSync.d.ts +3 -3
  204. package/dist/namedSessionTaskExportSync.d.ts.map +1 -1
  205. package/dist/namedSessionTaskExportSync.js +6 -6
  206. package/dist/namedSessionTaskExportSync.js.map +1 -1
  207. package/dist/namedSessionTrust.d.ts +2 -2
  208. package/dist/namedSessionTrust.d.ts.map +1 -1
  209. package/dist/namedSessionTrust.js +3 -2
  210. package/dist/namedSessionTrust.js.map +1 -1
  211. package/dist/namedSessionTrust.test.js +2 -1
  212. package/dist/namedSessionTrust.test.js.map +1 -1
  213. package/dist/ownedChildLifecycle.d.ts +13 -0
  214. package/dist/ownedChildLifecycle.d.ts.map +1 -0
  215. package/dist/ownedChildLifecycle.js +87 -0
  216. package/dist/ownedChildLifecycle.js.map +1 -0
  217. package/dist/ownedChildLifecycle.test.d.ts +2 -0
  218. package/dist/ownedChildLifecycle.test.d.ts.map +1 -0
  219. package/dist/ownedChildLifecycle.test.js +133 -0
  220. package/dist/ownedChildLifecycle.test.js.map +1 -0
  221. package/dist/pidLock.test.js +242 -9
  222. package/dist/pidLock.test.js.map +1 -1
  223. package/dist/providerSessionChannel.d.ts +1 -1
  224. package/dist/providerSessionChannel.d.ts.map +1 -1
  225. package/dist/providerSessionChannel.js +7 -3
  226. package/dist/providerSessionChannel.js.map +1 -1
  227. package/dist/providerSessionChannel.test.js +20 -0
  228. package/dist/providerSessionChannel.test.js.map +1 -1
  229. package/dist/providerSessionReplyRecovery.d.ts +2 -2
  230. package/dist/providerSessionReplyRecovery.d.ts.map +1 -1
  231. package/dist/providerSessionReplyRecovery.js +3 -3
  232. package/dist/providerSessionReplyRecovery.js.map +1 -1
  233. package/dist/relayAutostart.d.ts.map +1 -1
  234. package/dist/relayAutostart.js +12 -9
  235. package/dist/relayAutostart.js.map +1 -1
  236. package/dist/relayRuntimeUpgrade.d.ts +1 -1
  237. package/dist/relaySupervisor.d.ts.map +1 -1
  238. package/dist/relaySupervisor.js +19 -14
  239. package/dist/relaySupervisor.js.map +1 -1
  240. package/dist/relaySupervisor.test.js +26 -0
  241. package/dist/relaySupervisor.test.js.map +1 -1
  242. package/dist/relaySupervisorCleanup.test.d.ts +2 -0
  243. package/dist/relaySupervisorCleanup.test.d.ts.map +1 -0
  244. package/dist/relaySupervisorCleanup.test.js +69 -0
  245. package/dist/relaySupervisorCleanup.test.js.map +1 -0
  246. package/dist/repositoryInstallerFiles.d.ts +19 -1
  247. package/dist/repositoryInstallerFiles.d.ts.map +1 -1
  248. package/dist/repositoryInstallerFiles.js +205 -29
  249. package/dist/repositoryInstallerFiles.js.map +1 -1
  250. package/dist/repositoryInstallerScope.test.d.ts +2 -0
  251. package/dist/repositoryInstallerScope.test.d.ts.map +1 -0
  252. package/dist/repositoryInstallerScope.test.js +513 -0
  253. package/dist/repositoryInstallerScope.test.js.map +1 -0
  254. package/dist/repositoryKnowledge.d.ts.map +1 -1
  255. package/dist/repositoryKnowledge.js +177 -37
  256. package/dist/repositoryKnowledge.js.map +1 -1
  257. package/dist/repositoryKnowledgeScope.test.d.ts +2 -0
  258. package/dist/repositoryKnowledgeScope.test.d.ts.map +1 -0
  259. package/dist/repositoryKnowledgeScope.test.js +316 -0
  260. package/dist/repositoryKnowledgeScope.test.js.map +1 -0
  261. package/dist/repositoryOnboardingCaller.test.js +61 -4
  262. package/dist/repositoryOnboardingCaller.test.js.map +1 -1
  263. package/dist/repositoryPackage.d.ts.map +1 -1
  264. package/dist/repositoryPackage.js +340 -59
  265. package/dist/repositoryPackage.js.map +1 -1
  266. package/dist/repositoryPackageDelivery.test.js +65 -0
  267. package/dist/repositoryPackageDelivery.test.js.map +1 -1
  268. package/dist/repositoryPackageScope.test.d.ts +2 -0
  269. package/dist/repositoryPackageScope.test.d.ts.map +1 -0
  270. package/dist/repositoryPackageScope.test.js +578 -0
  271. package/dist/repositoryPackageScope.test.js.map +1 -0
  272. package/dist/schemas/codex-setup-child-start.schema.json +12 -0
  273. package/dist/schemas/codex-setup-intent.schema.json +27 -0
  274. package/dist/schemas/local-codex-setup-session.schema.json +39 -0
  275. package/dist/schemas/setup-claim-failure.schema.json +15 -0
  276. package/dist/skillInstallationScope.test.d.ts +2 -0
  277. package/dist/skillInstallationScope.test.d.ts.map +1 -0
  278. package/dist/skillInstallationScope.test.js +64 -0
  279. package/dist/skillInstallationScope.test.js.map +1 -0
  280. package/dist/skillPreparationCache.test.js +12 -4
  281. package/dist/skillPreparationCache.test.js.map +1 -1
  282. package/dist/skillPreparationCaller.test.js +31 -1
  283. package/dist/skillPreparationCaller.test.js.map +1 -1
  284. package/dist/startupCommitScope.test.d.ts +2 -0
  285. package/dist/startupCommitScope.test.d.ts.map +1 -0
  286. package/dist/startupCommitScope.test.js +172 -0
  287. package/dist/startupCommitScope.test.js.map +1 -0
  288. package/dist/workspaceRegistry.d.ts.map +1 -1
  289. package/dist/workspaceRegistry.js +7 -3
  290. package/dist/workspaceRegistry.js.map +1 -1
  291. package/dist/workspaceRegistry.test.js +51 -0
  292. package/dist/workspaceRegistry.test.js.map +1 -1
  293. package/dist/workspaceRegistryRecovery.d.ts.map +1 -1
  294. package/dist/workspaceRegistryRecovery.js +171 -64
  295. package/dist/workspaceRegistryRecovery.js.map +1 -1
  296. package/dist/workspaceRegistryRecoveryScope.test.d.ts +2 -0
  297. package/dist/workspaceRegistryRecoveryScope.test.d.ts.map +1 -0
  298. package/dist/workspaceRegistryRecoveryScope.test.js +416 -0
  299. package/dist/workspaceRegistryRecoveryScope.test.js.map +1 -0
  300. 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