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
@@ -151,7 +151,7 @@ export const probeDockerOrganizationReadiness = async (input) => {
151
151
  timeoutMs: input.timeoutMs
152
152
  });
153
153
  const inspection = await gateway.inspectUnit();
154
- if (input.evidence.hasExternalMoltnet || !input.evidence.worldBindings) {
154
+ if (input.evidence.hasExternalMoltnet) {
155
155
  return reconcileOrganizationReadiness({
156
156
  evidence: input.evidence, inspection, probe: null, record: correlation
157
157
  });
@@ -173,17 +173,23 @@ export const probeDockerOrganizationReadiness = async (input) => {
173
173
  });
174
174
  }
175
175
  const configs = new Map();
176
+ const attachmentReceipts = new Map();
176
177
  for (const network of input.evidence.networks) {
177
178
  for (const node of network.nodes) {
178
179
  const result = await gateway.exec(["cat", node.configPath]);
179
180
  configs.set(node.configPath, result.stdout);
181
+ const receipt = await gateway.exec(["cat", node.receiptPath]);
182
+ attachmentReceipts.set(node.receiptPath, receipt.stdout);
180
183
  }
181
184
  }
182
- const bindings = await gateway.exec(["cat", input.evidence.worldBindings.artifactPath]);
185
+ const daimonReceipt = input.evidence.daimon == null ? null : (await gateway.exec(["cat", input.evidence.daimon.receiptPath])).stdout;
186
+ const bindings = input.evidence.worldBindings === null
187
+ ? null
188
+ : await gateway.exec(["cat", input.evidence.worldBindings.artifactPath]);
183
189
  return reconcileOrganizationReadiness({
184
190
  evidence: input.evidence,
185
191
  inspection,
186
- probe: { configs, networks, worldBindings: bindings.stdout },
192
+ probe: { attachmentReceipts, configs, daimonReceipt, networks, worldBindings: bindings?.stdout ?? null },
187
193
  record: correlation
188
194
  });
189
195
  }
@@ -1,7 +1,21 @@
1
1
  import type { RuntimeProbeGateway } from "../runtime/index.js";
2
2
  import type { DeploymentRecord } from "./record.js";
3
3
  import type { DockerUnitInspection } from "./dockerInspect.js";
