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
@@ -2,48 +2,37 @@ import { constants } from "node:fs";
2
2
  import { link, lstat, open, unlink } from "node:fs/promises";
3
3
  import { dirname, resolve } from "node:path";
4
4
  import { TARGET_SECRET_SOURCE_ERROR, parseTargetSecretSourceOpaqueHandle } from "./targetSecretSourceRecordCommon.js";
5
+ import { directoryIdentityOf, fileIdentityOf, sameDirectory, sameFileExact, sameFileInode, sameFileNode } from "./targetSecretSourceFsIdentity.js";
5
6
  const MAX_BYTES = 65_536;
6
7
  const MAX_ATTEMPTS = 512;
7
8
  const fail = () => { throw new Error(TARGET_SECRET_SOURCE_ERROR); };
8
9
  const missing = (error) => error.code === "ENOENT";
9
10
  const exists = (error) => error.code === "EEXIST";
10
- const same = (a, b) => a.dev === b.dev && a.ino === b.ino && a.mode === b.mode && a.nlink === b.nlink && a.size === b.size && a.uid === b.uid;
11
- const sameNode = (a, b) => a.dev === b.dev && a.ino === b.ino && a.mode === b.mode && a.nlink === b.nlink && a.uid === b.uid;
12
- const sameInode = (a, b) => a.dev === b.dev && a.ino === b.ino && a.mode === b.mode && a.size === b.size && a.uid === b.uid;
13
11
  const ownerUid = () => {
14
12
  const value = process.getuid?.();
15
13
  return typeof value === "number" ? value : fail();
16
14
  };
