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.
- package/README.md +60 -159
- package/dist/audit/checksShared.d.ts +1 -1
- package/dist/auth/importers.d.ts +10 -0
- package/dist/auth/importers.js +29 -4
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.js +1 -0
- package/dist/auth/paths.d.ts +1 -1
- package/dist/auth/profileStore.js +9 -9
- package/dist/auth/targetSecretSourceFsIdentity.d.ts +40 -0
- package/dist/auth/targetSecretSourceFsIdentity.js +42 -0
- package/dist/auth/targetSecretSourceFsPublish.d.ts +2 -0
- package/dist/auth/targetSecretSourceFsPublish.js +3 -1
- package/dist/auth/targetSecretSourceFsPublishImmutable.d.ts +2 -1
- package/dist/auth/targetSecretSourceFsPublishImmutable.js +104 -71
- package/dist/auth/targetSecretSourceFsRead.js +5 -14
- package/dist/auth/trainingAuth.d.ts +21 -0
- package/dist/auth/trainingAuth.js +86 -0
- package/dist/auth/types.d.ts +1 -1
- package/dist/cli/authCommands.d.ts +1 -1
- package/dist/cli/authCommands.js +9 -0
- package/dist/cli/canaryCutoverCommand.d.ts +2 -0
- package/dist/cli/canaryCutoverCommand.js +30 -0
- package/dist/cli/capabilitiesCommand.d.ts +3 -0
- package/dist/cli/capabilitiesCommand.js +12 -0
- package/dist/cli/capabilitiesReceipt.d.ts +56 -0
- package/dist/cli/capabilitiesReceipt.js +56 -0
- package/dist/cli/compileBuildCommands.js +13 -0
- package/dist/cli/composedLifecycleContractSet.d.ts +21 -0
- package/dist/cli/composedLifecycleContractSet.js +204 -0
- package/dist/cli/devCommands.js +2 -0
- package/dist/cli/downCommand.js +19 -8
- package/dist/cli/evidenceExportHelperCommand.d.ts +13 -0
- package/dist/cli/evidenceExportHelperCommand.js +51 -0
- package/dist/cli/index.js +12 -3
- package/dist/cli/lifecycleMachine.d.ts +7 -1
- package/dist/cli/lifecycleMachine.js +2 -2
- package/dist/cli/paideiaDelegation.d.ts +17 -0
- package/dist/cli/paideiaDelegation.js +210 -0
- package/dist/cli/paideiaSupervisor.d.ts +17 -0
- package/dist/cli/paideiaSupervisor.js +48 -0
- package/dist/cli/productStateCloneCommand.d.ts +2 -0
- package/dist/cli/productStateCloneCommand.js +34 -0
- package/dist/cli/runCli.d.ts +13 -3
- package/dist/cli/runCli.js +37 -9
- package/dist/cli/targetCommands.d.ts +4 -7
- package/dist/cli/targetCommands.js +16 -46
- package/dist/cli/targetConfigPreparedPlan.d.ts +3 -0
- package/dist/cli/targetConfigPreparedPlan.js +74 -0
- package/dist/cli/targetConfigResolver.d.ts +3 -0
- package/dist/cli/targetConfigResolver.js +111 -0
- package/dist/cli/targetConfigResolverCommand.d.ts +6 -0
- package/dist/cli/targetConfigResolverCommand.js +43 -0
- package/dist/cli/targetConfigResolverContracts.d.ts +56 -0
- package/dist/cli/targetConfigResolverContracts.js +30 -0
- package/dist/cli/targetConfigResolverDocker.d.ts +4 -0
- package/dist/cli/targetConfigResolverDocker.js +47 -0
- package/dist/cli/targetConfigResolverValidation.d.ts +10 -0
- package/dist/cli/targetConfigResolverValidation.js +94 -0
- package/dist/cli/targetDefaultAuthorities.d.ts +2 -0
- package/dist/cli/targetDefaultAuthorities.js +3 -0
- package/dist/cli/targetDefaultConfig.d.ts +7 -0
- package/dist/cli/targetDefaultConfig.js +22 -5
- package/dist/cli/targetDefaultConfigStdin.js +7 -1
- package/dist/cli/targetDefaultHandlerFactory.js +23 -2
- package/dist/cli/targetDefaultHandlers.d.ts +2 -2
- package/dist/cli/targetProductionCommands.d.ts +5 -0
- package/dist/cli/targetProductionCommands.js +45 -0
- package/dist/cli/trainCommand.d.ts +3 -0
- package/dist/cli/trainCommand.js +61 -0
- package/dist/cli/upCommand.js +35 -6
- package/dist/cli/upLifecycleRecovery.d.ts +2 -2
- package/dist/cli/upLifecycleRecovery.js +188 -44
- package/dist/cli/usageCommand.d.ts +40 -0
- package/dist/cli/usageCommand.js +284 -0
- package/dist/cli/usageCommandLive.d.ts +84 -0
- package/dist/cli/usageCommandLive.js +95 -0
- package/dist/cli/usageDeploymentSource.d.ts +9 -0
- package/dist/cli/usageDeploymentSource.js +22 -0
- package/dist/cli/workspaceResourceMigrationCommand.d.ts +8 -0
- package/dist/cli/workspaceResourceMigrationCommand.js +36 -0
- package/dist/compiler/buildCompilePlanTeams.d.ts +1 -1
- package/dist/compiler/buildCompilePlanTeams.js +6 -1
- package/dist/compiler/compilePlanHelpers.js +3 -0
- package/dist/compiler/compileProject.d.ts +2 -0
- package/dist/compiler/compileProject.js +5 -1
- package/dist/compiler/compileProjectSupport.js +9 -0
- package/dist/compiler/containerArtifacts.d.ts +3 -1
- package/dist/compiler/containerArtifacts.js +92 -40
- package/dist/compiler/containerArtifactsPlans.d.ts +1 -1
- package/dist/compiler/containerArtifactsPlans.js +24 -7
- package/dist/compiler/containerArtifactsRender.d.ts +2 -1
- package/dist/compiler/containerArtifactsRender.js +91 -58
- package/dist/compiler/containerArtifactsTypes.d.ts +8 -0
- package/dist/compiler/containerBackedMountRender.d.ts +56 -0
- package/dist/compiler/containerBackedMountRender.js +101 -0
- package/dist/compiler/containerDaimonBrokerRender.d.ts +112 -0
- package/dist/compiler/containerDaimonBrokerRender.js +191 -0
- package/dist/compiler/containerDaimonGrokWorkerProvisioning.d.ts +38 -0
- package/dist/compiler/containerDaimonGrokWorkerProvisioning.js +108 -0
- package/dist/compiler/containerDaimonGrokWorkerRender.d.ts +172 -0
- package/dist/compiler/containerDaimonGrokWorkerRender.js +268 -0
- package/dist/compiler/containerDaimonOwnershipGuardRender.d.ts +12 -0
- package/dist/compiler/containerDaimonOwnershipGuardRender.js +191 -0
- package/dist/compiler/containerDaimonUidEntrypointRender.d.ts +24 -0
- package/dist/compiler/containerDaimonUidEntrypointRender.js +297 -0
- package/dist/compiler/containerEntrypointRender.d.ts +7 -0
- package/dist/compiler/containerEntrypointRender.js +28 -22
- package/dist/compiler/containerPersistentMounts.d.ts +30 -0
- package/dist/compiler/containerPersistentMounts.js +66 -0
- package/dist/compiler/containerReadinessPaths.d.ts +1 -0
- package/dist/compiler/containerReadinessPaths.js +1 -0
- package/dist/compiler/containerRuntimeLinkMaterializer.d.ts +2 -0
- package/dist/compiler/containerRuntimeLinkMaterializer.js +12 -0
- package/dist/compiler/containerRuntimeReadinessRender.d.ts +7 -0
- package/dist/compiler/containerRuntimeReadinessRender.js +40 -0
- package/dist/compiler/containerStateOwnershipRender.d.ts +4 -0
- package/dist/compiler/containerStateOwnershipRender.js +75 -0
- package/dist/compiler/containerTargetResources.d.ts +22 -1
- package/dist/compiler/containerTargetResources.js +94 -2
- package/dist/compiler/containerVolumeBootstrap.d.ts +3 -0
- package/dist/compiler/containerVolumeBootstrap.js +3 -0
- package/dist/compiler/containerWorkspaceResourceRender.js +49 -1
- package/dist/compiler/daimonTelemetryArtifacts.d.ts +2 -2
- package/dist/compiler/daimonTelemetryArtifacts.js +5 -10
- package/dist/compiler/deploymentLineage.d.ts +40 -0
- package/dist/compiler/deploymentLineage.js +50 -0
- package/dist/compiler/index.d.ts +3 -0
- package/dist/compiler/index.js +3 -0
- package/dist/compiler/initProject.d.ts +2 -0
- package/dist/compiler/initProject.js +39 -1
- package/dist/compiler/localMoltnetAuthority.d.ts +64 -0
- package/dist/compiler/localMoltnetAuthority.js +177 -0
- package/dist/compiler/memoryArtifacts.d.ts +1 -1
- package/dist/compiler/memoryArtifacts.js +108 -32
- package/dist/compiler/modelEnv.d.ts +5 -0
- package/dist/compiler/modelEnv.js +8 -2
- package/dist/compiler/moltnetArtifactPaths.d.ts +17 -12
- package/dist/compiler/moltnetArtifactPaths.js +17 -15
- package/dist/compiler/moltnetArtifactTypes.d.ts +10 -0
- package/dist/compiler/moltnetArtifacts.d.ts +1 -1
- package/dist/compiler/moltnetArtifacts.js +52 -12
- package/dist/compiler/moltnetBinaries.d.ts +16 -4
- package/dist/compiler/moltnetBinaries.js +46 -6
- package/dist/compiler/moltnetClientConfig.js +1 -1
- package/dist/compiler/moltnetConfigLowering.d.ts +3 -1
- package/dist/compiler/moltnetConfigLowering.js +30 -6
- package/dist/compiler/moltnetNodeConfig.js +1 -1
- package/dist/compiler/moltnetReleaseAuthority.d.ts +24 -1
- package/dist/compiler/moltnetReleaseAuthority.js +33 -4
- package/dist/compiler/moltnetRepresentativeResolution.d.ts +1 -1
- package/dist/compiler/moltnetRepresentativeResolution.js +2 -2
- package/dist/compiler/moltnetResolution.js +9 -15
- package/dist/compiler/moltnetRoomMemberships.js +20 -5
- package/dist/compiler/moltnetRoomPolicyCompatibility.d.ts +1 -1
- package/dist/compiler/moltnetRoomPolicyCompatibility.js +3 -1
- package/dist/compiler/moltnetRuntimeConfig.d.ts +1 -1
- package/dist/compiler/moltnetRuntimeConfig.js +22 -2
- package/dist/compiler/moltnetServerPlans.js +19 -0
- package/dist/compiler/organizationExternalParticipants.d.ts +3 -0
- package/dist/compiler/organizationExternalParticipants.js +176 -0
- package/dist/compiler/organizationIdentity.d.ts +3 -9
- package/dist/compiler/organizationIdentity.js +37 -270
- package/dist/compiler/organizationIdentityGraph.d.ts +15 -0
- package/dist/compiler/organizationIdentityGraph.js +115 -0
- package/dist/compiler/organizationReadyEvidence.d.ts +8 -0
- package/dist/compiler/organizationReadyEvidence.js +23 -3
- package/dist/compiler/runProject.d.ts +4 -2
- package/dist/compiler/runProject.js +32 -6
- package/dist/compiler/runProjectAuth.d.ts +3 -1
- package/dist/compiler/runProjectAuth.js +19 -3
- package/dist/compiler/runProjectDaimonCodexDocker.d.ts +3 -0
- package/dist/compiler/runProjectDaimonCodexDocker.js +36 -0
- package/dist/compiler/runProjectDocker.d.ts +8 -4
- package/dist/compiler/runProjectDocker.js +43 -18
- package/dist/compiler/runProjectDockerDaimonGuards.d.ts +15 -0
- package/dist/compiler/runProjectDockerDaimonGuards.js +122 -0
- package/dist/compiler/runProjectDockerReservation.d.ts +3 -0
- package/dist/compiler/runProjectDockerReservation.js +118 -0
- package/dist/compiler/runProjectLifecycle.js +1 -1
- package/dist/compiler/training/broker/declaration.d.ts +45 -0
- package/dist/compiler/training/broker/declaration.js +55 -0
- package/dist/compiler/training/broker/entrypoint.d.ts +39 -0
- package/dist/compiler/training/broker/entrypoint.js +111 -0
- package/dist/compiler/training/broker/index.d.ts +10 -0
- package/dist/compiler/training/broker/index.js +10 -0
- package/dist/compiler/training/broker/main.d.ts +2 -0
- package/dist/compiler/training/broker/main.js +14 -0
- package/dist/compiler/training/broker/paths.d.ts +196 -0
- package/dist/compiler/training/broker/paths.js +241 -0
- package/dist/compiler/training/broker/processes.d.ts +42 -0
- package/dist/compiler/training/broker/processes.js +99 -0
- package/dist/compiler/training/broker/projection.d.ts +51 -0
- package/dist/compiler/training/broker/projection.js +76 -0
- package/dist/compiler/training/broker/provisioning.d.ts +87 -0
- package/dist/compiler/training/broker/provisioning.js +213 -0
- package/dist/compiler/training/broker/receipt.d.ts +77 -0
- package/dist/compiler/training/broker/receipt.js +110 -0
- package/dist/compiler/training/broker/registration.d.ts +41 -0
- package/dist/compiler/training/broker/registration.js +102 -0
- package/dist/compiler/training/broker/runtime.d.ts +25 -0
- package/dist/compiler/training/broker/runtime.js +173 -0
- package/dist/compiler/training/broker/seccompRoutes.d.ts +31 -0
- package/dist/compiler/training/broker/seccompRoutes.js +36 -0
- package/dist/compiler/training/broker/supervisor.d.ts +109 -0
- package/dist/compiler/training/broker/supervisor.js +173 -0
- package/dist/compiler/training/container/contract.d.ts +31 -0
- package/dist/compiler/training/container/contract.js +33 -0
- package/dist/compiler/training/container/index.d.ts +4 -0
- package/dist/compiler/training/container/index.js +2 -0
- package/dist/compiler/training/container/launch.d.ts +18 -0
- package/dist/compiler/training/container/launch.js +173 -0
- package/dist/compiler/training/container/prepare.d.ts +8 -0
- package/dist/compiler/training/container/prepare.js +80 -0
- package/dist/compiler/training/container/process.d.ts +14 -0
- package/dist/compiler/training/container/process.js +70 -0
- package/dist/compiler/training/container/security.d.ts +36 -0
- package/dist/compiler/training/container/security.js +58 -0
- package/dist/compiler/training/context.d.ts +7 -0
- package/dist/compiler/training/context.js +93 -0
- package/dist/compiler/training/contract.d.ts +142 -0
- package/dist/compiler/training/contract.js +34 -0
- package/dist/compiler/training/index.d.ts +4 -0
- package/dist/compiler/training/index.js +3 -0
- package/dist/compiler/training/preparation/assets/Dockerfile +98 -0
- package/dist/compiler/training/preparation/assets/package-lock.json +3787 -0
- package/dist/compiler/training/preparation/broker.d.ts +21 -0
- package/dist/compiler/training/preparation/broker.js +43 -0
- package/dist/compiler/training/preparation/contextModes.d.ts +12 -0
- package/dist/compiler/training/preparation/contextModes.js +38 -0
- package/dist/compiler/training/preparation/contract.d.ts +182 -0
- package/dist/compiler/training/preparation/contract.js +94 -0
- package/dist/compiler/training/preparation/copyAssets.d.ts +1 -0
- package/dist/compiler/training/preparation/copyAssets.js +8 -0
- package/dist/compiler/training/preparation/daimonParent.d.ts +42 -0
- package/dist/compiler/training/preparation/daimonParent.js +114 -0
- package/dist/compiler/training/preparation/files.d.ts +25 -0
- package/dist/compiler/training/preparation/files.js +85 -0
- package/dist/compiler/training/preparation/image.d.ts +28 -0
- package/dist/compiler/training/preparation/image.js +102 -0
- package/dist/compiler/training/preparation/index.d.ts +3 -0
- package/dist/compiler/training/preparation/index.js +2 -0
- package/dist/compiler/training/preparation/inputs.d.ts +23 -0
- package/dist/compiler/training/preparation/inputs.js +93 -0
- package/dist/compiler/training/preparation/prepare.d.ts +33 -0
- package/dist/compiler/training/preparation/prepare.js +186 -0
- package/dist/compiler/training/preparation/scratch.d.ts +19 -0
- package/dist/compiler/training/preparation/scratch.js +48 -0
- package/dist/compiler/training/repair/compatibility.d.ts +11 -0
- package/dist/compiler/training/repair/compatibility.js +34 -0
- package/dist/compiler/training/repair/contract.d.ts +506 -0
- package/dist/compiler/training/repair/contract.js +31 -0
- package/dist/compiler/training/repair/index.d.ts +3 -0
- package/dist/compiler/training/repair/index.js +3 -0
- package/dist/compiler/training/repair/prepare.d.ts +230 -0
- package/dist/compiler/training/repair/prepare.js +74 -0
- package/dist/compiler/training/repair/witness.d.ts +203 -0
- package/dist/compiler/training/repair/witness.js +42 -0
- package/dist/compiler/types.d.ts +2 -0
- package/dist/compiler/upProject.d.ts +26 -1
- package/dist/compiler/upProject.js +117 -178
- package/dist/compiler/upProjectHandoff.d.ts +62 -0
- package/dist/compiler/upProjectHandoff.js +204 -0
- package/dist/compiler/upReceipt.js +49 -4
- package/dist/compiler/updateProjectModels.js +1 -0
- package/dist/compiler/view/types.d.ts +1 -1
- package/dist/compiler/workspaceBundleArtifacts.d.ts +3 -0
- package/dist/compiler/workspaceBundleArtifacts.js +106 -0
- package/dist/compiler/workspaceResources.d.ts +4 -1
- package/dist/compiler/workspaceResources.js +12 -7
- package/dist/deployment/artifactsExportPlan.js +51 -1
- package/dist/deployment/canaryCutover.d.ts +42 -0
- package/dist/deployment/canaryCutover.js +140 -0
- package/dist/deployment/candidateDiagnostics.d.ts +15 -0
- package/dist/deployment/candidateDiagnostics.js +90 -0
- package/dist/deployment/dockerLogs.js +4 -1
- package/dist/deployment/dockerManager.js +9 -3
- package/dist/deployment/dockerProbeGateway.d.ts +17 -0
- package/dist/deployment/dockerProbeGateway.js +17 -2
- package/dist/deployment/downDeployment.d.ts +5 -0
- package/dist/deployment/downDeployment.js +109 -8
- package/dist/deployment/downReceiptTypes.d.ts +17 -2
- package/dist/deployment/downReceiptTypes.js +17 -2
- package/dist/deployment/index.d.ts +4 -0
- package/dist/deployment/index.js +4 -0
- package/dist/deployment/lifecycleCompletionContracts.d.ts +66 -0
- package/dist/deployment/lifecycleCompletionContracts.js +34 -0
- package/dist/deployment/lifecycleCompletionPaths.d.ts +4 -1
- package/dist/deployment/lifecycleCompletionPaths.js +3 -0
- package/dist/deployment/lifecycleCompletionPublication.d.ts +2 -0
- package/dist/deployment/lifecycleCompletionPublication.js +18 -4
- package/dist/deployment/lifecycleCompletionStore.d.ts +1 -1
- package/dist/deployment/lifecycleCompletionStore.js +7 -7
- package/dist/deployment/lifecycleUpRecords.d.ts +11 -0
- package/dist/deployment/lifecycleUpRecords.js +127 -0
- package/dist/deployment/native/AGENTS.md +11 -0
- package/dist/deployment/native/rename-noreplace-arm64 +0 -0
- package/dist/deployment/native/rename-noreplace-arm64.provenance.json +1 -0
- package/dist/deployment/native/rename-noreplace-x64 +0 -0
- package/dist/deployment/native/rename-noreplace-x64.provenance.json +1 -0
- package/dist/deployment/noReplaceActivation.d.ts +17 -0
- package/dist/deployment/noReplaceActivation.js +50 -0
- package/dist/deployment/organizationHandoffAuthorityFsBudget.d.ts +110 -0
- package/dist/deployment/organizationHandoffAuthorityFsBudget.js +156 -0
- package/dist/deployment/organizationHandoffAuthorityFsClient.js +82 -27
- package/dist/deployment/organizationHandoffAuthorityFsElection.d.ts +21 -0
- package/dist/deployment/organizationHandoffAuthorityFsElection.js +57 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorker.js +254 -108
- package/dist/deployment/organizationHandoffAuthorityFsWorkerStall.fixture.d.ts +1 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorkerStall.fixture.js +16 -0
- package/dist/deployment/organizationHandoffAuthorityStore.js +14 -7
- package/dist/deployment/organizationHandoffAuthorityTypes.d.ts +2 -2
- package/dist/deployment/organizationHandoffAuthorityTypes.js +2 -1
- package/dist/deployment/organizationReady.d.ts +2 -0
- package/dist/deployment/organizationReady.js +36 -4
- package/dist/deployment/productStateClone.d.ts +43 -0
- package/dist/deployment/productStateClone.js +319 -0
- package/dist/deployment/upLifecycleRecoveryState.d.ts +23 -0
- package/dist/deployment/upLifecycleRecoveryState.js +12 -0
- package/dist/deployment/upReceiptTypes.d.ts +32 -6
- package/dist/deployment/upReceiptTypes.js +29 -2
- package/dist/deployment/workspaceResourceMigration.d.ts +55 -0
- package/dist/deployment/workspaceResourceMigration.js +315 -0
- package/dist/dev/project.d.ts +7 -0
- package/dist/dev/project.js +9 -0
- package/dist/distribution/consumeImage.d.ts +2 -0
- package/dist/distribution/consumeImage.js +98 -73
- package/dist/distribution/consumeImageDaimonDocker.d.ts +3 -0
- package/dist/distribution/consumeImageDaimonDocker.js +45 -0
- package/dist/distribution/consumeImageLifecycle.d.ts +17 -0
- package/dist/distribution/consumeImageLifecycle.js +231 -0
- package/dist/distribution/consumeImageSupport.d.ts +12 -0
- package/dist/distribution/consumeImageSupport.js +15 -0
- package/dist/distribution/distributionReportSchema.d.ts +11 -1
- package/dist/distribution/distributionReportSchema.js +15 -2
- package/dist/distribution/dockerRunner.d.ts +6 -1
- package/dist/distribution/dockerRunner.js +31 -4
- package/dist/distribution/imageRuntimeAuth.d.ts +9 -1
- package/dist/distribution/imageRuntimeAuth.js +70 -1
- package/dist/distribution/index.d.ts +1 -1
- package/dist/distribution/index.js +1 -1
- package/dist/distribution/preflight.js +5 -1
- package/dist/distribution/types.d.ts +14 -1
- package/dist/distribution/types.js +3 -0
- package/dist/evidenceExportHelper/boundedExecutor.d.ts +3 -0
- package/dist/evidenceExportHelper/boundedExecutor.js +33 -0
- package/dist/evidenceExportHelper/helperProgram.mjs +156 -0
- package/dist/evidenceExportHelper/index.d.ts +4 -0
- package/dist/evidenceExportHelper/index.js +4 -0
- package/dist/evidenceExportHelper/preparedAuthority.d.ts +64 -0
- package/dist/evidenceExportHelper/preparedAuthority.js +228 -0
- package/dist/evidenceExportHelper/preparedBuilder.d.ts +10 -0
- package/dist/evidenceExportHelper/preparedBuilder.js +183 -0
- package/dist/evidenceExportHelper/preparedBuilderTypes.d.ts +19 -0
- package/dist/evidenceExportHelper/preparedBuilderTypes.js +1 -0
- package/dist/evidenceExportHelper/recipe.d.ts +7 -0
- package/dist/evidenceExportHelper/recipe.js +83 -0
- package/dist/filesystem/io.d.ts +2 -0
- package/dist/filesystem/io.js +16 -1
- package/dist/manifest/executionSchemas.d.ts +27 -0
- package/dist/manifest/executionSchemas.js +21 -2
- package/dist/manifest/mcpSchemas.d.ts +1 -0
- package/dist/manifest/mcpSchemas.js +3 -0
- package/dist/manifest/renderSpawnfileNetworks.js +11 -0
- package/dist/manifest/renderSpawnfileWorkspace.js +5 -0
- package/dist/manifest/scheduleSchemas.d.ts +3 -1
- package/dist/manifest/scheduleSchemas.js +91 -5
- package/dist/manifest/schemas.d.ts +237 -12
- package/dist/manifest/schemas.js +5 -2
- package/dist/manifest/teamNetworkAccessSchemas.d.ts +5 -1
- package/dist/manifest/teamNetworkAccessSchemas.js +11 -0
- package/dist/manifest/teamNetworkAuthSchemas.d.ts +1 -1
- package/dist/manifest/teamNetworkSchemas.d.ts +17 -3
- package/dist/manifest/teamNetworkSchemas.js +19 -1
- package/dist/manifest/teamNetworkServerSchemas.d.ts +8 -3
- package/dist/manifest/teamNetworkServerSchemas.js +18 -2
- package/dist/manifest/workspaceSchemas.d.ts +16 -0
- package/dist/manifest/workspaceSchemas.js +11 -0
- package/dist/report/types.d.ts +34 -4
- package/dist/runtime/common.d.ts +28 -1
- package/dist/runtime/common.js +33 -3
- package/dist/runtime/container.js +49 -33
- package/dist/runtime/daimon/adapter.d.ts +14 -0
- package/dist/runtime/daimon/adapter.js +243 -0
- package/dist/runtime/daimon/attention.d.ts +8 -0
- package/dist/runtime/daimon/attention.js +32 -0
- package/dist/runtime/daimon/config.d.ts +25 -0
- package/dist/runtime/daimon/config.js +272 -0
- package/dist/runtime/daimon/contractManifest.d.ts +295 -0
- package/dist/runtime/daimon/contractManifest.js +319 -0
- package/dist/runtime/daimon/grokModel.d.ts +19 -0
- package/dist/runtime/daimon/grokModel.js +33 -0
- package/dist/runtime/daimon/grokWorkerConfigBytes.d.ts +26 -0
- package/dist/runtime/daimon/grokWorkerConfigBytes.js +36 -0
- package/dist/runtime/daimon/grokWorkerContract.d.ts +22 -0
- package/dist/runtime/daimon/grokWorkerContract.js +48 -0
- package/dist/runtime/daimon/memory.d.ts +57 -0
- package/dist/runtime/daimon/memory.js +125 -0
- package/dist/runtime/daimon/runAuth.d.ts +51 -0
- package/dist/runtime/daimon/runAuth.js +279 -0
- package/dist/runtime/daimon/runtimeIdentity.d.ts +22 -0
- package/dist/runtime/daimon/runtimeIdentity.js +22 -0
- package/dist/runtime/daimon/scheduleAuthority.d.ts +3 -0
- package/dist/runtime/daimon/scheduleAuthority.js +17 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.js +4 -0
- package/dist/runtime/install.d.ts +3 -0
- package/dist/runtime/install.js +3 -0
- package/dist/runtime/localDaimonAuthority.d.ts +11 -0
- package/dist/runtime/localDaimonAuthority.js +77 -0
- package/dist/runtime/mnemeMcp.d.ts +13 -0
- package/dist/runtime/mnemeMcp.js +26 -0
- package/dist/runtime/openclaw/adapter.js +2 -2
- package/dist/runtime/pi/adapter.d.ts +0 -1
- package/dist/runtime/pi/adapter.js +2 -6
- package/dist/runtime/pi/appCliSource.js +1 -1
- package/dist/runtime/pi/appScheduleSource.js +6 -2
- package/dist/runtime/pi/appTemplateTypes.d.ts +1 -1
- package/dist/runtime/picoclaw/adapter.js +2 -2
- package/dist/runtime/registry.d.ts +3 -0
- package/dist/runtime/registry.js +19 -2
- package/dist/runtime/scheduleUtils.d.ts +1 -0
- package/dist/runtime/scheduleUtils.js +5 -1
- package/dist/runtime/types.d.ts +25 -0
- package/dist/runtime/usageLedger.d.ts +158 -0
- package/dist/runtime/usageLedger.js +269 -0
- package/dist/runtime/usageLedgerRead.d.ts +48 -0
- package/dist/runtime/usageLedgerRead.js +102 -0
- package/dist/runtime/usageRequestLedger.d.ts +42 -0
- package/dist/runtime/usageRequestLedger.js +72 -0
- package/dist/shared/daimonCodexDocker.d.ts +32 -0
- package/dist/shared/daimonCodexDocker.js +120 -0
- package/dist/shared/daimonGrokSeccompProfile.d.ts +10 -0
- package/dist/shared/daimonGrokSeccompProfile.js +11 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.js +2 -0
- package/dist/shared/types.d.ts +1 -1
- package/dist/shared/volumeNames.d.ts +6 -0
- package/dist/shared/volumeNames.js +14 -0
- package/dist/target/dockerArtifactsProvider.js +34 -7
- package/dist/target/dockerBaseImage.d.ts +2 -0
- package/dist/target/dockerBaseImage.js +11 -0
- package/dist/target/dockerCommandExecutor.d.ts +11 -0
- package/dist/target/dockerCommandExecutor.js +53 -2
- package/dist/target/dockerCommandExecutorCore.d.ts +2 -1
- package/dist/target/dockerCommandExecutorCore.js +4 -2
- package/dist/target/dockerPublicArtifactSnapshot.d.ts +3 -3
- package/dist/target/dockerPublicArtifactSnapshot.js +17 -33
- package/dist/target/dockerTarget.d.ts +1 -0
- package/dist/target/dockerTargetBinding.d.ts +1 -2
- package/dist/target/dockerTargetBinding.js +2 -3
- package/dist/target/dockerTargetExecFile.d.ts +19 -0
- package/dist/target/dockerTargetExecFile.js +194 -0
- package/dist/target/dockerWorldServiceProvider.d.ts +4 -0
- package/dist/target/dockerWorldServiceProvider.js +13 -1
- package/dist/target/evidenceExport.d.ts +3 -1
- package/dist/target/evidenceExport.js +12 -3
- package/dist/target/evidenceExportOperationsTestKit.js +3 -3
- package/dist/target/evidenceExportProvider.d.ts +2 -0
- package/dist/target/evidenceExportProvider.js +15 -5
- package/dist/target/publicArtifactSnapshot.d.ts +31 -0
- package/dist/target/publicArtifactSnapshot.js +37 -3
- package/examples/README.md +45 -0
- package/examples/agent-with-subagents/AGENTS.md +3 -0
- package/examples/agent-with-subagents/Spawnfile +30 -0
- package/examples/agent-with-subagents/subagents/critic/AGENTS.md +3 -0
- package/examples/agent-with-subagents/subagents/critic/Spawnfile +15 -0
- package/examples/agent-with-subagents/subagents/researcher/AGENTS.md +3 -0
- package/examples/agent-with-subagents/subagents/researcher/Spawnfile +17 -0
- package/examples/daimon-org/Spawnfile +68 -0
- package/examples/daimon-org/TEAM.md +4 -0
- package/examples/daimon-org/agents/mapper/AGENTS.md +4 -0
- package/examples/daimon-org/agents/mapper/Spawnfile +37 -0
- package/examples/daimon-org/shared/skills/file-note/SKILL.md +9 -0
- package/examples/daimon-org/teams/review/Spawnfile +53 -0
- package/examples/daimon-org/teams/review/agents/reviewer/AGENTS.md +4 -0
- package/examples/daimon-org/teams/review/agents/reviewer/Spawnfile +37 -0
- package/examples/daimon-public-host/AGENTS.md +3 -0
- package/examples/daimon-public-host/Spawnfile +21 -0
- package/examples/distribution-org/Spawnfile +43 -0
- package/examples/distribution-org/TEAM.md +4 -0
- package/examples/distribution-org/agents/coordinator/AGENTS.md +1 -0
- package/examples/distribution-org/agents/coordinator/Spawnfile +20 -0
- package/examples/distribution-org/agents/researcher/AGENTS.md +1 -0
- package/examples/distribution-org/agents/researcher/Spawnfile +20 -0
- package/examples/jungian-daimon-org/Spawnfile +41 -0
- package/examples/jungian-daimon-org/TEAM.md +21 -0
- package/examples/jungian-daimon-org/teams/luna/Spawnfile +47 -0
- package/examples/jungian-daimon-org/teams/luna/TEAM.md +4 -0
- package/examples/jungian-daimon-org/teams/luna/agents/animus/AGENTS.md +10 -0
- package/examples/jungian-daimon-org/teams/luna/agents/animus/Spawnfile +33 -0
- package/examples/jungian-daimon-org/teams/luna/agents/representative/AGENTS.md +21 -0
- package/examples/jungian-daimon-org/teams/luna/agents/representative/Spawnfile +30 -0
- package/examples/jungian-daimon-org/teams/luna/agents/shadow/AGENTS.md +10 -0
- package/examples/jungian-daimon-org/teams/luna/agents/shadow/Spawnfile +33 -0
- package/examples/jungian-daimon-org/teams/selene/Spawnfile +47 -0
- package/examples/jungian-daimon-org/teams/selene/TEAM.md +4 -0
- package/examples/jungian-daimon-org/teams/selene/agents/animus/AGENTS.md +10 -0
- package/examples/jungian-daimon-org/teams/selene/agents/animus/Spawnfile +33 -0
- package/examples/jungian-daimon-org/teams/selene/agents/representative/AGENTS.md +19 -0
- package/examples/jungian-daimon-org/teams/selene/agents/representative/Spawnfile +33 -0
- package/examples/jungian-daimon-org/teams/selene/agents/shadow/AGENTS.md +10 -0
- package/examples/jungian-daimon-org/teams/selene/agents/shadow/Spawnfile +30 -0
- package/examples/mixed-runtime-org/Spawnfile +71 -0
- package/examples/mixed-runtime-org/TEAM.md +8 -0
- package/examples/mixed-runtime-org/agents/analyst/AGENTS.md +8 -0
- package/examples/mixed-runtime-org/agents/analyst/Spawnfile +27 -0
- package/examples/mixed-runtime-org/agents/conductor/AGENTS.md +8 -0
- package/examples/mixed-runtime-org/agents/conductor/Spawnfile +27 -0
- package/examples/mixed-runtime-org/agents/localist/AGENTS.md +7 -0
- package/examples/mixed-runtime-org/agents/localist/Spawnfile +50 -0
- package/examples/moltnet-team-chat/Spawnfile +43 -0
- package/examples/moltnet-team-chat/TEAM.md +5 -0
- package/examples/moltnet-team-chat/agents/coordinator/AGENTS.md +9 -0
- package/examples/moltnet-team-chat/agents/coordinator/Spawnfile +26 -0
- package/examples/moltnet-team-chat/teams/analysis/Spawnfile +23 -0
- package/examples/moltnet-team-chat/teams/analysis/TEAM.md +3 -0
- package/examples/moltnet-team-chat/teams/analysis/agents/observer/AGENTS.md +5 -0
- package/examples/moltnet-team-chat/teams/analysis/agents/observer/Spawnfile +19 -0
- package/examples/moltnet-team-chat/teams/analysis/agents/representative/AGENTS.md +5 -0
- package/examples/moltnet-team-chat/teams/analysis/agents/representative/Spawnfile +19 -0
- package/examples/moltnet-team-chat/teams/field/Spawnfile +41 -0
- package/examples/moltnet-team-chat/teams/field/TEAM.md +3 -0
- package/examples/moltnet-team-chat/teams/field/agents/observer/AGENTS.md +5 -0
- package/examples/moltnet-team-chat/teams/field/agents/observer/Spawnfile +26 -0
- package/examples/moltnet-team-chat/teams/field/agents/representative/AGENTS.md +11 -0
- package/examples/moltnet-team-chat/teams/field/agents/representative/Spawnfile +26 -0
- package/examples/single-agent/AGENTS.md +3 -0
- package/examples/single-agent/HEARTBEAT.md +3 -0
- package/examples/single-agent/IDENTITY.md +3 -0
- package/examples/single-agent/MEMORY.md +3 -0
- package/examples/single-agent/SOUL.md +3 -0
- package/examples/single-agent/Spawnfile +41 -0
- package/examples/single-agent/skills/web_search/SKILL.md +6 -0
- package/moltnet-releases.json +5 -4
- package/package.json +36 -9
- package/runtimes.yaml +5 -2
- package/dist/cli/targetWorldClockCrossProcess.test-helper.d.ts +0 -13
- package/dist/cli/targetWorldClockCrossProcess.test-helper.js +0 -109
- package/dist/deployment/providerRuntimeBoundaryScanner.test-helper.d.ts +0 -8
- package/dist/deployment/providerRuntimeBoundaryScanner.test-helper.js +0 -60
- package/dist/deployment/simfileFixtureBoundary.test-helper.d.ts +0 -8
- package/dist/deployment/simfileFixtureBoundary.test-helper.js +0 -103
- package/dist/ownership/simfileRunOperatorInputs.d.ts +0 -103
- package/dist/ownership/simfileRunOperatorInputs.js +0 -139
- package/dist/target/cleanupRunDocker.test-helper.d.ts +0 -67
- package/dist/target/cleanupRunDocker.test-helper.js +0 -238
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
2
|
+
export const ORGANIZATION_ID_SEGMENT_PATTERN_SOURCE = "^[a-z][a-z0-9-]{0,62}$";
|
|
3
|
+
export const ORGANIZATION_MEMBER_ID_PATTERN_SOURCE = "^[a-z][a-z0-9-]{0,62}(\\.[a-z][a-z0-9-]{0,62}){0,7}$";
|
|
4
|
+
export const MAX_ORGANIZATION_MEMBER_DEPTH = 8;
|
|
5
|
+
export const MAX_ORGANIZATION_MEMBER_ID_BYTES = 255;
|
|
6
|
+
export const MAX_ORGANIZATION_AGENT_MEMBERS = 128;
|
|
7
|
+
export const MAX_EXTERNAL_PARTICIPANTS = 32;
|
|
8
|
+
const segment = new RegExp(ORGANIZATION_ID_SEGMENT_PATTERN_SOURCE, "u");
|
|
9
|
+
export const organizationIdentityFail = (message) => {
|
|
10
|
+
throw new SpawnfileError("validation_error", message);
|
|
11
|
+
};
|
|
12
|
+
export const requiredOrganizationIdentity = (value, message) => value == null ? organizationIdentityFail(message) : value;
|
|
13
|
+
export const assertOrganizationSegment = (value, label) => {
|
|
14
|
+
if (!segment.test(value)) {
|
|
15
|
+
organizationIdentityFail(`${label} must match ${ORGANIZATION_ID_SEGMENT_PATTERN_SOURCE}`);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
export const freezeOrganizationIdentity = (value) => {
|
|
19
|
+
if (value && typeof value === "object") {
|
|
20
|
+
Object.freeze(value);
|
|
21
|
+
for (const child of Object.values(value)) {
|
|
22
|
+
freezeOrganizationIdentity(child);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
};
|
|
27
|
+
export const compareOrganizationIds = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
28
|
+
export const exactOrganizationStrings = (actual, expected) => actual?.length === expected.length
|
|
29
|
+
&& actual.every((value, index) => value === expected[index]);
|
|
30
|
+
const teamNodes = (plan) => new Map(plan.nodes.filter((node) => node.kind === "team")
|
|
31
|
+
.map((node) => [node.value.source, node.value]));
|
|
32
|
+
export const rootOrganizationTeam = (plan) => {
|
|
33
|
+
const node = plan.nodes.find((entry) => entry.id === plan.root || entry.value.source === plan.root);
|
|
34
|
+
return node?.value.kind === "team" ? node.value : undefined;
|
|
35
|
+
};
|
|
36
|
+
export const organizationAgentPaths = (plan) => {
|
|
37
|
+
const teams = teamNodes(plan);
|
|
38
|
+
const edges = plan.edges.filter((edge) => edge.kind === "team_member");
|
|
39
|
+
const paths = new Map();
|
|
40
|
+
const teamPaths = new Map();
|
|
41
|
+
const visitedNodeIds = new Set();
|
|
42
|
+
// External-participant authority needs one unambiguous path per principal.
|
|
43
|
+
// Ordinary organizations still have a canonical identity, but retain the
|
|
44
|
+
// compiler's long-standing ability to reuse an identical agent/team ref.
|
|
45
|
+
const requireUniquePaths = (rootOrganizationTeam(plan)?.externalParticipants?.length ?? 0) > 0;
|
|
46
|
+
const walk = (source, prefix, seen) => {
|
|
47
|
+
if (seen.has(source))
|
|
48
|
+
organizationIdentityFail(`organization member graph cycle at ${source}`);
|
|
49
|
+
const team = teams.get(source);
|
|
50
|
+
if (!team)
|
|
51
|
+
return;
|
|
52
|
+
if (teamPaths.has(source)) {
|
|
53
|
+
if (requireUniquePaths) {
|
|
54
|
+
organizationIdentityFail(`team is reached through multiple organization paths: ${source}`);
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
teamPaths.set(source, prefix);
|
|
59
|
+
const node = plan.nodes.find((entry) => entry.value.source === source);
|
|
60
|
+
if (!node || node.kind !== "team") {
|
|
61
|
+
throw new SpawnfileError("validation_error", `organization graph references missing team ${source}`);
|
|
62
|
+
}
|
|
63
|
+
visitedNodeIds.add(node.id);
|
|
64
|
+
const outgoing = edges.filter((entry) => entry.from === node.id)
|
|
65
|
+
.sort((left, right) => compareOrganizationIds(left.label, right.label));
|
|
66
|
+
const memberSlots = new Set(team.members.map((member) => member.id));
|
|
67
|
+
if (memberSlots.size !== team.members.length || outgoing.length !== team.members.length) {
|
|
68
|
+
organizationIdentityFail(`organization graph cardinality mismatch for team ${team.name}`);
|
|
69
|
+
}
|
|
70
|
+
const localSlots = new Set();
|
|
71
|
+
for (const edge of outgoing) {
|
|
72
|
+
if (localSlots.has(edge.label)) {
|
|
73
|
+
organizationIdentityFail(`duplicate organization member slot: ${edge.label}`);
|
|
74
|
+
}
|
|
75
|
+
localSlots.add(edge.label);
|
|
76
|
+
assertOrganizationSegment(edge.label, "organization member slot");
|
|
77
|
+
const next = [...prefix, edge.label];
|
|
78
|
+
if (next.length > MAX_ORGANIZATION_MEMBER_DEPTH) {
|
|
79
|
+
organizationIdentityFail("organization member depth exceeds 8");
|
|
80
|
+
}
|
|
81
|
+
const child = plan.nodes.find((candidate) => candidate.id === edge.to);
|
|
82
|
+
if (!child) {
|
|
83
|
+
throw new SpawnfileError("validation_error", `organization graph references missing node ${edge.to}`);
|
|
84
|
+
}
|
|
85
|
+
const member = team.members.find((entry) => entry.id === edge.label);
|
|
86
|
+
if (!member || member.kind !== child.kind || member.nodeSource !== child.value.source) {
|
|
87
|
+
organizationIdentityFail(`organization graph member edge mismatch: ${edge.label}`);
|
|
88
|
+
}
|
|
89
|
+
if (child.kind === "agent") {
|
|
90
|
+
if (paths.has(child.value.source) && requireUniquePaths) {
|
|
91
|
+
organizationIdentityFail(`agent source is reached through multiple organization paths: ${child.value.source}`);
|
|
92
|
+
}
|
|
93
|
+
const prior = paths.get(child.value.source);
|
|
94
|
+
if (!prior || compareOrganizationIds(next.join("."), prior.join(".")) < 0) {
|
|
95
|
+
paths.set(child.value.source, next);
|
|
96
|
+
}
|
|
97
|
+
visitedNodeIds.add(child.id);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
walk(child.value.source, next, new Set([...seen, source]));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
walk(plan.root, [], new Set());
|
|
105
|
+
const rootNode = plan.nodes.find((node) => node.value.source === plan.root);
|
|
106
|
+
const organizationNodeIds = new Set(rootNode ? [rootNode.id] : []);
|
|
107
|
+
for (const edge of edges) {
|
|
108
|
+
organizationNodeIds.add(edge.from);
|
|
109
|
+
organizationNodeIds.add(edge.to);
|
|
110
|
+
}
|
|
111
|
+
const extra = plan.nodes.find((node) => organizationNodeIds.has(node.id) && !visitedNodeIds.has(node.id));
|
|
112
|
+
if (extra)
|
|
113
|
+
organizationIdentityFail(`unreachable organization graph node: ${extra.id}`);
|
|
114
|
+
return paths;
|
|
115
|
+
};
|
|
@@ -22,6 +22,13 @@ export interface OrganizationReadinessEvidence {
|
|
|
22
22
|
readonly nodeId: string;
|
|
23
23
|
}[];
|
|
24
24
|
} | null;
|
|
25
|
+
readonly daimon?: {
|
|
26
|
+
readonly receiptPath: string;
|
|
27
|
+
readonly agents: readonly {
|
|
28
|
+
readonly agentId: string;
|
|
29
|
+
readonly engine: string;
|
|
30
|
+
}[];
|
|
31
|
+
} | null;
|
|
25
32
|
readonly networks: readonly {
|
|
26
33
|
readonly id: string;
|
|
27
34
|
readonly mode: "external" | "managed";
|
|
@@ -34,6 +41,7 @@ export interface OrganizationReadinessEvidence {
|
|
|
34
41
|
readonly nodeId: string;
|
|
35
42
|
readonly memberId: string;
|
|
36
43
|
readonly configPath: string;
|
|
44
|
+
readonly receiptPath: string;
|
|
37
45
|
readonly sha256: string;
|
|
38
46
|
}[];
|
|
39
47
|
}[];
|
|
@@ -96,6 +96,17 @@ const assertMemberId = (value, label) => {
|
|
|
96
96
|
if (!MEMBER_ID.test(value))
|
|
97
97
|
fail(`${label} is unbounded or noncanonical`);
|
|
98
98
|
};
|
|
99
|
+
const assertMoltnetRoomMemberId = (value, label) => {
|
|
100
|
+
if (MEMBER_ID.test(value))
|
|
101
|
+
return;
|
|
102
|
+
const separator = value.indexOf(":");
|
|
103
|
+
const networkId = value.slice(0, separator);
|
|
104
|
+
const agentId = value.slice(separator + 1);
|
|
105
|
+
if (separator <= 0 || separator === value.length - 1 || value.length > 128
|
|
106
|
+
|| !ID.test(networkId) || !ID.test(agentId)) {
|
|
107
|
+
fail(`${label} is unbounded or noncanonical`);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
99
110
|
const assertConfigPath = (value) => {
|
|
100
111
|
if (value.length > 255 || !CONFIG_PATH.test(value)) {
|
|
101
112
|
fail(`Moltnet config path is noncanonical: ${value}`);
|
|
@@ -167,14 +178,15 @@ const validateMoltnet = (artifacts, plan) => {
|
|
|
167
178
|
const rooms = sort(server.rooms.map((room) => {
|
|
168
179
|
assertId(room.id, "Moltnet room id");
|
|
169
180
|
assertUnique(room.members, (member) => member, `Moltnet room member on ${server.networkId}/${room.id}`);
|
|
170
|
-
for (const member of room.members)
|
|
171
|
-
|
|
181
|
+
for (const member of room.members) {
|
|
182
|
+
assertMoltnetRoomMemberId(member, `Moltnet room member on ${server.networkId}/${room.id}`);
|
|
183
|
+
}
|
|
172
184
|
return { id: room.id, members: sort(room.members, (member) => member) };
|
|
173
185
|
}), (room) => room.id);
|
|
174
186
|
assertUnique(rooms, (room) => room.id, `Moltnet room on ${server.networkId}`);
|
|
175
187
|
const nodes = sort(nodePlans.filter((node) => node.networkId === server.networkId).map((node) => {
|
|
176
188
|
const attachment = attachmentByKey.get(`${node.networkId}\u0000${node.memberId}`);
|
|
177
|
-
return { configPath: node.configPath, memberId: node.memberId, nodeId: attachment.nodeId,
|
|
189
|
+
return { configPath: node.configPath, receiptPath: `/run/spawnfile/moltnet-readiness/${node.networkId}-${node.memberId}.json`, memberId: node.memberId, nodeId: attachment.nodeId,
|
|
178
190
|
sha256: sha256(emittedConfigContent(artifacts, node.configPath)) };
|
|
179
191
|
}), (node) => `${node.memberId}\u0000${node.nodeId}`);
|
|
180
192
|
return { id: server.networkId, internalPort: server.mode === "managed" ? server.port : null,
|
|
@@ -248,9 +260,17 @@ export const createOrganizationReadinessEvidence = (input) => {
|
|
|
248
260
|
const projectLabel = normalizeProjectLabelSlug(distribution.organization.project);
|
|
249
261
|
if (projectLabel.length > 128 || !ID.test(projectLabel))
|
|
250
262
|
fail("project label is unbounded or noncanonical");
|
|
263
|
+
const daimonInstance = input.containerArtifacts.report.runtime_instances.find((instance) => instance.runtime === "daimon");
|
|
264
|
+
const daimon = daimonInstance === undefined ? null : {
|
|
265
|
+
receiptPath: "/var/lib/spawnfile/instances/daimon/daimon-organization/state/wake-acceptance/runtime-readiness.json",
|
|
266
|
+
agents: Object.entries(daimonInstance.engine_by_node_id ?? {}).sort(([left], [right]) => left.localeCompare(right)).map(([agentId, engine]) => ({ agentId, engine }))
|
|
267
|
+
};
|
|
268
|
+
if (daimon !== null && daimon.agents.length === 0)
|
|
269
|
+
fail("Daimon readiness has no compiled agent engines");
|
|
251
270
|
return freeze({
|
|
252
271
|
compileFingerprint: fingerprint,
|
|
253
272
|
compileVersion: input.compileVersion,
|
|
273
|
+
daimon,
|
|
254
274
|
hasExternalMoltnet: networks.some((network) => network.mode === "external"),
|
|
255
275
|
networks,
|
|
256
276
|
organizationMembers,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type ResolvedAuthProfile } from "../auth/index.js";
|
|
2
2
|
import { type DockerTargetExecFile } from "../deployment/index.js";
|
|
3
3
|
import { type CompileProjectOptions, type CompileProjectResult } from "./compileProject.js";
|
|
4
|
-
import { runDockerContainer, type DockerRunInvocation, type DockerRunResult, type DockerRunRunner } from "./runProjectDocker.js";
|
|
5
|
-
export { runDockerContainer };
|
|
4
|
+
import { inspectDetachedContainer as recoverDetachedDockerRun, runDockerContainer, type DockerRunInvocation, type DockerRunResult, type DockerRunRunner } from "./runProjectDocker.js";
|
|
5
|
+
export { recoverDetachedDockerRun, runDockerContainer };
|
|
6
6
|
export type { DockerRunInvocation, DockerRunResult, DockerRunRunner };
|
|
7
7
|
export interface RunProjectOptions extends CompileProjectOptions {
|
|
8
8
|
authProfile?: string;
|
|
@@ -29,6 +29,8 @@ export declare const createDockerRunInvocation: (compileResult: CompileProjectRe
|
|
|
29
29
|
name: string;
|
|
30
30
|
value: string;
|
|
31
31
|
};
|
|
32
|
+
/** See `RuntimeAuthPreparationInput.containerCredentialUid`. */
|
|
33
|
+
containerCredentialUid?: number;
|
|
32
34
|
containerName?: string;
|
|
33
35
|
detach?: boolean;
|
|
34
36
|
deploymentName?: string;
|
|
@@ -4,15 +4,16 @@ import { mkdtemp } from "node:fs/promises";
|
|
|
4
4
|
import { requireAuthProfile } from "../auth/index.js";
|
|
5
5
|
import { ensureDirectory, fileExists, removeDirectory, writeUtf8File } from "../filesystem/index.js";
|
|
6
6
|
import { appendDockerLabelArgs, createDockerDeploymentLabels, createDockerDeploymentUnitId, createDockerProjectLabel, dockerContextNameForTarget, dockerHostValueForTarget, normalizeDeploymentName, readDeploymentRecordFromOutput, resolveDeploymentRecordPath, verifyDockerDeploymentTarget, writeDockerDeploymentRecordForRun } from "../deployment/index.js";
|
|
7
|
-
import { DEFAULT_OUTPUT_DIRECTORY, SpawnfileError } from "../shared/index.js";
|
|
7
|
+
import { DAIMON_DOCKER_RUNTIME_SECURITY_ARGS, DEFAULT_OUTPUT_DIRECTORY, SpawnfileError } from "../shared/index.js";
|
|
8
8
|
import { ensureNoopolisRunId, resolveNoopolisRunId } from "../runtime/index.js";
|
|
9
9
|
import { compileProject } from "./compileProject.js";
|
|
10
10
|
import { createDefaultImageTag, resolveDockerBuildArchitecture } from "./buildProject.js";
|
|
11
11
|
import { slugify } from "./helpers.js";
|
|
12
|
-
import {
|
|
12
|
+
import { resolveDaimonCodexNativeSandboxDockerSecurityOptions } from "./runProjectDaimonCodexDocker.js";
|
|
13
|
+
import { inspectDetachedContainer as recoverDetachedDockerRun, runDockerContainer } from "./runProjectDocker.js";
|
|
13
14
|
import { executeDockerRunWithSupportCleanup } from "./runProjectLifecycle.js";
|
|
14
15
|
import { assertDeclaredModelAuthSatisfied, assertMoltnetCredentialValuesDistinct, assertRunEnvironmentSatisfied, prepareRuntimeAuthMounts, readRunEnvFile, renderDockerEnvFile, resolveAuthMountArgs, resolveRunEnvironment } from "./runProjectAuth.js";
|
|
15
|
-
export { runDockerContainer };
|
|
16
|
+
export { recoverDetachedDockerRun, runDockerContainer };
|
|
16
17
|
const resolveImageTagRoot = (inputPath) => {
|
|
17
18
|
const resolvedPath = path.resolve(inputPath);
|
|
18
19
|
return path.basename(resolvedPath).toLowerCase() === "spawnfile"
|
|
@@ -36,9 +37,11 @@ export const createDockerRunInvocation = async (compileResult, imageTag, options
|
|
|
36
37
|
...(await readRunEnvFile(options.envFilePath)),
|
|
37
38
|
...(options.cliCredential ? { [options.cliCredential.name]: options.cliCredential.value } : {})
|
|
38
39
|
});
|
|
39
|
-
const preparedRuntimeAuth = await prepareRuntimeAuthMounts(compileResult.outputDirectory, containerReport, options.authProfile ?? null, env, supportDirectory);
|
|
40
|
+
const preparedRuntimeAuth = await prepareRuntimeAuthMounts(compileResult.outputDirectory, containerReport, options.authProfile ?? null, env, supportDirectory, options.containerCredentialUid);
|
|
40
41
|
assertRunEnvironmentSatisfied(containerReport, env, preparedRuntimeAuth.coveredModelSecrets);
|
|
41
42
|
assertMoltnetCredentialValuesDistinct(containerReport, env);
|
|
43
|
+
const hasDaimon = containerReport.runtime_instances.some((instance) => instance.runtime === "daimon");
|
|
44
|
+
const opaqueDaimonCredentials = preparedRuntimeAuth.launchIdentity?.kind === "daimon";
|
|
42
45
|
await ensureDirectory(supportDirectory);
|
|
43
46
|
await writeUtf8File(envFilePath, renderDockerEnvFile(env));
|
|
44
47
|
const deploymentName = options.deploymentName
|
|
@@ -53,17 +56,32 @@ export const createDockerRunInvocation = async (compileResult, imageTag, options
|
|
|
53
56
|
? ["--host", options.dockerHost, "run"]
|
|
54
57
|
: ["run"];
|
|
55
58
|
if (options.detach) {
|
|
56
|
-
args.push("-d");
|
|
59
|
+
args.push("-d", "--restart", "unless-stopped");
|
|
57
60
|
}
|
|
58
61
|
else {
|
|
59
62
|
args.push("--rm");
|
|
60
63
|
}
|
|
61
64
|
args.push("--name", containerName);
|
|
65
|
+
if (hasDaimon) {
|
|
66
|
+
args.push(...DAIMON_DOCKER_RUNTIME_SECURITY_ARGS, ...(await resolveDaimonCodexNativeSandboxDockerSecurityOptions(compileResult)));
|
|
67
|
+
}
|
|
62
68
|
for (const port of containerReport.ports) {
|
|
63
69
|
args.push("-p", `${port}:${port}`);
|
|
64
70
|
}
|
|
71
|
+
// Compiler-owned persistent mounts are mounted WITHOUT `volume-nocopy`.
|
|
72
|
+
// The image is the authority for the bootstrap preimage at these paths:
|
|
73
|
+
// `createStateOwnershipCommand` writes a `.spawnfile-volume-init` marker
|
|
74
|
+
// into every one of them at build time, and the Daimon ownership guard
|
|
75
|
+
// (`secureVolumeIdentity`) and `prepare_volume_resource` both REQUIRE that
|
|
76
|
+
// marker as the fresh-volume preimage. `volume-nocopy` is exactly the flag
|
|
77
|
+
// that stops Docker copying image content into an empty volume, so it
|
|
78
|
+
// starved the guard and no Daimon organization with persistent volumes
|
|
79
|
+
// could bootstrap. Copy-up only ever populates an EMPTY volume, so a
|
|
80
|
+
// reattached volume that already holds state is untouched by dropping it.
|
|
81
|
+
// (Target/secrets volumes under src/target/* keep `volume-nocopy`: no
|
|
82
|
+
// image content backs those paths and they must stay opaque.)
|
|
65
83
|
for (const mount of containerReport.persistent_mounts ?? []) {
|
|
66
|
-
args.push("
|
|
84
|
+
args.push("--mount", `type=volume,source=${mount.volume_name},target=${mount.mount_path}`);
|
|
67
85
|
}
|
|
68
86
|
const deploymentLabels = options.detach && deploymentName ? (() => {
|
|
69
87
|
const compileFingerprint = compileResult.report.compile_fingerprint ?? "sf1:unknown";
|
|
@@ -91,7 +109,14 @@ export const createDockerRunInvocation = async (compileResult, imageTag, options
|
|
|
91
109
|
dockerContext: options.dockerContext ?? null,
|
|
92
110
|
dockerHost: options.dockerHost ?? null,
|
|
93
111
|
envFilePath,
|
|
112
|
+
...((containerReport.persistent_mounts ?? []).some((mount) => mount.lifecycle === "exclusive-reattach") ? {
|
|
113
|
+
exclusiveReattachVolumes: (containerReport.persistent_mounts ?? [])
|
|
114
|
+
.filter((mount) => mount.lifecycle === "exclusive-reattach")
|
|
115
|
+
.map((mount) => mount.volume_name)
|
|
116
|
+
.sort()
|
|
117
|
+
} : {}),
|
|
94
118
|
imageTag,
|
|
119
|
+
...(opaqueDaimonCredentials ? { opaqueDaimonCredentials } : {}),
|
|
95
120
|
supportDirectory
|
|
96
121
|
};
|
|
97
122
|
}
|
|
@@ -164,6 +189,7 @@ export const runProject = async (inputPath, options = {}) => {
|
|
|
164
189
|
const compileResult = await compileProject(inputPath, {
|
|
165
190
|
clean: options.clean,
|
|
166
191
|
containerArchitecture: targetArchitecture,
|
|
192
|
+
deploymentLineage: resolvedOptions.deploymentName ?? "ephemeral",
|
|
167
193
|
outputDirectory: options.outputDirectory,
|
|
168
194
|
...(options.worldBindingsPath !== undefined
|
|
169
195
|
? { worldBindingsPath: options.worldBindingsPath }
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { ResolvedAuthProfile } from "../auth/index.js";
|
|
2
2
|
import type { ContainerReport } from "../report/index.js";
|
|
3
|
+
import type { RuntimeAuthPreparationResult } from "../runtime/types.js";
|
|
3
4
|
interface PreparedRunAuth {
|
|
4
5
|
coveredModelSecrets: Set<string>;
|
|
6
|
+
launchIdentity?: RuntimeAuthPreparationResult["launchIdentity"];
|
|
5
7
|
mountArgs: string[];
|
|
6
8
|
}
|
|
7
9
|
export declare const resolveHostCliCredential: (containerReport: ContainerReport) => Promise<{
|
|
@@ -9,7 +11,7 @@ export declare const resolveHostCliCredential: (containerReport: ContainerReport
|
|
|
9
11
|
sourcePath: string;
|
|
10
12
|
value: string;
|
|
11
13
|
} | null>;
|
|
12
|
-
export declare const prepareRuntimeAuthMounts: (outputDirectory: string, containerReport: ContainerReport, authProfile: ResolvedAuthProfile | null, env: Record<string, string>, tempRoot: string) => Promise<PreparedRunAuth>;
|
|
14
|
+
export declare const prepareRuntimeAuthMounts: (outputDirectory: string, containerReport: ContainerReport, authProfile: ResolvedAuthProfile | null, env: Record<string, string>, tempRoot: string, containerCredentialUid?: number) => Promise<PreparedRunAuth>;
|
|
13
15
|
export declare const assertDeclaredModelAuthSatisfied: (containerReport: ContainerReport, authProfile: ResolvedAuthProfile | null, cliCredentialProvided?: boolean) => void;
|
|
14
16
|
export declare const resolveRunEnvironment: (containerReport: ContainerReport, authProfile: ResolvedAuthProfile | null, envFileEnv?: Record<string, string>) => Record<string, string>;
|
|
15
17
|
export declare const assertRunEnvironmentSatisfied: (containerReport: ContainerReport, env: Record<string, string>, coveredModelSecrets: Set<string>) => void;
|
|
@@ -10,6 +10,7 @@ const MODEL_AUTH_IMPORT_KINDS = {
|
|
|
10
10
|
api_key: null,
|
|
11
11
|
"claude-code": "claude-code",
|
|
12
12
|
codex: "codex",
|
|
13
|
+
grok: null,
|
|
13
14
|
none: null
|
|
14
15
|
};
|
|
15
16
|
export const resolveHostCliCredential = async (containerReport) => {
|
|
@@ -44,7 +45,7 @@ const addCoveredModelSecrets = (coveredModelSecrets, instanceId, secretNames) =>
|
|
|
44
45
|
coveredModelSecrets.add(`${instanceId}:${secretName}`);
|
|
45
46
|
}
|
|
46
47
|
};
|
|
47
|
-
export const prepareRuntimeAuthMounts = async (outputDirectory, containerReport, authProfile, env, tempRoot) => {
|
|
48
|
+
export const prepareRuntimeAuthMounts = async (outputDirectory, containerReport, authProfile, env, tempRoot, containerCredentialUid) => {
|
|
48
49
|
// No early return when `authProfile` is null: an adapter's
|
|
49
50
|
// `prepareRuntimeAuth` may still have host-credential staging to do that
|
|
50
51
|
// does not depend on an imported Spawnfile auth profile (e.g. the Pi
|
|
@@ -53,6 +54,7 @@ export const prepareRuntimeAuthMounts = async (outputDirectory, containerReport,
|
|
|
53
54
|
// responsible for treating a `null` `authProfile` as "no profile-derived
|
|
54
55
|
// imports available" rather than failing.
|
|
55
56
|
const coveredModelSecrets = new Set();
|
|
57
|
+
let launchIdentity;
|
|
56
58
|
const mountArgs = [];
|
|
57
59
|
for (const instance of containerReport.runtime_instances) {
|
|
58
60
|
const adapter = getRuntimeAdapter(instance.runtime);
|
|
@@ -61,15 +63,26 @@ export const prepareRuntimeAuthMounts = async (outputDirectory, containerReport,
|
|
|
61
63
|
}
|
|
62
64
|
const prepared = await adapter.prepareRuntimeAuth({
|
|
63
65
|
authProfile,
|
|
66
|
+
...(containerCredentialUid === undefined ? {} : { containerCredentialUid }),
|
|
64
67
|
env,
|
|
65
68
|
instance,
|
|
66
69
|
outputDirectory,
|
|
67
70
|
tempRoot
|
|
68
71
|
});
|
|
69
72
|
addCoveredModelSecrets(coveredModelSecrets, instance.id, prepared.coveredModelSecrets);
|
|
73
|
+
if (prepared.launchIdentity) {
|
|
74
|
+
if (launchIdentity && launchIdentity.uid !== prepared.launchIdentity.uid) {
|
|
75
|
+
throw new SpawnfileError("validation_error", "Opaque runtime credentials resolve conflicting launch UIDs");
|
|
76
|
+
}
|
|
77
|
+
launchIdentity = prepared.launchIdentity;
|
|
78
|
+
}
|
|
70
79
|
mountArgs.push(...prepared.mountArgs);
|
|
71
80
|
}
|
|
72
|
-
return {
|
|
81
|
+
return {
|
|
82
|
+
coveredModelSecrets,
|
|
83
|
+
...(launchIdentity ? { launchIdentity } : {}),
|
|
84
|
+
mountArgs
|
|
85
|
+
};
|
|
73
86
|
};
|
|
74
87
|
export const assertDeclaredModelAuthSatisfied = (containerReport, authProfile, cliCredentialProvided = false) => {
|
|
75
88
|
const requiredImportKinds = new Set();
|
|
@@ -108,6 +121,9 @@ const createGeneratedRuntimeSecret = (secretName, generatedMoltnetSecrets) => {
|
|
|
108
121
|
if (generatedMoltnetSecrets.has(secretName)) {
|
|
109
122
|
return randomBytes(32).toString("base64url");
|
|
110
123
|
}
|
|
124
|
+
if (secretName === "SPAWNFILE_DAIMON_CONTROL_TOKEN") {
|
|
125
|
+
return randomBytes(32).toString("base64url");
|
|
126
|
+
}
|
|
111
127
|
return null;
|
|
112
128
|
};
|
|
113
129
|
const hasEnvValue = (env, name) => typeof env[name] === "string" && env[name].length > 0;
|
|
@@ -215,7 +231,7 @@ export const resolveAuthMountArgs = async (containerReport, authProfile) => {
|
|
|
215
231
|
// Mounting the generic imported home onto the same destination would create
|
|
216
232
|
// duplicate Docker mount points and bypass the adapter's minimal-file staging.
|
|
217
233
|
const piRuntimeHomes = new Set(containerReport.runtime_instances
|
|
218
|
-
.filter((instance) => instance.runtime === "pi"
|
|
234
|
+
.filter((instance) => instance.runtime === "pi")
|
|
219
235
|
.map((instance) => instance.home_path)
|
|
220
236
|
.filter((homePath) => homePath !== null));
|
|
221
237
|
const genericRuntimeHomes = containerReport.runtime_homes
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CompileProjectResult } from "./compileProject.js";
|
|
2
|
+
export { DAIMON_CODEX_NATIVE_SANDBOX_DOCKER_SECURITY_OPTS } from "../shared/index.js";
|
|
3
|
+
export declare const resolveDaimonCodexNativeSandboxDockerSecurityOptions: (compileResult: CompileProjectResult) => Promise<string[]>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { readUtf8File } from "../filesystem/index.js";
|
|
3
|
+
import { daimonEngineDockerSecurityArgsForConfigs, materializeDaimonGrokSeccompProfile, SpawnfileError } from "../shared/index.js";
|
|
4
|
+
export { DAIMON_CODEX_NATIVE_SANDBOX_DOCKER_SECURITY_OPTS } from "../shared/index.js";
|
|
5
|
+
const assertContainedPath = (root, candidate) => {
|
|
6
|
+
const normalizedRoot = path.resolve(root);
|
|
7
|
+
const normalizedCandidate = path.resolve(candidate);
|
|
8
|
+
const relative = path.relative(normalizedRoot, normalizedCandidate);
|
|
9
|
+
if (relative === "" || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
|
10
|
+
throw new SpawnfileError("validation_error", "Daimon generated config path escapes the compiled container rootfs");
|
|
11
|
+
}
|
|
12
|
+
return normalizedCandidate;
|
|
13
|
+
};
|
|
14
|
+
const configPathInOutput = (outputDirectory, instance) => {
|
|
15
|
+
if (!instance.config_path.startsWith("/")) {
|
|
16
|
+
throw new SpawnfileError("validation_error", "Daimon runtime instance has a non-absolute generated config path");
|
|
17
|
+
}
|
|
18
|
+
const rootfs = path.join(outputDirectory, "container", "rootfs");
|
|
19
|
+
return assertContainedPath(rootfs, path.join(rootfs, `.${instance.config_path}`));
|
|
20
|
+
};
|
|
21
|
+
export const resolveDaimonCodexNativeSandboxDockerSecurityOptions = async (compileResult) => {
|
|
22
|
+
const instances = compileResult.report.container?.runtime_instances
|
|
23
|
+
.filter((instance) => instance.runtime === "daimon") ?? [];
|
|
24
|
+
const sources = [];
|
|
25
|
+
for (const instance of instances) {
|
|
26
|
+
try {
|
|
27
|
+
sources.push(await readUtf8File(configPathInOutput(compileResult.outputDirectory, instance)));
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (error instanceof SpawnfileError)
|
|
31
|
+
throw error;
|
|
32
|
+
throw new SpawnfileError("validation_error", "Could not read Daimon's generated organization config before Docker launch");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return daimonEngineDockerSecurityArgsForConfigs(sources, () => materializeDaimonGrokSeccompProfile(path.join(compileResult.outputDirectory, "container", "security")));
|
|
36
|
+
};
|
|
@@ -9,18 +9,22 @@ export interface DockerRunInvocation {
|
|
|
9
9
|
dockerContext?: string | null;
|
|
10
10
|
dockerHost?: string | null;
|
|
11
11
|
envFilePath: string;
|
|
12
|
+
/** Host-stable credential realms that must have at most one live deployment. */
|
|
13
|
+
exclusiveReattachVolumes?: readonly string[];
|
|
12
14
|
imageTag: string;
|
|
13
|
-
onDetachedStarted?: (result:
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
onDetachedStarted?: (result: DockerRunResult) => Promise<void>;
|
|
16
|
+
/** Ephemeral guard; never serialized into reports, records, or labels. */
|
|
17
|
+
opaqueDaimonCredentials?: boolean;
|
|
16
18
|
supportDirectory: string;
|
|
17
19
|
}
|
|
18
20
|
export interface DockerRunResult {
|
|
19
21
|
containerId?: string;
|
|
22
|
+
containerName?: string;
|
|
20
23
|
deploymentLabels?: Readonly<Record<string, string>>;
|
|
21
24
|
imageId?: string;
|
|
22
25
|
}
|
|
23
26
|
export type DockerRunRunner = (invocation: DockerRunInvocation) => Promise<DockerRunResult | void>;
|
|
24
27
|
export declare const createDetachedContainerInspectArgs: (invocation: DockerRunInvocation, containerId: string) => string[];
|
|
25
|
-
export declare const parseDetachedContainerInspect: (stdout: string, expectedContainerId: string, expectedLabels?: Readonly<Record<string, string
|
|
28
|
+
export declare const parseDetachedContainerInspect: (stdout: string, expectedContainerId: string, expectedLabels?: Readonly<Record<string, string>>, expectedContainerName?: string | null) => DockerRunResult;
|
|
29
|
+
export declare const inspectDetachedContainer: (invocation: DockerRunInvocation, containerId: string) => Promise<DockerRunResult>;
|
|
26
30
|
export declare const runDockerContainer: DockerRunRunner;
|
|
@@ -2,6 +2,8 @@ import { execFile as execFileCallback, spawn } from "node:child_process";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
4
|
import { SpawnfileError } from "../shared/index.js";
|
|
5
|
+
import { assertOpaqueDaimonCredentialsHaveNoUserNamespace, pinOpaqueDaimonDockerEndpoint } from "./runProjectDockerDaimonGuards.js";
|
|
6
|
+
import { withExclusiveVolumeReservations } from "./runProjectDockerReservation.js";
|
|
5
7
|
const execFile = promisify(execFileCallback);
|
|
6
8
|
const parseDockerContextHost = (stdout) => {
|
|
7
9
|
const trimmed = stdout.trim();
|
|
@@ -138,20 +140,22 @@ export const createDetachedContainerInspectArgs = (invocation, containerId) => {
|
|
|
138
140
|
: invocation.dockerHost
|
|
139
141
|
? ["--host", invocation.dockerHost, "inspect"]
|
|
140
142
|
: ["inspect"];
|
|
141
|
-
return [...base, "--format", "{{json .Id}}\n{{json .Image}}\n{{json .Config.Labels}}", containerId];
|
|
143
|
+
return [...base, "--format", "{{json .Id}}\n{{json .Name}}\n{{json .Image}}\n{{json .Config.Labels}}", containerId];
|
|
142
144
|
};
|
|
143
|
-
export const parseDetachedContainerInspect = (stdout, expectedContainerId, expectedLabels) => {
|
|
144
|
-
const [idRaw, imageRaw, labelsRaw, ...extra] = stdout.trim().split("\n");
|
|
145
|
-
if (!idRaw || !imageRaw || !labelsRaw || extra.length > 0)
|
|
145
|
+
export const parseDetachedContainerInspect = (stdout, expectedContainerId, expectedLabels, expectedContainerName) => {
|
|
146
|
+
const [idRaw, nameRaw, imageRaw, labelsRaw, ...extra] = stdout.trim().split("\n");
|
|
147
|
+
if (!idRaw || !nameRaw || !imageRaw || !labelsRaw || extra.length > 0)
|
|
146
148
|
throw new Error("unexpected inspect response");
|
|
147
149
|
const actualId = JSON.parse(idRaw);
|
|
150
|
+
const actualName = JSON.parse(nameRaw);
|
|
148
151
|
const imageId = JSON.parse(imageRaw);
|
|
149
152
|
const labels = JSON.parse(labelsRaw);
|
|
150
153
|
if (typeof actualId !== "string" || actualId !== expectedContainerId || !/^[a-f0-9]{64}$/u.test(actualId)
|
|
154
|
+
|| typeof actualName !== "string" || actualName !== `/${expectedContainerName ?? ""}`
|
|
151
155
|
|| typeof imageId !== "string" || !/^sha256:[a-f0-9]{64}$/u.test(imageId))
|
|
152
156
|
throw new Error("malformed detached container metadata");
|
|
153
157
|
if (!expectedLabels)
|
|
154
|
-
return { containerId: actualId, imageId };
|
|
158
|
+
return { containerId: actualId, containerName: actualName.slice(1), imageId };
|
|
155
159
|
if (!labels || typeof labels !== "object" || Array.isArray(labels))
|
|
156
160
|
throw new Error("missing detached deployment labels");
|
|
157
161
|
const actual = Object.fromEntries(Object.keys(expectedLabels).sort().map((key) => {
|
|
@@ -160,15 +164,15 @@ export const parseDetachedContainerInspect = (stdout, expectedContainerId, expec
|
|
|
160
164
|
throw new Error("detached deployment label drift");
|
|
161
165
|
return [key, value];
|
|
162
166
|
}));
|
|
163
|
-
return { containerId: actualId, imageId, deploymentLabels: actual };
|
|
167
|
+
return { containerId: actualId, containerName: actualName.slice(1), imageId, deploymentLabels: actual };
|
|
164
168
|
};
|
|
165
|
-
const inspectDetachedContainer = async (invocation, containerId) => {
|
|
169
|
+
export const inspectDetachedContainer = async (invocation, containerId) => {
|
|
166
170
|
try {
|
|
167
171
|
const { stdout } = await execFile(invocation.command, createDetachedContainerInspectArgs(invocation, containerId), {
|
|
168
172
|
cwd: invocation.cwd,
|
|
169
173
|
timeout: 10_000
|
|
170
174
|
});
|
|
171
|
-
return parseDetachedContainerInspect(stdout, containerId, invocation.deploymentLabels);
|
|
175
|
+
return parseDetachedContainerInspect(stdout, containerId, invocation.deploymentLabels, invocation.containerName);
|
|
172
176
|
}
|
|
173
177
|
catch (error) {
|
|
174
178
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -203,8 +207,11 @@ const runPreparedDockerContainer = (prepared) => new Promise((resolve, reject) =
|
|
|
203
207
|
settle(() => resolve(undefined));
|
|
204
208
|
return;
|
|
205
209
|
}
|
|
206
|
-
Promise.resolve(prepared.invocation
|
|
207
|
-
.then(() =>
|
|
210
|
+
Promise.resolve(inspectDetachedContainer(prepared.invocation, containerId))
|
|
211
|
+
.then(async (result) => {
|
|
212
|
+
await prepared.invocation.onDetachedStarted?.(result);
|
|
213
|
+
return result;
|
|
214
|
+
})
|
|
208
215
|
.then(resolve)
|
|
209
216
|
.catch(reject);
|
|
210
217
|
return;
|
|
@@ -214,12 +221,30 @@ const runPreparedDockerContainer = (prepared) => new Promise((resolve, reject) =
|
|
|
214
221
|
: `Docker run for ${prepared.invocation.imageTag} failed with exit code ${code ?? "unknown"}`));
|
|
215
222
|
});
|
|
216
223
|
});
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
224
|
+
const runDockerContainerPrepared = async (invocation) => {
|
|
225
|
+
const run = async () => {
|
|
226
|
+
if (!invocation.dockerContext || collectBindMountSources(invocation.args).length === 0) {
|
|
227
|
+
if (invocation.opaqueDaimonCredentials && !invocation.dockerEndpointPinned) {
|
|
228
|
+
await assertOpaqueDaimonCredentialsHaveNoUserNamespace(invocation);
|
|
229
|
+
return await runPreparedDockerContainer({
|
|
230
|
+
cleanup: async () => undefined,
|
|
231
|
+
invocation
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return await runPreparedDockerContainer({
|
|
235
|
+
cleanup: async () => undefined,
|
|
236
|
+
invocation
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return await runPreparedDockerContainer(await prepareRemoteBindMounts(invocation));
|
|
240
|
+
};
|
|
241
|
+
return withExclusiveVolumeReservations(invocation, run);
|
|
225
242
|
};
|
|
243
|
+
export const runDockerContainer = (invocation) => invocation.opaqueDaimonCredentials
|
|
244
|
+
? pinOpaqueDaimonDockerEndpoint(invocation)
|
|
245
|
+
.then(async (pinned) => {
|
|
246
|
+
await assertOpaqueDaimonCredentialsHaveNoUserNamespace(pinned);
|
|
247
|
+
return pinned;
|
|
248
|
+
})
|
|
249
|
+
.then((pinned) => runDockerContainerPrepared({ ...pinned, dockerEndpointPinned: true }))
|
|
250
|
+
: runDockerContainerPrepared(invocation);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface DaimonDockerGuardInvocation {
|
|
2
|
+
args: string[];
|
|
3
|
+
command: string;
|
|
4
|
+
cwd: string;
|
|
5
|
+
dockerContext?: string | null;
|
|
6
|
+
dockerHost?: string | null;
|
|
7
|
+
opaqueDaimonCredentials?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolves a possibly mutable Docker context once, validates that endpoint,
|
|
11
|
+
* then makes every remaining Docker operation use the immutable endpoint.
|
|
12
|
+
*/
|
|
13
|
+
export declare const pinOpaqueDaimonDockerEndpoint: <T extends DaimonDockerGuardInvocation>(invocation: T) => Promise<T>;
|
|
14
|
+
export declare const assertOpaqueDaimonCredentialsUseLocalDaemon: (invocation: DaimonDockerGuardInvocation) => Promise<void>;
|
|
15
|
+
export declare const assertOpaqueDaimonCredentialsHaveNoUserNamespace: (invocation: DaimonDockerGuardInvocation) => Promise<void>;
|