4
+ /**
5
+ * The ledger this gateway reads (`spawnfile usage`) rotates once a generation
6
+ * reaches `DAIMON_GROK_TURN_USAGE_LEDGER.rotateBytes`, and rotation happens on
7
+ * the append *after* that threshold is crossed — so a rotated generation is
8
+ * always at least the bound and the crossing line pushes it over. A maxBuffer
9
+ * merely equal to the bound therefore rejects the exact read this feature
10
+ * exists to perform (Node's `execFile` accepts a payload of exactly
11
+ * `maxBuffer` bytes and fails the next one with
12
+ * `ERR_CHILD_PROCESS_STDIO_MAXBUFFER`). Doubling the bound leaves a full
13
+ * generation of headroom, and is derived from the ledger constant rather than
14
+ * restated so the two cannot drift apart.
15
+ */
16
+ export declare const DEFAULT_DOCKER_PROBE_MAX_BUFFER_BYTES: number;
4
17
  export type DockerProbeExecFile = (file: string, args: string[], options: {
18
+ maxBuffer?: number;
5
19
  timeout: number;
6
20
  }) => Promise<{
7
21
  stderr: string;
@@ -11,6 +25,9 @@ export interface DockerProbeGatewayOptions {
11
25
  dockerCommand?: string;
12
26
  execFile?: DockerProbeExecFile;
13
27
  inspection: DockerUnitInspection;
28
+ /** Overrides Node's 1 MiB `execFile` default `maxBuffer`. Defaults to
29
+ * {@link DEFAULT_DOCKER_PROBE_MAX_BUFFER_BYTES}. */
30
+ maxBufferBytes?: number;
14
31
  timeoutMs?: number;
15
32
  }
16
33
  export declare const createDockerProbeGateway: (record: DeploymentRecord, unit: DeploymentRecord["units"][number], options: DockerProbeGatewayOptions) => RuntimeProbeGateway;
@@ -1,7 +1,21 @@
1
1
  import { execFile as execFileCallback } from "node:child_process";
2
2
  import { promisify } from "node:util";
3
+ import { DAIMON_GROK_TURN_USAGE_LEDGER } from "../runtime/daimon/contractManifest.js";
3
4
  import { dockerContextNameForTarget } from "./target.js";
4
5
  const execFile = promisify(execFileCallback);
6
+ /**
7
+ * The ledger this gateway reads (`spawnfile usage`) rotates once a generation
8
+ * reaches `DAIMON_GROK_TURN_USAGE_LEDGER.rotateBytes`, and rotation happens on
9
+ * the append *after* that threshold is crossed — so a rotated generation is
10
+ * always at least the bound and the crossing line pushes it over. A maxBuffer
11
+ * merely equal to the bound therefore rejects the exact read this feature
12
+ * exists to perform (Node's `execFile` accepts a payload of exactly
13
+ * `maxBuffer` bytes and fails the next one with
14
+ * `ERR_CHILD_PROCESS_STDIO_MAXBUFFER`). Doubling the bound leaves a full
15
+ * generation of headroom, and is derived from the ledger constant rather than
16
+ * restated so the two cannot drift apart.
17
+ */
18
+ export const DEFAULT_DOCKER_PROBE_MAX_BUFFER_BYTES = 2 * DAIMON_GROK_TURN_USAGE_LEDGER.rotateBytes;
5
19
  const targetRefForUnit = (unit) => {
6
20
  const targetRef = unit.container_id ?? unit.container_name;
7
21
  if (!targetRef) {
@@ -80,9 +94,10 @@ export const createDockerProbeGateway = (record, unit, options) => {
80
94
  const dockerCommand = options.dockerCommand ?? "docker";
81
95
  const runExec = options.execFile ?? execFile;
82
96
  const timeout = options.timeoutMs ?? 10_000;
97
+ const maxBuffer = options.maxBufferBytes ?? DEFAULT_DOCKER_PROBE_MAX_BUFFER_BYTES;
83
98
  const exec = async (command) => {
84
99
  const targetRef = targetRefForUnit(unit);
85
- return runExec(dockerCommand, withDockerTarget(record, ["exec", targetRef, ...command]), { timeout });
100
+ return runExec(dockerCommand, withDockerTarget(record, ["exec", targetRef, ...command]), { maxBuffer, timeout });
86
101
  };
87
102
  return {
88
103
  exec,
@@ -93,7 +108,7 @@ export const createDockerProbeGateway = (record, unit, options) => {
93
108
  const url = `http://127.0.0.1:${port}${requestPath.startsWith("/") ? requestPath : `/${requestPath}`}`;
94
109
  try {
95
110
  const targetRef = targetRefForUnit(unit);
96
- const result = await runExec(dockerCommand, withDockerTarget(record, httpProbeArgs(targetRef, imageRefForUnit(unit), url)), { timeout });
111
+ const result = await runExec(dockerCommand, withDockerTarget(record, httpProbeArgs(targetRef, imageRefForUnit(unit), url)), { maxBuffer, timeout });
97
112
  return parseCurlHttpOutput(result.stdout);
98
113
  }
99
114
  catch (error) {
@@ -1,6 +1,7 @@
1
1
  import { type DeploymentLifecycleCorrelation } from "./deploymentLifecycleCorrelation.js";
2
2
  import { type DockerTeardownExecFile } from "./dockerTeardown.js";
3
3
  import { type DownReceipt } from "./downReceiptTypes.js";
4
+ import type { DeploymentRecord } from "./record.js";
4
5
  export interface DownDeploymentOptions {
5
6
  /** Where the deployment record + compile report already live (the compile's own
6
7
  * `--out` directory) — same convention as `exportRunArtifacts`'s `compiledOutputDirectory`. */
@@ -23,6 +24,10 @@ export interface DownDeploymentOptions {
23
24
  expectedLifecycleCorrelation?: DeploymentLifecycleCorrelation;
24
25
  timeoutMs?: number;
25
26
  }
27
+ export declare const readCanonicalDownRecord: (compiledOutputDirectory: string, deploymentName: string) => Promise<{
28
+ mode: "image" | "project";
29
+ record: DeploymentRecord;
30
+ }>;
26
31
  /**
27
32
  * `spawnfile down` — record-driven teardown: resolves the deployment record, enforces the
28
33
  * export-before-teardown invariant, `docker rm -f`s every recorded container unit, and
@@ -1,5 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { fileExists, readUtf8File } from "../filesystem/index.js";
3
+ import { derivePersistentMountVolumeName, parseDistributionReport } from "../distribution/index.js";
3
4
  import { REPORT_FILENAME, SpawnfileError } from "../shared/index.js";
4
5
  import { exportRunArtifacts } from "./artifactsExport.js";
5
6
  import { assertDeploymentLifecycleCorrelation, } from "./deploymentLifecycleCorrelation.js";
@@ -7,6 +8,102 @@ import { defaultDockerTeardownExecFile, removeDockerContainer, removeDockerVolum
7
8
  import { DOWN_RECEIPT_VERSION } from "./downReceiptTypes.js";
8
9
  import { initializeOrganizationHandoffAuthorityStore, } from "./organizationHandoffAuthorityStore.js";
9
10
  import { readDeploymentRecordFromOutput } from "./record.js";
11
+ import { readHomeDeploymentRecord, readHomeDeploymentReport, resolveHomeRecordPath } from "./homeStore.js";
12
+ import { resolveDeploymentRecordPath } from "./names.js";
13
+ import { dockerContextNameForTarget } from "./target.js";
14
+ export const readCanonicalDownRecord = async (compiledOutputDirectory, deploymentName) => {
15
+ const projectPath = resolveDeploymentRecordPath(path.resolve(compiledOutputDirectory), deploymentName);
16
+ const homePath = resolveHomeRecordPath(deploymentName);
17
+ const [projectExists, homeExists] = await Promise.all([fileExists(projectPath), fileExists(homePath)]);
18
+ if (projectExists && homeExists)
19
+ throw new SpawnfileError("runtime_error", "Deployment record is ambiguous between project and image stores");
20
+ if (projectExists) {
21
+ const record = await readDeploymentRecordFromOutput(path.resolve(compiledOutputDirectory), deploymentName);
22
+ if (record.source.kind !== "project")
23
+ throw new SpawnfileError("runtime_error", "Project deployment store contains a non-project record");
24
+ return { mode: "project", record };
25
+ }
26
+ if (homeExists) {
27
+ const record = await readHomeDeploymentRecord(deploymentName);
28
+ if (record.source.kind !== "image")
29
+ throw new SpawnfileError("runtime_error", "Image deployment store contains a non-image record");
30
+ return { mode: "image", record };
31
+ }
32
+ throw new SpawnfileError("validation_error", `No recorded deployment named ${deploymentName}`);
33
+ };
34
+ const imageDown = async (record, options, runner) => {
35
+ if (record.source.kind !== "image" || record.units.length !== 1)
36
+ throw new SpawnfileError("runtime_error", "Image deployment record is invalid for teardown");
37
+ if (!record.export_index && !options.force)
38
+ throw new SpawnfileError("runtime_error", "Image deployment artifact export is unsupported; pass --force to discard unexported artifacts");
39
+ const unit = record.units[0];
40
+ if (!unit.container_id || !unit.image_id)
41
+ throw new SpawnfileError("runtime_error", "Image deployment has no exact recorded container or image identity");
42
+ const context = dockerContextNameForTarget(record.target);
43
+ const prefix = context ? ["--context", context] : record.target.kind === "host" ? ["--host", record.target.value] : [];
44
+ const inspected = await runner.execFile(runner.dockerCommand, [...prefix, "container", "inspect", "--format", "{{json .Id}}\n{{json .Name}}\n{{json .Image}}\n{{json .Config.Labels}}", unit.container_id], { timeout: runner.timeoutMs });
45
+ let identity;
46
+ try {
47
+ const [idLine, nameLine, imageLine, labelsLine, ...extra] = inspected.stdout.trim().split("\n");
48
+ if (!idLine || !nameLine || !imageLine || !labelsLine || extra.length)
49
+ throw new Error();
50
+ identity = { id: JSON.parse(idLine), imageId: JSON.parse(imageLine), name: JSON.parse(nameLine), labels: JSON.parse(labelsLine) };
51
+ }
52
+ catch {
53
+ throw new SpawnfileError("runtime_error", "Image deployment container identity is malformed");
54
+ }
55
+ if (identity.id !== unit.container_id || identity.name !== `/${unit.container_name}` || identity.imageId !== unit.image_id
56
+ || identity.labels["com.spawnfile.deployment"] !== record.name
57
+ || identity.labels["com.spawnfile.compile_fingerprint"] !== record.compile_fingerprint
58
+ || identity.labels["com.spawnfile.unit"] !== unit.id) {
59
+ throw new SpawnfileError("runtime_error", "Image deployment container identity does not match its record");
60
+ }
61
+ let reportValue;
62
+ try {
63
+ reportValue = JSON.parse(await readHomeDeploymentReport(record.name));
64
+ }
65
+ catch (error) {
66
+ const reason = error instanceof Error ? error.message : String(error);
67
+ throw new SpawnfileError("runtime_error", `Cached image distribution report is unreadable: ${reason}`);
68
+ }
69
+ const report = parseDistributionReport(reportValue, "cached image distribution report");
70
+ if (report.compile_fingerprint !== record.compile_fingerprint)
71
+ throw new SpawnfileError("runtime_error", "Cached image distribution report does not match its deployment record");
72
+ const { owned, skipped } = partitionDeclaredVolumes(report.persistent_mounts, (mount) => derivePersistentMountVolumeName(record.name, mount));
73
+ const volumes = [...owned, ...skipped].sort();
74
+ const removed = await removeDockerContainer(record.target, unit.container_id, runner);
75
+ if (!removed.removed)
76
+ return { deployment: record.name, errors: [`unable to remove container ${unit.container_id} (unit ${unit.id}): ${removed.error}`], retained_volumes: volumes, units_stopped: [], version: DOWN_RECEIPT_VERSION, ...(skipped.length > 0 ? { skipped_volumes: skipped } : {}) };
77
+ const errors = [], retained = [...skipped];
78
+ if (options.removeVolumes)
79
+ for (const volume of owned) {
80
+ const result = await removeDockerVolume(record.target, volume, runner);
81
+ if (!result.removed) {
82
+ errors.push(`unable to remove volume ${volume}: ${result.error}`);
83
+ retained.push(volume);
84
+ }
85
+ }
86
+ else
87
+ retained.push(...owned);
88
+ return { deployment: record.name, errors, retained_volumes: retained.sort(), units_stopped: [unit.id], version: DOWN_RECEIPT_VERSION, ...(skipped.length > 0 ? { skipped_volumes: skipped } : {}) };
89
+ };
90
+ /**
91
+ * Splits the volumes a `--volumes` teardown found into the ones this deployment
92
+ * owns and the author-declared ones it shares with every other deployment of the
93
+ * project. See downReceiptTypes.ts for why the declared ones are never removed.
94
+ */
95
+ const partitionDeclaredVolumes = (mounts, volumeNameOf) => {
96
+ const skipped = new Set();
97
+ const owned = new Set();
98
+ for (const mount of mounts) {
99
+ (mount.declared_volume_name?.trim() ? skipped : owned).add(volumeNameOf(mount));
100
+ }
101
+ // A name claimed by both is shared state, and the compiler already rejects that
102
+ // collision; fail safe here regardless by never removing it.
103
+ for (const name of skipped)
104
+ owned.delete(name);
105
+ return { owned: [...owned].sort(), skipped: [...skipped].sort() };
106
+ };
10
107
  const targetRefForUnit = (unit) => unit.container_id ?? unit.container_name;
11
108
  const readCompileReport = async (compiledOutputDirectory) => {
12
109
  const reportPath = path.join(compiledOutputDirectory, REPORT_FILENAME);
@@ -95,15 +192,18 @@ export const downDeployment = async (options) => {
95
192
  const dockerCommand = options.dockerCommand ?? "docker";
96
193
  const execFileImpl = options.execFile ?? defaultDockerTeardownExecFile;
97
194
  const timeoutMs = options.timeoutMs ?? 30_000;
98
- const initialRecord = await readDeploymentRecordFromOutput(compiledOutputDirectory, options.deploymentName);
195
+ const resolved = await readCanonicalDownRecord(compiledOutputDirectory, options.deploymentName);
196
+ const initialRecord = resolved.record;
99
197
  assertDeploymentLifecycleCorrelation(initialRecord, options.expectedLifecycleCorrelation);
198
+ const runnerOptions = { dockerCommand, execFile: execFileImpl, timeoutMs };
199
+ if (resolved.mode === "image")
200
+ return imageDown(initialRecord, options, runnerOptions);
100
201
  const record = await ensureExported(initialRecord, {
101
202
  ...options,
102
203
  compiledOutputDirectory,
103
204
  });
104
205
  assertDeploymentLifecycleCorrelation(record, options.expectedLifecycleCorrelation);
105
206
  await closeOrganizationHandoff(record);
106
- const runnerOptions = { dockerCommand, execFile: execFileImpl, timeoutMs };
107
207
  const unitsStopped = [];
108
208
  const errors = [];
109
209
  for (const unit of record.units) {
@@ -121,12 +221,12 @@ export const downDeployment = async (options) => {
121
221
  }
122
222
  }
123
223
  const report = await readCompileReport(compiledOutputDirectory);
124
- const volumeNames = [
125
- ...new Set((report?.container?.persistent_mounts ?? []).map((mount) => mount.volume_name)),
126
- ].sort();
127
- const retainedVolumes = [];
224
+ const { owned, skipped } = partitionDeclaredVolumes(report?.container?.persistent_mounts ?? [], (mount) => mount.volume_name);
225
+ // Declared volumes are retained unconditionally: they are shared project
226
+ // state, not this deployment's, so `--volumes` must never destroy them.
227
+ const retainedVolumes = [...skipped];
128
228
  if (options.removeVolumes) {
129
- for (const volumeName of volumeNames) {
229
+ for (const volumeName of owned) {
130
230
  const outcome = await removeDockerVolume(record.target, volumeName, runnerOptions);
131
231
  if (!outcome.removed) {
132
232
  errors.push(`unable to remove volume ${volumeName}: ${outcome.error}`);
@@ -135,12 +235,13 @@ export const downDeployment = async (options) => {
135
235
  }
136
236
  }
137
237
  else {
138
- retainedVolumes.push(...volumeNames);
238
+ retainedVolumes.push(...owned);
139
239
  }
140
240
  return {
141
241
  deployment: record.name,
142
242
  errors,
143
243
  retained_volumes: retainedVolumes.sort(),
244
+ ...(skipped.length > 0 ? { skipped_volumes: skipped } : {}),
144
245
  units_stopped: unitsStopped.sort(),
145
246
  version: DOWN_RECEIPT_VERSION,
146
247
  };
@@ -6,8 +6,22 @@ import { z } from "zod";
6
6
  * `unit.id`, e.g. `"<deployment>-container"`), not raw Docker container ids, so a caller
7
7
  * can cross-reference the up-receipt/deployment record without re-deriving anything.
8
8
  * `retained_volumes` is "named volumes still present on disk after this call returns" —
9
- * true whether they were never touched (the default) or survived an attempted
10
- * `--volumes` removal that failed (surfaced in `errors`, not silently dropped).
9
+ * true whether they were never touched (the default), survived an attempted
10
+ * `--volumes` removal that failed (surfaced in `errors`, not silently dropped), or
11
+ * were deliberately skipped as shared project state (`skipped_volumes`).
12
+ *
13
+ * `skipped_volumes` is the third outcome this contract originally could not express.
14
+ * An author-declared volume name (a workspace resource `name`, a
15
+ * `store.persistence.name`, a memory bank's `persistence.name`) is verbatim in every
16
+ * mode and every deployment, so it is NOT "this deployment's named volume" — a
17
+ * `down --volumes` of a dev or scratch deployment would otherwise destroy the
18
+ * production state that same name refers to, whenever production happens to be
19
+ * stopped (Docker only refuses a volume that is currently in use). Those volumes are
20
+ * skipped, listed here AND in `retained_volumes`, and removing one is a deliberate
21
+ * project-level act: `docker volume rm <name>`.
22
+ *
23
+ * The field is OMITTED when nothing was skipped, so every receipt that could be
24
+ * produced before this existed is still byte-identical.
11
25
  */
12
26
  export declare const DOWN_RECEIPT_VERSION: "spawnfile.down-receipt.v1";
13
27
  export declare const downReceiptSchema: z.ZodObject<{
@@ -15,6 +29,7 @@ export declare const downReceiptSchema: z.ZodObject<{
15
29
  deployment: z.ZodString;
16
30
  units_stopped: z.ZodArray<z.ZodString>;
17
31
  retained_volumes: z.ZodArray<z.ZodString>;
32
+ skipped_volumes: z.ZodOptional<z.ZodArray<z.ZodString>>;
18
33
  errors: z.ZodArray<z.ZodString>;
19
34
  }, z.core.$strict>;
20
35
  export type DownReceipt = z.infer<typeof downReceiptSchema>;
@@ -6,8 +6,22 @@ import { z } from "zod";
6
6
  * `unit.id`, e.g. `"<deployment>-container"`), not raw Docker container ids, so a caller
7
7
  * can cross-reference the up-receipt/deployment record without re-deriving anything.
8
8
  * `retained_volumes` is "named volumes still present on disk after this call returns" —
9
- * true whether they were never touched (the default) or survived an attempted
10
- * `--volumes` removal that failed (surfaced in `errors`, not silently dropped).
9
+ * true whether they were never touched (the default), survived an attempted
10
+ * `--volumes` removal that failed (surfaced in `errors`, not silently dropped), or
11
+ * were deliberately skipped as shared project state (`skipped_volumes`).
12
+ *
13
+ * `skipped_volumes` is the third outcome this contract originally could not express.
14
+ * An author-declared volume name (a workspace resource `name`, a
15
+ * `store.persistence.name`, a memory bank's `persistence.name`) is verbatim in every
16
+ * mode and every deployment, so it is NOT "this deployment's named volume" — a
17
+ * `down --volumes` of a dev or scratch deployment would otherwise destroy the
18
+ * production state that same name refers to, whenever production happens to be
19
+ * stopped (Docker only refuses a volume that is currently in use). Those volumes are
20
+ * skipped, listed here AND in `retained_volumes`, and removing one is a deliberate
21
+ * project-level act: `docker volume rm <name>`.
22
+ *
23
+ * The field is OMITTED when nothing was skipped, so every receipt that could be
24
+ * produced before this existed is still byte-identical.
11
25
  */
12
26
  export const DOWN_RECEIPT_VERSION = "spawnfile.down-receipt.v1";
13
27
  export const downReceiptSchema = z
@@ -16,6 +30,7 @@ export const downReceiptSchema = z
16
30
  deployment: z.string().min(1),
17
31
  units_stopped: z.array(z.string().min(1)),
18
32
  retained_volumes: z.array(z.string().min(1)),
33
+ skipped_volumes: z.array(z.string().min(1)).optional(),
19
34
  errors: z.array(z.string().min(1))
20
35
  })
21
36
  .strict();
@@ -4,6 +4,7 @@ export * from "./artifactsExportPlan.js";
4
4
  export * from "./artifactsExportTypes.js";
5
5
  export * from "./privateArtifactsExport.js";
6
6
  export * from "./buildImageCacheStore.js";
7
+ export * from "./candidateDiagnostics.js";
7
8
  export * from "./dockerLabels.js";
8
9
  export * from "./dockerInspect.js";
9
10
  export * from "./dockerLogs.js";
@@ -16,11 +17,14 @@ export * from "./downDeployment.js";
16
17
  export * from "./downReceiptTypes.js";
17
18
  export * from "./homeStore.js";
18
19
  export * from "./lifecycleCompletion.js";
20
+ export * from "./lifecycleUpRecords.js";
19
21
  export * from "./names.js";
20
22
  export * from "./organizationHandoffTypes.js";
21
23
  export * from "./organizationHandoffAuthorityTypes.js";
22
24
  export * from "./organizationHandoffAuthorityStore.js";
23
25
  export * from "./organizationReady.js";
26
+ export * from "./canaryCutover.js";
27
+ export * from "./productStateClone.js";
24
28
  export * from "./record.js";
25
29
  export * from "./target.js";
26
30
  export * from "./upReceiptTypes.js";
@@ -4,6 +4,7 @@ export * from "./artifactsExportPlan.js";
4
4
  export * from "./artifactsExportTypes.js";
5
5
  export * from "./privateArtifactsExport.js";
6
6
  export * from "./buildImageCacheStore.js";
7
+ export * from "./candidateDiagnostics.js";
7
8
  export * from "./dockerLabels.js";
8
9
  export * from "./dockerInspect.js";
9
10
  export * from "./dockerLogs.js";
@@ -16,11 +17,14 @@ export * from "./downDeployment.js";
16
17
  export * from "./downReceiptTypes.js";
17
18
  export * from "./homeStore.js";
18
19
  export * from "./lifecycleCompletion.js";
20
+ export * from "./lifecycleUpRecords.js";
19
21
  export * from "./names.js";
20
22
  export * from "./organizationHandoffTypes.js";
21
23
  export * from "./organizationHandoffAuthorityTypes.js";
22
24
  export * from "./organizationHandoffAuthorityStore.js";
23
25
  export * from "./organizationReady.js";
26
+ export * from "./canaryCutover.js";
27
+ export * from "./productStateClone.js";
24
28
  export * from "./record.js";
25
29
  // Compatibility target exports remain available from this legacy deployment barrel.
26
30
  export * from "./target.js";
@@ -6,6 +6,10 @@ export declare const LIFECYCLE_OWNER_VERSION: "spawnfile.lifecycle-owner.v1";
6
6
  export declare const LIFECYCLE_ADMISSION_VERSION: "spawnfile.lifecycle-admission.v1";
7
7
  export declare const LIFECYCLE_AMBIGUOUS_VERSION: "spawnfile.lifecycle-ambiguous.v1";
8
8
  export declare const LIFECYCLE_TERMINAL_VERSION: "spawnfile.lifecycle-terminal.v1";
9
+ export declare const LIFECYCLE_UP_START_VERSION: "spawnfile.lifecycle-up-start.v1";
10
+ export declare const LIFECYCLE_UP_RESERVATION_VERSION: "spawnfile.lifecycle-up-reservation.v1";
11
+ export declare const LIFECYCLE_UP_CLEANUP_VERSION: "spawnfile.lifecycle-up-cleanup.v1";
12
+ export declare const LIFECYCLE_UP_EXTRA_LABELS: "image-config-labels";
9
13
  export declare const LIFECYCLE_RECORD_MAX_BYTES = 1000000;
10
14
  export declare const lifecycleIdSchema: z.ZodString;
11
15
  export declare const lifecycleInvocationSchema: z.ZodObject<{
@@ -94,6 +98,68 @@ export declare const lifecycleCompletionSchema: z.ZodObject<{
94
98
  version: z.ZodLiteral<"spawnfile.lifecycle-completion.v1">;
95
99
  }, z.core.$strict>;
96
100
  export type LifecycleCompletion = z.infer<typeof lifecycleCompletionSchema>;
101
+ export declare const lifecycleUpReservationSchema: z.ZodObject<{
102
+ container_name: z.ZodString;
103
+ docker_command: z.ZodString;
104
+ docker_context: z.ZodNullable<z.ZodString>;
105
+ invocation: z.ZodObject<{
106
+ correlation: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodNull]>>;
107
+ id: z.ZodString;
108
+ operation: z.ZodEnum<{
109
+ down: "down";
110
+ up: "up";
111
+ artifacts_export: "artifacts_export";
112
+ }>;
113
+ request_policy: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodNull]>>;
114
+ version: z.ZodLiteral<"spawnfile.lifecycle-invocation.v1">;
115
+ }, z.core.$strict>;
116
+ label_authority: z.ZodObject<{
117
+ required: z.ZodRecord<z.ZodString, z.ZodString>;
118
+ permitted_extra_labels: z.ZodLiteral<"image-config-labels">;
119
+ }, z.core.$strict>;
120
+ version: z.ZodLiteral<"spawnfile.lifecycle-up-reservation.v1">;
121
+ }, z.core.$strict>;
122
+ export type LifecycleUpReservation = z.infer<typeof lifecycleUpReservationSchema>;
123
+ export declare const lifecycleUpStartSchema: z.ZodObject<{
124
+ attempt: z.ZodNumber;
125
+ container_id: z.ZodString;
126
+ container_name: z.ZodString;
127
+ image_id: z.ZodString;
128
+ invocation: z.ZodObject<{
129
+ correlation: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodNull]>>;
130
+ id: z.ZodString;
131
+ operation: z.ZodEnum<{
132
+ down: "down";
133
+ up: "up";
134
+ artifacts_export: "artifacts_export";
135
+ }>;
136
+ request_policy: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodNull]>>;
137
+ version: z.ZodLiteral<"spawnfile.lifecycle-invocation.v1">;
138
+ }, z.core.$strict>;
139
+ label_authority: z.ZodObject<{
140
+ required: z.ZodRecord<z.ZodString, z.ZodString>;
141
+ permitted_extra_labels: z.ZodLiteral<"image-config-labels">;
142
+ }, z.core.$strict>;
143
+ version: z.ZodLiteral<"spawnfile.lifecycle-up-start.v1">;
144
+ }, z.core.$strict>;
145
+ export type LifecycleUpStart = z.infer<typeof lifecycleUpStartSchema>;
146
+ export declare const lifecycleUpCleanupSchema: z.ZodObject<{
147
+ attempt: z.ZodNumber;
148
+ container_id: z.ZodString;
149
+ invocation: z.ZodObject<{
150
+ correlation: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodNull]>>;
151
+ id: z.ZodString;
152
+ operation: z.ZodEnum<{
153
+ down: "down";
154
+ up: "up";
155
+ artifacts_export: "artifacts_export";
156
+ }>;
157
+ request_policy: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodNull]>>;
158
+ version: z.ZodLiteral<"spawnfile.lifecycle-invocation.v1">;
159
+ }, z.core.$strict>;
160
+ version: z.ZodLiteral<"spawnfile.lifecycle-up-cleanup.v1">;
161
+ }, z.core.$strict>;
162
+ export type LifecycleUpCleanup = z.infer<typeof lifecycleUpCleanupSchema>;
97
163
  export declare const lifecycleTerminalSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
98
164
  completion: z.ZodObject<{
99
165
  invocation: z.ZodObject<{
@@ -7,6 +7,11 @@ export const LIFECYCLE_OWNER_VERSION = "spawnfile.lifecycle-owner.v1";
7
7
  export const LIFECYCLE_ADMISSION_VERSION = "spawnfile.lifecycle-admission.v1";
8
8
  export const LIFECYCLE_AMBIGUOUS_VERSION = "spawnfile.lifecycle-ambiguous.v1";
9
9
  export const LIFECYCLE_TERMINAL_VERSION = "spawnfile.lifecycle-terminal.v1";
10
+ export const LIFECYCLE_UP_START_VERSION = "spawnfile.lifecycle-up-start.v1";
11
+ export const LIFECYCLE_UP_RESERVATION_VERSION = "spawnfile.lifecycle-up-reservation.v1";
12
+ export const LIFECYCLE_UP_CLEANUP_VERSION = "spawnfile.lifecycle-up-cleanup.v1";
13
+ // Docker carries an image's config labels onto a container; no other extras are allowed.
14
+ export const LIFECYCLE_UP_EXTRA_LABELS = "image-config-labels";
10
15
  export const LIFECYCLE_RECORD_MAX_BYTES = 1_000_000;
11
16
  export const lifecycleIdSchema = z
12
17
  .string()
@@ -70,6 +75,35 @@ export const lifecycleCompletionSchema = z
70
75
  version: z.literal(LIFECYCLE_COMPLETION_VERSION),
71
76
  })
72
77
  .strict();
78
+ const lifecycleUpLabelAuthoritySchema = z.object({
79
+ required: z.record(z.string().min(1).max(255), z.string().max(4096)),
80
+ permitted_extra_labels: z.literal(LIFECYCLE_UP_EXTRA_LABELS),
81
+ }).strict();
82
+ export const lifecycleUpReservationSchema = z.object({
83
+ container_name: z.string().min(1).max(255),
84
+ docker_command: z.string().min(1).max(4096),
85
+ docker_context: z.string().min(1).max(128).nullable(),
86
+ invocation: lifecycleInvocationSchema,
87
+ label_authority: lifecycleUpLabelAuthoritySchema,
88
+ version: z.literal(LIFECYCLE_UP_RESERVATION_VERSION),
89
+ }).strict();
90
+ export const lifecycleUpStartSchema = z
91
+ .object({
92
+ attempt: z.number().int().min(0).max(16),
93
+ container_id: z.string().regex(/^[a-f0-9]{64}$/u),
94
+ container_name: z.string().min(1).max(255),
95
+ image_id: z.string().regex(/^sha256:[a-f0-9]{64}$/u),
96
+ invocation: lifecycleInvocationSchema,
97
+ label_authority: lifecycleUpLabelAuthoritySchema,
98
+ version: z.literal(LIFECYCLE_UP_START_VERSION),
99
+ })
100
+ .strict();
101
+ export const lifecycleUpCleanupSchema = z.object({
102
+ attempt: z.number().int().min(0).max(16),
103
+ container_id: z.string().regex(/^[a-f0-9]{64}$/u),
104
+ invocation: lifecycleInvocationSchema,
105
+ version: z.literal(LIFECYCLE_UP_CLEANUP_VERSION),
106
+ }).strict();
73
107
  export const lifecycleTerminalSchema = z.discriminatedUnion("status", [
74
108
  z
75
109
  .object({
@@ -1,9 +1,12 @@
1
1
  export declare const failLifecycleStore: (message: string) => never;
2
2
  export declare const resolveLifecycleCompletionDirectory: () => string;
3
- export declare const lifecycleRecordName: (id: string, kind: "admission" | "completion" | "evidence" | "plan" | "recovery") => string;
3
+ export declare const lifecycleRecordName: (id: string, kind: "admission" | "completion" | "evidence" | "plan" | "recovery" | "up-reservation") => string;
4
4
  export declare const resolveLifecycleCompletionPath: (id: string) => string;
5
5
  export declare const admissionPath: (id: string) => string;
6
6
  export declare const planPath: (id: string) => string;
7
7
  export declare const recoveryPath: (id: string) => string;
8
8
  export declare const evidencePath: (id: string) => string;
9
+ export declare const upReservationPath: (id: string) => string;
10
+ export declare const upStartPath: (id: string, attempt: number) => string;
11
+ export declare const upCleanupPath: (id: string, attempt: number) => string;
9
12
  export declare const heartbeatPath: (id: string) => string;
@@ -13,4 +13,7 @@ export const admissionPath = (id) => lifecyclePath(id, "admission");
13
13
  export const planPath = (id) => lifecyclePath(id, "plan");
14
14
  export const recoveryPath = (id) => lifecyclePath(id, "recovery");
15
15
  export const evidencePath = (id) => lifecyclePath(id, "evidence");
16
+ export const upReservationPath = (id) => lifecyclePath(id, "up-reservation");
17
+ export const upStartPath = (id, attempt) => path.join(resolveLifecycleCompletionDirectory(), `${lifecycleIdSchema.parse(id)}.up-start-${attempt}`);
18
+ export const upCleanupPath = (id, attempt) => path.join(resolveLifecycleCompletionDirectory(), `${lifecycleIdSchema.parse(id)}.up-cleanup-${attempt}`);
16
19
  export const heartbeatPath = (id) => path.join(resolveLifecycleCompletionDirectory(), `${lifecycleIdSchema.parse(id)}.heartbeat`);
@@ -1,5 +1,7 @@
1
1
  type RecordReader = (file: string, links?: readonly number[]) => Promise<string | null>;
2
+ export declare const LIFECYCLE_PUBLICATION_SETTLE_TIMEOUT_MS = 1000;
2
3
  export declare const settleLifecyclePublication: (file: string) => Promise<void>;
4
+ export declare const settleLifecyclePublicationUntil: (settled: () => Promise<boolean>) => Promise<void>;
3
5
  export declare const readSettledLifecycleRecord: (file: string, read: RecordReader) => Promise<string | null>;
4
6
  export declare const matchesSettledLifecyclePublication: (file: string, expected: string, read: RecordReader) => Promise<boolean>;
5
7
  export {};
@@ -1,16 +1,30 @@
1
1
  import { lstat } from "node:fs/promises";
2
+ import { performance } from "node:perf_hooks";
2
3
  import { SpawnfileError } from "../shared/index.js";
4
+ // A competing publisher removes its temporary hard link asynchronously. A
5
+ // short run of event-loop turns can elapse before that unlink is scheduled
6
+ // when many lifecycle operations are active, so leave a bounded but practical
7
+ // window before treating an extra link as hostile.
8
+ export const LIFECYCLE_PUBLICATION_SETTLE_TIMEOUT_MS = 1_000;
9
+ const LIFECYCLE_PUBLICATION_SETTLE_BACKOFF_MS = 2;
3
10
  const refuse = (message) => {
4
11
  throw new SpawnfileError("runtime_error", `Lifecycle completion store refused: ${message}`);
5
12
  };
6
13
  export const settleLifecyclePublication = async (file) => {
7
- for (let attempt = 0; attempt < 16; attempt += 1) {
14
+ await settleLifecyclePublicationUntil(async () => {
8
15
  const info = await lstat(file).catch(() => refuse("publication changed"));
9
- if (info.nlink === 1)
16
+ return info.nlink === 1;
17
+ });
18
+ };
19
+ export const settleLifecyclePublicationUntil = async (settled) => {
20
+ const deadline = performance.now() + LIFECYCLE_PUBLICATION_SETTLE_TIMEOUT_MS;
21
+ while (true) {
22
+ if (await settled())
10
23
  return;
11
- await new Promise((resolve) => setImmediate(resolve));
24
+ if (performance.now() >= deadline)
25
+ refuse("publication did not settle");
26
+ await new Promise((resolve) => setTimeout(resolve, LIFECYCLE_PUBLICATION_SETTLE_BACKOFF_MS));
12
27
  }
13
- refuse("publication did not settle");
14
28
  };
15
29
  export const readSettledLifecycleRecord = async (file, read) => {
16
30
  const text = await read(file, [1, 2]);
@@ -1,4 +1,4 @@
1
- export { admissionPath, evidencePath, failLifecycleStore, heartbeatPath, lifecycleRecordName, planPath, recoveryPath, resolveLifecycleCompletionDirectory, resolveLifecycleCompletionPath } from "./lifecycleCompletionPaths.js";
1
+ export { admissionPath, evidencePath, failLifecycleStore, heartbeatPath, lifecycleRecordName, planPath, recoveryPath, upCleanupPath, upReservationPath, upStartPath, resolveLifecycleCompletionDirectory, resolveLifecycleCompletionPath } from "./lifecycleCompletionPaths.js";
2
2
  export { existingLifecycleRoot, lifecycleRoot, syncLifecycleDirectory } from "./lifecycleCompletionRoot.js";
3
3
  export type LifecycleStoreTestHookPoint = "before_missing_return" | "before_record_open" | "before_publish_link" | "before_publish_temp_open" | "before_publish_unlink";
4
4
  export declare const setLifecycleStoreTestHook: (hook: ((point: LifecycleStoreTestHookPoint) => Promise<void> | void) | null) => void;