spawnfile 0.1.14 → 0.1.17

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 (546) hide show
  1. package/README.md +60 -159
  2. package/dist/audit/checksShared.d.ts +1 -1
  3. package/dist/auth/importers.d.ts +10 -0
  4. package/dist/auth/importers.js +29 -4
  5. package/dist/auth/index.d.ts +2 -0
  6. package/dist/auth/index.js +1 -0
  7. package/dist/auth/paths.d.ts +1 -1
  8. package/dist/auth/profileStore.js +9 -9
  9. package/dist/auth/targetSecretSourceFsIdentity.d.ts +40 -0
  10. package/dist/auth/targetSecretSourceFsIdentity.js +42 -0
  11. package/dist/auth/targetSecretSourceFsPublish.d.ts +2 -0
  12. package/dist/auth/targetSecretSourceFsPublish.js +3 -1
  13. package/dist/auth/targetSecretSourceFsPublishImmutable.d.ts +2 -1
  14. package/dist/auth/targetSecretSourceFsPublishImmutable.js +104 -71
  15. package/dist/auth/targetSecretSourceFsRead.js +5 -14
  16. package/dist/auth/trainingAuth.d.ts +21 -0
  17. package/dist/auth/trainingAuth.js +86 -0
  18. package/dist/auth/types.d.ts +1 -1
  19. package/dist/cli/authCommands.d.ts +1 -1
  20. package/dist/cli/authCommands.js +9 -0
  21. package/dist/cli/canaryCutoverCommand.d.ts +2 -0
  22. package/dist/cli/canaryCutoverCommand.js +30 -0
  23. package/dist/cli/capabilitiesCommand.d.ts +3 -0
  24. package/dist/cli/capabilitiesCommand.js +12 -0
  25. package/dist/cli/capabilitiesReceipt.d.ts +56 -0
  26. package/dist/cli/capabilitiesReceipt.js +56 -0
  27. package/dist/cli/compileBuildCommands.js +13 -0
  28. package/dist/cli/composedLifecycleContractSet.d.ts +21 -0
  29. package/dist/cli/composedLifecycleContractSet.js +204 -0
  30. package/dist/cli/devCommands.js +2 -0
  31. package/dist/cli/downCommand.js +19 -8
  32. package/dist/cli/evidenceExportHelperCommand.d.ts +13 -0
  33. package/dist/cli/evidenceExportHelperCommand.js +51 -0
  34. package/dist/cli/index.js +12 -3
  35. package/dist/cli/lifecycleMachine.d.ts +7 -1
  36. package/dist/cli/lifecycleMachine.js +2 -2
  37. package/dist/cli/paideiaDelegation.d.ts +17 -0
  38. package/dist/cli/paideiaDelegation.js +210 -0
  39. package/dist/cli/paideiaSupervisor.d.ts +17 -0
  40. package/dist/cli/paideiaSupervisor.js +48 -0
  41. package/dist/cli/productStateCloneCommand.d.ts +2 -0
  42. package/dist/cli/productStateCloneCommand.js +34 -0
  43. package/dist/cli/runCli.d.ts +13 -3
  44. package/dist/cli/runCli.js +37 -9
  45. package/dist/cli/targetCommands.d.ts +4 -7
  46. package/dist/cli/targetCommands.js +16 -46
  47. package/dist/cli/targetConfigPreparedPlan.d.ts +3 -0
  48. package/dist/cli/targetConfigPreparedPlan.js +74 -0
  49. package/dist/cli/targetConfigResolver.d.ts +3 -0
  50. package/dist/cli/targetConfigResolver.js +111 -0
  51. package/dist/cli/targetConfigResolverCommand.d.ts +6 -0
  52. package/dist/cli/targetConfigResolverCommand.js +43 -0
  53. package/dist/cli/targetConfigResolverContracts.d.ts +56 -0
  54. package/dist/cli/targetConfigResolverContracts.js +30 -0
  55. package/dist/cli/targetConfigResolverDocker.d.ts +4 -0
  56. package/dist/cli/targetConfigResolverDocker.js +47 -0
  57. package/dist/cli/targetConfigResolverValidation.d.ts +10 -0
  58. package/dist/cli/targetConfigResolverValidation.js +94 -0
  59. package/dist/cli/targetDefaultAuthorities.d.ts +2 -0
  60. package/dist/cli/targetDefaultAuthorities.js +3 -0
  61. package/dist/cli/targetDefaultConfig.d.ts +7 -0
  62. package/dist/cli/targetDefaultConfig.js +22 -5
  63. package/dist/cli/targetDefaultConfigStdin.js +7 -1
  64. package/dist/cli/targetDefaultHandlerFactory.js +23 -2
  65. package/dist/cli/targetDefaultHandlers.d.ts +2 -2
  66. package/dist/cli/targetProductionCommands.d.ts +5 -0
  67. package/dist/cli/targetProductionCommands.js +45 -0
  68. package/dist/cli/trainCommand.d.ts +3 -0
  69. package/dist/cli/trainCommand.js +61 -0
  70. package/dist/cli/upCommand.js +35 -6
  71. package/dist/cli/upLifecycleRecovery.d.ts +2 -2
  72. package/dist/cli/upLifecycleRecovery.js +188 -44
  73. package/dist/cli/usageCommand.d.ts +40 -0
  74. package/dist/cli/usageCommand.js +284 -0
  75. package/dist/cli/usageCommandLive.d.ts +84 -0
  76. package/dist/cli/usageCommandLive.js +95 -0
  77. package/dist/cli/usageDeploymentSource.d.ts +9 -0
  78. package/dist/cli/usageDeploymentSource.js +22 -0
  79. package/dist/cli/workspaceResourceMigrationCommand.d.ts +8 -0
  80. package/dist/cli/workspaceResourceMigrationCommand.js +36 -0
  81. package/dist/compiler/buildCompilePlanTeams.d.ts +1 -1
  82. package/dist/compiler/buildCompilePlanTeams.js +6 -1
  83. package/dist/compiler/compilePlanHelpers.js +3 -0
  84. package/dist/compiler/compileProject.d.ts +2 -0
  85. package/dist/compiler/compileProject.js +5 -1
  86. package/dist/compiler/compileProjectSupport.js +9 -0
  87. package/dist/compiler/containerArtifacts.d.ts +3 -1
  88. package/dist/compiler/containerArtifacts.js +92 -40
  89. package/dist/compiler/containerArtifactsPlans.d.ts +1 -1
  90. package/dist/compiler/containerArtifactsPlans.js +24 -7
  91. package/dist/compiler/containerArtifactsRender.d.ts +2 -1
  92. package/dist/compiler/containerArtifactsRender.js +91 -58
  93. package/dist/compiler/containerArtifactsTypes.d.ts +8 -0
  94. package/dist/compiler/containerBackedMountRender.d.ts +56 -0
  95. package/dist/compiler/containerBackedMountRender.js +101 -0
  96. package/dist/compiler/containerDaimonBrokerRender.d.ts +112 -0
  97. package/dist/compiler/containerDaimonBrokerRender.js +191 -0
  98. package/dist/compiler/containerDaimonGrokWorkerProvisioning.d.ts +38 -0
  99. package/dist/compiler/containerDaimonGrokWorkerProvisioning.js +108 -0
  100. package/dist/compiler/containerDaimonGrokWorkerRender.d.ts +172 -0
  101. package/dist/compiler/containerDaimonGrokWorkerRender.js +268 -0
  102. package/dist/compiler/containerDaimonOwnershipGuardRender.d.ts +12 -0
  103. package/dist/compiler/containerDaimonOwnershipGuardRender.js +191 -0
  104. package/dist/compiler/containerDaimonUidEntrypointRender.d.ts +24 -0
  105. package/dist/compiler/containerDaimonUidEntrypointRender.js +297 -0
  106. package/dist/compiler/containerEntrypointRender.d.ts +7 -0
  107. package/dist/compiler/containerEntrypointRender.js +28 -22
  108. package/dist/compiler/containerPersistentMounts.d.ts +30 -0
  109. package/dist/compiler/containerPersistentMounts.js +66 -0
  110. package/dist/compiler/containerReadinessPaths.d.ts +1 -0
  111. package/dist/compiler/containerReadinessPaths.js +1 -0
  112. package/dist/compiler/containerRuntimeLinkMaterializer.d.ts +2 -0
  113. package/dist/compiler/containerRuntimeLinkMaterializer.js +12 -0
  114. package/dist/compiler/containerRuntimeReadinessRender.d.ts +7 -0
  115. package/dist/compiler/containerRuntimeReadinessRender.js +40 -0
  116. package/dist/compiler/containerStateOwnershipRender.d.ts +4 -0
  117. package/dist/compiler/containerStateOwnershipRender.js +75 -0
  118. package/dist/compiler/containerTargetResources.d.ts +22 -1
  119. package/dist/compiler/containerTargetResources.js +94 -2
  120. package/dist/compiler/containerVolumeBootstrap.d.ts +3 -0
  121. package/dist/compiler/containerVolumeBootstrap.js +3 -0
  122. package/dist/compiler/containerWorkspaceResourceRender.js +49 -1
  123. package/dist/compiler/daimonTelemetryArtifacts.d.ts +2 -2
  124. package/dist/compiler/daimonTelemetryArtifacts.js +5 -10
  125. package/dist/compiler/deploymentLineage.d.ts +40 -0
  126. package/dist/compiler/deploymentLineage.js +50 -0
  127. package/dist/compiler/index.d.ts +3 -0
  128. package/dist/compiler/index.js +3 -0
  129. package/dist/compiler/initProject.d.ts +2 -0
  130. package/dist/compiler/initProject.js +39 -1
  131. package/dist/compiler/localMoltnetAuthority.d.ts +64 -0
  132. package/dist/compiler/localMoltnetAuthority.js +177 -0
  133. package/dist/compiler/memoryArtifacts.d.ts +1 -1
  134. package/dist/compiler/memoryArtifacts.js +108 -32
  135. package/dist/compiler/modelEnv.d.ts +5 -0
  136. package/dist/compiler/modelEnv.js +8 -2
  137. package/dist/compiler/moltnetArtifactPaths.d.ts +17 -12
  138. package/dist/compiler/moltnetArtifactPaths.js +17 -15
  139. package/dist/compiler/moltnetArtifactTypes.d.ts +10 -0
  140. package/dist/compiler/moltnetArtifacts.d.ts +1 -1
  141. package/dist/compiler/moltnetArtifacts.js +52 -12
  142. package/dist/compiler/moltnetBinaries.d.ts +16 -4
  143. package/dist/compiler/moltnetBinaries.js +46 -6
  144. package/dist/compiler/moltnetClientConfig.js +1 -1
  145. package/dist/compiler/moltnetConfigLowering.d.ts +3 -1
  146. package/dist/compiler/moltnetConfigLowering.js +30 -6
  147. package/dist/compiler/moltnetNodeConfig.js +1 -1
  148. package/dist/compiler/moltnetReleaseAuthority.d.ts +24 -1
  149. package/dist/compiler/moltnetReleaseAuthority.js +33 -4
  150. package/dist/compiler/moltnetRepresentativeResolution.d.ts +1 -1
  151. package/dist/compiler/moltnetRepresentativeResolution.js +2 -2
  152. package/dist/compiler/moltnetResolution.js +9 -15
  153. package/dist/compiler/moltnetRoomMemberships.js +20 -5
  154. package/dist/compiler/moltnetRoomPolicyCompatibility.d.ts +1 -1
  155. package/dist/compiler/moltnetRoomPolicyCompatibility.js +3 -1
  156. package/dist/compiler/moltnetRuntimeConfig.d.ts +1 -1
  157. package/dist/compiler/moltnetRuntimeConfig.js +22 -2
  158. package/dist/compiler/moltnetServerPlans.js +19 -0
  159. package/dist/compiler/organizationExternalParticipants.d.ts +3 -0
  160. package/dist/compiler/organizationExternalParticipants.js +176 -0
  161. package/dist/compiler/organizationIdentity.d.ts +3 -9
  162. package/dist/compiler/organizationIdentity.js +37 -270
  163. package/dist/compiler/organizationIdentityGraph.d.ts +15 -0
  164. package/dist/compiler/organizationIdentityGraph.js +115 -0
  165. package/dist/compiler/organizationReadyEvidence.d.ts +8 -0
  166. package/dist/compiler/organizationReadyEvidence.js +23 -3
  167. package/dist/compiler/runProject.d.ts +4 -2
  168. package/dist/compiler/runProject.js +32 -6
  169. package/dist/compiler/runProjectAuth.d.ts +3 -1
  170. package/dist/compiler/runProjectAuth.js +19 -3
  171. package/dist/compiler/runProjectDaimonCodexDocker.d.ts +3 -0
  172. package/dist/compiler/runProjectDaimonCodexDocker.js +36 -0
  173. package/dist/compiler/runProjectDocker.d.ts +8 -4
  174. package/dist/compiler/runProjectDocker.js +43 -18
  175. package/dist/compiler/runProjectDockerDaimonGuards.d.ts +15 -0
  176. package/dist/compiler/runProjectDockerDaimonGuards.js +122 -0
  177. package/dist/compiler/runProjectDockerReservation.d.ts +3 -0
  178. package/dist/compiler/runProjectDockerReservation.js +118 -0
  179. package/dist/compiler/runProjectLifecycle.js +1 -1
  180. package/dist/compiler/training/broker/declaration.d.ts +45 -0
  181. package/dist/compiler/training/broker/declaration.js +55 -0
  182. package/dist/compiler/training/broker/entrypoint.d.ts +39 -0
  183. package/dist/compiler/training/broker/entrypoint.js +111 -0
  184. package/dist/compiler/training/broker/index.d.ts +10 -0
  185. package/dist/compiler/training/broker/index.js +10 -0
  186. package/dist/compiler/training/broker/main.d.ts +2 -0
  187. package/dist/compiler/training/broker/main.js +14 -0
  188. package/dist/compiler/training/broker/paths.d.ts +196 -0
  189. package/dist/compiler/training/broker/paths.js +241 -0
  190. package/dist/compiler/training/broker/processes.d.ts +42 -0
  191. package/dist/compiler/training/broker/processes.js +99 -0
  192. package/dist/compiler/training/broker/projection.d.ts +51 -0
  193. package/dist/compiler/training/broker/projection.js +76 -0
  194. package/dist/compiler/training/broker/provisioning.d.ts +87 -0
  195. package/dist/compiler/training/broker/provisioning.js +213 -0
  196. package/dist/compiler/training/broker/receipt.d.ts +77 -0
  197. package/dist/compiler/training/broker/receipt.js +110 -0
  198. package/dist/compiler/training/broker/registration.d.ts +41 -0
  199. package/dist/compiler/training/broker/registration.js +102 -0
  200. package/dist/compiler/training/broker/runtime.d.ts +25 -0
  201. package/dist/compiler/training/broker/runtime.js +173 -0
  202. package/dist/compiler/training/broker/seccompRoutes.d.ts +31 -0
  203. package/dist/compiler/training/broker/seccompRoutes.js +36 -0
  204. package/dist/compiler/training/broker/supervisor.d.ts +109 -0
  205. package/dist/compiler/training/broker/supervisor.js +173 -0
  206. package/dist/compiler/training/container/contract.d.ts +31 -0
  207. package/dist/compiler/training/container/contract.js +33 -0
  208. package/dist/compiler/training/container/index.d.ts +4 -0
  209. package/dist/compiler/training/container/index.js +2 -0
  210. package/dist/compiler/training/container/launch.d.ts +18 -0
  211. package/dist/compiler/training/container/launch.js +173 -0
  212. package/dist/compiler/training/container/prepare.d.ts +8 -0
  213. package/dist/compiler/training/container/prepare.js +80 -0
  214. package/dist/compiler/training/container/process.d.ts +14 -0
  215. package/dist/compiler/training/container/process.js +70 -0
  216. package/dist/compiler/training/container/security.d.ts +36 -0
  217. package/dist/compiler/training/container/security.js +58 -0
  218. package/dist/compiler/training/context.d.ts +7 -0
  219. package/dist/compiler/training/context.js +93 -0
  220. package/dist/compiler/training/contract.d.ts +142 -0
  221. package/dist/compiler/training/contract.js +34 -0
  222. package/dist/compiler/training/index.d.ts +4 -0
  223. package/dist/compiler/training/index.js +3 -0
  224. package/dist/compiler/training/preparation/assets/Dockerfile +98 -0
  225. package/dist/compiler/training/preparation/assets/package-lock.json +3787 -0
  226. package/dist/compiler/training/preparation/broker.d.ts +21 -0
  227. package/dist/compiler/training/preparation/broker.js +43 -0
  228. package/dist/compiler/training/preparation/contextModes.d.ts +12 -0
  229. package/dist/compiler/training/preparation/contextModes.js +38 -0
  230. package/dist/compiler/training/preparation/contract.d.ts +182 -0
  231. package/dist/compiler/training/preparation/contract.js +94 -0
  232. package/dist/compiler/training/preparation/copyAssets.d.ts +1 -0
  233. package/dist/compiler/training/preparation/copyAssets.js +8 -0
  234. package/dist/compiler/training/preparation/daimonParent.d.ts +42 -0
  235. package/dist/compiler/training/preparation/daimonParent.js +114 -0
  236. package/dist/compiler/training/preparation/files.d.ts +25 -0
  237. package/dist/compiler/training/preparation/files.js +85 -0
  238. package/dist/compiler/training/preparation/image.d.ts +28 -0
  239. package/dist/compiler/training/preparation/image.js +102 -0
  240. package/dist/compiler/training/preparation/index.d.ts +3 -0
  241. package/dist/compiler/training/preparation/index.js +2 -0
  242. package/dist/compiler/training/preparation/inputs.d.ts +23 -0
  243. package/dist/compiler/training/preparation/inputs.js +93 -0
  244. package/dist/compiler/training/preparation/prepare.d.ts +33 -0
  245. package/dist/compiler/training/preparation/prepare.js +186 -0
  246. package/dist/compiler/training/preparation/scratch.d.ts +19 -0
  247. package/dist/compiler/training/preparation/scratch.js +48 -0
  248. package/dist/compiler/training/repair/compatibility.d.ts +11 -0
  249. package/dist/compiler/training/repair/compatibility.js +34 -0
  250. package/dist/compiler/training/repair/contract.d.ts +506 -0
  251. package/dist/compiler/training/repair/contract.js +31 -0
  252. package/dist/compiler/training/repair/index.d.ts +3 -0
  253. package/dist/compiler/training/repair/index.js +3 -0
  254. package/dist/compiler/training/repair/prepare.d.ts +230 -0
  255. package/dist/compiler/training/repair/prepare.js +74 -0
  256. package/dist/compiler/training/repair/witness.d.ts +203 -0
  257. package/dist/compiler/training/repair/witness.js +42 -0
  258. package/dist/compiler/types.d.ts +2 -0
  259. package/dist/compiler/upProject.d.ts +26 -1
  260. package/dist/compiler/upProject.js +117 -178
  261. package/dist/compiler/upProjectHandoff.d.ts +62 -0
  262. package/dist/compiler/upProjectHandoff.js +204 -0
  263. package/dist/compiler/upReceipt.js +49 -4
  264. package/dist/compiler/updateProjectModels.js +1 -0
  265. package/dist/compiler/view/types.d.ts +1 -1
  266. package/dist/compiler/workspaceBundleArtifacts.d.ts +3 -0
  267. package/dist/compiler/workspaceBundleArtifacts.js +106 -0
  268. package/dist/compiler/workspaceResources.d.ts +4 -1
  269. package/dist/compiler/workspaceResources.js +12 -7
  270. package/dist/deployment/artifactsExportPlan.js +51 -1
  271. package/dist/deployment/canaryCutover.d.ts +42 -0
  272. package/dist/deployment/canaryCutover.js +140 -0
  273. package/dist/deployment/candidateDiagnostics.d.ts +15 -0
  274. package/dist/deployment/candidateDiagnostics.js +90 -0
  275. package/dist/deployment/dockerLogs.js +4 -1
  276. package/dist/deployment/dockerManager.js +9 -3
  277. package/dist/deployment/dockerProbeGateway.d.ts +17 -0
  278. package/dist/deployment/dockerProbeGateway.js +17 -2
  279. package/dist/deployment/downDeployment.d.ts +5 -0
  280. package/dist/deployment/downDeployment.js +109 -8
  281. package/dist/deployment/downReceiptTypes.d.ts +17 -2
  282. package/dist/deployment/downReceiptTypes.js +17 -2
  283. package/dist/deployment/index.d.ts +4 -0
  284. package/dist/deployment/index.js +4 -0
  285. package/dist/deployment/lifecycleCompletionContracts.d.ts +66 -0
  286. package/dist/deployment/lifecycleCompletionContracts.js +34 -0
  287. package/dist/deployment/lifecycleCompletionPaths.d.ts +4 -1
  288. package/dist/deployment/lifecycleCompletionPaths.js +3 -0
  289. package/dist/deployment/lifecycleCompletionPublication.d.ts +2 -0
  290. package/dist/deployment/lifecycleCompletionPublication.js +18 -4
  291. package/dist/deployment/lifecycleCompletionStore.d.ts +1 -1
  292. package/dist/deployment/lifecycleCompletionStore.js +7 -7
  293. package/dist/deployment/lifecycleUpRecords.d.ts +11 -0
  294. package/dist/deployment/lifecycleUpRecords.js +127 -0
  295. package/dist/deployment/native/AGENTS.md +11 -0
  296. package/dist/deployment/native/rename-noreplace-arm64 +0 -0
  297. package/dist/deployment/native/rename-noreplace-arm64.provenance.json +1 -0
  298. package/dist/deployment/native/rename-noreplace-x64 +0 -0
  299. package/dist/deployment/native/rename-noreplace-x64.provenance.json +1 -0
  300. package/dist/deployment/noReplaceActivation.d.ts +17 -0
  301. package/dist/deployment/noReplaceActivation.js +50 -0
  302. package/dist/deployment/organizationHandoffAuthorityFsBudget.d.ts +110 -0
  303. package/dist/deployment/organizationHandoffAuthorityFsBudget.js +156 -0
  304. package/dist/deployment/organizationHandoffAuthorityFsClient.js +82 -27
  305. package/dist/deployment/organizationHandoffAuthorityFsElection.d.ts +21 -0
  306. package/dist/deployment/organizationHandoffAuthorityFsElection.js +57 -0
  307. package/dist/deployment/organizationHandoffAuthorityFsWorker.js +254 -108
  308. package/dist/deployment/organizationHandoffAuthorityFsWorkerStall.fixture.d.ts +1 -0
  309. package/dist/deployment/organizationHandoffAuthorityFsWorkerStall.fixture.js +16 -0
  310. package/dist/deployment/organizationHandoffAuthorityStore.js +14 -7
  311. package/dist/deployment/organizationHandoffAuthorityTypes.d.ts +2 -2
  312. package/dist/deployment/organizationHandoffAuthorityTypes.js +2 -1
  313. package/dist/deployment/organizationReady.d.ts +2 -0
  314. package/dist/deployment/organizationReady.js +36 -4
  315. package/dist/deployment/productStateClone.d.ts +43 -0
  316. package/dist/deployment/productStateClone.js +319 -0
  317. package/dist/deployment/upLifecycleRecoveryState.d.ts +23 -0
  318. package/dist/deployment/upLifecycleRecoveryState.js +12 -0
  319. package/dist/deployment/upReceiptTypes.d.ts +32 -6
  320. package/dist/deployment/upReceiptTypes.js +29 -2
  321. package/dist/deployment/workspaceResourceMigration.d.ts +55 -0
  322. package/dist/deployment/workspaceResourceMigration.js +315 -0
  323. package/dist/dev/project.d.ts +7 -0
  324. package/dist/dev/project.js +9 -0
  325. package/dist/distribution/consumeImage.d.ts +2 -0
  326. package/dist/distribution/consumeImage.js +98 -73
  327. package/dist/distribution/consumeImageDaimonDocker.d.ts +3 -0
  328. package/dist/distribution/consumeImageDaimonDocker.js +45 -0
  329. package/dist/distribution/consumeImageLifecycle.d.ts +17 -0
  330. package/dist/distribution/consumeImageLifecycle.js +231 -0
  331. package/dist/distribution/consumeImageSupport.d.ts +12 -0
  332. package/dist/distribution/consumeImageSupport.js +15 -0
  333. package/dist/distribution/distributionReportSchema.d.ts +11 -1
  334. package/dist/distribution/distributionReportSchema.js +15 -2
  335. package/dist/distribution/dockerRunner.d.ts +6 -1
  336. package/dist/distribution/dockerRunner.js +31 -4
  337. package/dist/distribution/imageRuntimeAuth.d.ts +9 -1
  338. package/dist/distribution/imageRuntimeAuth.js +70 -1
  339. package/dist/distribution/index.d.ts +1 -1
  340. package/dist/distribution/index.js +1 -1
  341. package/dist/distribution/preflight.js +5 -1
  342. package/dist/distribution/types.d.ts +14 -1
  343. package/dist/distribution/types.js +3 -0
  344. package/dist/evidenceExportHelper/boundedExecutor.d.ts +3 -0
  345. package/dist/evidenceExportHelper/boundedExecutor.js +33 -0
  346. package/dist/evidenceExportHelper/helperProgram.mjs +156 -0
  347. package/dist/evidenceExportHelper/index.d.ts +4 -0
  348. package/dist/evidenceExportHelper/index.js +4 -0
  349. package/dist/evidenceExportHelper/preparedAuthority.d.ts +64 -0
  350. package/dist/evidenceExportHelper/preparedAuthority.js +228 -0
  351. package/dist/evidenceExportHelper/preparedBuilder.d.ts +10 -0
  352. package/dist/evidenceExportHelper/preparedBuilder.js +183 -0
  353. package/dist/evidenceExportHelper/preparedBuilderTypes.d.ts +19 -0
  354. package/dist/evidenceExportHelper/preparedBuilderTypes.js +1 -0
  355. package/dist/evidenceExportHelper/recipe.d.ts +7 -0
  356. package/dist/evidenceExportHelper/recipe.js +83 -0
  357. package/dist/filesystem/io.d.ts +2 -0
  358. package/dist/filesystem/io.js +16 -1
  359. package/dist/manifest/executionSchemas.d.ts +27 -0
  360. package/dist/manifest/executionSchemas.js +21 -2
  361. package/dist/manifest/mcpSchemas.d.ts +1 -0
  362. package/dist/manifest/mcpSchemas.js +3 -0
  363. package/dist/manifest/renderSpawnfileNetworks.js +11 -0
  364. package/dist/manifest/renderSpawnfileWorkspace.js +5 -0
  365. package/dist/manifest/scheduleSchemas.d.ts +3 -1
  366. package/dist/manifest/scheduleSchemas.js +91 -5
  367. package/dist/manifest/schemas.d.ts +237 -12
  368. package/dist/manifest/schemas.js +5 -2
  369. package/dist/manifest/teamNetworkAccessSchemas.d.ts +5 -1
  370. package/dist/manifest/teamNetworkAccessSchemas.js +11 -0
  371. package/dist/manifest/teamNetworkAuthSchemas.d.ts +1 -1
  372. package/dist/manifest/teamNetworkSchemas.d.ts +17 -3
  373. package/dist/manifest/teamNetworkSchemas.js +19 -1
  374. package/dist/manifest/teamNetworkServerSchemas.d.ts +8 -3
  375. package/dist/manifest/teamNetworkServerSchemas.js +18 -2
  376. package/dist/manifest/workspaceSchemas.d.ts +16 -0
  377. package/dist/manifest/workspaceSchemas.js +11 -0
  378. package/dist/report/types.d.ts +34 -4
  379. package/dist/runtime/common.d.ts +28 -1
  380. package/dist/runtime/common.js +33 -3
  381. package/dist/runtime/container.js +49 -33
  382. package/dist/runtime/daimon/adapter.d.ts +14 -0
  383. package/dist/runtime/daimon/adapter.js +243 -0
  384. package/dist/runtime/daimon/attention.d.ts +8 -0
  385. package/dist/runtime/daimon/attention.js +32 -0
  386. package/dist/runtime/daimon/config.d.ts +25 -0
  387. package/dist/runtime/daimon/config.js +272 -0
  388. package/dist/runtime/daimon/contractManifest.d.ts +295 -0
  389. package/dist/runtime/daimon/contractManifest.js +319 -0
  390. package/dist/runtime/daimon/grokModel.d.ts +19 -0
  391. package/dist/runtime/daimon/grokModel.js +33 -0
  392. package/dist/runtime/daimon/grokWorkerConfigBytes.d.ts +26 -0
  393. package/dist/runtime/daimon/grokWorkerConfigBytes.js +36 -0
  394. package/dist/runtime/daimon/grokWorkerContract.d.ts +22 -0
  395. package/dist/runtime/daimon/grokWorkerContract.js +48 -0
  396. package/dist/runtime/daimon/memory.d.ts +57 -0
  397. package/dist/runtime/daimon/memory.js +125 -0
  398. package/dist/runtime/daimon/runAuth.d.ts +51 -0
  399. package/dist/runtime/daimon/runAuth.js +279 -0
  400. package/dist/runtime/daimon/runtimeIdentity.d.ts +22 -0
  401. package/dist/runtime/daimon/runtimeIdentity.js +22 -0
  402. package/dist/runtime/daimon/scheduleAuthority.d.ts +3 -0
  403. package/dist/runtime/daimon/scheduleAuthority.js +17 -0
  404. package/dist/runtime/index.d.ts +4 -0
  405. package/dist/runtime/index.js +4 -0
  406. package/dist/runtime/install.d.ts +3 -0
  407. package/dist/runtime/install.js +3 -0
  408. package/dist/runtime/localDaimonAuthority.d.ts +11 -0
  409. package/dist/runtime/localDaimonAuthority.js +77 -0
  410. package/dist/runtime/mnemeMcp.d.ts +13 -0
  411. package/dist/runtime/mnemeMcp.js +26 -0
  412. package/dist/runtime/openclaw/adapter.js +2 -2
  413. package/dist/runtime/pi/adapter.d.ts +0 -1
  414. package/dist/runtime/pi/adapter.js +2 -6
  415. package/dist/runtime/pi/appCliSource.js +1 -1
  416. package/dist/runtime/pi/appScheduleSource.js +6 -2
  417. package/dist/runtime/pi/appTemplateTypes.d.ts +1 -1
  418. package/dist/runtime/picoclaw/adapter.js +2 -2
  419. package/dist/runtime/registry.d.ts +3 -0
  420. package/dist/runtime/registry.js +19 -2
  421. package/dist/runtime/scheduleUtils.d.ts +1 -0
  422. package/dist/runtime/scheduleUtils.js +5 -1
  423. package/dist/runtime/types.d.ts +25 -0
  424. package/dist/runtime/usageLedger.d.ts +158 -0
  425. package/dist/runtime/usageLedger.js +269 -0
  426. package/dist/runtime/usageLedgerRead.d.ts +48 -0
  427. package/dist/runtime/usageLedgerRead.js +102 -0
  428. package/dist/runtime/usageRequestLedger.d.ts +42 -0
  429. package/dist/runtime/usageRequestLedger.js +72 -0
  430. package/dist/shared/daimonCodexDocker.d.ts +32 -0
  431. package/dist/shared/daimonCodexDocker.js +120 -0
  432. package/dist/shared/daimonGrokSeccompProfile.d.ts +10 -0
  433. package/dist/shared/daimonGrokSeccompProfile.js +11 -0
  434. package/dist/shared/index.d.ts +2 -0
  435. package/dist/shared/index.js +2 -0
  436. package/dist/shared/types.d.ts +1 -1
  437. package/dist/shared/volumeNames.d.ts +6 -0
  438. package/dist/shared/volumeNames.js +14 -0
  439. package/dist/target/dockerArtifactsProvider.js +34 -7
  440. package/dist/target/dockerBaseImage.d.ts +2 -0
  441. package/dist/target/dockerBaseImage.js +11 -0
  442. package/dist/target/dockerCommandExecutor.d.ts +11 -0
  443. package/dist/target/dockerCommandExecutor.js +53 -2
  444. package/dist/target/dockerCommandExecutorCore.d.ts +2 -1
  445. package/dist/target/dockerCommandExecutorCore.js +4 -2
  446. package/dist/target/dockerPublicArtifactSnapshot.d.ts +3 -3
  447. package/dist/target/dockerPublicArtifactSnapshot.js +17 -33
  448. package/dist/target/dockerTarget.d.ts +1 -0
  449. package/dist/target/dockerTargetBinding.d.ts +1 -2
  450. package/dist/target/dockerTargetBinding.js +2 -3
  451. package/dist/target/dockerTargetExecFile.d.ts +19 -0
  452. package/dist/target/dockerTargetExecFile.js +194 -0
  453. package/dist/target/dockerWorldServiceProvider.d.ts +4 -0
  454. package/dist/target/dockerWorldServiceProvider.js +13 -1
  455. package/dist/target/evidenceExport.d.ts +3 -1
  456. package/dist/target/evidenceExport.js +12 -3
  457. package/dist/target/evidenceExportOperationsTestKit.js +3 -3
  458. package/dist/target/evidenceExportProvider.d.ts +2 -0
  459. package/dist/target/evidenceExportProvider.js +15 -5
  460. package/dist/target/publicArtifactSnapshot.d.ts +31 -0
  461. package/dist/target/publicArtifactSnapshot.js +37 -3
  462. package/examples/README.md +45 -0
  463. package/examples/agent-with-subagents/AGENTS.md +3 -0
  464. package/examples/agent-with-subagents/Spawnfile +30 -0
  465. package/examples/agent-with-subagents/subagents/critic/AGENTS.md +3 -0
  466. package/examples/agent-with-subagents/subagents/critic/Spawnfile +15 -0
  467. package/examples/agent-with-subagents/subagents/researcher/AGENTS.md +3 -0
  468. package/examples/agent-with-subagents/subagents/researcher/Spawnfile +17 -0
  469. package/examples/daimon-org/Spawnfile +68 -0
  470. package/examples/daimon-org/TEAM.md +4 -0
  471. package/examples/daimon-org/agents/mapper/AGENTS.md +4 -0
  472. package/examples/daimon-org/agents/mapper/Spawnfile +37 -0
  473. package/examples/daimon-org/shared/skills/file-note/SKILL.md +9 -0
  474. package/examples/daimon-org/teams/review/Spawnfile +53 -0
  475. package/examples/daimon-org/teams/review/agents/reviewer/AGENTS.md +4 -0
  476. package/examples/daimon-org/teams/review/agents/reviewer/Spawnfile +37 -0
  477. package/examples/daimon-public-host/AGENTS.md +3 -0
  478. package/examples/daimon-public-host/Spawnfile +21 -0
  479. package/examples/distribution-org/Spawnfile +43 -0
  480. package/examples/distribution-org/TEAM.md +4 -0
  481. package/examples/distribution-org/agents/coordinator/AGENTS.md +1 -0
  482. package/examples/distribution-org/agents/coordinator/Spawnfile +20 -0
  483. package/examples/distribution-org/agents/researcher/AGENTS.md +1 -0
  484. package/examples/distribution-org/agents/researcher/Spawnfile +20 -0
  485. package/examples/jungian-daimon-org/Spawnfile +41 -0
  486. package/examples/jungian-daimon-org/TEAM.md +21 -0
  487. package/examples/jungian-daimon-org/teams/luna/Spawnfile +47 -0
  488. package/examples/jungian-daimon-org/teams/luna/TEAM.md +4 -0
  489. package/examples/jungian-daimon-org/teams/luna/agents/animus/AGENTS.md +10 -0
  490. package/examples/jungian-daimon-org/teams/luna/agents/animus/Spawnfile +33 -0
  491. package/examples/jungian-daimon-org/teams/luna/agents/representative/AGENTS.md +21 -0
  492. package/examples/jungian-daimon-org/teams/luna/agents/representative/Spawnfile +30 -0
  493. package/examples/jungian-daimon-org/teams/luna/agents/shadow/AGENTS.md +10 -0
  494. package/examples/jungian-daimon-org/teams/luna/agents/shadow/Spawnfile +33 -0
  495. package/examples/jungian-daimon-org/teams/selene/Spawnfile +47 -0
  496. package/examples/jungian-daimon-org/teams/selene/TEAM.md +4 -0
  497. package/examples/jungian-daimon-org/teams/selene/agents/animus/AGENTS.md +10 -0
  498. package/examples/jungian-daimon-org/teams/selene/agents/animus/Spawnfile +33 -0
  499. package/examples/jungian-daimon-org/teams/selene/agents/representative/AGENTS.md +19 -0
  500. package/examples/jungian-daimon-org/teams/selene/agents/representative/Spawnfile +33 -0
  501. package/examples/jungian-daimon-org/teams/selene/agents/shadow/AGENTS.md +10 -0
  502. package/examples/jungian-daimon-org/teams/selene/agents/shadow/Spawnfile +30 -0
  503. package/examples/mixed-runtime-org/Spawnfile +71 -0
  504. package/examples/mixed-runtime-org/TEAM.md +8 -0
  505. package/examples/mixed-runtime-org/agents/analyst/AGENTS.md +8 -0
  506. package/examples/mixed-runtime-org/agents/analyst/Spawnfile +27 -0
  507. package/examples/mixed-runtime-org/agents/conductor/AGENTS.md +8 -0
  508. package/examples/mixed-runtime-org/agents/conductor/Spawnfile +27 -0
  509. package/examples/mixed-runtime-org/agents/localist/AGENTS.md +7 -0
  510. package/examples/mixed-runtime-org/agents/localist/Spawnfile +50 -0
  511. package/examples/moltnet-team-chat/Spawnfile +43 -0
  512. package/examples/moltnet-team-chat/TEAM.md +5 -0
  513. package/examples/moltnet-team-chat/agents/coordinator/AGENTS.md +9 -0
  514. package/examples/moltnet-team-chat/agents/coordinator/Spawnfile +26 -0
  515. package/examples/moltnet-team-chat/teams/analysis/Spawnfile +23 -0
  516. package/examples/moltnet-team-chat/teams/analysis/TEAM.md +3 -0
  517. package/examples/moltnet-team-chat/teams/analysis/agents/observer/AGENTS.md +5 -0
  518. package/examples/moltnet-team-chat/teams/analysis/agents/observer/Spawnfile +19 -0
  519. package/examples/moltnet-team-chat/teams/analysis/agents/representative/AGENTS.md +5 -0
  520. package/examples/moltnet-team-chat/teams/analysis/agents/representative/Spawnfile +19 -0
  521. package/examples/moltnet-team-chat/teams/field/Spawnfile +41 -0
  522. package/examples/moltnet-team-chat/teams/field/TEAM.md +3 -0
  523. package/examples/moltnet-team-chat/teams/field/agents/observer/AGENTS.md +5 -0
  524. package/examples/moltnet-team-chat/teams/field/agents/observer/Spawnfile +26 -0
  525. package/examples/moltnet-team-chat/teams/field/agents/representative/AGENTS.md +11 -0
  526. package/examples/moltnet-team-chat/teams/field/agents/representative/Spawnfile +26 -0
  527. package/examples/single-agent/AGENTS.md +3 -0
  528. package/examples/single-agent/HEARTBEAT.md +3 -0
  529. package/examples/single-agent/IDENTITY.md +3 -0
  530. package/examples/single-agent/MEMORY.md +3 -0
  531. package/examples/single-agent/SOUL.md +3 -0
  532. package/examples/single-agent/Spawnfile +41 -0
  533. package/examples/single-agent/skills/web_search/SKILL.md +6 -0
  534. package/moltnet-releases.json +5 -4
  535. package/package.json +36 -9
  536. package/runtimes.yaml +5 -2
  537. package/dist/cli/targetWorldClockCrossProcess.test-helper.d.ts +0 -13
  538. package/dist/cli/targetWorldClockCrossProcess.test-helper.js +0 -109
  539. package/dist/deployment/providerRuntimeBoundaryScanner.test-helper.d.ts +0 -8
  540. package/dist/deployment/providerRuntimeBoundaryScanner.test-helper.js +0 -60
  541. package/dist/deployment/simfileFixtureBoundary.test-helper.d.ts +0 -8
  542. package/dist/deployment/simfileFixtureBoundary.test-helper.js +0 -103
  543. package/dist/ownership/simfileRunOperatorInputs.d.ts +0 -103
  544. package/dist/ownership/simfileRunOperatorInputs.js +0 -139
  545. package/dist/target/cleanupRunDocker.test-helper.d.ts +0 -67
  546. package/dist/target/cleanupRunDocker.test-helper.js +0 -238
