spawnfile 0.1.12 → 0.1.14
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 +58 -12
- package/dist/audit/auditCli.d.ts +19 -0
- package/dist/audit/auditCli.js +63 -0
- package/dist/audit/checks.d.ts +100 -0
- package/dist/audit/checks.js +279 -0
- package/dist/audit/checksShared.d.ts +74 -0
- package/dist/audit/checksShared.js +37 -0
- package/dist/audit/generateAudit.d.ts +19 -0
- package/dist/audit/generateAudit.js +122 -0
- package/dist/audit/index.d.ts +4 -0
- package/dist/audit/index.js +4 -0
- package/dist/audit/readAudit.d.ts +50 -0
- package/dist/audit/readAudit.js +59 -0
- package/dist/audit/types.d.ts +40 -0
- package/dist/audit/types.js +8 -0
- package/dist/auth/credentialEnvFile.d.ts +11 -0
- package/dist/auth/credentialEnvFile.js +60 -0
- package/dist/auth/credentialProvisioning.d.ts +15 -0
- package/dist/auth/credentialProvisioning.js +75 -0
- package/dist/auth/credentialProvisioningReceipt.d.ts +28 -0
- package/dist/auth/credentialProvisioningReceipt.js +70 -0
- package/dist/auth/credentialProvisioningRequest.d.ts +51 -0
- package/dist/auth/credentialProvisioningRequest.js +169 -0
- package/dist/auth/credentialWorldBindings.d.ts +21 -0
- package/dist/auth/credentialWorldBindings.js +104 -0
- package/dist/auth/index.d.ts +7 -0
- package/dist/auth/index.js +7 -0
- package/dist/auth/paths.d.ts +11 -0
- package/dist/auth/paths.js +21 -0
- package/dist/auth/runtimeCredentials.js +18 -2
- package/dist/auth/targetSecretSourceAuthor.d.ts +18 -0
- package/dist/auth/targetSecretSourceAuthor.js +52 -0
- package/dist/auth/targetSecretSourceFsPublish.d.ts +15 -0
- package/dist/auth/targetSecretSourceFsPublish.js +49 -0
- package/dist/auth/targetSecretSourceFsPublishImmutable.d.ts +16 -0
- package/dist/auth/targetSecretSourceFsPublishImmutable.js +435 -0
- package/dist/auth/targetSecretSourceFsRead.d.ts +14 -0
- package/dist/auth/targetSecretSourceFsRead.js +198 -0
- package/dist/auth/targetSecretSourceGrant.d.ts +16 -0
- package/dist/auth/targetSecretSourceGrant.js +99 -0
- package/dist/auth/targetSecretSourceGrantRecords.d.ts +84 -0
- package/dist/auth/targetSecretSourceGrantRecords.js +214 -0
- package/dist/auth/targetSecretSourceLifecycle.d.ts +30 -0
- package/dist/auth/targetSecretSourceLifecycle.js +52 -0
- package/dist/auth/targetSecretSourceOwnerEntropy.d.ts +6 -0
- package/dist/auth/targetSecretSourceOwnerEntropy.js +28 -0
- package/dist/auth/targetSecretSourceRecordCommon.d.ts +14 -0
- package/dist/auth/targetSecretSourceRecordCommon.js +100 -0
- package/dist/auth/targetSecretSourceRecordPublish.d.ts +10 -0
- package/dist/auth/targetSecretSourceRecordPublish.js +104 -0
- package/dist/auth/targetSecretSourceResolver.d.ts +10 -0
- package/dist/auth/targetSecretSourceResolver.js +137 -0
- package/dist/auth/targetSecretSourceRevoke.d.ts +20 -0
- package/dist/auth/targetSecretSourceRevoke.js +92 -0
- package/dist/auth/targetSecretSourceRotate.d.ts +19 -0
- package/dist/auth/targetSecretSourceRotate.js +121 -0
- package/dist/auth/targetSecretSourceVersionRecords.d.ts +49 -0
- package/dist/auth/targetSecretSourceVersionRecords.js +166 -0
- package/dist/cli/artifactsCommands.d.ts +27 -0
- package/dist/cli/artifactsCommands.js +132 -0
- package/dist/cli/authCommands.d.ts +5 -0
- package/dist/cli/authCommands.js +221 -0
- package/dist/cli/compileBuildCommands.d.ts +3 -0
- package/dist/cli/compileBuildCommands.js +35 -0
- package/dist/cli/containerBundleCommand.d.ts +6 -0
- package/dist/cli/containerBundleCommand.js +116 -0
- package/dist/cli/devCommands.d.ts +3 -0
- package/dist/cli/devCommands.js +115 -0
- package/dist/cli/downCommand.d.ts +25 -0
- package/dist/cli/downCommand.js +134 -0
- package/dist/cli/index.js +6 -3
- package/dist/cli/lifecycleCommands.d.ts +1 -1
- package/dist/cli/lifecycleCommands.js +11 -179
- package/dist/cli/lifecycleMachine.d.ts +19 -0
- package/dist/cli/lifecycleMachine.js +78 -0
- package/dist/cli/lifecyclePlan.d.ts +35 -0
- package/dist/cli/lifecyclePlan.js +240 -0
- package/dist/cli/lifecyclePlanningCommands.d.ts +3 -0
- package/dist/cli/lifecyclePlanningCommands.js +30 -0
- package/dist/cli/runCli.d.ts +15 -2
- package/dist/cli/runCli.js +31 -71
- package/dist/cli/runPublishCommands.d.ts +3 -0
- package/dist/cli/runPublishCommands.js +70 -0
- package/dist/cli/statusCommand.d.ts +3 -32
- package/dist/cli/statusCommand.js +37 -233
- package/dist/cli/statusCommandLive.d.ts +20 -0
- package/dist/cli/statusCommandLive.js +188 -0
- package/dist/cli/statusCommandOptions.d.ts +40 -0
- package/dist/cli/statusCommandOptions.js +42 -0
- package/dist/cli/targetCliRoute.d.ts +2 -0
- package/dist/cli/targetCliRoute.js +30 -0
- package/dist/cli/targetCommands.d.ts +33 -0
- package/dist/cli/targetCommands.js +257 -0
- package/dist/cli/targetComposedPreparationCommand.d.ts +6 -0
- package/dist/cli/targetComposedPreparationCommand.js +39 -0
- package/dist/cli/targetDefaultArtifactAuthority.d.ts +5 -0
- package/dist/cli/targetDefaultArtifactAuthority.js +28 -0
- package/dist/cli/targetDefaultAuthorities.d.ts +53 -0
- package/dist/cli/targetDefaultAuthorities.js +210 -0
- package/dist/cli/targetDefaultConfig.d.ts +68 -0
- package/dist/cli/targetDefaultConfig.js +317 -0
- package/dist/cli/targetDefaultConfigStdin.d.ts +13 -0
- package/dist/cli/targetDefaultConfigStdin.js +215 -0
- package/dist/cli/targetDefaultEnvelope.d.ts +1 -0
- package/dist/cli/targetDefaultEnvelope.js +13 -0
- package/dist/cli/targetDefaultHandlerFactory.d.ts +28 -0
- package/dist/cli/targetDefaultHandlerFactory.js +247 -0
- package/dist/cli/targetDefaultHandlers.d.ts +21 -0
- package/dist/cli/targetDefaultHandlers.js +72 -0
- package/dist/cli/targetDefaultJournalAuthority.d.ts +35 -0
- package/dist/cli/targetDefaultJournalAuthority.js +135 -0
- package/dist/cli/targetDefaultWorldClock.d.ts +4 -0
- package/dist/cli/targetDefaultWorldClock.js +14 -0
- package/dist/cli/targetDefaultWorldQueries.d.ts +5 -0
- package/dist/cli/targetDefaultWorldQueries.js +11 -0
- package/dist/cli/targetDefaultWorldReadiness.d.ts +4 -0
- package/dist/cli/targetDefaultWorldReadiness.js +17 -0
- package/dist/cli/targetEvidenceHelperResolution.d.ts +14 -0
- package/dist/cli/targetEvidenceHelperResolution.js +23 -0
- package/dist/cli/targetLookupCli.d.ts +3 -0
- package/dist/cli/targetLookupCli.js +31 -0
- package/dist/cli/targetLookupCommands.d.ts +12 -0
- package/dist/cli/targetLookupCommands.js +69 -0
- package/dist/cli/targetOperationDispatch.d.ts +58 -0
- package/dist/cli/targetOperationDispatch.js +21 -0
- package/dist/cli/targetReceiptOutput.d.ts +14 -0
- package/dist/cli/targetReceiptOutput.js +21 -0
- package/dist/cli/targetRequestFile.d.ts +14 -0
- package/dist/cli/targetRequestFile.js +63 -0
- package/dist/cli/targetSecretSourceInput.d.ts +28 -0
- package/dist/cli/targetSecretSourceInput.js +121 -0
- package/dist/cli/targetWorldClockCommand.d.ts +10 -0
- package/dist/cli/targetWorldClockCommand.js +42 -0
- package/dist/cli/targetWorldClockCrossProcess.test-helper.d.ts +13 -0
- package/dist/cli/targetWorldClockCrossProcess.test-helper.js +109 -0
- package/dist/cli/targetWorldReadinessCommand.d.ts +10 -0
- package/dist/cli/targetWorldReadinessCommand.js +43 -0
- package/dist/cli/upCommand.d.ts +3 -0
- package/dist/cli/upCommand.js +133 -0
- package/dist/cli/upImageCommand.d.ts +11 -0
- package/dist/cli/upImageCommand.js +41 -0
- package/dist/cli/upLifecycleInvocation.d.ts +41 -0
- package/dist/cli/upLifecycleInvocation.js +48 -0
- package/dist/cli/upLifecycleRecovery.d.ts +4 -0
- package/dist/cli/upLifecycleRecovery.js +53 -0
- package/dist/compiler/agentNodeMerge.d.ts +2 -0
- package/dist/compiler/agentNodeMerge.js +79 -0
- package/dist/compiler/agentSurfaces.js +11 -1
- package/dist/compiler/buildCompilePlan.js +17 -0
- package/dist/compiler/buildCompilePlanAgent.d.ts +11 -0
- package/dist/compiler/buildCompilePlanAgent.js +56 -0
- package/dist/compiler/buildCompilePlanTeams.d.ts +1 -0
- package/dist/compiler/buildCompilePlanTeams.js +4 -1
- package/dist/compiler/buildCompilePlanTraversal.js +75 -82
- package/dist/compiler/buildProject.d.ts +20 -1
- package/dist/compiler/buildProject.js +121 -7
- package/dist/compiler/compilePlanHelpers.js +2 -0
- package/dist/compiler/compileProject.d.ts +15 -0
- package/dist/compiler/compileProject.js +29 -75
- package/dist/compiler/compileProjectPolicy.d.ts +5 -0
- package/dist/compiler/compileProjectPolicy.js +21 -0
- package/dist/compiler/compileProjectReports.d.ts +9 -0
- package/dist/compiler/compileProjectReports.js +52 -0
- package/dist/compiler/containerArtifactSummaries.d.ts +7 -0
- package/dist/compiler/containerArtifactSummaries.js +138 -0
- package/dist/compiler/containerArtifacts.d.ts +10 -0
- package/dist/compiler/containerArtifacts.js +126 -125
- package/dist/compiler/containerArtifactsPlans.d.ts +5 -3
- package/dist/compiler/containerArtifactsPlans.js +31 -118
- package/dist/compiler/containerArtifactsRender.d.ts +3 -1
- package/dist/compiler/containerArtifactsRender.js +40 -81
- package/dist/compiler/containerArtifactsTypes.d.ts +12 -0
- package/dist/compiler/containerConfigEnvRender.d.ts +3 -0
- package/dist/compiler/containerConfigEnvRender.js +54 -0
- package/dist/compiler/containerEntrypointRender.d.ts +1 -0
- package/dist/compiler/containerEntrypointRender.js +60 -53
- package/dist/compiler/containerEntrypointShell.d.ts +5 -0
- package/dist/compiler/containerEntrypointShell.js +29 -0
- package/dist/compiler/containerPackageOverrides.d.ts +27 -0
- package/dist/compiler/containerPackageOverrides.js +63 -0
- package/dist/compiler/containerPackageRender.d.ts +15 -0
- package/dist/compiler/containerPackageRender.js +63 -0
- package/dist/compiler/containerTargetPlanResolution.d.ts +20 -0
- package/dist/compiler/containerTargetPlanResolution.js +97 -0
- package/dist/compiler/containerTargetResources.js +3 -1
- package/dist/compiler/daimonTelemetryArtifacts.d.ts +22 -0
- package/dist/compiler/daimonTelemetryArtifacts.js +61 -0
- package/dist/compiler/dockerBuildContext.d.ts +16 -0
- package/dist/compiler/dockerBuildContext.js +159 -0
- package/dist/compiler/dockerBuildSkip.d.ts +30 -0
- package/dist/compiler/dockerBuildSkip.js +81 -0
- package/dist/compiler/index.d.ts +4 -0
- package/dist/compiler/index.js +4 -0
- package/dist/compiler/memoryArtifacts.d.ts +26 -0
- package/dist/compiler/memoryArtifacts.js +134 -0
- package/dist/compiler/memoryResolution.d.ts +4 -0
- package/dist/compiler/memoryResolution.js +147 -0
- package/dist/compiler/modelEnv.d.ts +2 -0
- package/dist/compiler/modelEnv.js +6 -0
- package/dist/compiler/moltnetAllowedWakeSendersValidation.d.ts +2 -0
- package/dist/compiler/moltnetAllowedWakeSendersValidation.js +42 -0
- package/dist/compiler/moltnetArtifactPaths.d.ts +26 -0
- package/dist/compiler/moltnetArtifactPaths.js +49 -0
- package/dist/compiler/moltnetArtifactTypes.d.ts +46 -0
- package/dist/compiler/moltnetArtifactTypes.js +1 -0
- package/dist/compiler/moltnetArtifacts.d.ts +2 -40
- package/dist/compiler/moltnetArtifacts.js +56 -95
- package/dist/compiler/moltnetBinaries.d.ts +21 -1
- package/dist/compiler/moltnetBinaries.js +156 -28
- package/dist/compiler/moltnetClientConfig.js +18 -2
- package/dist/compiler/moltnetConfigLowering.d.ts +16 -1
- package/dist/compiler/moltnetConfigLowering.js +67 -5
- package/dist/compiler/moltnetExternalParticipantArtifact.d.ts +38 -0
- package/dist/compiler/moltnetExternalParticipantArtifact.js +188 -0
- package/dist/compiler/moltnetNodeConfig.js +7 -2
- package/dist/compiler/moltnetReleaseAuthority.d.ts +17 -0
- package/dist/compiler/moltnetReleaseAuthority.js +73 -0
- package/dist/compiler/moltnetReleaseDownload.d.ts +12 -0
- package/dist/compiler/moltnetReleaseDownload.js +85 -0
- package/dist/compiler/moltnetRepresentativeResolution.d.ts +1 -0
- package/dist/compiler/moltnetRepresentativeResolution.js +16 -2
- package/dist/compiler/moltnetResolution.js +72 -20
- package/dist/compiler/moltnetRoomMemberships.js +37 -9
- package/dist/compiler/moltnetRuntimeConfig.js +11 -0
- package/dist/compiler/moltnetServerPlans.d.ts +9 -0
- package/dist/compiler/moltnetServerPlans.js +132 -0
- package/dist/compiler/organizationIdentity.d.ts +27 -0
- package/dist/compiler/organizationIdentity.js +297 -0
- package/dist/compiler/organizationReadyEvidence.d.ts +49 -0
- package/dist/compiler/organizationReadyEvidence.js +261 -0
- package/dist/compiler/projectManifestGraph.d.ts +4 -0
- package/dist/compiler/projectManifestGraph.js +24 -0
- package/dist/compiler/runProject.d.ts +4 -0
- package/dist/compiler/runProject.js +37 -22
- package/dist/compiler/runProjectAuth.d.ts +7 -1
- package/dist/compiler/runProjectAuth.js +87 -9
- package/dist/compiler/runProjectDocker.d.ts +7 -0
- package/dist/compiler/runProjectDocker.js +187 -19
- package/dist/compiler/runProjectLifecycle.d.ts +7 -0
- package/dist/compiler/runProjectLifecycle.js +40 -0
- package/dist/compiler/syncProjectAuth.js +4 -1
- package/dist/compiler/teamContextActiveEnvironments.d.ts +13 -0
- package/dist/compiler/teamContextActiveEnvironments.js +255 -0
- package/dist/compiler/teamContextSupport.js +32 -40
- package/dist/compiler/teamContextTypes.d.ts +2 -0
- package/dist/compiler/types.d.ts +82 -1
- package/dist/compiler/upProject.d.ts +5 -0
- package/dist/compiler/upProject.js +257 -20
- package/dist/compiler/upReceipt.d.ts +36 -0
- package/dist/compiler/upReceipt.js +82 -0
- package/dist/compiler/updateProjectModels.js +42 -60
- package/dist/compiler/updateProjectRuntime.js +22 -35
- package/dist/compiler/updateProjectSurfaces.js +53 -47
- package/dist/compiler/worldBindings.d.ts +39 -0
- package/dist/compiler/worldBindings.js +247 -0
- package/dist/compiler/worldBindingsFile.d.ts +5 -0
- package/dist/compiler/worldBindingsFile.js +162 -0
- package/dist/deployment/artifactsExport.d.ts +49 -0
- package/dist/deployment/artifactsExport.js +217 -0
- package/dist/deployment/artifactsExportDocker.d.ts +48 -0
- package/dist/deployment/artifactsExportDocker.js +91 -0
- package/dist/deployment/artifactsExportPlan.d.ts +24 -0
- package/dist/deployment/artifactsExportPlan.js +135 -0
- package/dist/deployment/artifactsExportTypes.d.ts +50 -0
- package/dist/deployment/artifactsExportTypes.js +52 -0
- package/dist/deployment/buildImageCacheStore.d.ts +23 -0
- package/dist/deployment/buildImageCacheStore.js +54 -0
- package/dist/deployment/deploymentLifecycleCorrelation.d.ts +11 -0
- package/dist/deployment/deploymentLifecycleCorrelation.js +33 -0
- package/dist/deployment/dockerInspect.d.ts +9 -0
- package/dist/deployment/dockerInspect.js +24 -1
- package/dist/deployment/dockerLabels.d.ts +2 -0
- package/dist/deployment/dockerLabels.js +2 -0
- package/dist/deployment/dockerLogs.js +2 -10
- package/dist/deployment/dockerManager.d.ts +51 -0
- package/dist/deployment/dockerManager.js +118 -1
- package/dist/deployment/dockerProbeGateway.js +64 -5
- package/dist/deployment/dockerRecover.d.ts +17 -0
- package/dist/deployment/dockerRecover.js +137 -0
- package/dist/deployment/dockerTeardown.d.ts +32 -0
- package/dist/deployment/dockerTeardown.js +61 -0
- package/dist/deployment/downDeployment.d.ts +34 -0
- package/dist/deployment/downDeployment.js +147 -0
- package/dist/deployment/downReceiptTypes.d.ts +21 -0
- package/dist/deployment/downReceiptTypes.js +30 -0
- package/dist/deployment/index.d.ts +17 -0
- package/dist/deployment/index.js +18 -0
- package/dist/deployment/lifecycleCompletion.d.ts +37 -0
- package/dist/deployment/lifecycleCompletion.js +236 -0
- package/dist/deployment/lifecycleCompletionContracts.d.ts +158 -0
- package/dist/deployment/lifecycleCompletionContracts.js +106 -0
- package/dist/deployment/lifecycleCompletionHeartbeat.d.ts +2 -0
- package/dist/deployment/lifecycleCompletionHeartbeat.js +50 -0
- package/dist/deployment/lifecycleCompletionLookup.d.ts +18 -0
- package/dist/deployment/lifecycleCompletionLookup.js +88 -0
- package/dist/deployment/lifecycleCompletionOwner.d.ts +8 -0
- package/dist/deployment/lifecycleCompletionOwner.js +31 -0
- package/dist/deployment/lifecycleCompletionParsing.d.ts +12 -0
- package/dist/deployment/lifecycleCompletionParsing.js +108 -0
- package/dist/deployment/lifecycleCompletionPaths.d.ts +9 -0
- package/dist/deployment/lifecycleCompletionPaths.js +16 -0
- package/dist/deployment/lifecycleCompletionPublication.d.ts +5 -0
- package/dist/deployment/lifecycleCompletionPublication.js +35 -0
- package/dist/deployment/lifecycleCompletionRecovery.d.ts +21 -0
- package/dist/deployment/lifecycleCompletionRecovery.js +56 -0
- package/dist/deployment/lifecycleCompletionRoot.d.ts +21 -0
- package/dist/deployment/lifecycleCompletionRoot.js +243 -0
- package/dist/deployment/lifecycleCompletionStore.d.ts +6 -0
- package/dist/deployment/lifecycleCompletionStore.js +151 -0
- package/dist/deployment/organizationHandoffAuthorityFsClient.d.ts +17 -0
- package/dist/deployment/organizationHandoffAuthorityFsClient.js +132 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorker.d.ts +1 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorker.js +285 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorkerParent.fixture.d.ts +1 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorkerParent.fixture.js +26 -0
- package/dist/deployment/organizationHandoffAuthorityStore.d.ts +41 -0
- package/dist/deployment/organizationHandoffAuthorityStore.js +348 -0
- package/dist/deployment/organizationHandoffAuthorityTypes.d.ts +76 -0
- package/dist/deployment/organizationHandoffAuthorityTypes.js +148 -0
- package/dist/deployment/organizationHandoffTypes.d.ts +29 -0
- package/dist/deployment/organizationHandoffTypes.js +80 -0
- package/dist/deployment/organizationReady.d.ts +52 -0
- package/dist/deployment/organizationReady.js +200 -0
- package/dist/deployment/privateArtifactsExport.d.ts +18 -0
- package/dist/deployment/privateArtifactsExport.js +80 -0
- package/dist/deployment/providerRuntimeBoundaryScanner.test-helper.d.ts +8 -0
- package/dist/deployment/providerRuntimeBoundaryScanner.test-helper.js +60 -0
- package/dist/deployment/record.d.ts +26 -1
- package/dist/deployment/record.js +49 -4
- package/dist/deployment/simfileFixtureBoundary.test-helper.d.ts +8 -0
- package/dist/deployment/simfileFixtureBoundary.test-helper.js +103 -0
- package/dist/deployment/target.d.ts +1 -35
- package/dist/deployment/target.js +1 -96
- package/dist/deployment/upReceiptTypes.d.ts +111 -0
- package/dist/deployment/upReceiptTypes.js +164 -0
- package/dist/dev/activity.d.ts +14 -0
- package/dist/dev/activity.js +48 -0
- package/dist/dev/docker.d.ts +16 -0
- package/dist/dev/docker.js +71 -0
- package/dist/dev/index.d.ts +2 -0
- package/dist/dev/index.js +2 -0
- package/dist/dev/project.d.ts +35 -0
- package/dist/dev/project.js +170 -0
- package/dist/distribution/buildDistributionReport.d.ts +2 -1
- package/dist/distribution/buildDistributionReport.js +2 -1
- package/dist/distribution/distributionReportSchema.d.ts +5 -0
- package/dist/distribution/distributionReportSchema.js +7 -2
- package/dist/distribution/index.d.ts +2 -2
- package/dist/distribution/index.js +1 -1
- package/dist/distribution/types.d.ts +7 -0
- package/dist/distribution/types.js +1 -0
- package/dist/filesystem/paths.js +10 -1
- package/dist/ledger/causalConformanceCli.d.ts +1 -0
- package/dist/ledger/causalConformanceCli.js +41 -0
- package/dist/ledger/causeNamespace.d.ts +8 -0
- package/dist/ledger/causeNamespace.js +24 -0
- package/dist/ledger/conformance.d.ts +83 -0
- package/dist/ledger/conformance.js +259 -0
- package/dist/ledger/emitters.d.ts +76 -0
- package/dist/ledger/emitters.js +188 -0
- package/dist/ledger/index.d.ts +4 -0
- package/dist/ledger/index.js +4 -0
- package/dist/ledger/principal.d.ts +96 -0
- package/dist/ledger/principal.js +121 -0
- package/dist/manifest/externalParticipantSchemas.d.ts +18 -0
- package/dist/manifest/externalParticipantSchemas.js +17 -0
- package/dist/manifest/index.d.ts +1 -0
- package/dist/manifest/index.js +1 -0
- package/dist/manifest/inlineAgentMember.d.ts +2 -0
- package/dist/manifest/inlineAgentMember.js +9 -0
- package/dist/manifest/loadManifest.js +14 -8
- package/dist/manifest/mcpSchemas.d.ts +17 -0
- package/dist/manifest/mcpSchemas.js +41 -0
- package/dist/manifest/memorySchemas.d.ts +245 -0
- package/dist/manifest/memorySchemas.js +148 -0
- package/dist/manifest/renderSpawnfile.js +22 -131
- package/dist/manifest/renderSpawnfileNetworks.js +9 -2
- package/dist/manifest/renderSpawnfileSurfaces.d.ts +2 -0
- package/dist/manifest/renderSpawnfileSurfaces.js +134 -0
- package/dist/manifest/schemas.d.ts +1868 -99
- package/dist/manifest/schemas.js +78 -32
- package/dist/manifest/surfaceSchemas.d.ts +17 -0
- package/dist/manifest/surfaceSchemas.js +24 -1
- package/dist/manifest/teamNetworkAccessSchemas.d.ts +1 -1
- package/dist/manifest/teamNetworkAuthSchemas.d.ts +48 -0
- package/dist/manifest/teamNetworkAuthSchemas.js +103 -0
- package/dist/manifest/teamNetworkSchemas.d.ts +8 -187
- package/dist/manifest/teamNetworkSchemas.js +3 -317
- package/dist/manifest/teamNetworkServerSchemas.d.ts +150 -0
- package/dist/manifest/teamNetworkServerSchemas.js +199 -0
- package/dist/ownership/siblingBuildFreshness.d.ts +20 -0
- package/dist/ownership/siblingBuildFreshness.js +20 -0
- package/dist/ownership/simfileRunOperatorInputs.d.ts +103 -0
- package/dist/ownership/simfileRunOperatorInputs.js +139 -0
- package/dist/report/types.d.ts +142 -0
- package/dist/runtime/common.d.ts +37 -0
- package/dist/runtime/common.js +56 -1
- package/dist/runtime/container.d.ts +29 -1
- package/dist/runtime/container.js +127 -11
- package/dist/runtime/containerPackageOverrides.d.ts +37 -0
- package/dist/runtime/containerPackageOverrides.js +33 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/install.d.ts +1 -1
- package/dist/runtime/install.js +43 -1
- package/dist/runtime/mnemeMcp.d.ts +15 -0
- package/dist/runtime/mnemeMcp.js +109 -0
- package/dist/runtime/openclaw/adapter.js +15 -4
- package/dist/runtime/openclaw/mcp.d.ts +10 -0
- package/dist/runtime/openclaw/mcp.js +69 -0
- package/dist/runtime/openclaw/runAuth.js +2 -2
- package/dist/runtime/openclaw/scaffold.js +1 -1
- package/dist/runtime/openclaw/schedules.d.ts +38 -0
- package/dist/runtime/openclaw/schedules.js +74 -0
- package/dist/runtime/pi/adapter.d.ts +4 -0
- package/dist/runtime/pi/adapter.js +231 -0
- package/dist/runtime/pi/appActivitySource.d.ts +1 -0
- package/dist/runtime/pi/appActivitySource.js +199 -0
- package/dist/runtime/pi/appAgentConfig.d.ts +11 -0
- package/dist/runtime/pi/appAgentConfig.js +264 -0
- package/dist/runtime/pi/appCliEnginesSource.d.ts +1 -0
- package/dist/runtime/pi/appCliEnginesSource.js +183 -0
- package/dist/runtime/pi/appCliSource.d.ts +1 -0
- package/dist/runtime/pi/appCliSource.js +353 -0
- package/dist/runtime/pi/appControlSource.d.ts +1 -0
- package/dist/runtime/pi/appControlSource.js +390 -0
- package/dist/runtime/pi/appControlWakeIdentitySource.d.ts +1 -0
- package/dist/runtime/pi/appControlWakeIdentitySource.js +19 -0
- package/dist/runtime/pi/appCoreSource.d.ts +4 -0
- package/dist/runtime/pi/appCoreSource.js +244 -0
- package/dist/runtime/pi/appPreludeSource.d.ts +1 -0
- package/dist/runtime/pi/appPreludeSource.js +191 -0
- package/dist/runtime/pi/appScheduleSource.d.ts +1 -0
- package/dist/runtime/pi/appScheduleSource.js +80 -0
- package/dist/runtime/pi/appScriptedEngine.d.ts +31 -0
- package/dist/runtime/pi/appScriptedEngine.js +42 -0
- package/dist/runtime/pi/appSource.d.ts +4 -0
- package/dist/runtime/pi/appSource.js +12 -0
- package/dist/runtime/pi/appTemplate.d.ts +14 -0
- package/dist/runtime/pi/appTemplate.js +27 -0
- package/dist/runtime/pi/appTemplateTypes.d.ts +64 -0
- package/dist/runtime/pi/appTemplateTypes.js +18 -0
- package/dist/runtime/pi/appWakeContextSource.d.ts +1 -0
- package/dist/runtime/pi/appWakeContextSource.js +398 -0
- package/dist/runtime/pi/containerTargets.d.ts +4 -0
- package/dist/runtime/pi/containerTargets.js +57 -0
- package/dist/runtime/pi/runAuth.d.ts +2 -0
- package/dist/runtime/pi/runAuth.js +185 -0
- package/dist/runtime/pi/testHelpers.d.ts +2 -0
- package/dist/runtime/pi/testHelpers.js +40 -0
- package/dist/runtime/picoclaw/adapter.js +23 -27
- package/dist/runtime/picoclaw/mcp.d.ts +4 -0
- package/dist/runtime/picoclaw/mcp.js +43 -0
- package/dist/runtime/picoclaw/memory.d.ts +7 -0
- package/dist/runtime/picoclaw/memory.js +17 -0
- package/dist/runtime/picoclaw/runAuth.js +1 -1
- package/dist/runtime/picoclaw/scaffold.js +1 -1
- package/dist/runtime/picoclaw/schedules.d.ts +26 -0
- package/dist/runtime/picoclaw/schedules.js +62 -3
- package/dist/runtime/registry.js +3 -0
- package/dist/runtime/scheduleUtils.d.ts +2 -0
- package/dist/runtime/scheduleUtils.js +15 -0
- package/dist/runtime/types.d.ts +26 -2
- package/dist/shared/errors.d.ts +1 -1
- package/dist/shared/errors.js +2 -2
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/shared/redaction.d.ts +2 -0
- package/dist/shared/redaction.js +10 -0
- package/dist/status/buildStatus.d.ts +1 -0
- package/dist/status/buildStatus.js +2 -0
- package/dist/status/compileReport.d.ts +22 -0
- package/dist/status/compileReport.js +16 -2
- package/dist/status/compiledProbeCollection.d.ts +21 -0
- package/dist/status/compiledProbeCollection.js +27 -0
- package/dist/status/deployments.js +5 -12
- package/dist/status/imageStatusReport.js +6 -0
- package/dist/status/index.d.ts +3 -0
- package/dist/status/index.js +3 -0
- package/dist/status/lifecycleProbes.d.ts +19 -0
- package/dist/status/lifecycleProbes.js +174 -0
- package/dist/status/moltnetProbes.d.ts +7 -8
- package/dist/status/moltnetProbes.js +27 -198
- package/dist/status/moltnetWiringProbes.d.ts +19 -0
- package/dist/status/moltnetWiringProbes.js +178 -0
- package/dist/target/cleanupRun.d.ts +41 -0
- package/dist/target/cleanupRun.js +139 -0
- package/dist/target/cleanupRunDocker.d.ts +16 -0
- package/dist/target/cleanupRunDocker.js +66 -0
- package/dist/target/cleanupRunDocker.test-helper.d.ts +67 -0
- package/dist/target/cleanupRunDocker.test-helper.js +238 -0
- package/dist/target/cleanupRunDockerPreflight.d.ts +17 -0
- package/dist/target/cleanupRunDockerPreflight.js +224 -0
- package/dist/target/composedPreparation.d.ts +205 -0
- package/dist/target/composedPreparation.js +223 -0
- package/dist/target/containerBundle.d.ts +82 -0
- package/dist/target/containerBundle.js +243 -0
- package/dist/target/containerBundleArchive.d.ts +31 -0
- package/dist/target/containerBundleArchive.js +140 -0
- package/dist/target/containerBundleAuthority.d.ts +25 -0
- package/dist/target/containerBundleAuthority.js +65 -0
- package/dist/target/containerBundleContracts.d.ts +114 -0
- package/dist/target/containerBundleContracts.js +173 -0
- package/dist/target/containerBundleFilesystemStore.d.ts +3 -0
- package/dist/target/containerBundleFilesystemStore.js +247 -0
- package/dist/target/containerBundlePolicy.d.ts +33 -0
- package/dist/target/containerBundlePolicy.js +64 -0
- package/dist/target/containerBundleStore.d.ts +127 -0
- package/dist/target/containerBundleStore.js +284 -0
- package/dist/target/contracts.d.ts +538 -0
- package/dist/target/contracts.js +373 -0
- package/dist/target/dockerArtifactIdentityTypes.d.ts +56 -0
- package/dist/target/dockerArtifactIdentityTypes.js +1 -0
- package/dist/target/dockerArtifactInspection.d.ts +40 -0
- package/dist/target/dockerArtifactInspection.js +125 -0
- package/dist/target/dockerArtifacts.d.ts +21 -0
- package/dist/target/dockerArtifacts.js +110 -0
- package/dist/target/dockerArtifactsProvider.d.ts +41 -0
- package/dist/target/dockerArtifactsProvider.js +449 -0
- package/dist/target/dockerCommandExecutor.d.ts +27 -0
- package/dist/target/dockerCommandExecutor.js +200 -0
- package/dist/target/dockerCommandExecutorCore.d.ts +34 -0
- package/dist/target/dockerCommandExecutorCore.js +273 -0
- package/dist/target/dockerContainerBundleBuilder.d.ts +8 -0
- package/dist/target/dockerContainerBundleBuilder.js +256 -0
- package/dist/target/dockerContextSnapshot.d.ts +21 -0
- package/dist/target/dockerContextSnapshot.js +158 -0
- package/dist/target/dockerEndpointFingerprint.d.ts +1 -0
- package/dist/target/dockerEndpointFingerprint.js +9 -0
- package/dist/target/dockerPreparedArtifact.d.ts +48 -0
- package/dist/target/dockerPreparedArtifact.js +131 -0
- package/dist/target/dockerProjectionJson.d.ts +1 -0
- package/dist/target/dockerProjectionJson.js +80 -0
- package/dist/target/dockerPublicArtifactSnapshot.d.ts +17 -0
- package/dist/target/dockerPublicArtifactSnapshot.js +99 -0
- package/dist/target/dockerResources.d.ts +26 -0
- package/dist/target/dockerResources.js +162 -0
- package/dist/target/dockerResourcesProvider.d.ts +44 -0
- package/dist/target/dockerResourcesProvider.js +207 -0
- package/dist/target/dockerSecrets.d.ts +39 -0
- package/dist/target/dockerSecrets.js +249 -0
- package/dist/target/dockerSecretsAuthority.d.ts +26 -0
- package/dist/target/dockerSecretsAuthority.js +216 -0
- package/dist/target/dockerSecretsLifecycle.d.ts +25 -0
- package/dist/target/dockerSecretsLifecycle.js +133 -0
- package/dist/target/dockerSecretsProvider.d.ts +68 -0
- package/dist/target/dockerSecretsProvider.js +329 -0
- package/dist/target/dockerTarget.d.ts +52 -0
- package/dist/target/dockerTarget.js +48 -0
- package/dist/target/dockerTargetBinding.d.ts +14 -0
- package/dist/target/dockerTargetBinding.js +96 -0
- package/dist/target/dockerWorldClock.d.ts +17 -0
- package/dist/target/dockerWorldClock.js +111 -0
- package/dist/target/dockerWorldReadiness.d.ts +17 -0
- package/dist/target/dockerWorldReadiness.js +119 -0
- package/dist/target/dockerWorldService.d.ts +23 -0
- package/dist/target/dockerWorldService.js +216 -0
- package/dist/target/dockerWorldServiceAuthority.d.ts +80 -0
- package/dist/target/dockerWorldServiceAuthority.js +182 -0
- package/dist/target/dockerWorldServiceLifecycle.d.ts +41 -0
- package/dist/target/dockerWorldServiceLifecycle.js +275 -0
- package/dist/target/dockerWorldServiceProvider.d.ts +60 -0
- package/dist/target/dockerWorldServiceProvider.js +318 -0
- package/dist/target/dockerWorldServiceStore.d.ts +73 -0
- package/dist/target/dockerWorldServiceStore.js +367 -0
- package/dist/target/evidenceExport.d.ts +55 -0
- package/dist/target/evidenceExport.js +518 -0
- package/dist/target/evidenceExportArchive.d.ts +10 -0
- package/dist/target/evidenceExportArchive.js +302 -0
- package/dist/target/evidenceExportContract.d.ts +27 -0
- package/dist/target/evidenceExportContract.js +40 -0
- package/dist/target/evidenceExportOperationsTestKit.d.ts +87 -0
- package/dist/target/evidenceExportOperationsTestKit.js +312 -0
- package/dist/target/evidenceExportProvider.d.ts +85 -0
- package/dist/target/evidenceExportProvider.js +187 -0
- package/dist/target/evidenceExportPublicationTypes.d.ts +16 -0
- package/dist/target/evidenceExportPublicationTypes.js +1 -0
- package/dist/target/evidenceExportStore.d.ts +70 -0
- package/dist/target/evidenceExportStore.js +498 -0
- package/dist/target/evidenceExportStorePublication.d.ts +7 -0
- package/dist/target/evidenceExportStorePublication.js +395 -0
- package/dist/target/handles.d.ts +20 -0
- package/dist/target/handles.js +56 -0
- package/dist/target/index.d.ts +12 -0
- package/dist/target/index.js +11 -0
- package/dist/target/journal.d.ts +59 -0
- package/dist/target/journal.js +529 -0
- package/dist/target/journalFilesystem.d.ts +3 -0
- package/dist/target/journalFilesystem.js +111 -0
- package/dist/target/journalRoot.d.ts +4 -0
- package/dist/target/journalRoot.js +6 -0
- package/dist/target/organizationAttachment.d.ts +23 -0
- package/dist/target/organizationAttachment.js +263 -0
- package/dist/target/organizationAttachmentAuthority.d.ts +65 -0
- package/dist/target/organizationAttachmentAuthority.js +161 -0
- package/dist/target/organizationAttachmentLifecycle.d.ts +17 -0
- package/dist/target/organizationAttachmentLifecycle.js +101 -0
- package/dist/target/organizationAttachmentProvider.d.ts +76 -0
- package/dist/target/organizationAttachmentProvider.js +289 -0
- package/dist/target/organizationAttachmentStore.d.ts +51 -0
- package/dist/target/organizationAttachmentStore.js +316 -0
- package/dist/target/publicArtifactSnapshot.d.ts +41 -0
- package/dist/target/publicArtifactSnapshot.js +150 -0
- package/dist/target/topologyActivation.d.ts +51 -0
- package/dist/target/topologyActivation.js +149 -0
- package/dist/target/topologyAttestation.d.ts +37 -0
- package/dist/target/topologyAttestation.js +300 -0
- package/dist/target/topologyAttestationErrors.d.ts +1 -0
- package/dist/target/topologyAttestationErrors.js +1 -0
- package/dist/target/worldClock.d.ts +60 -0
- package/dist/target/worldClock.js +129 -0
- package/dist/target/worldReadiness.d.ts +103 -0
- package/dist/target/worldReadiness.js +153 -0
- package/moltnet-releases.json +20 -0
- package/package.json +29 -8
- package/runtimes.yaml +28 -27
- package/dist/runtime/openclaw/scaffold-assets/CLAUDE.md +0 -5
- package/dist/runtime/picoclaw/scaffold-assets/CLAUDE.md +0 -5
- /package/dist/runtime/openclaw/scaffold-assets/{AGENTS.md → WORKSPACE_AGENTS.md} +0 -0
- /package/dist/runtime/picoclaw/scaffold-assets/{AGENTS.md → WORKSPACE_AGENTS.md} +0 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { types as nodeTypes } from "node:util";
|
|
3
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
4
|
+
import { MAX_ORGANIZATION_AGENT_MEMBERS, MAX_ORGANIZATION_MEMBER_ID_BYTES, ORGANIZATION_MEMBER_ID_PATTERN_SOURCE, resolveCanonicalAgentMemberId } from "./organizationIdentity.js";
|
|
5
|
+
export const SIMFILE_WORLD_BINDINGS_VERSION = "simfile.world-bindings.v1";
|
|
6
|
+
export const WORLD_BINDINGS_OUTPUT_FILE = "world-bindings.json";
|
|
7
|
+
const MEMBER_ID = new RegExp(ORGANIZATION_MEMBER_ID_PATTERN_SOURCE, "u");
|
|
8
|
+
const BINDING_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
9
|
+
const DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
10
|
+
const ENV_NAME = /^[A-Z_][A-Z0-9_]{0,127}$/u;
|
|
11
|
+
const MAX_ENDPOINT_BYTES = 2_048;
|
|
12
|
+
const MAX_HOSTILE_DEPTH = 16;
|
|
13
|
+
const MAX_HOSTILE_NODES = 2_048;
|
|
14
|
+
const fail = (message) => {
|
|
15
|
+
throw new SpawnfileError("validation_error", `invalid ${SIMFILE_WORLD_BINDINGS_VERSION}: ${message}`);
|
|
16
|
+
};
|
|
17
|
+
const compareAscii = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
18
|
+
const rejectUnsafeGraph = (value, state = { nodes: 0, seen: new WeakSet() }, depth = 0) => {
|
|
19
|
+
if (value === null || typeof value !== "object")
|
|
20
|
+
return;
|
|
21
|
+
if (nodeTypes.isProxy(value))
|
|
22
|
+
fail("proxy values are not allowed");
|
|
23
|
+
if (depth > MAX_HOSTILE_DEPTH)
|
|
24
|
+
fail(`object depth exceeds ${MAX_HOSTILE_DEPTH}`);
|
|
25
|
+
state.nodes += 1;
|
|
26
|
+
if (state.nodes > MAX_HOSTILE_NODES)
|
|
27
|
+
fail(`object node count exceeds ${MAX_HOSTILE_NODES}`);
|
|
28
|
+
if (state.seen.has(value))
|
|
29
|
+
fail("aliases and cycles are not allowed");
|
|
30
|
+
state.seen.add(value);
|
|
31
|
+
if (Array.isArray(value)) {
|
|
32
|
+
if (Object.getPrototypeOf(value) !== Array.prototype)
|
|
33
|
+
fail("array prototype is not canonical");
|
|
34
|
+
const length = Object.getOwnPropertyDescriptor(value, "length");
|
|
35
|
+
if (!length || !("value" in length) || !Number.isSafeInteger(length.value)) {
|
|
36
|
+
return fail("array length is unsafe");
|
|
37
|
+
}
|
|
38
|
+
const count = length.value;
|
|
39
|
+
if (count > MAX_ORGANIZATION_AGENT_MEMBERS)
|
|
40
|
+
fail("binding cardinality exceeds organization limit");
|
|
41
|
+
const keys = Reflect.ownKeys(value);
|
|
42
|
+
if (keys.length !== count + 1 || keys.some((key) => key !== "length" && (typeof key !== "string" || !/^(?:0|[1-9][0-9]*)$/u.test(key)))) {
|
|
43
|
+
fail("array contains extended properties");
|
|
44
|
+
}
|
|
45
|
+
for (let index = 0; index < count; index += 1) {
|
|
46
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
47
|
+
if (!descriptor?.enumerable || !("value" in descriptor)) {
|
|
48
|
+
return fail("sparse or accessor array");
|
|
49
|
+
}
|
|
50
|
+
rejectUnsafeGraph(descriptor.value, state, depth + 1);
|
|
51
|
+
}
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const keys = Reflect.ownKeys(value);
|
|
55
|
+
if (keys.length > 32)
|
|
56
|
+
fail("object property count exceeds 32");
|
|
57
|
+
for (const key of keys) {
|
|
58
|
+
if (typeof key !== "string")
|
|
59
|
+
fail("symbol properties are not allowed");
|
|
60
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
61
|
+
if (!descriptor?.enumerable || !("value" in descriptor)) {
|
|
62
|
+
return fail("accessor or non-enumerable property");
|
|
63
|
+
}
|
|
64
|
+
rejectUnsafeGraph(descriptor.value, state, depth + 1);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const exactObject = (value, fields, label) => {
|
|
68
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)
|
|
69
|
+
|| Object.getPrototypeOf(value) !== Object.prototype) {
|
|
70
|
+
return fail(`${label} must be a plain object`);
|
|
71
|
+
}
|
|
72
|
+
const keys = Object.getOwnPropertyNames(value);
|
|
73
|
+
if (keys.length !== fields.length || Object.keys(value).length !== fields.length
|
|
74
|
+
|| keys.some((key) => !fields.includes(key))
|
|
75
|
+
|| fields.some((field) => !Object.hasOwn(value, field))) {
|
|
76
|
+
return fail(`${label} keys must be ${fields.join(",")}`);
|
|
77
|
+
}
|
|
78
|
+
return value;
|
|
79
|
+
};
|
|
80
|
+
const exactArray = (value, label) => {
|
|
81
|
+
if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) {
|
|
82
|
+
return fail(`${label} must be a plain array`);
|
|
83
|
+
}
|
|
84
|
+
return value;
|
|
85
|
+
};
|
|
86
|
+
const boundedId = (value, label) => {
|
|
87
|
+
if (typeof value !== "string" || !BINDING_ID.test(value)
|
|
88
|
+
|| Buffer.byteLength(value, "ascii") > 128) {
|
|
89
|
+
return fail(`${label} is invalid`);
|
|
90
|
+
}
|
|
91
|
+
return value;
|
|
92
|
+
};
|
|
93
|
+
const canonicalEndpoint = (value, label) => {
|
|
94
|
+
if (typeof value !== "string" || value.length === 0
|
|
95
|
+
|| Buffer.byteLength(value, "utf8") > MAX_ENDPOINT_BYTES) {
|
|
96
|
+
return fail(`${label} endpoint is invalid`);
|
|
97
|
+
}
|
|
98
|
+
let parsed;
|
|
99
|
+
try {
|
|
100
|
+
parsed = new URL(value);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return fail(`${label} endpoint is invalid`);
|
|
104
|
+
}
|
|
105
|
+
if ((parsed.protocol !== "http:" && parsed.protocol !== "https:")
|
|
106
|
+
|| parsed.username !== "" || parsed.password !== ""
|
|
107
|
+
|| parsed.search !== "" || parsed.hash !== "" || parsed.hostname === ""
|
|
108
|
+
|| value.includes("?") || value.includes("#")
|
|
109
|
+
|| parsed.href !== value || parsed.pathname.endsWith("/")) {
|
|
110
|
+
return fail(`${label} endpoint must be a canonical credential-free http(s) URL`);
|
|
111
|
+
}
|
|
112
|
+
if (label === "json" && !parsed.pathname.endsWith("/v1/world")) {
|
|
113
|
+
return fail("json endpoint must end with /v1/world");
|
|
114
|
+
}
|
|
115
|
+
return value;
|
|
116
|
+
};
|
|
117
|
+
const parseBinding = (value, index) => {
|
|
118
|
+
const entry = exactObject(value, [
|
|
119
|
+
"member",
|
|
120
|
+
"run_id",
|
|
121
|
+
"world_instance_id",
|
|
122
|
+
"capability_manifest_digest",
|
|
123
|
+
"token_env",
|
|
124
|
+
"json",
|
|
125
|
+
"mcp"
|
|
126
|
+
], `bindings[${index}]`);
|
|
127
|
+
const member = exactObject(entry.member, ["id", "principal_id"], `bindings[${index}].member`);
|
|
128
|
+
const memberId = typeof member.id === "string" ? member.id : "";
|
|
129
|
+
if (!MEMBER_ID.test(memberId)
|
|
130
|
+
|| Buffer.byteLength(memberId, "ascii") > MAX_ORGANIZATION_MEMBER_ID_BYTES
|
|
131
|
+
|| member.principal_id !== `agent:${memberId}`) {
|
|
132
|
+
return fail(`bindings[${index}] member identity is invalid`);
|
|
133
|
+
}
|
|
134
|
+
const digest = entry.capability_manifest_digest;
|
|
135
|
+
if (typeof digest !== "string" || !DIGEST.test(digest)) {
|
|
136
|
+
return fail(`bindings[${index}] capability manifest digest is invalid`);
|
|
137
|
+
}
|
|
138
|
+
const tokenEnv = entry.token_env;
|
|
139
|
+
if (typeof tokenEnv !== "string" || !ENV_NAME.test(tokenEnv)) {
|
|
140
|
+
return fail(`bindings[${index}] token env is invalid`);
|
|
141
|
+
}
|
|
142
|
+
const json = exactObject(entry.json, ["auth", "url"], `bindings[${index}].json`);
|
|
143
|
+
const mcp = exactObject(entry.mcp, ["auth", "transport", "url"], `bindings[${index}].mcp`);
|
|
144
|
+
if (json.auth !== "bearer" || mcp.auth !== "bearer" || mcp.transport !== "streamable_http") {
|
|
145
|
+
return fail(`bindings[${index}] endpoint authentication is invalid`);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
member: { id: memberId, principal_id: member.principal_id },
|
|
149
|
+
run_id: boundedId(entry.run_id, `bindings[${index}].run_id`),
|
|
150
|
+
world_instance_id: boundedId(entry.world_instance_id, `bindings[${index}].world_instance_id`),
|
|
151
|
+
capability_manifest_digest: digest,
|
|
152
|
+
token_env: tokenEnv,
|
|
153
|
+
json: { auth: "bearer", url: canonicalEndpoint(json.url, "json") },
|
|
154
|
+
mcp: { auth: "bearer", transport: "streamable_http", url: canonicalEndpoint(mcp.url, "mcp") }
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
const freezeCopy = (value) => {
|
|
158
|
+
const copy = structuredClone(value);
|
|
159
|
+
const freeze = (current) => {
|
|
160
|
+
if (current === null || typeof current !== "object" || Object.isFrozen(current))
|
|
161
|
+
return;
|
|
162
|
+
Object.freeze(current);
|
|
163
|
+
for (const child of Object.values(current))
|
|
164
|
+
freeze(child);
|
|
165
|
+
};
|
|
166
|
+
freeze(copy);
|
|
167
|
+
return copy;
|
|
168
|
+
};
|
|
169
|
+
export const parseSimfileWorldBindings = (raw) => {
|
|
170
|
+
rejectUnsafeGraph(raw);
|
|
171
|
+
const root = exactObject(raw, ["schema", "bindings"], "root");
|
|
172
|
+
if (root.schema !== SIMFILE_WORLD_BINDINGS_VERSION)
|
|
173
|
+
fail("schema is invalid");
|
|
174
|
+
const input = exactArray(root.bindings, "bindings");
|
|
175
|
+
if (input.length === 0 || input.length > MAX_ORGANIZATION_AGENT_MEMBERS) {
|
|
176
|
+
fail("bindings must contain 1 to 128 entries");
|
|
177
|
+
}
|
|
178
|
+
const bindings = input.map((entry, index) => parseBinding(entry, index));
|
|
179
|
+
const members = new Set();
|
|
180
|
+
const principals = new Set();
|
|
181
|
+
const tokenEnvs = new Set();
|
|
182
|
+
const first = bindings[0];
|
|
183
|
+
for (const binding of bindings) {
|
|
184
|
+
if (members.has(binding.member.id) || principals.has(binding.member.principal_id)
|
|
185
|
+
|| tokenEnvs.has(binding.token_env)) {
|
|
186
|
+
fail("bindings contain a duplicate member, principal, or token env");
|
|
187
|
+
}
|
|
188
|
+
if (binding.run_id !== first.run_id || binding.world_instance_id !== first.world_instance_id) {
|
|
189
|
+
fail("bindings must share one run and world instance");
|
|
190
|
+
}
|
|
191
|
+
members.add(binding.member.id);
|
|
192
|
+
principals.add(binding.member.principal_id);
|
|
193
|
+
tokenEnvs.add(binding.token_env);
|
|
194
|
+
}
|
|
195
|
+
bindings.sort((left, right) => compareAscii(left.member.principal_id, right.member.principal_id)
|
|
196
|
+
|| compareAscii(left.member.id, right.member.id));
|
|
197
|
+
return freezeCopy({ schema: SIMFILE_WORLD_BINDINGS_VERSION, bindings });
|
|
198
|
+
};
|
|
199
|
+
export const renderSimfileWorldBindings = (artifact) => `${JSON.stringify(parseSimfileWorldBindings(artifact), null, 2)}\n`;
|
|
200
|
+
export const resolveWorldBindings = (plan, raw) => {
|
|
201
|
+
const artifact = parseSimfileWorldBindings(raw);
|
|
202
|
+
const identity = plan.organizationIdentity;
|
|
203
|
+
if (!identity)
|
|
204
|
+
return fail("organization identity is required");
|
|
205
|
+
const authorityByMember = new Map(identity.agentMembers.map((member) => [member.memberId, member]));
|
|
206
|
+
const nodeByMember = new Map();
|
|
207
|
+
for (const node of plan.nodes) {
|
|
208
|
+
if (node.kind !== "agent")
|
|
209
|
+
continue;
|
|
210
|
+
const memberId = resolveCanonicalAgentMemberId(plan, node.value.source);
|
|
211
|
+
if (memberId === undefined)
|
|
212
|
+
continue;
|
|
213
|
+
const authority = authorityByMember.get(memberId);
|
|
214
|
+
if (!authority || authority.principalId !== `agent:${memberId}` || nodeByMember.has(memberId)) {
|
|
215
|
+
fail(`organization identity does not resolve exactly once for ${memberId}`);
|
|
216
|
+
}
|
|
217
|
+
nodeByMember.set(memberId, node.id);
|
|
218
|
+
}
|
|
219
|
+
if (nodeByMember.size !== identity.agentMembers.length
|
|
220
|
+
|| artifact.bindings.length !== identity.agentMembers.length) {
|
|
221
|
+
fail("binding and organization cardinality do not match");
|
|
222
|
+
}
|
|
223
|
+
const assignments = artifact.bindings.map((binding) => {
|
|
224
|
+
const authority = authorityByMember.get(binding.member.id);
|
|
225
|
+
const nodeId = nodeByMember.get(binding.member.id);
|
|
226
|
+
if (!authority || authority.principalId !== binding.member.principal_id || !nodeId) {
|
|
227
|
+
return fail(`binding does not join organization member ${binding.member.id}`);
|
|
228
|
+
}
|
|
229
|
+
return { binding: freezeCopy(binding), nodeId };
|
|
230
|
+
});
|
|
231
|
+
if (new Set(assignments.map((assignment) => assignment.nodeId)).size !== assignments.length) {
|
|
232
|
+
fail("binding assignments contain a duplicate node");
|
|
233
|
+
}
|
|
234
|
+
return freezeCopy({
|
|
235
|
+
artifact,
|
|
236
|
+
assignments,
|
|
237
|
+
canonicalBytes: renderSimfileWorldBindings(artifact)
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
export const findWorldBindingForNode = (resolved, nodeId) => {
|
|
241
|
+
if (!resolved)
|
|
242
|
+
return undefined;
|
|
243
|
+
const matches = resolved.assignments.filter((assignment) => assignment.nodeId === nodeId);
|
|
244
|
+
if (matches.length > 1)
|
|
245
|
+
fail(`node ${nodeId} has duplicate binding assignments`);
|
|
246
|
+
return matches[0]?.binding;
|
|
247
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CompilePlan } from "./types.js";
|
|
2
|
+
import { type ResolvedWorldBindings } from "./worldBindings.js";
|
|
3
|
+
export declare const MAX_WORLD_BINDINGS_FILE_BYTES = 1048576;
|
|
4
|
+
export declare const readSimfileWorldBindingsFile: (inputPath: string) => Promise<unknown>;
|
|
5
|
+
export declare const loadWorldBindingsForCompile: (plan: CompilePlan, inputPath: string, expectedRunId: string | undefined) => Promise<ResolvedWorldBindings>;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { open } from "node:fs/promises";
|
|
4
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
5
|
+
import { resolveWorldBindings, SIMFILE_WORLD_BINDINGS_VERSION } from "./worldBindings.js";
|
|
6
|
+
export const MAX_WORLD_BINDINGS_FILE_BYTES = 1_048_576;
|
|
7
|
+
class DuplicateJsonKeyError extends Error {
|
|
8
|
+
}
|
|
9
|
+
const fail = (message) => {
|
|
10
|
+
throw new SpawnfileError("validation_error", `invalid ${SIMFILE_WORLD_BINDINGS_VERSION} file: ${message}`);
|
|
11
|
+
};
|
|
12
|
+
const assertNoDuplicateJsonKeys = (source) => {
|
|
13
|
+
let offset = 0;
|
|
14
|
+
const whitespace = () => {
|
|
15
|
+
while (/\s/u.test(source[offset] ?? ""))
|
|
16
|
+
offset += 1;
|
|
17
|
+
};
|
|
18
|
+
const string = () => {
|
|
19
|
+
const start = offset;
|
|
20
|
+
offset += 1;
|
|
21
|
+
while (offset < source.length) {
|
|
22
|
+
if (source[offset] === "\\") {
|
|
23
|
+
offset += 2;
|
|
24
|
+
}
|
|
25
|
+
else if (source[offset] === "\"") {
|
|
26
|
+
offset += 1;
|
|
27
|
+
return JSON.parse(source.slice(start, offset));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
offset += 1;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return fail("JSON is malformed");
|
|
34
|
+
};
|
|
35
|
+
const value = () => {
|
|
36
|
+
whitespace();
|
|
37
|
+
if (source[offset] === "{") {
|
|
38
|
+
object();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (source[offset] === "[") {
|
|
42
|
+
array();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (source[offset] === "\"") {
|
|
46
|
+
string();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
while (offset < source.length && !/[\s,\]}]/u.test(source[offset] ?? "")) {
|
|
50
|
+
offset += 1;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const object = () => {
|
|
54
|
+
offset += 1;
|
|
55
|
+
whitespace();
|
|
56
|
+
const keys = new Set();
|
|
57
|
+
if (source[offset] === "}") {
|
|
58
|
+
offset += 1;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
while (offset < source.length) {
|
|
62
|
+
const key = string();
|
|
63
|
+
if (keys.has(key))
|
|
64
|
+
throw new DuplicateJsonKeyError();
|
|
65
|
+
keys.add(key);
|
|
66
|
+
whitespace();
|
|
67
|
+
offset += 1;
|
|
68
|
+
value();
|
|
69
|
+
whitespace();
|
|
70
|
+
if (source[offset] === "}") {
|
|
71
|
+
offset += 1;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
offset += 1;
|
|
75
|
+
whitespace();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const array = () => {
|
|
79
|
+
offset += 1;
|
|
80
|
+
whitespace();
|
|
81
|
+
if (source[offset] === "]") {
|
|
82
|
+
offset += 1;
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
while (offset < source.length) {
|
|
86
|
+
value();
|
|
87
|
+
whitespace();
|
|
88
|
+
if (source[offset] === "]") {
|
|
89
|
+
offset += 1;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
offset += 1;
|
|
93
|
+
whitespace();
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
value();
|
|
97
|
+
whitespace();
|
|
98
|
+
if (offset !== source.length)
|
|
99
|
+
fail("JSON must contain exactly one value");
|
|
100
|
+
};
|
|
101
|
+
const decodeJson = (bytes) => {
|
|
102
|
+
let source;
|
|
103
|
+
try {
|
|
104
|
+
source = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return fail("content must be valid UTF-8");
|
|
108
|
+
}
|
|
109
|
+
let parsed;
|
|
110
|
+
try {
|
|
111
|
+
parsed = JSON.parse(source);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return fail("content must be exactly one valid JSON value");
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
assertNoDuplicateJsonKeys(source);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (error instanceof DuplicateJsonKeyError)
|
|
121
|
+
return fail("duplicate JSON keys are not allowed");
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
return parsed;
|
|
125
|
+
};
|
|
126
|
+
export const readSimfileWorldBindingsFile = async (inputPath) => {
|
|
127
|
+
const filePath = path.resolve(inputPath);
|
|
128
|
+
let handle;
|
|
129
|
+
try {
|
|
130
|
+
handle = await open(filePath, constants.O_RDONLY | constants.O_NONBLOCK);
|
|
131
|
+
const metadata = await handle.stat();
|
|
132
|
+
if (!metadata.isFile() || metadata.size <= 0
|
|
133
|
+
|| metadata.size > MAX_WORLD_BINDINGS_FILE_BYTES) {
|
|
134
|
+
return fail(`content must be a non-empty regular file no larger than ${MAX_WORLD_BINDINGS_FILE_BYTES} bytes`);
|
|
135
|
+
}
|
|
136
|
+
const buffer = new Uint8Array(MAX_WORLD_BINDINGS_FILE_BYTES + 1);
|
|
137
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.byteLength, 0);
|
|
138
|
+
const afterRead = await handle.stat();
|
|
139
|
+
if (bytesRead !== metadata.size || afterRead.size !== metadata.size
|
|
140
|
+
|| bytesRead > MAX_WORLD_BINDINGS_FILE_BYTES) {
|
|
141
|
+
return fail("content changed while it was being read or exceeds the byte limit");
|
|
142
|
+
}
|
|
143
|
+
return decodeJson(buffer.subarray(0, bytesRead));
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
if (error instanceof SpawnfileError)
|
|
147
|
+
throw error;
|
|
148
|
+
return fail("content could not be read");
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
await handle?.close().catch(() => undefined);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
export const loadWorldBindingsForCompile = async (plan, inputPath, expectedRunId) => {
|
|
155
|
+
if (!expectedRunId)
|
|
156
|
+
return fail("NOOPOLIS_RUN_ID must be set before compile");
|
|
157
|
+
const resolved = resolveWorldBindings(plan, await readSimfileWorldBindingsFile(inputPath));
|
|
158
|
+
if (resolved.artifact.bindings[0]?.run_id !== expectedRunId) {
|
|
159
|
+
return fail("binding run_id does not match the compile NOOPOLIS_RUN_ID");
|
|
160
|
+
}
|
|
161
|
+
return resolved;
|
|
162
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type DockerArtifactExecFile } from "./artifactsExportDocker.js";
|
|
2
|
+
import { type ExportIndex } from "./artifactsExportTypes.js";
|
|
3
|
+
import { type DeploymentLifecycleCorrelation } from "./deploymentLifecycleCorrelation.js";
|
|
4
|
+
export interface ExportRunArtifactsOptions {
|
|
5
|
+
/** Where the deployment record + compile report already live (the compile's own
|
|
6
|
+
* `--out` directory) — NOT the export destination. */
|
|
7
|
+
compiledOutputDirectory: string;
|
|
8
|
+
deploymentName?: string;
|
|
9
|
+
/** Where `raw/**` and `spawnfile/export-index.json` are written. */
|
|
10
|
+
destinationDirectory: string;
|
|
11
|
+
dockerCommand?: string;
|
|
12
|
+
execFile?: DockerArtifactExecFile;
|
|
13
|
+
/** Explicitly export unredacted private runtime training artifacts. */
|
|
14
|
+
includePrivate?: boolean;
|
|
15
|
+
/** Overrides the image used to read named volumes; defaults to the deployment's own
|
|
16
|
+
* recorded `image_tag` (already present locally — see artifactsExportDocker.ts). */
|
|
17
|
+
readerImage?: string;
|
|
18
|
+
runId?: string;
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
expectedLifecycleCorrelation?: DeploymentLifecycleCorrelation;
|
|
21
|
+
}
|
|
22
|
+
export interface ExportRunArtifactsResult {
|
|
23
|
+
deploymentName: string;
|
|
24
|
+
/** Planned files that failed to copy despite the container/volume being reachable
|
|
25
|
+
* (a real per-file problem, worth surfacing — as opposed to `missingOptionalFiles`). */
|
|
26
|
+
failedFiles: string[];
|
|
27
|
+
index: ExportIndex;
|
|
28
|
+
indexPath: string;
|
|
29
|
+
/** Planned files that were legitimately absent (e.g. no recall yet) — not failures. */
|
|
30
|
+
missingOptionalFiles: string[];
|
|
31
|
+
}
|
|
32
|
+
export declare const resolveArtifactsExportLifecycleCorrelation: (options: Pick<ExportRunArtifactsOptions, "compiledOutputDirectory" | "deploymentName" | "runId">) => Promise<DeploymentLifecycleCorrelation>;
|
|
33
|
+
/**
|
|
34
|
+
* `spawnfile artifacts export` — mechanical egress of a run's durable artifacts (moltnet
|
|
35
|
+
* causal log, mneme bank ledgers, daimon per-agent telemetry) into the compose-and-observe
|
|
36
|
+
* run-dir layout (`decisions.md` Decision 21 §2), plus the `spawnfile.export-index.v1`
|
|
37
|
+
* index simfile's observer folds into its own run manifest.
|
|
38
|
+
*
|
|
39
|
+
* As of Piece 4b, every planned file is volume-sourced (moltnet + mneme already were;
|
|
40
|
+
* daimon telemetry joined them — see `artifactsExportPlan.ts`'s `planDaimonFiles`), and a
|
|
41
|
+
* named volume outlives its container across a plain `docker rm` (no `--volumes`). So this
|
|
42
|
+
* no longer requires the deployment's container to still be alive in the general case: the
|
|
43
|
+
* container-liveness check below (`requiresLiveContainer`) only runs when the plan actually
|
|
44
|
+
* contains a `kind: "container"` file, which today only happens for a legacy pre-Piece-4b
|
|
45
|
+
* compile report. This is the real relaxation of the export-before-teardown invariant
|
|
46
|
+
* Piece 4b unlocks: `spawnfile down` (without `--volumes`) can run BEFORE `spawnfile
|
|
47
|
+
* artifacts export`, and export still recovers everything from the named volumes.
|
|
48
|
+
*/
|
|
49
|
+
export declare const exportRunArtifacts: (options: ExportRunArtifactsOptions) => Promise<ExportRunArtifactsResult>;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { readFile, rm } from "node:fs/promises";
|
|
4
|
+
import { ensureDirectory, fileExists, readUtf8File, writeUtf8File } from "../filesystem/index.js";
|
|
5
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
6
|
+
import { REPORT_FILENAME } from "../shared/index.js";
|
|
7
|
+
import { containerExists, copyContainerFileToHost, copyVolumeFileToHost, defaultDockerArtifactExecFile } from "./artifactsExportDocker.js";
|
|
8
|
+
import { EXPORT_INDEX_VERSION } from "./artifactsExportTypes.js";
|
|
9
|
+
import { planArtifactExports } from "./artifactsExportPlan.js";
|
|
10
|
+
import { exportPrivateRuntimeArtifacts } from "./privateArtifactsExport.js";
|
|
11
|
+
import { assertDeploymentLifecycleCorrelation, createDeploymentLifecycleCorrelation, } from "./deploymentLifecycleCorrelation.js";
|
|
12
|
+
import { listDeploymentRecords, readDeploymentRecordFromOutput, writeDeploymentRecord } from "./record.js";
|
|
13
|
+
const sha256Hex = (buffer) => createHash("sha256").update(buffer).digest("hex");
|
|
14
|
+
const targetRefForUnit = (unit) => unit.container_id ?? unit.container_name;
|
|
15
|
+
const resolveDeploymentRecord = async (compiledOutputDirectory, options) => {
|
|
16
|
+
if (options.deploymentName && options.runId) {
|
|
17
|
+
throw new SpawnfileError("validation_error", "spawnfile artifacts export accepts only one of --deployment or --run-id");
|
|
18
|
+
}
|
|
19
|
+
if (!options.deploymentName && !options.runId) {
|
|
20
|
+
throw new SpawnfileError("validation_error", "spawnfile artifacts export requires --deployment <name> or --run-id <id>");
|
|
21
|
+
}
|
|
22
|
+
if (options.deploymentName) {
|
|
23
|
+
try {
|
|
24
|
+
return await readDeploymentRecordFromOutput(compiledOutputDirectory, options.deploymentName);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
28
|
+
throw new SpawnfileError("runtime_error", `No deployment record named "${options.deploymentName}" under ${compiledOutputDirectory}. ` +
|
|
29
|
+
`Has it already been torn down, or never brought up with --detach? (${reason})`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const records = await listDeploymentRecords(compiledOutputDirectory);
|
|
33
|
+
const match = records.find((entry) => entry.record.run_id === options.runId);
|
|
34
|
+
if (!match) {
|
|
35
|
+
const known = records.map((entry) => entry.record.name).sort().join(", ") || "none";
|
|
36
|
+
throw new SpawnfileError("runtime_error", `No deployment record found for run id "${options.runId}" under ${compiledOutputDirectory}. ` +
|
|
37
|
+
`Known deployments: ${known}`);
|
|
38
|
+
}
|
|
39
|
+
return match.record;
|
|
40
|
+
};
|
|
41
|
+
export const resolveArtifactsExportLifecycleCorrelation = async (options) => createDeploymentLifecycleCorrelation(await resolveDeploymentRecord(path.resolve(options.compiledOutputDirectory), options));
|
|
42
|
+
const readCompileReport = async (compiledOutputDirectory) => {
|
|
43
|
+
const reportPath = path.join(compiledOutputDirectory, REPORT_FILENAME);
|
|
44
|
+
if (!(await fileExists(reportPath))) {
|
|
45
|
+
throw new SpawnfileError("validation_error", `No compile report found at ${reportPath}; recompile the project before exporting artifacts.`);
|
|
46
|
+
}
|
|
47
|
+
const parsed = JSON.parse(await readUtf8File(reportPath));
|
|
48
|
+
if (!parsed.container) {
|
|
49
|
+
throw new SpawnfileError("validation_error", `Compile report at ${reportPath} has no container section; nothing to export.`);
|
|
50
|
+
}
|
|
51
|
+
return parsed;
|
|
52
|
+
};
|
|
53
|
+
const hostPathFor = (destinationDirectory, relativePath) => path.join(destinationDirectory, ...relativePath.split("/"));
|
|
54
|
+
const exportOnePlannedFile = async (input) => {
|
|
55
|
+
const hostPath = hostPathFor(input.destinationDirectory, input.plan.relativePath);
|
|
56
|
+
await ensureDirectory(path.dirname(hostPath));
|
|
57
|
+
const runnerOptions = { dockerCommand: input.dockerCommand, execFile: input.execFile, timeoutMs: input.timeoutMs };
|
|
58
|
+
let copied;
|
|
59
|
+
let source;
|
|
60
|
+
if (input.plan.source.kind === "container") {
|
|
61
|
+
copied = await copyContainerFileToHost({
|
|
62
|
+
containerPath: input.plan.source.containerPath,
|
|
63
|
+
containerRef: input.containerRef,
|
|
64
|
+
hostPath,
|
|
65
|
+
target: input.target,
|
|
66
|
+
...runnerOptions
|
|
67
|
+
});
|
|
68
|
+
source = { kind: "container", ref: `${input.containerRef}:${input.plan.source.containerPath}` };
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
copied = await copyVolumeFileToHost({
|
|
72
|
+
hostPath,
|
|
73
|
+
readerImage: input.readerImage,
|
|
74
|
+
target: input.target,
|
|
75
|
+
volumeName: input.plan.source.volumeName,
|
|
76
|
+
volumePath: input.plan.source.volumePath,
|
|
77
|
+
...runnerOptions
|
|
78
|
+
});
|
|
79
|
+
source = { kind: "volume", ref: `${input.plan.source.volumeName}:/${input.plan.source.volumePath}` };
|
|
80
|
+
}
|
|
81
|
+
if (!copied) {
|
|
82
|
+
// docker cp never creates a partial file on failure, but be defensive: never leave a
|
|
83
|
+
// stray empty file behind for a copy this function considers failed.
|
|
84
|
+
await rm(hostPath, { force: true });
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
const buffer = await readFile(hostPath);
|
|
88
|
+
return {
|
|
89
|
+
bytes: buffer.byteLength,
|
|
90
|
+
path: input.plan.relativePath,
|
|
91
|
+
sha256: sha256Hex(buffer),
|
|
92
|
+
source
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* `spawnfile artifacts export` — mechanical egress of a run's durable artifacts (moltnet
|
|
97
|
+
* causal log, mneme bank ledgers, daimon per-agent telemetry) into the compose-and-observe
|
|
98
|
+
* run-dir layout (`decisions.md` Decision 21 §2), plus the `spawnfile.export-index.v1`
|
|
99
|
+
* index simfile's observer folds into its own run manifest.
|
|
100
|
+
*
|
|
101
|
+
* As of Piece 4b, every planned file is volume-sourced (moltnet + mneme already were;
|
|
102
|
+
* daimon telemetry joined them — see `artifactsExportPlan.ts`'s `planDaimonFiles`), and a
|
|
103
|
+
* named volume outlives its container across a plain `docker rm` (no `--volumes`). So this
|
|
104
|
+
* no longer requires the deployment's container to still be alive in the general case: the
|
|
105
|
+
* container-liveness check below (`requiresLiveContainer`) only runs when the plan actually
|
|
106
|
+
* contains a `kind: "container"` file, which today only happens for a legacy pre-Piece-4b
|
|
107
|
+
* compile report. This is the real relaxation of the export-before-teardown invariant
|
|
108
|
+
* Piece 4b unlocks: `spawnfile down` (without `--volumes`) can run BEFORE `spawnfile
|
|
109
|
+
* artifacts export`, and export still recovers everything from the named volumes.
|
|
110
|
+
*/
|
|
111
|
+
export const exportRunArtifacts = async (options) => {
|
|
112
|
+
const compiledOutputDirectory = path.resolve(options.compiledOutputDirectory);
|
|
113
|
+
const destinationDirectory = path.resolve(options.destinationDirectory);
|
|
114
|
+
const dockerCommand = options.dockerCommand ?? "docker";
|
|
115
|
+
const execFileImpl = options.execFile ?? defaultDockerArtifactExecFile;
|
|
116
|
+
const timeoutMs = options.timeoutMs ?? 30_000;
|
|
117
|
+
const record = await resolveDeploymentRecord(compiledOutputDirectory, options);
|
|
118
|
+
assertDeploymentLifecycleCorrelation(record, options.expectedLifecycleCorrelation);
|
|
119
|
+
const unit = record.units[0];
|
|
120
|
+
if (!unit) {
|
|
121
|
+
throw new SpawnfileError("validation_error", `Deployment "${record.name}" has no recorded container unit`);
|
|
122
|
+
}
|
|
123
|
+
const containerRef = targetRefForUnit(unit);
|
|
124
|
+
if (!containerRef) {
|
|
125
|
+
throw new SpawnfileError("validation_error", `Deployment "${record.name}" has no recorded container id or name`);
|
|
126
|
+
}
|
|
127
|
+
const runId = record.run_id;
|
|
128
|
+
if (!runId) {
|
|
129
|
+
throw new SpawnfileError("validation_error", `Deployment "${record.name}" has no recorded run id (it predates run-id tracking, or was ` +
|
|
130
|
+
"compiled with no NOOPOLIS_RUN_ID set), so a conformant export-index.json cannot be " +
|
|
131
|
+
"written. Recompile and redeploy the project (with NOOPOLIS_RUN_ID set, or via a plain " +
|
|
132
|
+
"`spawnfile up --detach`, which always generates one) before exporting artifacts.");
|
|
133
|
+
}
|
|
134
|
+
const report = await readCompileReport(compiledOutputDirectory);
|
|
135
|
+
const planned = planArtifactExports(report);
|
|
136
|
+
// Only a `kind: "container"` planned file needs the live container (see this function's
|
|
137
|
+
// own doc comment) — every other source reads a named volume, which survives a plain
|
|
138
|
+
// `docker rm` on its own. Gating on this, rather than checking unconditionally, is the
|
|
139
|
+
// actual export-before-teardown relaxation Piece 4b delivers.
|
|
140
|
+
const requiresLiveContainer = options.includePrivate === true
|
|
141
|
+
|| planned.some((entry) => entry.source.kind === "container");
|
|
142
|
+
if (requiresLiveContainer) {
|
|
143
|
+
const exists = await containerExists(record.target, containerRef, {
|
|
144
|
+
dockerCommand,
|
|
145
|
+
execFile: execFileImpl,
|
|
146
|
+
timeoutMs
|
|
147
|
+
});
|
|
148
|
+
if (!exists) {
|
|
149
|
+
throw new SpawnfileError("runtime_error", `Deployment "${record.name}" has no live container ("${containerRef}"), and its planned export ` +
|
|
150
|
+
"includes at least one file that can only be read from a live container (a legacy, " +
|
|
151
|
+
"pre-Piece-4b compile report — recompile to move it onto a durable volume). Run " +
|
|
152
|
+
"`spawnfile artifacts export` BEFORE `spawnfile down` removes the container, or recompile.");
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const readerImage = options.readerImage ?? unit.image_tag;
|
|
156
|
+
const files = [];
|
|
157
|
+
const missingOptionalFiles = [];
|
|
158
|
+
const failedFiles = [];
|
|
159
|
+
for (const plan of planned) {
|
|
160
|
+
const entry = await exportOnePlannedFile({
|
|
161
|
+
containerRef,
|
|
162
|
+
destinationDirectory,
|
|
163
|
+
dockerCommand,
|
|
164
|
+
execFile: execFileImpl,
|
|
165
|
+
plan,
|
|
166
|
+
readerImage,
|
|
167
|
+
target: record.target,
|
|
168
|
+
timeoutMs
|
|
169
|
+
});
|
|
170
|
+
if (entry) {
|
|
171
|
+
files.push(entry);
|
|
172
|
+
}
|
|
173
|
+
else if (plan.optional) {
|
|
174
|
+
missingOptionalFiles.push(plan.relativePath);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
failedFiles.push(plan.relativePath);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (options.includePrivate === true) {
|
|
181
|
+
const privateResult = await exportPrivateRuntimeArtifacts({
|
|
182
|
+
containerRef,
|
|
183
|
+
destinationDirectory,
|
|
184
|
+
dockerCommand,
|
|
185
|
+
execFile: execFileImpl,
|
|
186
|
+
report,
|
|
187
|
+
target: record.target,
|
|
188
|
+
timeoutMs,
|
|
189
|
+
});
|
|
190
|
+
files.push(...privateResult.files);
|
|
191
|
+
failedFiles.push(...privateResult.missing);
|
|
192
|
+
}
|
|
193
|
+
const index = {
|
|
194
|
+
deployment: record.name,
|
|
195
|
+
exported_at: new Date().toISOString(),
|
|
196
|
+
files: files.sort((left, right) => left.path.localeCompare(right.path)),
|
|
197
|
+
run_id: runId,
|
|
198
|
+
version: EXPORT_INDEX_VERSION
|
|
199
|
+
};
|
|
200
|
+
const indexPath = path.join(destinationDirectory, "spawnfile", "export-index.json");
|
|
201
|
+
await ensureDirectory(path.dirname(indexPath));
|
|
202
|
+
await writeUtf8File(indexPath, `${JSON.stringify(index, null, 2)}\n`);
|
|
203
|
+
// Stamp the export-before-teardown marker onto the SAME deployment record `spawnfile
|
|
204
|
+
// down` resolves (record.ts's `export_index`), so down never needs a second, out-of-band
|
|
205
|
+
// way to learn that this run's artifacts are already safe to discard the container for.
|
|
206
|
+
await writeDeploymentRecord(compiledOutputDirectory, {
|
|
207
|
+
...record,
|
|
208
|
+
export_index: { exported_at: index.exported_at, path: indexPath, run_id: runId }
|
|
209
|
+
});
|
|
210
|
+
return {
|
|
211
|
+
deploymentName: record.name,
|
|
212
|
+
failedFiles,
|
|
213
|
+
index,
|
|
214
|
+
indexPath,
|
|
215
|
+
missingOptionalFiles
|
|
216
|
+
};
|
|
217
|
+
};
|