17
- const directoryIdentity = (value, uid) => {
18
- if (!value.isDirectory() || value.isSymbolicLink() || value.uid !== uid || (value.mode & 0o7777) !== 0o700)
19
- fail();
20
- return { dev: value.dev, ino: value.ino, mode: value.mode, nlink: 0, size: 0, uid: value.uid };
21
- };
22
- const fileIdentity = (value, uid, links, zero = false) => {
23
- if (!value.isFile() || value.isSymbolicLink() || value.uid !== uid || !links.includes(value.nlink)
24
- || (value.mode & 0o7777) !== 0o600 || value.size < 0 || value.size > MAX_BYTES || (zero && value.size !== 0))
25
- fail();
26
- return { dev: value.dev, ino: value.ino, mode: value.mode, nlink: value.nlink, size: value.size, uid: value.uid };
27
- };
28
- const yieldTurn = () => new Promise((resolve) => setImmediate(resolve));
15
+ const directoryIdentity = (value, uid) => directoryIdentityOf(value, uid);
16
+ const fileIdentity = (value, uid, links, zero = false) => fileIdentityOf(value, uid, links, MAX_BYTES, zero);
17
+ const contentionDelay = (attempt) => new Promise((resolve) => setTimeout(resolve, Math.min(5, 1 + Math.floor(attempt / 32))));
29
18
  export const initializeTargetSecretSourceFsPublishImmutable = async (options) => {
30
19
  if (!options || typeof options !== "object" || !Array.isArray(options.directory_chain) || options.directory_chain.length < 1
31
20
  || options.directory_chain.some((entry) => typeof entry !== "string" || entry.length < 1))
32
21
  fail();
33
22
  const uid = ownerUid();
34
23
  const paths = [...options.directory_chain];
35
- const roots = await Promise.all(paths.map(async (path) => directoryIdentity(await lstat(path), uid)));
24
+ const roots = await Promise.all(paths.map(async (path) => directoryIdentity(await lstat(path, { bigint: true }), uid)));
36
25
  const checkChain = async () => {
37
26
  for (let index = 0; index < paths.length; index += 1) {
38
- const named = directoryIdentity(await lstat(paths[index]), uid);
39
- if (!same(named, roots[index]))
27
+ const named = directoryIdentity(await lstat(paths[index], { bigint: true }), uid);
28
+ if (!sameDirectory(named, roots[index]))
40
29
  fail();
41
30
  let fd;
42
31
  try {
43
32
  fd = await open(paths[index], constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
44
- const opened = directoryIdentity(await fd.stat(), uid);
45
- const after = directoryIdentity(await lstat(paths[index]), uid);
46
- if (!same(opened, roots[index]) || !same(after, roots[index]))
33
+ const opened = directoryIdentity(await fd.stat({ bigint: true }), uid);
34
+ const after = directoryIdentity(await lstat(paths[index], { bigint: true }), uid);
35
+ if (!sameDirectory(opened, roots[index]) || !sameDirectory(after, roots[index]))
47
36
  fail();
48
37
  }
49
38
  catch {
@@ -60,13 +49,13 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
60
49
  let fd;
61
50
  try {
62
51
  fd = await open(paths.at(-1), constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
63
- const opened = directoryIdentity(await fd.stat(), uid);
64
- if (!same(opened, roots.at(-1)))
52
+ const opened = directoryIdentity(await fd.stat({ bigint: true }), uid);
53
+ if (!sameDirectory(opened, roots.at(-1)))
65
54
  fail();
66
55
  await fd.sync();
67
- const after = directoryIdentity(await fd.stat(), uid);
68
- const named = directoryIdentity(await lstat(paths.at(-1)), uid);
69
- if (!same(after, roots.at(-1)) || !same(named, roots.at(-1)))
56
+ const after = directoryIdentity(await fd.stat({ bigint: true }), uid);
57
+ const named = directoryIdentity(await lstat(paths.at(-1), { bigint: true }), uid);
58
+ if (!sameDirectory(after, roots.at(-1)) || !sameDirectory(named, roots.at(-1)))
70
59
  fail();
71
60
  }
72
61
  catch {
@@ -81,8 +70,8 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
81
70
  await checkChain();
82
71
  let before;
83
72
  try {
84
- const beforeInfo = await lstat(path);
85
- if (beforeInfo.nlink === 0) {
73
+ const beforeInfo = await lstat(path, { bigint: true });
74
+ if (beforeInfo.nlink === 0n) {
86
75
  fileIdentity(beforeInfo, uid, [0], true);
87
76
  return null;
88
77
  }
@@ -93,6 +82,7 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
93
82
  return null;
94
83
  return fail();
95
84
  }
85
+ await options.hookForTest?.("after_zero_lstat", path);
96
86
  let fd;
97
87
  try {
98
88
  try {
@@ -105,16 +95,16 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
105
95
  }
106
96
  if (!fd)
107
97
  return fail();
108
- const openedInfo = await fd.stat();
109
- if (openedInfo.nlink === 0) {
98
+ const openedInfo = await fd.stat({ bigint: true });
99
+ if (openedInfo.nlink === 0n) {
110
100
  fileIdentity(openedInfo, uid, [0], true);
111
101
  return null;
112
102
  }
113
103
  const opened = fileIdentity(openedInfo, uid, links, true);
114
104
  let after;
115
105
  try {
116
- const afterInfo = await lstat(path);
117
- if (afterInfo.nlink === 0) {
106
+ const afterInfo = await lstat(path, { bigint: true });
107
+ if (afterInfo.nlink === 0n) {
118
108
  fileIdentity(afterInfo, uid, [0], true);
119
109
  return null;
120
110
  }
@@ -125,7 +115,7 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
125
115
  return null;
126
116
  return fail();
127
117
  }
128
- if (!sameInode(before, opened) || !sameInode(opened, after) || !same(before, opened) || !same(opened, after))
118
+ if (!sameFileInode(before, opened) || !sameFileInode(opened, after) || !sameFileExact(before, opened) || !sameFileExact(opened, after))
129
119
  return null;
130
120
  return opened;
131
121
  }
@@ -139,15 +129,16 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
139
129
  const unlinkExact = async (path, expected) => {
140
130
  await checkChain();
141
131
  const current = await snapshotZero(path, [1, 2]);
142
- if (current === null || !sameInode(current, expected) || !same(current, expected))
132
+ if (current === null || !sameFileInode(current, expected) || !sameFileExact(current, expected))
143
133
  return false;
144
134
  const immediate = await snapshotZero(path, [1, 2]);
145
135
  if (immediate === null) {
146
136
  await syncDirectory();
147
137
  return false;
148
138
  }
149
- if (!sameInode(immediate, expected) || !same(immediate, expected))
139
+ if (!sameFileInode(immediate, expected) || !sameFileExact(immediate, expected))
150
140
  return false;
141
+ await options.hookForTest?.("before_unlink_exact", path);
151
142
  try {
152
143
  await unlink(path);
153
144
  }
@@ -164,21 +155,22 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
164
155
  await checkChain();
165
156
  let before;
166
157
  try {
167
- before = fileIdentity(await lstat(path), uid, [1]);
158
+ before = fileIdentity(await lstat(path, { bigint: true }), uid, [1]);
168
159
  }
169
160
  catch (error) {
170
161
  if (missing(error))
171
162
  return "absent";
172
163
  return fail();
173
164
  }
165
+ await options.hookForTest?.("after_final_lstat", path);
174
166
  if (before.size > expected.length)
175
167
  fail();
176
168
  let fd;
177
169
  let bytes;
178
170
  try {
179
171
  fd = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
180
- const opened = fileIdentity(await fd.stat(), uid, [1]);
181
- if (!sameNode(before, opened) || opened.size > expected.length)
172
+ const opened = fileIdentity(await fd.stat({ bigint: true }), uid, [1]);
173
+ if (!sameFileNode(before, opened) || opened.size > expected.length)
182
174
  fail();
183
175
  bytes = new Uint8Array(opened.size);
184
176
  let offset = 0;
@@ -188,18 +180,20 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
188
180
  fail();
189
181
  offset += read.bytesRead;
190
182
  }
191
- const after = fileIdentity(await fd.stat(), uid, [1]);
192
- const named = fileIdentity(await lstat(path), uid, [1]);
193
- if (!sameNode(opened, after) || !sameNode(opened, named))
183
+ const after = fileIdentity(await fd.stat({ bigint: true }), uid, [1]);
184
+ const named = fileIdentity(await lstat(path, { bigint: true }), uid, [1]);
185
+ if (!sameFileNode(opened, after) || !sameFileNode(opened, named))
194
186
  fail();
195
- if (!same(opened, after) || !same(opened, named))
187
+ if (!sameFileExact(opened, after) || !sameFileExact(opened, named))
196
188
  return "prefix";
197
189
  for (let index = 0; index < bytes.length; index += 1)
198
190
  if (bytes[index] !== expected[index])
199
191
  fail();
200
192
  return bytes.length === expected.length ? "exact" : "prefix";
201
193
  }
202
- catch {
194
+ catch (error) {
195
+ if (missing(error))
196
+ return "absent";
203
197
  return fail();
204
198
  }
205
199
  finally {
@@ -213,15 +207,24 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
213
207
  try {
214
208
  fd = await open(token, constants.O_CREAT | constants.O_EXCL | constants.O_RDWR | constants.O_NOFOLLOW, 0o600);
215
209
  await fd.chmod(0o600);
216
- const opened = fileIdentity(await fd.stat(), uid, [1], true);
210
+ await options.hookForTest?.("after_token_open", token);
211
+ // An identical publisher may link or finish tearing down this token as soon
212
+ // as O_EXCL makes the pathname visible, before its creator reaches fstat.
213
+ const openedInfo = await fd.stat({ bigint: true });
214
+ if (openedInfo.nlink === 0n) {
215
+ fileIdentity(openedInfo, uid, [0], true);
216
+ return null;
217
+ }
218
+ const opened = fileIdentity(openedInfo, uid, [1, 2], true);
217
219
  await fd.sync();
218
- const afterInfo = await fd.stat();
219
- if (afterInfo.nlink === 0) {
220
+ await options.hookForTest?.("after_token_sync", token);
221
+ const afterInfo = await fd.stat({ bigint: true });
222
+ if (afterInfo.nlink === 0n) {
220
223
  fileIdentity(afterInfo, uid, [0], true);
221
224
  return null;
222
225
  }
223
226
  const after = fileIdentity(afterInfo, uid, [1, 2], true);
224
- if (!sameInode(opened, after))
227
+ if (!sameFileInode(opened, after))
225
228
  fail();
226
229
  await syncDirectory();
227
230
  await options.hookForTest?.("after_token_create", token);
@@ -271,6 +274,13 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
271
274
  await proveOwned();
272
275
  const claim = `${final}.claim`;
273
276
  const token = `${final}.token.${publicationHandle}`;
277
+ const retryContention = async (attempt, contestedPath, reason) => {
278
+ options.contentionForTest?.(reason, attempt);
279
+ await options.hookForTest?.("before_contention_retry", contestedPath);
280
+ if (attempt >= MAX_ATTEMPTS - 1)
281
+ fail();
282
+ await contentionDelay(attempt);
283
+ };
274
284
  const proveFinal = async () => {
275
285
  if (await readFinal(final, owned) !== "exact")
276
286
  return false;
@@ -288,14 +298,22 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
288
298
  return;
289
299
  }
290
300
  if (claimState !== null && tokenState === null) {
291
- if (finalState !== "exact" || claimState.nlink !== 1) {
292
- await yieldTurn();
301
+ if (finalState !== "exact" || claimState.nlink !== 1n) {
302
+ await retryContention(attempt, claim, "orphan-claim-not-cleanable");
293
303
  continue;
294
304
  }
295
305
  if (!await proveFinal())
296
306
  fail();
297
307
  if (!await unlinkExact(claim, claimState)) {
298
- await yieldTurn();
308
+ const latestClaim = await snapshotZero(claim, [1, 2]);
309
+ if (latestClaim === null) {
310
+ if (!await proveFinal())
311
+ fail();
312
+ return;
313
+ }
314
+ if (!sameFileInode(latestClaim, claimState))
315
+ fail();
316
+ await retryContention(attempt, claim, "orphan-claim-cleanup-race");
299
317
  continue;
300
318
  }
301
319
  return;
@@ -304,11 +322,11 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
304
322
  if (ownedToken === null)
305
323
  ownedToken = await createToken(token);
306
324
  if (ownedToken === null) {
307
- await yieldTurn();
325
+ await retryContention(attempt, token, "token-election-race");
308
326
  continue;
309
327
  }
310
328
  let currentClaim = await snapshotZero(claim, [1, 2]);
311
- if (currentClaim === null && ownedToken.nlink === 1) {
329
+ if (currentClaim === null && ownedToken.nlink === 1n) {
312
330
  try {
313
331
  await checkChain();
314
332
  await link(token, claim);
@@ -323,21 +341,21 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
323
341
  ownedToken = await snapshotZero(token, [1, 2]);
324
342
  }
325
343
  if (!currentClaim || !ownedToken) {
326
- await yieldTurn();
344
+ await retryContention(attempt, claim, "topology-observation-race");
327
345
  continue;
328
346
  }
329
347
  if (currentClaim.dev !== ownedToken.dev || currentClaim.ino !== ownedToken.ino) {
330
348
  await options.hookForTest?.("after_mismatch_snapshot", token);
331
- if (ownedToken.nlink === 1) {
349
+ if (ownedToken.nlink === 1n) {
332
350
  const latest = await snapshotZero(token, [1, 2]);
333
- if (latest?.nlink === 1 && same(latest, ownedToken))
351
+ if (latest?.nlink === 1n && sameFileExact(latest, ownedToken))
334
352
  await unlinkExact(token, latest);
335
353
  }
336
- await yieldTurn();
354
+ await retryContention(attempt, claim, "foreign-token-race");
337
355
  continue;
338
356
  }
339
- if (currentClaim.nlink !== 2 || ownedToken.nlink !== 2) {
340
- await yieldTurn();
357
+ if (currentClaim.nlink !== 2n || ownedToken.nlink !== 2n) {
358
+ await retryContention(attempt, claim, "link-count-race");
341
359
  continue;
342
360
  }
343
361
  const state = await readFinal(final, owned);
@@ -346,18 +364,21 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
346
364
  try {
347
365
  fd = await open(final, constants.O_CREAT | constants.O_EXCL | constants.O_RDWR | constants.O_NOFOLLOW, 0o600);
348
366
  await fd.chmod(0o600);
349
- const empty = fileIdentity(await fd.stat(), uid, [1], true);
367
+ await options.hookForTest?.("after_final_open", final);
368
+ const created = fileIdentity(await fd.stat({ bigint: true }), uid, [1]);
369
+ if (created.size > owned.length)
370
+ fail();
350
371
  await options.hookForTest?.("after_final_create", final);
351
- const split = Math.max(1, Math.floor(owned.length / 2));
352
- let offset = 0;
372
+ const split = Math.max(created.size, 1, Math.floor(owned.length / 2));
373
+ let offset = created.size;
353
374
  while (offset < split)
354
375
  offset += await writeSome(fd, owned, offset, split - offset);
355
376
  await options.hookForTest?.("after_partial_write", final);
356
377
  while (offset < owned.length)
357
378
  offset += await writeSome(fd, owned, offset, owned.length - offset);
358
379
  await fd.sync();
359
- const complete = fileIdentity(await fd.stat(), uid, [1]);
360
- if (empty.dev !== complete.dev || empty.ino !== complete.ino || complete.size !== owned.length)
380
+ const complete = fileIdentity(await fd.stat({ bigint: true }), uid, [1]);
381
+ if (!sameFileNode(created, complete) || complete.size !== owned.length)
361
382
  fail();
362
383
  await options.hookForTest?.("after_file_sync", final);
363
384
  }
@@ -373,15 +394,15 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
373
394
  let fd;
374
395
  try {
375
396
  fd = await open(final, constants.O_RDWR | constants.O_NOFOLLOW);
376
- const before = fileIdentity(await fd.stat(), uid, [1]);
397
+ const before = fileIdentity(await fd.stat({ bigint: true }), uid, [1]);
377
398
  if (before.size > owned.length)
378
399
  fail();
379
400
  let offset = before.size;
380
401
  while (offset < owned.length)
381
402
  offset += await writeSome(fd, owned, offset, owned.length - offset);
382
403
  await fd.sync();
383
- const after = fileIdentity(await fd.stat(), uid, [1]);
384
- if (before.dev !== after.dev || before.ino !== after.ino || after.size !== owned.length)
404
+ const after = fileIdentity(await fd.stat({ bigint: true }), uid, [1]);
405
+ if (!sameFileNode(before, after) || after.size !== owned.length)
385
406
  fail();
386
407
  }
387
408
  catch {
@@ -392,7 +413,7 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
392
413
  }
393
414
  }
394
415
  if (!await proveFinal()) {
395
- await yieldTurn();
416
+ await retryContention(attempt, final, "final-write-race");
396
417
  continue;
397
418
  }
398
419
  await syncDirectory();
@@ -401,8 +422,8 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
401
422
  await options.hookForTest?.("after_exact_token_snapshot", token);
402
423
  const exactClaim = await snapshotZero(claim, [1, 2]);
403
424
  if (!exactToken || !exactClaim || exactToken.dev !== exactClaim.dev || exactToken.ino !== exactClaim.ino
404
- || exactToken.nlink !== 2 || exactClaim.nlink !== 2) {
405
- await yieldTurn();
425
+ || exactToken.nlink !== 2n || exactClaim.nlink !== 2n) {
426
+ await retryContention(attempt, claim, "cleanup-snapshot-race");
406
427
  continue;
407
428
  }
408
429
  await unlinkExact(token, exactToken);
@@ -413,8 +434,20 @@ export const initializeTargetSecretSourceFsPublishImmutable = async (options) =>
413
434
  fail();
414
435
  return;
415
436
  }
416
- if (remainingClaim.nlink !== 1 || !await unlinkExact(claim, remainingClaim)) {
417
- await yieldTurn();
437
+ if (remainingClaim.nlink !== 1n) {
438
+ await retryContention(attempt, claim, "claim-final-cleanup-race");
439
+ continue;
440
+ }
441
+ if (!await unlinkExact(claim, remainingClaim)) {
442
+ const latestClaim = await snapshotZero(claim, [1, 2]);
443
+ if (latestClaim === null) {
444
+ if (!await proveFinal())
445
+ fail();
446
+ return;
447
+ }
448
+ if (!sameFileInode(latestClaim, remainingClaim))
449
+ fail();
450
+ await retryContention(attempt, claim, "claim-final-cleanup-race");
418
451
  continue;
419
452
  }
420
453
  await options.hookForTest?.("after_claim_cleanup", claim);
@@ -2,6 +2,7 @@ import { Buffer } from "node:buffer";
2
2
  import { constants } from "node:fs";
3
3
  import { lstat, mkdir, open } from "node:fs/promises";
4
4
  import { MAX_JSON_GRAPH_STRING_BYTES, TARGET_SECRET_SOURCE_ERROR, parseTargetSecretSourceOpaqueHandle } from "./targetSecretSourceRecordCommon.js";
5
+ import { directoryIdentityOf, fileIdentityOf, sameDirectory, sameFileExact } from "./targetSecretSourceFsIdentity.js";
5
6
  import { parseTargetSecretSourceAliasRecordBytes, parseTargetSecretSourceVersionRecordBytes } from "./targetSecretSourceVersionRecords.js";
6
7
  import { parseTargetSecretSourceGrantRecordBytes, parseTargetSecretSourceRedemptionRecordBytes, parseTargetSecretSourceRevocationRecordBytes } from "./targetSecretSourceGrantRecords.js";
7
8
  import { resolveAuthHome, resolveSpawnfileHome, resolveTargetSecretAliasPath, resolveTargetSecretAliasesDirectory, resolveTargetSecretGrantPath, resolveTargetSecretGrantsDirectory, resolveTargetSecretRedemptionPath, resolveTargetSecretRedemptionsDirectory, resolveTargetSecretRevocationPath, resolveTargetSecretRevocationsDirectory, resolveTargetSecretVersionPath, resolveTargetSecretVersionsDirectory, resolveTargetSecretsRoot } from "./paths.js";
@@ -9,18 +10,8 @@ const fail = () => { throw new Error(TARGET_SECRET_SOURCE_ERROR); };
9
10
  const absent = (error) => error.code === "ENOENT";
10
11
  const uid = () => { const value = process.getuid?.(); if (typeof value !== "number")
11
12
  return fail(); return value; };
12
- const directoryIdentity = (info, owner) => {
13
- if (!info.isDirectory() || info.isSymbolicLink() || info.uid !== BigInt(owner) || (info.mode & 4095n) !== 448n)
14
- return fail();
15
- return { birthtimeNs: info.birthtimeNs, dev: info.dev, ino: info.ino, mode: info.mode, uid: info.uid };
16
- };
17
- const fileIdentity = (info, owner) => {
18
- if (!info.isFile() || info.isSymbolicLink() || info.uid !== BigInt(owner) || info.nlink !== 1n || info.size < 0n || info.size > BigInt(MAX_JSON_GRAPH_STRING_BYTES) || (info.mode & 4095n) !== 384n)
19
- return fail();
20
- return { birthtimeNs: info.birthtimeNs, ctimeNs: info.ctimeNs, dev: info.dev, ino: info.ino, mode: info.mode, nlink: info.nlink, size: Number(info.size), uid: info.uid };
21
- };
22
- const sameDirectory = (left, right) => left.birthtimeNs === right.birthtimeNs && left.dev === right.dev && left.ino === right.ino && left.mode === right.mode && left.uid === right.uid;
23
- const sameFile = (left, right) => left.birthtimeNs === right.birthtimeNs && left.ctimeNs === right.ctimeNs && left.dev === right.dev && left.ino === right.ino && left.mode === right.mode && left.nlink === right.nlink && left.size === right.size && left.uid === right.uid;
13
+ const directoryIdentity = (info, owner) => directoryIdentityOf(info, owner);
14
+ const fileIdentity = (info, owner) => fileIdentityOf(info, owner, [1], MAX_JSON_GRAPH_STRING_BYTES);
24
15
  const initializeDirectory = async (directory, owner, create) => {
25
16
  let info;
26
17
  try {
@@ -134,7 +125,7 @@ const readRecord = async (file, expected, parse, chain, owner, hooks) => {
134
125
  let bytes;
135
126
  try {
136
127
  const opened = fileIdentity(await handle.stat({ bigint: true }), owner);
137
- if (!sameFile(before, opened))
128
+ if (!sameFileExact(before, opened))
138
129
  return fail();
139
130
  bytes = Buffer.alloc(opened.size + 1);
140
131
  let offset = 0;
@@ -152,7 +143,7 @@ const readRecord = async (file, expected, parse, chain, owner, hooks) => {
152
143
  catch {
153
144
  return fail();
154
145
  }
155
- if (offset !== opened.size || !sameFile(opened, after) || !sameFile(opened, pathname))
146
+ if (offset !== opened.size || !sameFileExact(opened, after) || !sameFileExact(opened, pathname))
156
147
  return fail();
157
148
  await checkChain(chain, owner);
158
149
  const content = Uint8Array.from(bytes.subarray(0, offset));
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Grok is deliberately absent. `spawnfile.training-container.v3` holds the one
3
+ * dedicated training Grok login in a broker-owned realm volume seeded from a
4
+ * read-only bootstrap leaf, and judges spend it through short inference grants
5
+ * (D2). Staging a Grok credential into a shared runtime home would put a
6
+ * rotating login where the evaluator and the image both reach it.
7
+ */
8
+ export type TrainingAuthProvider = "codex" | "claude";
9
+ export interface TrainingAuthStageOptions {
10
+ /** Caller-provisioned, existing private runtime home; never a host home mount. */
11
+ home: string;
12
+ provider: TrainingAuthProvider;
13
+ /** Explicit provisioned leaf; default is the fixed training ingress. */
14
+ source?: string;
15
+ }
16
+ /** Stages opaque credential bytes once. Never imports configuration, logs bytes, or overwrites renewed auth. */
17
+ export declare const stageTrainingAuth: (options: TrainingAuthStageOptions) => Promise<{
18
+ version: "spawnfile.training-auth-stage.v1";
19
+ provider: TrainingAuthProvider;
20
+ destination: string;
21
+ }>;
@@ -0,0 +1,86 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { constants } from "node:fs";
3
+ import { link, lstat, mkdir, open, realpath, unlink } from "node:fs/promises";
4
+ import path from "node:path";
5
+ const targets = {
6
+ codex: [".daimon-inbound", "codex-auth"],
7
+ claude: [".claude", ".credentials.json"]
8
+ };
9
+ /** Stages opaque credential bytes once. Never imports configuration, logs bytes, or overwrites renewed auth. */
10
+ export const stageTrainingAuth = async (options) => {
11
+ if (!Object.hasOwn(targets, options.provider))
12
+ throw Error("Unsupported training auth provider");
13
+ const home = path.resolve(options.home), source = options.source ?? `/run/paideia-auth/${options.provider}`;
14
+ if (!path.isAbsolute(options.home) || await realpath(home) !== home || !(await lstat(home)).isDirectory())
15
+ throw Error("Training home must be a canonical existing directory");
16
+ if (!path.isAbsolute(source) || await realpath(source) !== path.resolve(source))
17
+ throw Error("Training auth source must be a canonical regular leaf");
18
+ const input = await open(source, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
19
+ try {
20
+ const before = await input.stat({ bigint: true });
21
+ if (!before.isFile() || before.size < 1n || before.size > 1048576n)
22
+ throw Error("Training auth source must be a bounded nonempty regular leaf");
23
+ const [folder, leaf] = targets[options.provider];
24
+ const directory = path.join(home, folder);
25
+ try {
26
+ await mkdir(directory, { mode: 0o700 });
27
+ }
28
+ catch (error) {
29
+ if (error.code !== "EEXIST")
30
+ throw error;
31
+ }
32
+ const existing = await lstat(directory);
33
+ if (!existing.isDirectory() || existing.isSymbolicLink() || existing.mode % 512 !== 0o700 || await realpath(directory) !== directory)
34
+ throw Error("Training auth directory must be private and canonical");
35
+ const bytes = Buffer.alloc(Number(before.size) + 1);
36
+ let primary;
37
+ const destination = path.join(directory, leaf), temporary = path.join(directory, `.stage-${randomUUID()}`);
38
+ try {
39
+ let length = 0;
40
+ while (length < bytes.length) {
41
+ const read = await input.read(bytes, length, bytes.length - length, null);
42
+ if (read.bytesRead === 0)
43
+ break;
44
+ length += read.bytesRead;
45
+ }
46
+ const after = await input.stat({ bigint: true });
47
+ if (BigInt(length) !== before.size || after.size !== before.size || after.mtimeNs !== before.mtimeNs || after.ctimeNs !== before.ctimeNs || after.ino !== before.ino || after.dev !== before.dev || after.birthtimeNs !== before.birthtimeNs)
48
+ throw Error("Training auth source changed during staging");
49
+ const output = await open(temporary, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
50
+ try {
51
+ await output.writeFile(bytes.subarray(0, length));
52
+ await output.sync();
53
+ }
54
+ finally {
55
+ await output.close();
56
+ }
57
+ // Exclusive publication preserves renewed credentials and never exposes a partial leaf.
58
+ try {
59
+ await link(temporary, destination);
60
+ }
61
+ catch (error) {
62
+ if (error.code === "EEXIST")
63
+ throw Error("Training auth already present; renewed credential preserved");
64
+ throw error;
65
+ }
66
+ }
67
+ catch (error) {
68
+ primary = error;
69
+ throw error;
70
+ }
71
+ finally {
72
+ bytes.fill(0);
73
+ await unlink(temporary).catch((error) => {
74
+ if (error.code === "ENOENT")
75
+ return;
76
+ if (primary)
77
+ throw new AggregateError([primary, error], "Training auth staging failed and temporary cleanup is incomplete");
78
+ throw error;
79
+ });
80
+ }
81
+ return { version: "spawnfile.training-auth-stage.v1", provider: options.provider, destination };
82
+ }
83
+ finally {
84
+ await input.close();
85
+ }
86
+ };
@@ -1,4 +1,4 @@
1
- export type ImportedAuthKind = "claude-code" | "codex";
1
+ export type ImportedAuthKind = "claude-code" | "codex" | "grok";
2
2
  export interface ImportedAuthEntry {
3
3
  kind: ImportedAuthKind;
4
4
  relativePath: string;
@@ -1,5 +1,5 @@
1
1
  import type { Command } from "commander";
2
2
  import type { CliHandlers, CliStreams } from "./runCli.js";
3
- type AuthCommandHandlers = Pick<CliHandlers, "importClaudeCodeAuth" | "importCodexAuth" | "importEnvFile" | "initializeTargetSecretSourceLifecycle" | "provisionCredentials" | "requireAuthProfile" | "syncProjectAuth">;
3
+ type AuthCommandHandlers = Pick<CliHandlers, "importClaudeCodeAuth" | "importCodexAuth" | "importGrokAuth" | "importEnvFile" | "initializeTargetSecretSourceLifecycle" | "provisionCredentials" | "requireAuthProfile" | "syncProjectAuth">;
4
4
  export declare const registerAuthCommands: (program: Command, handlers: AuthCommandHandlers, streams: CliStreams, stdin: AsyncIterable<unknown>) => void;
5
5
  export {};
@@ -89,6 +89,15 @@ export const registerAuthCommands = (program, handlers, streams, stdin) => {
89
89
  const profile = await handlers.importClaudeCodeAuth(options.profile, options.from);
90
90
  emitLines(streams, formatAuthProfileSummary(profile));
91
91
  });
92
+ authImportCommand
93
+ .command("grok")
94
+ .description("Import a dedicated training Grok login into a profile")
95
+ .option("-p, --profile <name>", "Auth profile name", "default")
96
+ .requiredOption("--from <directory>", "Source Grok config directory holding the dedicated login")
97
+ .action(async (options) => {
98
+ const profile = await handlers.importGrokAuth(options.profile, options.from);
99
+ emitLines(streams, formatAuthProfileSummary(profile));
100
+ });
92
101
  authImportCommand
93
102
  .command("codex")
94
103
  .description("Import Codex subscription credentials into a profile")
@@ -0,0 +1,2 @@
1
+ export declare const isCanaryCutoverInvocation: (argv: readonly string[]) => boolean;
2
+ export declare const runCanaryCutoverCommand: (argv: readonly string[]) => Promise<number>;
@@ -0,0 +1,30 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { z } from "zod";
3
+ import { issueDeploymentIdentity, runCanaryCutover, verifyEquivalentRollbackReadiness } from "../deployment/canaryCutover.js";
4
+ const boundedArgs = z.array(z.string().max(4096)).max(32);
5
+ const request = z.object({ version: z.literal("spawnfile.canary-cutover-request.v1"), live_report_path: z.string().min(1), candidate_report_path: z.string().min(1), readiness_path: z.string().min(1), expected_identity: z.unknown(), docker_command: z.string().min(1), nonce: z.string().regex(/^[a-f0-9]{32}$/u), transaction_path: z.string().min(1), ingress_command: z.string().min(1), ingress_args: boundedArgs, ingress_receipt_path: z.string().min(1), teardown_command: z.string().min(1), teardown_args: boundedArgs, teardown_policy: z.enum(["export", "force"]), teardown_project_path: z.string().min(1), teardown_compiled_path: z.string().min(1), decision_receipt_path: z.string().min(1), from_deployment: z.string().min(1), to_deployment: z.string().min(1) }).strict();
6
+ const rollback = z.object({ version: z.literal("spawnfile.canary-rollback-readiness-request.v1"), rollback_readiness_path: z.string().min(1), expected_identity: z.unknown() }).strict();
7
+ const identity = z.object({ version: z.literal("spawnfile.deployment-identity-request.v1"), readiness_path: z.string().min(1), deployment_mode: z.enum(["project", "image"]), docker_command: z.string().min(1), receipt_path: z.string().min(1) }).strict();
8
+ export const isCanaryCutoverInvocation = (argv) => argv[0] === "canary" && ["identity", "cutover", "verify-rollback"].includes(argv[1] ?? "");
9
+ export const runCanaryCutoverCommand = async (argv) => {
10
+ try {
11
+ const bytes = await readFile(argv[2] ?? "", "utf8");
12
+ if (argv[1] === "identity") {
13
+ const value = identity.parse(JSON.parse(bytes)), receipt = await issueDeploymentIdentity(value.readiness_path, value.deployment_mode, value.docker_command);
14
+ await writeFile(value.receipt_path, `${JSON.stringify(receipt)}\n`, { flag: "wx", mode: 0o600 });
15
+ }
16
+ else if (argv[1] === "verify-rollback") {
17
+ const value = rollback.parse(JSON.parse(bytes));
18
+ await verifyEquivalentRollbackReadiness(value.rollback_readiness_path, value.expected_identity);
19
+ }
20
+ else {
21
+ const value = request.parse(JSON.parse(bytes));
22
+ await runCanaryCutover({ liveReportPath: value.live_report_path, candidateReportPath: value.candidate_report_path, readinessPath: value.readiness_path, expectedIdentity: value.expected_identity, dockerCommand: value.docker_command, nonce: value.nonce, transactionPath: value.transaction_path, ingressCommand: value.ingress_command, ingressArgs: value.ingress_args, ingressReceiptPath: value.ingress_receipt_path, teardownCommand: value.teardown_command, teardownArgs: value.teardown_args, teardownPolicy: value.teardown_policy, teardownProjectPath: value.teardown_project_path, teardownCompiledPath: value.teardown_compiled_path, decisionReceiptPath: value.decision_receipt_path, fromDeployment: value.from_deployment, toDeployment: value.to_deployment });
23
+ }
24
+ return 0;
25
+ }
26
+ catch {
27
+ process.stderr.write("error: Canary operation failed\n");
28
+ return 1;
29
+ }
30
+ };
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ import type { CliStreams } from "./runCli.js";
3
+ export declare const registerCapabilitiesCommand: (program: Command, streams: CliStreams, packageVersion: string) => void;
@@ -0,0 +1,12 @@
1
+ import { SpawnfileError } from "../shared/index.js";
2
+ import { createCapabilitiesReceipt, createCapabilitiesReceiptBytes, } from "./capabilitiesReceipt.js";
3
+ export const registerCapabilitiesCommand = (program, streams, packageVersion) => {
4
+ program.command("capabilities")
5
+ .description("Report supported public CLI contracts")
6
+ .requiredOption("--json", "Emit one strict versioned JSON receipt")
7
+ .action((options) => {
8
+ if (options.json !== true)
9
+ throw new SpawnfileError("validation_error", "`capabilities` requires --json");
10
+ streams.stdout(createCapabilitiesReceiptBytes(createCapabilitiesReceipt(packageVersion)));
11
+ });
12
+ };