@@ -1,8 +1,6 @@
1
- import path from "node:path/posix";
2
- import { resolveNoopolisRunId } from "../runtime/index.js";
1
+ import { resolveMnemeDurableMemoryMountPath } from "../runtime/mnemeMcp.js";
2
+ import { createExclusiveReattachVolumeName, SpawnfileError } from "../shared/index.js";
3
3
  import { slugify } from "./helpers.js";
4
- import { createPersistentVolumeName } from "./moltnetArtifactPaths.js";
5
- const normalizePosixPath = (value) => path.normalize(value).replace(/\/+$/u, "") || "/";
6
4
  const safeSlug = (value) => slugify(value).trim() || "memory";
7
5
  const createMountId = (mountPath) => `memory-${safeSlug(mountPath)}`;
8
6
  const isFileBackedMemoryStore = (bank) => bank.store.kind === "sqlite" || bank.store.kind === "json";
@@ -10,7 +8,33 @@ const transportFromRuntime = (runtimeName, bank) => {
10
8
  switch (runtimeName) {
11
9
  case "pi":
12
10
  case "daimon":
13
- return "direct";
11
+ // Mneme runs in-process for these runtimes (no MCP subprocess), but
12
+ // whether that in-process runtime is reachable -- and whether it
13
+ // persists anything -- depends on the store:
14
+ // - sqlite/json WITH a durable mount: a real runtime home backed by
15
+ // a persistent volume this same module emits.
16
+ // - sqlite/json WITHOUT one (persistence.mode "ephemeral", or no
17
+ // resolvable path at all): no volume is mounted and Daimon emits no
18
+ // memory block, so recall lasts at most the container's lifetime --
19
+ // exactly the "memory" kind's situation, and reported the same way.
20
+ // - memory: Mneme still runs in-process against a synthesized runtime
21
+ // home path, but no persistent volume is emitted for this kind.
22
+ // - postgres: no runtime home path at all; the in-process runtime
23
+ // gets no memory whatsoever.
24
+ //
25
+ // The durable/ephemeral half of that decision is NOT re-derived here:
26
+ // it comes from resolveMnemeDurableMemoryMountPath, the same authority
27
+ // that decides the mount below, so the report cannot disagree with what
28
+ // was actually emitted.
29
+ switch (bank.store.kind) {
30
+ case "sqlite":
31
+ case "json":
32
+ return resolveMnemeDurableMemoryMountPath(bank) === null ? "degraded" : "direct";
33
+ case "memory":
34
+ return "degraded";
35
+ default:
36
+ return "unsupported";
37
+ }
14
38
  case "picoclaw":
15
39
  case "openclaw":
16
40
  return isFileBackedMemoryStore(bank) ? "mcp" : "degraded_mcp";
@@ -18,20 +42,10 @@ const transportFromRuntime = (runtimeName, bank) => {
18
42
  return "unsupported";
19
43
  }
20
44
  };
21
- const memoryMountPath = (bank) => {
22
- if (bank.store.kind !== "sqlite" && bank.store.kind !== "json") {
23
- return null;
24
- }
25
- if (bank.store.persistence?.mode === "ephemeral") {
26
- return null;
27
- }
28
- if (bank.store.persistence?.mount) {
29
- return normalizePosixPath(bank.store.persistence.mount);
30
- }
31
- return bank.store.path
32
- ? path.dirname(normalizePosixPath(bank.store.path))
33
- : null;
34
- };
45
+ // The mount decision itself lives in runtime/mnemeMcp.ts so that runtime config
46
+ // emitters (which must only point an in-process Mneme runtime at a path this
47
+ // module actually mounts) and this module cannot drift apart.
48
+ const memoryMountPath = resolveMnemeDurableMemoryMountPath;
35
49
  const summarizeMemoryStore = (bank, mountId) => {
36
50
  const persistenceMode = bank.store.kind === "sqlite" || bank.store.kind === "json"
37
51
  ? (bank.store.persistence?.mode ?? "durable")
@@ -44,13 +58,69 @@ const summarizeMemoryStore = (bank, mountId) => {
44
58
  ...(bank.store.kind === "postgres" ? { dsn_secret: bank.store.dsn_secret } : {})
45
59
  };
46
60
  };
47
- export const createMemoryArtifactBundle = (plan) => {
48
- // Run-scoping key for every derived volume name below (see
49
- // createPersistentVolumeName's doc comment in moltnetArtifactPaths.ts):
50
- // present whenever this compile was driven by `spawnfile run`/`up`
51
- // (which always call ensureNoopolisRunId() first), absent for a bare
52
- // `spawnfile compile`/`spawnfile build`.
53
- const runId = resolveNoopolisRunId(process.env);
61
+ /**
62
+ * The identity of the PHYSICAL store a declared bank resolves to.
63
+ *
64
+ * Mneme addresses a store by its runtime home directory and then discards the
65
+ * declared filename: `JsonlMemoryStore` always writes `<home>/memory/events.jsonl`
66
+ * and `SQLiteMemoryIndex` always opens `<home>/memory/<default>.db`
67
+ * (mneme/src/store/store.ts, mneme/src/store/sqliteIndex.ts). Spawnfile resolves
68
+ * that home as `dirname(store.path)` unless `persistence.mount` overrides it, so
69
+ * `/data/mem/a.jsonl` and `/data/mem/b.jsonl` are ONE physical store wearing two
70
+ * declared names — two concurrent MemoryRuntimes appending to one file and
71
+ * opening one SQLite database.
72
+ *
73
+ * Two declarations may therefore share a durable directory only when they are
74
+ * the same bank said twice (the legitimate case: one bank declared in an org
75
+ * scope and again in a nested team scope so both sides can access it). Anything
76
+ * that differs — a different id, a different declared file, a different index
77
+ * intent — means the author believes they have two stores and the runtime will
78
+ * silently give them one.
79
+ */
80
+ const physicalStoreIdentity = (bank) => JSON.stringify({
81
+ consolidation: bank.consolidation,
82
+ id: bank.id,
83
+ index: bank.index,
84
+ retention: bank.retention,
85
+ store: {
86
+ kind: bank.store.kind,
87
+ mount: bank.store.persistence?.mount ?? null,
88
+ name: bank.store.persistence?.name ?? null,
89
+ path: bank.store.path ?? null
90
+ }
91
+ });
92
+ const collidingBankMessage = (mountPath, prior, next) => `Memory banks ${prior.bankId} (declared in ${prior.source}) and ${next.bankId} `
93
+ + `(declared in ${next.source}) both resolve to the durable memory directory ${mountPath}, `
94
+ + "but do not declare the same store. Mneme keys a store by that directory and ignores the "
95
+ + "declared filename, so these two banks would silently become one physical store with two "
96
+ + "runtimes writing it. Give each bank its own directory (a distinct store.path parent or "
97
+ + "persistence.mount), or declare them identically if one shared bank is what you meant.";
98
+ /**
99
+ * The docker volume name for a durable memory directory.
100
+ *
101
+ * Deliberately NOT run-scoped. `createPersistentVolumeName` folds NOOPOLIS_RUN_ID
102
+ * into the name, and `ensureNoopolisRunId` mints a fresh id on every `spawnfile
103
+ * run`/`up`, so a run-scoped memory volume means the organization you redeploy
104
+ * tomorrow starts with an empty memory bank. There is no working escape hatch
105
+ * today either: `spawnfile product-state clone` refuses SQLite paths, and reusing
106
+ * yesterday's NOOPOLIS_RUN_ID to reproduce the volume name would collapse two
107
+ * distinct causal runs onto one run_id in the ledger (specs/CAUSAL.md).
108
+ *
109
+ * `exclusive-reattach` is the existing lifecycle for exactly this: a host-stable
110
+ * name derived from the project root plus the deployment lineage, with a
111
+ * daemon-side reservation that refuses to start when another live container
112
+ * already holds the volume (src/compiler/runProjectDockerReservation.ts). That
113
+ * mutual exclusion is a requirement here rather than a cost — Mneme's append-only
114
+ * JSONL plus its SQLite index are single-writer — and it is why an organization
115
+ * with durable memory cannot use the concurrent blue/green canary workflow and
116
+ * must stop-and-reattach instead (specs/CONTAINERS.md).
117
+ *
118
+ * An author-declared `persistence.name` is honored verbatim: naming a volume is
119
+ * precisely a request for a host-stable identity.
120
+ */
121
+ const durableMemoryVolumeName = (planRoot, mountId, declaredName, deploymentLineage) => declaredName?.trim()
122
+ || createExclusiveReattachVolumeName(`${planRoot}\0${deploymentLineage}`, mountId);
123
+ export const createMemoryArtifactBundle = (plan, deploymentLineage = "compile") => {
54
124
  const sourceToNode = new Map(plan.nodes.map((node) => [node.value.source, node]));
55
125
  const groupedMemory = new Map();
56
126
  for (const access of plan.memoryAccess ?? []) {
@@ -66,6 +136,7 @@ export const createMemoryArtifactBundle = (plan) => {
66
136
  const mounts = [];
67
137
  const mountPathMemoryMap = new Map();
68
138
  const mountByPath = new Map();
139
+ const claimantByPath = new Map();
69
140
  const memories = [...groupedMemory.entries()]
70
141
  .sort(([left], [right]) => left.localeCompare(right))
71
142
  .map(([, entry]) => {
@@ -89,18 +160,23 @@ export const createMemoryArtifactBundle = (plan) => {
89
160
  let persistentMountId;
90
161
  if (mountPath !== null) {
91
162
  const mountId = createMountId(mountPath);
92
- // createPersistentVolumeName also folds in plan.root (previously
93
- // missing here entirely), so two different projects that happen to
94
- // share a mount-path convention no longer derive the same volume
95
- // name — the same isolation moltnet's own persistent mounts already
96
- // had before this change.
97
- const volumeName = createPersistentVolumeName(plan.root, mountId, entry.bank.store.persistence?.name, runId);
163
+ const declaredVolumeName = entry.bank.store.persistence?.name?.trim();
164
+ const volumeName = durableMemoryVolumeName(plan.root, mountId, entry.bank.store.persistence?.name, deploymentLineage);
165
+ const identity = physicalStoreIdentity(entry.bank);
166
+ const claimant = { bankId: entry.bank.id, identity, source: entry.source };
167
+ const priorClaimant = claimantByPath.get(mountPath);
168
+ if (priorClaimant && priorClaimant.identity !== identity) {
169
+ throw new SpawnfileError("validation_error", collidingBankMessage(mountPath, priorClaimant, claimant));
170
+ }
171
+ claimantByPath.set(mountPath, claimant);
98
172
  const existingMount = mountByPath.get(mountPath);
99
173
  if (existingMount && existingMount.volume_name !== volumeName) {
100
174
  throw new Error(`Memory store mount ${mountPath} resolves to conflicting volume names`);
101
175
  }
102
176
  const mount = existingMount ?? {
177
+ ...(declaredVolumeName ? { declared_volume_name: declaredVolumeName } : {}),
103
178
  id: mountId,
179
+ lifecycle: "exclusive-reattach",
104
180
  mount_path: mountPath,
105
181
  reason: `durable memory stores under ${mountPath}`,
106
182
  volume_name: volumeName
@@ -2,6 +2,11 @@ import type { ExecutionBlock, ModelTarget } from "../manifest/index.js";
2
2
  import { type ModelAuthMethod } from "../shared/index.js";
3
3
  import type { EffectiveModelTarget } from "./types.js";
4
4
  export declare const CLI_CREDENTIAL_SECRET_NAME = "SPAWNFILE_CLI_AUTH_JSON";
5
+ /**
6
+ * Only the host-imported CLI logins travel as `SPAWNFILE_CLI_AUTH_JSON`. `grok`
7
+ * is a Daimon-owned subscription: its credential is the broker's bootstrap
8
+ * slot (`runtime/daimon/runAuth.ts`), never this secret.
9
+ */
5
10
  export declare const modelAuthMethodNeedsCliCredential: (method: ModelAuthMethod) => boolean;
6
11
  export declare const resolveModelProviderEnvName: (provider: string) => string;
7
12
  export declare const listExecutionModelTargets: (execution: ExecutionBlock | undefined) => ModelTarget[];
@@ -9,7 +9,12 @@ const MODEL_PROVIDER_ENV_VARS = new Map([
9
9
  ["xai", "XAI_API_KEY"]
10
10
  ]);
11
11
  export const CLI_CREDENTIAL_SECRET_NAME = "SPAWNFILE_CLI_AUTH_JSON";
12
- export const modelAuthMethodNeedsCliCredential = (method) => method !== "api_key" && method !== "none";
12
+ /**
13
+ * Only the host-imported CLI logins travel as `SPAWNFILE_CLI_AUTH_JSON`. `grok`
14
+ * is a Daimon-owned subscription: its credential is the broker's bootstrap
15
+ * slot (`runtime/daimon/runAuth.ts`), never this secret.
16
+ */
17
+ export const modelAuthMethodNeedsCliCredential = (method) => method === "claude-code" || method === "codex";
13
18
  const resolveLegacyModelAuthMethod = (execution, provider) => {
14
19
  const auth = execution?.model?.auth;
15
20
  if (!auth) {
@@ -68,7 +73,8 @@ export const resolveEffectiveModelTarget = (target, execution) => {
68
73
  },
69
74
  ...(target.endpoint ? { endpoint: target.endpoint } : {}),
70
75
  name: target.name,
71
- provider: target.provider
76
+ provider: target.provider,
77
+ ...(target.reasoning_effort ? { reasoningEffort: target.reasoning_effort } : {})
72
78
  };
73
79
  };
74
80
  export const listEffectiveExecutionModelTargets = (execution) => listExecutionModelTargets(execution).map((target) => resolveEffectiveModelTarget(target, execution));
@@ -1,26 +1,31 @@
1
1
  import type { ResolvedTeamNode } from "./types.js";
2
2
  export declare const createMoltnetExternalParticipantArtifactPath: (networkId: string, memberId: string) => string;
3
3
  /**
4
- * Derives the host-mounted docker volume name for a durable mount.
4
+ * Derives the host-mounted docker volume name for a **run-scoped** durable
5
+ * mount — state whose whole point is to be fresh per run (today: the Moltnet
6
+ * causal event log, Daimon telemetry, per-network Moltnet runtime state).
5
7
  *
6
8
  * `runId` (the compiling process's resolved NOOPOLIS_RUN_ID, see
7
9
  * src/runtime/common.ts) is the run-scoping key: `spawnfile run`/`spawnfile
8
10
  * up` always call `ensureNoopolisRunId()` before compiling, so a fresh
9
11
  * invocation with no host-pinned run id gets a fresh generated one and
10
12
  * therefore a fresh volume — two concurrent/successive runs (e.g. two
11
- * memetics replicates) never share durable state. A cold restart that wants
12
- * to recall the same run's memory sets the SAME `NOOPOLIS_RUN_ID` before
13
- * re-running, which reproduces this same volume name and remounts it.
14
- * Omitted (a bare `spawnfile compile`/`spawnfile build` with no run id in
15
- * the host env) reproduces the pre-run-scoping name exactly, so standard
16
- * compiles stay byte-identical.
13
+ * memetics replicates) never share it. A cold restart that wants the same
14
+ * run's state sets the SAME `NOOPOLIS_RUN_ID` before re-running, which
15
+ * reproduces this name and remounts it. Omitted (a bare `spawnfile
16
+ * compile`/`spawnfile build` with no run id in the host env) reproduces the
17
+ * pre-run-scoping name exactly, so standard compiles stay byte-identical.
17
18
  *
18
- * `explicitName` (an author-declared `persistence.name`) always wins over
19
- * both project/id and run scoping — an explicit name is opt-in shared/
20
- * reused state by author intent, not something this helper should silently
21
- * fragment across runs.
19
+ * State that must SURVIVE a redeploy — workspace `kind: volume` resources,
20
+ * durable Moltnet stores, open-mode agent token directories, durable memory
21
+ * banks, the Daimon usage ledger — must NEVER be named here. Those are
22
+ * `lifecycle: "exclusive-reattach"` and are named by
23
+ * `createExclusiveReattachVolumeName` from the plan root and the deployment
24
+ * lineage, honouring an author-declared name verbatim. This function
25
+ * deliberately takes no author-declared name: a run-scoped volume is never
26
+ * the thing an author names.
22
27
  */
23
- export declare const createPersistentVolumeName: (planRoot: string, id: string, explicitName?: string, runId?: string) => string;
28
+ export declare const createPersistentVolumeName: (planRoot: string, id: string, runId?: string) => string;
24
29
  export declare const toContainerRootfsPath: (rootfsPath: string) => string;
25
30
  export declare const isNetworkHttpEnabled: (network: NonNullable<ResolvedTeamNode["networks"]>[number]) => boolean;
26
31
  export declare const resolveNetworkPort: (network: NonNullable<ResolvedTeamNode["networks"]>[number], fallbackPort: number) => number;
@@ -12,29 +12,31 @@ export const createMoltnetExternalParticipantArtifactPath = (networkId, memberId
12
12
  };
13
13
  const truncateSegment = (value, maxLength) => value.length > maxLength ? value.slice(0, maxLength).replace(/[-_.]+$/u, "") : value;
14
14
  /**
15
- * Derives the host-mounted docker volume name for a durable mount.
15
+ * Derives the host-mounted docker volume name for a **run-scoped** durable
16
+ * mount — state whose whole point is to be fresh per run (today: the Moltnet
17
+ * causal event log, Daimon telemetry, per-network Moltnet runtime state).
16
18
  *
17
19
  * `runId` (the compiling process's resolved NOOPOLIS_RUN_ID, see
18
20
  * src/runtime/common.ts) is the run-scoping key: `spawnfile run`/`spawnfile
19
21
  * up` always call `ensureNoopolisRunId()` before compiling, so a fresh
20
22
  * invocation with no host-pinned run id gets a fresh generated one and
21
23
  * therefore a fresh volume — two concurrent/successive runs (e.g. two
22
- * memetics replicates) never share durable state. A cold restart that wants
23
- * to recall the same run's memory sets the SAME `NOOPOLIS_RUN_ID` before
24
- * re-running, which reproduces this same volume name and remounts it.
25
- * Omitted (a bare `spawnfile compile`/`spawnfile build` with no run id in
26
- * the host env) reproduces the pre-run-scoping name exactly, so standard
27
- * compiles stay byte-identical.
24
+ * memetics replicates) never share it. A cold restart that wants the same
25
+ * run's state sets the SAME `NOOPOLIS_RUN_ID` before re-running, which
26
+ * reproduces this name and remounts it. Omitted (a bare `spawnfile
27
+ * compile`/`spawnfile build` with no run id in the host env) reproduces the
28
+ * pre-run-scoping name exactly, so standard compiles stay byte-identical.
28
29
  *
29
- * `explicitName` (an author-declared `persistence.name`) always wins over
30
- * both project/id and run scoping — an explicit name is opt-in shared/
31
- * reused state by author intent, not something this helper should silently
32
- * fragment across runs.
30
+ * State that must SURVIVE a redeploy — workspace `kind: volume` resources,
31
+ * durable Moltnet stores, open-mode agent token directories, durable memory
32
+ * banks, the Daimon usage ledger — must NEVER be named here. Those are
33
+ * `lifecycle: "exclusive-reattach"` and are named by
34
+ * `createExclusiveReattachVolumeName` from the plan root and the deployment
35
+ * lineage, honouring an author-declared name verbatim. This function
36
+ * deliberately takes no author-declared name: a run-scoped volume is never
37
+ * the thing an author names.
33
38
  */
34
- export const createPersistentVolumeName = (planRoot, id, explicitName, runId) => {
35
- if (explicitName && explicitName.trim().length > 0) {
36
- return explicitName.trim();
37
- }
39
+ export const createPersistentVolumeName = (planRoot, id, runId) => {
38
40
  const project = truncateSegment(slugify(planRoot.split("/").slice(-2, -1)[0] ?? "project") || "project", 32);
39
41
  const suffix = truncateSegment(slugify(id) || "state", 48);
40
42
  const trimmedRunId = runId?.trim();
@@ -11,6 +11,7 @@ export interface MoltnetServerPlan {
11
11
  networkId: string;
12
12
  port?: number;
13
13
  rooms: Array<{
14
+ federation?: "all" | "none" | string[];
14
15
  id: string;
15
16
  members: string[];
16
17
  name?: string;
@@ -28,9 +29,18 @@ export interface MoltnetNodePlan {
28
29
  credentialSecret?: string;
29
30
  memberId?: string;
30
31
  networkId: string;
32
+ receiptStorePath?: string;
31
33
  }
32
34
  export interface MoltnetPersistentMount {
35
+ /** The author's `store.persistence.name`, when declared. */
36
+ declaredVolumeName?: string;
33
37
  id: string;
38
+ /**
39
+ * `exclusive-reattach` marks state that MUST survive container replacement
40
+ * and redeploy: its volume name is deployment-stable (never run-scoped) and
41
+ * only one live container may hold it at a time.
42
+ */
43
+ lifecycle?: "exclusive-reattach";
34
44
  mountPath: string;
35
45
  reason: string;
36
46
  volumeName: string;
@@ -1,4 +1,4 @@
1
1
  import type { MoltnetArtifacts } from "./moltnetArtifactTypes.js";
2
2
  import type { CompilePlan } from "./types.js";
3
3
  export type { MoltnetArtifacts, MoltnetNodePlan, MoltnetPersistentMount, MoltnetServerPlan } from "./moltnetArtifactTypes.js";
4
- export declare const generateMoltnetArtifacts: (plan: CompilePlan) => Promise<MoltnetArtifacts | null>;
4
+ export declare const generateMoltnetArtifacts: (plan: CompilePlan, deploymentLineage?: string) => Promise<MoltnetArtifacts | null>;
@@ -1,29 +1,44 @@
1
1
  import { resolveNoopolisRunId } from "../runtime/index.js";
2
- import { SpawnfileError } from "../shared/index.js";
3
- import { createMoltnetCausalDirectory, createMoltnetServerConfigPath, createMoltnetOpenTokenDirectory, createMoltnetNativeServerConfig, createMoltnetNodeConfigPath, resolveMoltnetClientAuth, resolveMoltnetStorePersistenceMountPath } from "./moltnetConfigLowering.js";
2
+ import { createExclusiveReattachVolumeName, SpawnfileError } from "../shared/index.js";
3
+ import { createMoltnetCausalDirectory, createMoltnetDaimonReceiptStorePath, createMoltnetNetworkStateDirectory, createMoltnetServerConfigPath, createMoltnetOpenTokenDirectory, createMoltnetNativeServerConfig, createMoltnetNodeConfigPath, resolveMoltnetClientAuth, resolveMoltnetStorePersistenceMountPath } from "./moltnetConfigLowering.js";
4
4
  import { assertNetworkBindingEnvUniqueness } from "./networkBinding.js";
5
5
  import { createMoltnetNodeConfigContent } from "./moltnetNodeConfig.js";
6
6
  import { createPersistentVolumeName, isNetworkHttpEnabled, toContainerRootfsPath } from "./moltnetArtifactPaths.js";
7
7
  import { createMoltnetExternalParticipantArtifactFiles } from "./moltnetExternalParticipantArtifact.js";
8
8
  import { resolveMoltnetServerPlans } from "./moltnetServerPlans.js";
9
9
  const createServerKey = (networkId) => networkId;
10
- export const generateMoltnetArtifacts = async (plan) => {
10
+ export const generateMoltnetArtifacts = async (plan, deploymentLineage = "compile") => {
11
11
  const teamNodes = plan.nodes
12
12
  .filter((node) => node.kind === "team")
13
13
  .filter((node) => (node.value.networks?.length ?? 0) > 0);
14
14
  if (teamNodes.length === 0) {
15
15
  return null;
16
16
  }
17
- // Run-scoping key for every persistent volume name derived below (see
18
- // createPersistentVolumeName's doc comment). Read once per compile so
19
- // every mount in this compile agrees on the same value.
17
+ // Run-scoping key for the RUN-SCOPED mounts derived below — the causal
18
+ // event log and per-network Moltnet runtime state (see
19
+ // createPersistentVolumeName's doc comment). Read once per compile so every
20
+ // such mount in this compile agrees on the same value. Durable stores and
21
+ // token directories deliberately do NOT use it; see durableVolumeName.
20
22
  const runId = resolveNoopolisRunId(process.env);
23
+ /**
24
+ * Deployment-stable name for state that must be REATTACHED across a
25
+ * redeploy, never recreated empty: durable Moltnet `sqlite`/`json` stores
26
+ * and the open-mode agent token directories. An author-declared name
27
+ * (`server.store.persistence.name`) is honoured verbatim so an operator can
28
+ * pre-create or migrate the volume under that exact name; otherwise the
29
+ * name comes from the plan root plus the deployment lineage, exactly as
30
+ * durable memory banks are named (`memoryArtifacts.ts`'s
31
+ * `durableMemoryVolumeName`).
32
+ */
33
+ const durableVolumeName = (mountId, declaredName) => declaredName?.trim()
34
+ || createExclusiveReattachVolumeName(`${plan.root}\0${deploymentLineage}`, mountId);
21
35
  const serverPlans = resolveMoltnetServerPlans(plan, teamNodes);
22
36
  const nodePlans = [];
23
37
  const nodePlanKeys = new Set();
24
38
  const configFiles = [];
25
39
  const persistentMounts = new Map();
26
40
  const external = createMoltnetExternalParticipantArtifactFiles(plan.moltnetExternalParticipantIntents ?? []);
41
+ const receiptStoreOwners = new Map();
27
42
  configFiles.push(...external.files);
28
43
  const addPersistentMount = (mount) => {
29
44
  const existing = persistentMounts.get(mount.id);
@@ -31,7 +46,10 @@ export const generateMoltnetArtifacts = async (plan) => {
31
46
  persistentMounts.set(mount.id, mount);
32
47
  return;
33
48
  }
34
- if (existing.mountPath !== mount.mountPath || existing.volumeName !== mount.volumeName) {
49
+ if (existing.mountPath !== mount.mountPath ||
50
+ existing.volumeName !== mount.volumeName ||
51
+ existing.lifecycle !== mount.lifecycle ||
52
+ existing.declaredVolumeName !== mount.declaredVolumeName) {
35
53
  throw new SpawnfileError("validation_error", `Moltnet persistent mount ${mount.id} resolves to conflicting targets`);
36
54
  }
37
55
  };
@@ -63,7 +81,7 @@ export const generateMoltnetArtifacts = async (plan) => {
63
81
  id: causalMountId,
64
82
  mountPath: createMoltnetCausalDirectory(serverPlan.configPath),
65
83
  reason: `managed Moltnet causal event log for ${serverPlan.networkId}`,
66
- volumeName: createPersistentVolumeName(plan.root, causalMountId, undefined, runId)
84
+ volumeName: createPersistentVolumeName(plan.root, causalMountId, runId)
67
85
  });
68
86
  const storeMountPath = resolveMoltnetStorePersistenceMountPath(serverPlan.networkId, serverPlan.server.store);
69
87
  if (storeMountPath) {
@@ -73,10 +91,12 @@ export const generateMoltnetArtifacts = async (plan) => {
73
91
  ? store.persistence?.name
74
92
  : undefined;
75
93
  addPersistentMount({
94
+ ...(explicitVolumeName?.trim() ? { declaredVolumeName: explicitVolumeName.trim() } : {}),
76
95
  id: mountId,
96
+ lifecycle: "exclusive-reattach",
77
97
  mountPath: storeMountPath,
78
98
  reason: `managed Moltnet ${serverPlan.server.store.kind} store for ${serverPlan.networkId}`,
79
- volumeName: createPersistentVolumeName(plan.root, mountId, explicitVolumeName, runId)
99
+ volumeName: durableVolumeName(mountId, explicitVolumeName)
80
100
  });
81
101
  }
82
102
  }
@@ -110,6 +130,23 @@ export const generateMoltnetArtifacts = async (plan) => {
110
130
  throw new SpawnfileError("validation_error", `Moltnet network ${attachment.network} disables direct messages but ${agentNode.name} declares dms`);
111
131
  }
112
132
  const configPath = createMoltnetNodeConfigPath(teamNode.slug, attachment.network, attachment.memberId);
133
+ const receiptStorePath = agentNode.runtime.name === "daimon"
134
+ ? createMoltnetDaimonReceiptStorePath(attachment.network, attachment.memberId)
135
+ : undefined;
136
+ if (receiptStorePath) {
137
+ const owner = `${attachment.network}\u0000${attachment.memberId}`;
138
+ const existingOwner = receiptStoreOwners.get(receiptStorePath);
139
+ if (existingOwner !== undefined && existingOwner !== owner) {
140
+ throw new SpawnfileError("validation_error", "Daimon receipt-store paths collide");
141
+ }
142
+ receiptStoreOwners.set(receiptStorePath, owner);
143
+ const networkRoot = createMoltnetNetworkStateDirectory(attachment.network);
144
+ const covered = [...persistentMounts.values()].some((mount) => networkRoot === mount.mountPath || networkRoot.startsWith(`${mount.mountPath}/`));
145
+ if (!covered) {
146
+ const mountId = `moltnet-${attachment.network}-runtime-state`;
147
+ addPersistentMount({ id: mountId, mountPath: networkRoot, reason: `Moltnet runtime state for ${attachment.network}`, volumeName: createPersistentVolumeName(plan.root, mountId, runId) });
148
+ }
149
+ }
113
150
  const nodePlanKey = `${attachment.network}::${attachment.memberId}`;
114
151
  if (nodePlanKeys.has(nodePlanKey)) {
115
152
  throw new SpawnfileError("validation_error", `Duplicate Moltnet node attachment for ${attachment.network}/${attachment.memberId}`);
@@ -124,9 +161,10 @@ export const generateMoltnetArtifacts = async (plan) => {
124
161
  const mountId = `agent-${node.slug}-moltnet-tokens`;
125
162
  addPersistentMount({
126
163
  id: mountId,
164
+ lifecycle: "exclusive-reattach",
127
165
  mountPath: createMoltnetOpenTokenDirectory(node.slug),
128
166
  reason: `Moltnet open-mode generated agent tokens for ${agentNode.name}`,
129
- volumeName: createPersistentVolumeName(plan.root, mountId, undefined, runId)
167
+ volumeName: durableVolumeName(mountId)
130
168
  });
131
169
  }
132
170
  }
@@ -143,9 +181,10 @@ export const generateMoltnetArtifacts = async (plan) => {
143
181
  const mountId = `agent-${node.slug}-moltnet-tokens`;
144
182
  addPersistentMount({
145
183
  id: mountId,
184
+ lifecycle: "exclusive-reattach",
146
185
  mountPath: createMoltnetOpenTokenDirectory(node.slug),
147
186
  reason: `Moltnet open-mode generated agent tokens for ${agentNode.name}`,
148
- volumeName: createPersistentVolumeName(plan.root, mountId, undefined, runId)
187
+ volumeName: durableVolumeName(mountId)
149
188
  });
150
189
  }
151
190
  configFiles.push({
@@ -161,7 +200,8 @@ export const generateMoltnetArtifacts = async (plan) => {
161
200
  ...(clientAuth.credentialId ? { credentialId: clientAuth.credentialId } : {}),
162
201
  ...(clientAuth.tokenEnv ? { credentialSecret: clientAuth.tokenEnv } : {}),
163
202
  memberId: attachment.memberId,
164
- networkId: attachment.network
203
+ networkId: attachment.network,
204
+ ...(receiptStorePath ? { receiptStorePath } : {})
165
205
  });
166
206
  }
167
207
  }
@@ -1,22 +1,34 @@
1
- import { type MoltnetTargetArchitecture } from "./moltnetReleaseAuthority.js";
1
+ import { type MoltnetBridgeCapabilities, type MoltnetTargetArchitecture } from "./moltnetReleaseAuthority.js";
2
+ import { type MoltnetExecutionHost, type LocalMoltnetReleaseIdentity } from "./localMoltnetAuthority.js";
2
3
  /** Explicit operator override for a locally staged, authority-bound release. */
3
4
  export declare const MOLTNET_RELEASE_DIR_ENV = "SPAWNFILE_MOLTNET_RELEASE_DIR";
5
+ /** Explicit development-only local archive authority; never consulted by production compiles. */
6
+ export declare const MOLTNET_LOCAL_RELEASE_DIR_ENV = "SPAWNFILE_LOCAL_MOLTNET_RELEASE_DIR";
7
+ export declare const MOLTNET_ALLOW_LOCAL_E2E_ENV = "SPAWNFILE_ALLOW_LOCAL_E2E";
4
8
  export declare const MOLTNET_BIN_DIRECTORY = "moltnet-bin";
5
9
  export declare const MOLTNET_BINARY_NAMES: readonly ["moltnet"];
6
10
  export declare const MOLTNET_RELEASE_IDENTITY_VERSION: "spawnfile.moltnet-release-identity.v1";
7
11
  export declare const MOLTNET_RELEASE_STAMP_VERSION: "spawnfile.moltnet-release-stamp.v1";
8
12
  export type { MoltnetTargetArchitecture } from "./moltnetReleaseAuthority.js";
9
- export interface MoltnetReleaseIdentity {
13
+ /** Re-exported so existing importers keep one shape; defined in the lowest layer. */
14
+ export type { MoltnetBridgeCapabilities } from "./moltnetReleaseAuthority.js";
15
+ interface MoltnetIdentityBase {
10
16
  readonly architecture: MoltnetTargetArchitecture;
11
17
  readonly asset: string;
12
18
  readonly asset_sha256: `sha256:${string}`;
13
- readonly capabilities: readonly ["pi-bridge"];
19
+ readonly capabilities: MoltnetBridgeCapabilities;
20
+ readonly version: typeof MOLTNET_RELEASE_IDENTITY_VERSION;
21
+ }
22
+ export interface PublishedMoltnetReleaseIdentity extends MoltnetIdentityBase {
23
+ readonly capabilities: MoltnetBridgeCapabilities;
14
24
  readonly release_version: string;
15
25
  readonly source_revision: string;
16
- readonly version: typeof MOLTNET_RELEASE_IDENTITY_VERSION;
17
26
  }
27
+ export type MoltnetReleaseIdentity = PublishedMoltnetReleaseIdentity | LocalMoltnetReleaseIdentity;
18
28
  export interface MoltnetBinaryStageOptions {
19
29
  readonly architecture?: MoltnetTargetArchitecture;
30
+ /** Overrides the detected execution host for the local-build capability probe. Tests only. */
31
+ readonly executionHost?: MoltnetExecutionHost;
20
32
  /** Explicit local source directory; bytes remain bound to trusted authority. */
21
33
  readonly releaseDirectory?: string;
22
34
  }
@@ -5,12 +5,16 @@ import { chmod, readFile } from "node:fs/promises";
5
5
  import { promisify } from "node:util";
6
6
  import { ensureDirectory, fileExists } from "../filesystem/index.js";
7
7
  import { SpawnfileError } from "../shared/index.js";
8
- import { parseTrustedMoltnetReleaseAuthority, readTrustedMoltnetReleaseAuthority, trustedMoltnetReleaseAsset } from "./moltnetReleaseAuthority.js";
8
+ import { parseMoltnetBridgeCapabilities, parseTrustedMoltnetReleaseAuthority, readTrustedMoltnetReleaseAuthority, trustedMoltnetReleaseAsset } from "./moltnetReleaseAuthority.js";
9
9
  import { downloadTrustedMoltnetReleaseAsset } from "./moltnetReleaseDownload.js";
10
+ import { readLocalMoltnetReleaseIdentity } from "./localMoltnetAuthority.js";
10
11
  const execFile = promisify(execFileCallback);
11
12
  const MOLTNET_CLI_ENV = "SPAWNFILE_MOLTNET_CLI";
12
13
  /** Explicit operator override for a locally staged, authority-bound release. */
13
14
  export const MOLTNET_RELEASE_DIR_ENV = "SPAWNFILE_MOLTNET_RELEASE_DIR";
15
+ /** Explicit development-only local archive authority; never consulted by production compiles. */
16
+ export const MOLTNET_LOCAL_RELEASE_DIR_ENV = "SPAWNFILE_LOCAL_MOLTNET_RELEASE_DIR";
17
+ export const MOLTNET_ALLOW_LOCAL_E2E_ENV = "SPAWNFILE_ALLOW_LOCAL_E2E";
14
18
  const MOLTNET_TARGET_ARCH_ENV = "SPAWNFILE_MOLTNET_TARGET_ARCH";
15
19
  const MOLTNET_TARGET_OS = "linux";
16
20
  export const MOLTNET_BIN_DIRECTORY = "moltnet-bin";
@@ -50,6 +54,26 @@ const resolveTargetArchitecture = (architecture) => {
50
54
  throw new SpawnfileError("compile_error", `Moltnet container installs do not support host architecture ${process.arch}`);
51
55
  }
52
56
  };
57
+ /**
58
+ * The platform executing this compile, for the local-build capability probe.
59
+ *
60
+ * Deliberately NOT `resolveTargetArchitecture()`: that helper honours the
61
+ * `SPAWNFILE_MOLTNET_TARGET_ARCH` build-target override and falls back to
62
+ * `process.arch`, so passing it as the host made the host and the target the
63
+ * same value by construction and pinned the probe to its direct-exec branch.
64
+ * This reads the real host only, and reports `architecture: undefined` for a
65
+ * CPU that is not a nameable Moltnet target rather than throwing -- an
66
+ * unsupported host is not a compile error, it just cannot exec the binary
67
+ * directly.
68
+ *
69
+ * Private: this module's export surface is pinned by test.
70
+ */
71
+ const resolveMoltnetExecutionHost = () => ({
72
+ ...(process.arch === "arm64"
73
+ ? { architecture: "arm64" }
74
+ : process.arch === "x64" ? { architecture: "amd64" } : {}),
75
+ platform: process.platform
76
+ });
53
77
  const createReleaseAssetName = (architecture) => `moltnet_${MOLTNET_TARGET_OS}_${architecture}.tar.gz`;
54
78
  const createReleaseStampName = (architecture) => `moltnet_release_stamp_${architecture}.json`;
55
79
  const exactKeys = (value, keys) => Object.keys(value).sort().join("\0") === [...keys].sort().join("\0");
@@ -76,9 +100,7 @@ const parseReleaseStamp = (raw, architecture) => {
76
100
  || value.asset !== createReleaseAssetName(architecture)
77
101
  || typeof value.built_at !== "string"
78
102
  || !Number.isFinite(Date.parse(value.built_at))
79
- || !Array.isArray(capabilities)
80
- || capabilities.length !== 1
81
- || capabilities[0] !== "pi-bridge"
103
+ || parseMoltnetBridgeCapabilities(capabilities) === null
82
104
  || value.pi_bridge !== true
83
105
  || typeof value.sha256 !== "string"
84
106
  || !SHA256.test(value.sha256)
@@ -121,7 +143,7 @@ const verifyReleaseIdentity = async (releaseDirectory, architecture, authority)
121
143
  architecture,
122
144
  asset,
123
145
  asset_sha256: `sha256:${sha256}`,
124
- capabilities: Object.freeze(["pi-bridge"]),
146
+ capabilities: stamp.capabilities,
125
147
  release_version: stamp.version,
126
148
  source_revision: stamp.source_revision,
127
149
  version: MOLTNET_RELEASE_IDENTITY_VERSION
@@ -170,6 +192,18 @@ const resolveConfiguredReleaseDirectory = async () => {
170
192
  }
171
193
  return configuredDirectory;
172
194
  };
195
+ const resolveConfiguredLocalReleaseDirectory = async () => {
196
+ const configuredDirectory = process.env[MOLTNET_LOCAL_RELEASE_DIR_ENV]?.trim();
197
+ if (!configuredDirectory)
198
+ return null;
199
+ if (process.env[MOLTNET_ALLOW_LOCAL_E2E_ENV] !== "1") {
200
+ throw new SpawnfileError("compile_error", "Local Moltnet identity requires explicit SPAWNFILE_ALLOW_LOCAL_E2E=1 opt-in");
201
+ }
202
+ if (!path.isAbsolute(configuredDirectory) || !(await fileExists(configuredDirectory))) {
203
+ throw new SpawnfileError("compile_error", "Local Moltnet release directory is invalid");
204
+ }
205
+ return configuredDirectory;
206
+ };
173
207
  const findPathMoltnetCli = async () => {
174
208
  try {
175
209
  await execFile("moltnet", ["version"]);
@@ -205,6 +239,12 @@ const stageMoltnetBinariesAtReleaseDirectory = async (outputDirectory, releaseDi
205
239
  return stageMoltnetReleaseAsset(outputDirectory, releaseAssetPath, identity);
206
240
  };
207
241
  export const stageMoltnetBinaries = async (outputDirectory, options = {}) => {
242
+ const localReleaseDirectory = await resolveConfiguredLocalReleaseDirectory();
243
+ if (localReleaseDirectory) {
244
+ const architecture = resolveTargetArchitecture(options.architecture);
245
+ const identity = await readLocalMoltnetReleaseIdentity(localReleaseDirectory, architecture, options.executionHost ?? resolveMoltnetExecutionHost());
246
+ return stageMoltnetReleaseAsset(outputDirectory, path.join(localReleaseDirectory, createReleaseAssetName(architecture)), identity);
247
+ }
208
248
  const releaseDirectory = options.releaseDirectory
209
249
  ?? await resolveConfiguredReleaseDirectory();
210
250
  if (releaseDirectory) {
@@ -219,7 +259,7 @@ export const stageMoltnetBinaries = async (outputDirectory, options = {}) => {
219
259
  architecture,
220
260
  asset: trustedAsset.asset,
221
261
  asset_sha256: trustedAsset.asset_sha256,
222
- capabilities: Object.freeze(["pi-bridge"]),
262
+ capabilities: authority.capabilities,
223
263
  release_version: authority.release_version,
224
264
  source_revision: authority.source_revision,
225
265
  version: MOLTNET_RELEASE_IDENTITY_VERSION