spawnfile 0.1.17 → 0.1.18
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 +1 -1
- package/dist/auth/importers.js +21 -5
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.js +1 -0
- package/dist/auth/profileStore.js +4 -1
- package/dist/auth/trainingGrokWriteback.d.ts +4 -0
- package/dist/auth/trainingGrokWriteback.js +119 -0
- package/dist/auth/trainingGrokWritebackLock.d.ts +5 -0
- package/dist/auth/trainingGrokWritebackLock.js +56 -0
- package/dist/cli/authCommands.js +9 -5
- package/dist/cli/compileBuildCommands.js +4 -0
- package/dist/cli/devCommands.js +4 -2
- package/dist/cli/downCommand.d.ts +2 -0
- package/dist/cli/downCommand.js +3 -0
- package/dist/cli/envFileOption.d.ts +18 -0
- package/dist/cli/envFileOption.js +20 -0
- package/dist/cli/lifecycleCommands.d.ts +1 -1
- package/dist/cli/lifecycleCommands.js +3 -1
- package/dist/cli/lifecyclePlan.d.ts +1 -0
- package/dist/cli/lifecyclePlan.js +2 -0
- package/dist/cli/paideiaDelegation.d.ts +2 -1
- package/dist/cli/paideiaDelegation.js +5 -4
- package/dist/cli/recordCommands.d.ts +17 -0
- package/dist/cli/recordCommands.js +43 -0
- package/dist/cli/releaseCommand.d.ts +6 -0
- package/dist/cli/releaseCommand.js +91 -0
- package/dist/cli/runCli.d.ts +7 -1
- package/dist/cli/runCli.js +11 -6
- package/dist/cli/runPublishCommands.js +5 -3
- package/dist/cli/trainCommand.js +73 -20
- package/dist/cli/upCommand.js +5 -1
- package/dist/cli/volumeCommands.d.ts +8 -0
- package/dist/cli/volumeCommands.js +53 -0
- package/dist/compiler/agentNodeMerge.js +3 -2
- package/dist/compiler/buildCompilePlan.js +4 -0
- package/dist/compiler/buildCompilePlanAgent.js +3 -1
- package/dist/compiler/buildCompilePlanTraversal.js +2 -0
- package/dist/compiler/buildCompilePlanTraversalHelpers.d.ts +2 -2
- package/dist/compiler/buildCompilePlanTraversalHelpers.js +4 -3
- package/dist/compiler/buildProject.d.ts +10 -0
- package/dist/compiler/buildProject.js +14 -2
- package/dist/compiler/cleanCompileOutput.d.ts +2 -0
- package/dist/compiler/cleanCompileOutput.js +14 -0
- package/dist/compiler/compilePlanHelpers.js +2 -0
- package/dist/compiler/compileProject.d.ts +10 -0
- package/dist/compiler/compileProject.js +29 -3
- package/dist/compiler/containerArtifactSummaries.js +1 -0
- package/dist/compiler/containerArtifacts.d.ts +4 -4
- package/dist/compiler/containerArtifacts.js +18 -34
- package/dist/compiler/containerArtifactsPlans.js +7 -0
- package/dist/compiler/containerArtifactsTypes.d.ts +7 -0
- package/dist/compiler/containerDaimonBrokerRender.d.ts +3 -1
- package/dist/compiler/containerDaimonBrokerRender.js +6 -3
- package/dist/compiler/containerDaimonGrokTaskClock.d.ts +5 -0
- package/dist/compiler/containerDaimonGrokTaskClock.js +29 -0
- package/dist/compiler/containerDaimonGrokWorkerProvisioning.d.ts +1 -1
- package/dist/compiler/containerDaimonGrokWorkerProvisioning.js +38 -16
- package/dist/compiler/containerDaimonGrokWorkerRender.d.ts +33 -8
- package/dist/compiler/containerDaimonGrokWorkerRender.js +18 -5
- package/dist/compiler/containerDaimonOwnershipGuardRender.d.ts +14 -1
- package/dist/compiler/containerDaimonOwnershipGuardRender.js +15 -2
- package/dist/compiler/containerDaimonUidEntrypointRender.js +6 -12
- package/dist/compiler/containerTargetResources.d.ts +10 -0
- package/dist/compiler/containerTargetResources.js +21 -13
- package/dist/compiler/containerWorkspaceResourceRender.js +4 -1
- package/dist/compiler/index.d.ts +2 -0
- package/dist/compiler/index.js +2 -0
- package/dist/compiler/mcpPlaceholders.d.ts +11 -0
- package/dist/compiler/mcpPlaceholders.js +58 -0
- package/dist/compiler/mcpServerInheritance.d.ts +18 -0
- package/dist/compiler/mcpServerInheritance.js +43 -0
- package/dist/compiler/moltnetArtifactTypes.d.ts +1 -0
- package/dist/compiler/moltnetArtifacts.js +1 -0
- package/dist/compiler/preflightCompilePlan.d.ts +9 -0
- package/dist/compiler/preflightCompilePlan.js +38 -0
- package/dist/compiler/recordingAgentFacts.d.ts +4 -0
- package/dist/compiler/recordingAgentFacts.js +35 -0
- package/dist/compiler/recordingCapability.d.ts +4 -0
- package/dist/compiler/recordingCapability.js +22 -0
- package/dist/compiler/recordingReport.d.ts +4 -0
- package/dist/compiler/recordingReport.js +18 -0
- package/dist/compiler/runProject.d.ts +2 -1
- package/dist/compiler/runProject.js +2 -0
- package/dist/compiler/surfaces.d.ts +1 -2
- package/dist/compiler/surfaces.js +0 -1
- package/dist/compiler/syncProjectAuth.js +2 -1
- package/dist/compiler/training/broker/clockProbe.d.ts +6 -0
- package/dist/compiler/training/broker/clockProbe.js +27 -0
- package/dist/compiler/training/broker/declaration.d.ts +4 -2
- package/dist/compiler/training/broker/declaration.js +4 -2
- package/dist/compiler/training/broker/entrypoint.js +33 -18
- package/dist/compiler/training/broker/evaluatorSecrets.d.ts +2 -0
- package/dist/compiler/training/broker/evaluatorSecrets.js +60 -0
- package/dist/compiler/training/broker/index.d.ts +3 -2
- package/dist/compiler/training/broker/index.js +3 -2
- package/dist/compiler/training/broker/main.js +1 -1
- package/dist/compiler/training/broker/paths.d.ts +96 -56
- package/dist/compiler/training/broker/paths.js +97 -89
- package/dist/compiler/training/broker/processes.d.ts +9 -0
- package/dist/compiler/training/broker/processes.js +4 -1
- package/dist/compiler/training/broker/projection.d.ts +3 -2
- package/dist/compiler/training/broker/projection.js +21 -9
- package/dist/compiler/training/broker/provisioning.d.ts +6 -15
- package/dist/compiler/training/broker/provisioning.js +71 -53
- package/dist/compiler/training/broker/registration.d.ts +3 -1
- package/dist/compiler/training/broker/registration.js +29 -21
- package/dist/compiler/training/broker/reset.d.ts +9 -0
- package/dist/compiler/training/broker/reset.js +71 -0
- package/dist/compiler/training/broker/runtime.d.ts +10 -13
- package/dist/compiler/training/broker/runtime.js +69 -115
- package/dist/compiler/training/broker/supervisor.d.ts +10 -11
- package/dist/compiler/training/broker/supervisor.js +22 -23
- package/dist/compiler/training/broker/taskClock.d.ts +5 -0
- package/dist/compiler/training/broker/taskClock.js +41 -0
- package/dist/compiler/training/compiledAgent.d.ts +21 -0
- package/dist/compiler/training/compiledAgent.js +62 -0
- package/dist/compiler/training/container/contract.d.ts +23 -0
- package/dist/compiler/training/container/contract.js +23 -5
- package/dist/compiler/training/container/evaluators.d.ts +48 -0
- package/dist/compiler/training/container/evaluators.js +50 -0
- package/dist/compiler/training/container/grokWriteback.d.ts +8 -0
- package/dist/compiler/training/container/grokWriteback.js +26 -0
- package/dist/compiler/training/container/index.d.ts +2 -1
- package/dist/compiler/training/container/index.js +2 -1
- package/dist/compiler/training/container/launch.d.ts +3 -0
- package/dist/compiler/training/container/launch.js +119 -28
- package/dist/compiler/training/container/nativeSlots.d.ts +14 -0
- package/dist/compiler/training/container/nativeSlots.js +13 -0
- package/dist/compiler/training/container/outputCopy.d.ts +2 -0
- package/dist/compiler/training/container/outputCopy.js +72 -0
- package/dist/compiler/training/container/outputVolume.d.ts +27 -0
- package/dist/compiler/training/container/outputVolume.js +161 -0
- package/dist/compiler/training/container/prepare.d.ts +3 -1
- package/dist/compiler/training/container/prepare.js +57 -12
- package/dist/compiler/training/container/security.d.ts +5 -3
- package/dist/compiler/training/container/security.js +15 -5
- package/dist/compiler/training/container/subjectIsolation.d.ts +5 -0
- package/dist/compiler/training/container/subjectIsolation.js +15 -0
- package/dist/compiler/training/context.d.ts +8 -0
- package/dist/compiler/training/context.js +12 -12
- package/dist/compiler/training/contract.d.ts +2 -0
- package/dist/compiler/training/contract.js +2 -0
- package/dist/compiler/training/execution.d.ts +417 -0
- package/dist/compiler/training/execution.js +160 -0
- package/dist/compiler/training/index.d.ts +8 -0
- package/dist/compiler/training/index.js +7 -0
- package/dist/compiler/training/moments.d.ts +80 -0
- package/dist/compiler/training/moments.js +118 -0
- package/dist/compiler/training/output.d.ts +2 -0
- package/dist/compiler/training/output.js +20 -0
- package/dist/compiler/training/plan/contract.d.ts +287 -0
- package/dist/compiler/training/plan/contract.js +49 -0
- package/dist/compiler/training/plan/index.d.ts +5 -0
- package/dist/compiler/training/plan/index.js +4 -0
- package/dist/compiler/training/plan/load.d.ts +9 -0
- package/dist/compiler/training/plan/load.js +153 -0
- package/dist/compiler/training/plan/references.d.ts +19 -0
- package/dist/compiler/training/plan/references.js +57 -0
- package/dist/compiler/training/plan/resolve.d.ts +4 -0
- package/dist/compiler/training/plan/resolve.js +73 -0
- package/dist/compiler/training/plan/targets.d.ts +11 -0
- package/dist/compiler/training/plan/targets.js +71 -0
- package/dist/compiler/training/plan/types.d.ts +36 -0
- package/dist/compiler/training/plan/types.js +1 -0
- package/dist/compiler/training/preparation/assets/Dockerfile +13 -2
- package/dist/compiler/training/preparation/assets/package-lock.json +2 -2
- package/dist/compiler/training/preparation/broker.d.ts +3 -3
- package/dist/compiler/training/preparation/broker.js +6 -4
- package/dist/compiler/training/preparation/contract.d.ts +27 -2
- package/dist/compiler/training/preparation/contract.js +23 -4
- package/dist/compiler/training/preparation/files.d.ts +5 -1
- package/dist/compiler/training/preparation/files.js +76 -15
- package/dist/compiler/training/preparation/image.js +9 -4
- package/dist/compiler/training/preparation/inputs.d.ts +1 -0
- package/dist/compiler/training/preparation/inputs.js +18 -10
- package/dist/compiler/training/preparation/prepare.d.ts +5 -0
- package/dist/compiler/training/preparation/prepare.js +66 -29
- package/dist/compiler/training/preparation/scratch.d.ts +6 -17
- package/dist/compiler/training/preparation/scratch.js +89 -23
- package/dist/compiler/training/repair/contract.d.ts +338 -4
- package/dist/compiler/training/repair/contract.js +2 -0
- package/dist/compiler/training/repair/index.d.ts +1 -1
- package/dist/compiler/training/repair/index.js +1 -1
- package/dist/compiler/training/repair/prepare.d.ts +155 -3
- package/dist/compiler/training/repair/prepare.js +6 -2
- package/dist/compiler/training/repair/witness.d.ts +152 -3
- package/dist/compiler/training/repair/witness.js +8 -2
- package/dist/compiler/training/resolution.d.ts +25 -0
- package/dist/compiler/training/resolution.js +69 -0
- package/dist/compiler/training/rewind/contract.d.ts +321 -0
- package/dist/compiler/training/rewind/contract.js +39 -0
- package/dist/compiler/training/rewind/deployedResource.d.ts +22 -0
- package/dist/compiler/training/rewind/deployedResource.js +19 -0
- package/dist/compiler/training/rewind/feed.d.ts +12 -0
- package/dist/compiler/training/rewind/feed.js +182 -0
- package/dist/compiler/training/rewind/feedContent.d.ts +6 -0
- package/dist/compiler/training/rewind/feedContent.js +38 -0
- package/dist/compiler/training/rewind/git.d.ts +8 -0
- package/dist/compiler/training/rewind/git.js +159 -0
- package/dist/compiler/training/rewind/gitArchive.d.ts +2 -0
- package/dist/compiler/training/rewind/gitArchive.js +7 -0
- package/dist/compiler/training/rewind/gitHistory.d.ts +3 -0
- package/dist/compiler/training/rewind/gitHistory.js +55 -0
- package/dist/compiler/training/rewind/gitProcess.d.ts +19 -0
- package/dist/compiler/training/rewind/gitProcess.js +81 -0
- package/dist/compiler/training/rewind/gitTree.d.ts +14 -0
- package/dist/compiler/training/rewind/gitTree.js +90 -0
- package/dist/compiler/training/rewind/history.d.ts +28 -0
- package/dist/compiler/training/rewind/history.js +239 -0
- package/dist/compiler/training/rewind/index.d.ts +18 -0
- package/dist/compiler/training/rewind/index.js +15 -0
- package/dist/compiler/training/rewind/inputs.d.ts +9 -0
- package/dist/compiler/training/rewind/inputs.js +67 -0
- package/dist/compiler/training/rewind/instant.d.ts +4 -0
- package/dist/compiler/training/rewind/instant.js +24 -0
- package/dist/compiler/training/rewind/leakCheck.d.ts +10 -0
- package/dist/compiler/training/rewind/leakCheck.js +56 -0
- package/dist/compiler/training/rewind/leakFeed.d.ts +5 -0
- package/dist/compiler/training/rewind/leakFeed.js +25 -0
- package/dist/compiler/training/rewind/leakFiles.d.ts +10 -0
- package/dist/compiler/training/rewind/leakFiles.js +106 -0
- package/dist/compiler/training/rewind/leakGit.d.ts +3 -0
- package/dist/compiler/training/rewind/leakGit.js +78 -0
- package/dist/compiler/training/rewind/leakGitPayload.d.ts +4 -0
- package/dist/compiler/training/rewind/leakGitPayload.js +57 -0
- package/dist/compiler/training/rewind/leakInputs.d.ts +7 -0
- package/dist/compiler/training/rewind/leakInputs.js +135 -0
- package/dist/compiler/training/rewind/leakLayout.d.ts +2 -0
- package/dist/compiler/training/rewind/leakLayout.js +17 -0
- package/dist/compiler/training/rewind/leakProvenance.d.ts +3 -0
- package/dist/compiler/training/rewind/leakProvenance.js +88 -0
- package/dist/compiler/training/rewind/materialize.d.ts +136 -0
- package/dist/compiler/training/rewind/materialize.js +212 -0
- package/dist/compiler/training/rewind/memory.d.ts +10 -0
- package/dist/compiler/training/rewind/memory.js +84 -0
- package/dist/compiler/training/rewind/memorySchemas.d.ts +87 -0
- package/dist/compiler/training/rewind/memorySchemas.js +50 -0
- package/dist/compiler/training/rewind/moltnet.d.ts +2 -0
- package/dist/compiler/training/rewind/moltnet.js +54 -0
- package/dist/compiler/training/rewind/moltnetJson.d.ts +13 -0
- package/dist/compiler/training/rewind/moltnetJson.js +180 -0
- package/dist/compiler/training/rewind/moltnetSchemas.d.ts +1226 -0
- package/dist/compiler/training/rewind/moltnetSchemas.js +75 -0
- package/dist/compiler/training/rewind/moltnetSqlite.d.ts +31 -0
- package/dist/compiler/training/rewind/moltnetSqlite.js +192 -0
- package/dist/compiler/training/rewind/moltnetSqliteData.d.ts +10 -0
- package/dist/compiler/training/rewind/moltnetSqliteData.js +113 -0
- package/dist/compiler/training/rewind/recordInput.d.ts +40 -0
- package/dist/compiler/training/rewind/recordInput.js +49 -0
- package/dist/compiler/training/rewind/recordedBundle.d.ts +4 -0
- package/dist/compiler/training/rewind/recordedBundle.js +58 -0
- package/dist/compiler/training/rewind/recordedCommit.d.ts +2 -0
- package/dist/compiler/training/rewind/recordedCommit.js +10 -0
- package/dist/compiler/training/rewind/select.d.ts +18 -0
- package/dist/compiler/training/rewind/select.js +64 -0
- package/dist/compiler/training/rewind/snapshotManifest.d.ts +42 -0
- package/dist/compiler/training/rewind/snapshotManifest.js +134 -0
- package/dist/compiler/training/rewind/taskClock.d.ts +12 -0
- package/dist/compiler/training/rewind/taskClock.js +40 -0
- package/dist/compiler/training/rewind/timestamps.d.ts +4 -0
- package/dist/compiler/training/rewind/timestamps.js +26 -0
- package/dist/compiler/training/rewind/types.d.ts +43 -0
- package/dist/compiler/training/rewind/types.js +1 -0
- package/dist/compiler/training/rewind/volumes.d.ts +12 -0
- package/dist/compiler/training/rewind/volumes.js +58 -0
- package/dist/compiler/training/selection.d.ts +7 -0
- package/dist/compiler/training/selection.js +15 -0
- package/dist/compiler/types.d.ts +6 -3
- package/dist/compiler/upProject.d.ts +1 -0
- package/dist/compiler/upProject.js +21 -5
- package/dist/compiler/workspaceBundleArtifacts.d.ts +16 -1
- package/dist/compiler/workspaceBundleArtifacts.js +69 -20
- package/dist/compiler/workspaceBundleCache.d.ts +23 -0
- package/dist/compiler/workspaceBundleCache.js +79 -0
- package/dist/compiler/workspaceBundleDependencies.d.ts +21 -0
- package/dist/compiler/workspaceBundleDependencies.js +122 -0
- package/dist/compiler/workspaceBundleFiles.d.ts +51 -0
- package/dist/compiler/workspaceBundleFiles.js +251 -0
- package/dist/compiler/workspaceBundleGenerated.d.ts +25 -0
- package/dist/compiler/workspaceBundleGenerated.js +103 -0
- package/dist/compiler/workspaceBundleGit.d.ts +64 -0
- package/dist/compiler/workspaceBundleGit.js +154 -0
- package/dist/compiler/workspaceBundleKey.d.ts +34 -0
- package/dist/compiler/workspaceBundleKey.js +17 -0
- package/dist/compiler/workspaceBundleResolve.d.ts +56 -0
- package/dist/compiler/workspaceBundleResolve.js +144 -0
- package/dist/compiler/workspaceBundleRun.d.ts +41 -0
- package/dist/compiler/workspaceBundleRun.js +79 -0
- package/dist/compiler/workspaceBundleTar.d.ts +47 -0
- package/dist/compiler/workspaceBundleTar.js +140 -0
- package/dist/compiler/workspaceBundleTree.d.ts +15 -0
- package/dist/compiler/workspaceBundleTree.js +58 -0
- package/dist/compiler/workspaceGitFetch.d.ts +41 -0
- package/dist/compiler/workspaceGitFetch.js +155 -0
- package/dist/compiler/workspaceGitPins.d.ts +33 -0
- package/dist/compiler/workspaceGitPins.js +127 -0
- package/dist/compiler/workspaceResources.d.ts +5 -1
- package/dist/compiler/workspaceResources.js +32 -5
- package/dist/deployment/activation.d.ts +3 -0
- package/dist/deployment/activation.js +12 -0
- package/dist/deployment/canaryCutover.d.ts +1 -1
- package/dist/deployment/candidateRecording.d.ts +8 -0
- package/dist/deployment/candidateRecording.js +22 -0
- package/dist/deployment/dockerManager.d.ts +5 -3
- package/dist/deployment/dockerManager.js +12 -2
- package/dist/deployment/downDeployment.d.ts +2 -0
- package/dist/deployment/downDeployment.js +6 -2
- package/dist/deployment/homeStore.d.ts +9 -1
- package/dist/deployment/homeStore.js +16 -53
- package/dist/deployment/index.d.ts +6 -0
- package/dist/deployment/index.js +6 -0
- package/dist/deployment/pidLock.d.ts +25 -0
- package/dist/deployment/pidLock.js +81 -0
- package/dist/deployment/record.d.ts +85 -1
- package/dist/deployment/record.js +11 -5
- package/dist/deployment/recordPublication.d.ts +15 -0
- package/dist/deployment/recordPublication.js +76 -0
- package/dist/deployment/recordedMemoryRetention.d.ts +18 -0
- package/dist/deployment/recordedMemoryRetention.js +27 -0
- package/dist/deployment/resourceLog.d.ts +140 -0
- package/dist/deployment/resourceLog.js +78 -0
- package/dist/distribution/buildDistributionReport.d.ts +3 -0
- package/dist/distribution/buildDistributionReport.js +5 -0
- package/dist/distribution/consumeImage.d.ts +3 -0
- package/dist/distribution/consumeImage.js +23 -31
- package/dist/distribution/consumeImageLifecycle.d.ts +4 -1
- package/dist/distribution/consumeImageLifecycle.js +14 -3
- package/dist/distribution/consumeImageSupport.d.ts +7 -0
- package/dist/distribution/consumeImageSupport.js +25 -0
- package/dist/distribution/distributionReportSchema.d.ts +47 -0
- package/dist/distribution/distributionReportSchema.js +20 -0
- package/dist/distribution/renderImageInterface.js +1 -1
- package/dist/distribution/types.d.ts +15 -0
- package/dist/filesystem/durableWrite.d.ts +10 -0
- package/dist/filesystem/durableWrite.js +87 -0
- package/dist/filesystem/index.d.ts +2 -0
- package/dist/filesystem/index.js +2 -0
- package/dist/filesystem/retainedJsonl.d.ts +23 -0
- package/dist/filesystem/retainedJsonl.js +123 -0
- package/dist/manifest/commandSchemas.d.ts +5 -0
- package/dist/manifest/commandSchemas.js +5 -0
- package/dist/manifest/executionSchemas.d.ts +20 -0
- package/dist/manifest/executionSchemas.js +13 -3
- package/dist/manifest/index.d.ts +2 -0
- package/dist/manifest/index.js +2 -0
- package/dist/manifest/loadManifest.js +3 -26
- package/dist/manifest/mcpSchemas.d.ts +61 -0
- package/dist/manifest/mcpSchemas.js +57 -11
- package/dist/manifest/memorySchemas.d.ts +1 -1
- package/dist/manifest/memorySchemas.js +1 -1
- package/dist/manifest/parseManifest.d.ts +7 -0
- package/dist/manifest/parseManifest.js +65 -0
- package/dist/manifest/renderSpawnfile.js +4 -1
- package/dist/manifest/renderSpawnfileWorkspace.js +6 -2
- package/dist/manifest/schemas.d.ts +1206 -132
- package/dist/manifest/schemas.js +14 -4
- package/dist/manifest/teamNetworkSchemas.d.ts +1 -1
- package/dist/manifest/trainingDataSchemas.d.ts +357 -0
- package/dist/manifest/trainingDataSchemas.js +31 -0
- package/dist/manifest/trainingSchemas.d.ts +49 -0
- package/dist/manifest/trainingSchemas.js +44 -0
- package/dist/manifest/volumeFeedSchemas.d.ts +52 -0
- package/dist/manifest/volumeFeedSchemas.js +104 -0
- package/dist/manifest/workspaceSchemas.d.ts +182 -5
- package/dist/manifest/workspaceSchemas.js +111 -7
- package/dist/recording/compose.d.ts +3 -0
- package/dist/recording/compose.js +93 -0
- package/dist/recording/deployment.d.ts +15 -0
- package/dist/recording/deployment.js +38 -0
- package/dist/recording/history.d.ts +16 -0
- package/dist/recording/history.js +47 -0
- package/dist/recording/index.d.ts +9 -0
- package/dist/recording/index.js +9 -0
- package/dist/recording/moment.d.ts +61 -0
- package/dist/recording/moment.js +36 -0
- package/dist/recording/parse.d.ts +15 -0
- package/dist/recording/parse.js +74 -0
- package/dist/recording/read.d.ts +8 -0
- package/dist/recording/read.js +61 -0
- package/dist/recording/store.d.ts +10 -0
- package/dist/recording/store.js +94 -0
- package/dist/recording/sync.d.ts +24 -0
- package/dist/recording/sync.js +126 -0
- package/dist/recording/types.d.ts +45 -0
- package/dist/recording/types.js +2 -0
- package/dist/release/drainControl.d.ts +54 -0
- package/dist/release/drainControl.js +137 -0
- package/dist/release/drainPhase.d.ts +37 -0
- package/dist/release/drainPhase.js +161 -0
- package/dist/release/index.d.ts +11 -0
- package/dist/release/index.js +11 -0
- package/dist/release/ledger.d.ts +75 -0
- package/dist/release/ledger.js +111 -0
- package/dist/release/notify.d.ts +58 -0
- package/dist/release/notify.js +126 -0
- package/dist/release/pending.d.ts +35 -0
- package/dist/release/pending.js +60 -0
- package/dist/release/postDeploy.d.ts +32 -0
- package/dist/release/postDeploy.js +62 -0
- package/dist/release/releaseDefaults.d.ts +9 -0
- package/dist/release/releaseDefaults.js +115 -0
- package/dist/release/releaseDocker.d.ts +38 -0
- package/dist/release/releaseDocker.js +94 -0
- package/dist/release/releaseTypes.d.ts +94 -0
- package/dist/release/releaseTypes.js +1 -0
- package/dist/release/runRelease.d.ts +9 -0
- package/dist/release/runRelease.js +218 -0
- package/dist/release/swap.d.ts +23 -0
- package/dist/release/swap.js +55 -0
- package/dist/release/types.d.ts +50 -0
- package/dist/release/types.js +29 -0
- package/dist/report/index.d.ts +1 -0
- package/dist/report/index.js +1 -0
- package/dist/report/recording.d.ts +57 -0
- package/dist/report/recording.js +26 -0
- package/dist/report/types.d.ts +58 -0
- package/dist/runtime/container.js +8 -13
- package/dist/runtime/daimon/adapter.js +15 -4
- package/dist/runtime/daimon/config.d.ts +4 -0
- package/dist/runtime/daimon/config.js +53 -4
- package/dist/runtime/daimon/contract-manifest.json +1 -0
- package/dist/runtime/daimon/contract-manifest.sha256 +1 -0
- package/dist/runtime/daimon/contractManifest.d.ts +59 -8
- package/dist/runtime/daimon/contractManifest.js +26 -10
- package/dist/runtime/daimon/grokTurnLimits.d.ts +25 -0
- package/dist/runtime/daimon/grokTurnLimits.js +51 -0
- package/dist/runtime/daimon/grokWorkerConfigBytes.d.ts +17 -0
- package/dist/runtime/daimon/grokWorkerConfigBytes.js +17 -0
- package/dist/runtime/daimon/grokWorkerContract.d.ts +5 -0
- package/dist/runtime/daimon/grokWorkerContract.js +13 -1
- package/dist/runtime/daimon/recording.d.ts +19 -0
- package/dist/runtime/daimon/recording.js +50 -0
- package/dist/runtime/daimon/scheduleAuthority.d.ts +8 -0
- package/dist/runtime/daimon/scheduleAuthority.js +19 -5
- package/dist/runtime/daimon/wakeMoments.d.ts +15 -0
- package/dist/runtime/daimon/wakeMoments.js +17 -0
- package/dist/runtime/daimonInstall.d.ts +3 -0
- package/dist/runtime/daimonInstall.js +25 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/install.d.ts +2 -0
- package/dist/runtime/install.js +1 -0
- package/dist/runtime/openclaw/adapter.js +3 -0
- package/dist/runtime/pi/adapter.js +3 -0
- package/dist/runtime/pi/containerTargets.js +6 -0
- package/dist/runtime/picoclaw/adapter.js +3 -0
- package/dist/runtime/registry.d.ts +3 -0
- package/dist/runtime/registry.js +13 -1
- package/dist/runtime/types.d.ts +15 -0
- package/dist/runtime/usageLedgerRead.d.ts +6 -0
- package/dist/runtime/usageLedgerRead.js +3 -3
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/shared/recording.d.ts +8 -0
- package/dist/shared/recording.js +25 -0
- package/dist/target/dockerCommandExecutorCore.js +1 -1
- package/dist/target/dockerTargetBinding.js +2 -1
- package/dist/volume/feedLand.d.ts +31 -0
- package/dist/volume/feedLand.js +174 -0
- package/dist/volume/feedLandings.d.ts +45 -0
- package/dist/volume/feedLandings.js +111 -0
- package/dist/volume/feedLayout.d.ts +61 -0
- package/dist/volume/feedLayout.js +234 -0
- package/dist/volume/feedLock.d.ts +7 -0
- package/dist/volume/feedLock.js +131 -0
- package/dist/volume/feedManifest.d.ts +27 -0
- package/dist/volume/feedManifest.js +123 -0
- package/dist/volume/feedPrepare.d.ts +16 -0
- package/dist/volume/feedPrepare.js +228 -0
- package/dist/volume/feedProject.d.ts +39 -0
- package/dist/volume/feedProject.js +92 -0
- package/dist/volume/feedRecord.d.ts +55 -0
- package/dist/volume/feedRecord.js +148 -0
- package/dist/volume/feedRef.d.ts +43 -0
- package/dist/volume/feedRef.js +117 -0
- package/dist/volume/feedRefresh.d.ts +15 -0
- package/dist/volume/feedRefresh.js +187 -0
- package/dist/volume/feedSource.d.ts +66 -0
- package/dist/volume/feedSource.js +104 -0
- package/dist/volume/feedTarget.d.ts +70 -0
- package/dist/volume/feedTarget.js +9 -0
- package/dist/volume/feedTestKit.d.ts +11 -0
- package/dist/volume/feedTestKit.js +45 -0
- package/dist/volume/feedVerify.d.ts +18 -0
- package/dist/volume/feedVerify.js +104 -0
- package/dist/volume/index.d.ts +13 -0
- package/dist/volume/index.js +13 -0
- package/package.json +3 -3
- package/runtimes.yaml +8 -6
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { SpawnfileError } from "../shared/index.js";
|
|
3
|
+
import { resolveDaimonGrokRegistrationLimits } from "../runtime/daimon/grokTurnLimits.js";
|
|
3
4
|
import { DAIMON_ORGANIZATION_TARGET_ID, DAIMON_RUNTIME_ACCEPTANCE_STORE_DIRECTORY, DAIMON_RUNTIME_HOMES_DIRECTORY, DAIMON_WAKE_FUSE_DIRECTORY } from "../runtime/daimon/config.js";
|
|
4
5
|
import { DAIMON_AGY_SUBSCRIPTION_REALM, DAIMON_GROK_BROKER_MODELS, DAIMON_GROK_BROKER_REASONING_EFFORTS, DAIMON_GROK_ENGINE_BROKER, DAIMON_GROK_SUBSCRIPTION_REALM, DAIMON_GROK_TURN_USAGE_LEDGER, DAIMON_RUNTIME_HOME_ROOT } from "../runtime/daimon/contractManifest.js";
|
|
5
6
|
import { DAIMON_GROK_WORKER_HOME_DIRECTORY, daimonGrokWorkerSandboxProfileSha256, renderDaimonGrokWorkerSandboxProfile, resolveDaimonGrokWorkerConfig } from "../runtime/daimon/grokWorkerContract.js";
|
|
@@ -193,6 +194,10 @@ export const resolveDaimonGrokRegistrations = (plans) => {
|
|
|
193
194
|
const { model, reasoningEffort } = declaredModel(plan, agentId);
|
|
194
195
|
const config = resolveDaimonGrokWorkerConfig(model, reasoningEffort);
|
|
195
196
|
const denyPaths = resolveDaimonGrokWorkerDenyPaths(plans, plan, agentId, homes, home);
|
|
197
|
+
// The registration's per-turn budget: the contract defaults unless the agent declared its own.
|
|
198
|
+
// A wake may only lower this, so an organization that needs more than four minutes a turn has
|
|
199
|
+
// to declare it here rather than at wake time, where the broker refuses any raise.
|
|
200
|
+
const limits = resolveDaimonGrokRegistrationLimits(plan.grokTurnLimitsByNodeId?.[agentId]);
|
|
196
201
|
const profile = renderDaimonGrokWorkerSandboxProfile(denyPaths);
|
|
197
202
|
for (const [label, value] of [["GROK_HOME", grokHome], ["profile", path.posix.join(grokHome, "sandbox.toml")], ["events", path.posix.join(grokHome, DAIMON_GROK_ENGINE_BROKER.worker.home.sandboxEvents.relativePath)], ["private temp", path.posix.join(home, DAIMON_GROK_ENGINE_BROKER.worker.home.privateTmp.relativeToWorkerHome)]])
|
|
198
203
|
assertCanonicalRegisteredPath(label, value);
|
|
@@ -202,6 +207,7 @@ export const resolveDaimonGrokRegistrations = (plans) => {
|
|
|
202
207
|
const backings = new Set(plans.flatMap((candidate) => candidate.resources ?? []).map((resource) => resource.backingPath));
|
|
203
208
|
return {
|
|
204
209
|
deferredDenyPaths: denyPaths.filter((entry) => backings.has(entry)),
|
|
210
|
+
limits,
|
|
205
211
|
agentId,
|
|
206
212
|
config: config.bytes,
|
|
207
213
|
configSha256: config.sha256,
|
|
@@ -249,9 +255,11 @@ const resolveDaimonGrokInferenceLedger = (inferenceLedgerPath, registrations) =>
|
|
|
249
255
|
};
|
|
250
256
|
/** `service.json` v2, exactly the shape Daimon's strict `parseEngineBrokerServiceConfig` accepts. */
|
|
251
257
|
export const renderDaimonGrokServiceConfig = (registrations, options = {}) => ({
|
|
252
|
-
version: DAIMON_GROK_ENGINE_BROKER.serviceConfigVersions[1],
|
|
258
|
+
version: DAIMON_GROK_ENGINE_BROKER.serviceConfigVersions[options.version === "v3" ? 2 : 1],
|
|
253
259
|
credentialHome: DAIMON_GROK_ENGINE_BROKER.credentialHomePath,
|
|
254
260
|
turnStore: resolveDaimonGrokTurnStore(options.turnStore),
|
|
261
|
+
...(options.maxRunRequests === undefined ? {} : { maxRunRequests: options.maxRunRequests }),
|
|
262
|
+
...(options.runRequestStore === undefined ? {} : { runRequestStore: assertCanonicalRegisteredPath("run request store", options.runRequestStore) }),
|
|
255
263
|
...(options.inferenceLedgerPath === undefined ? {} : { inferenceLedgerPath: resolveDaimonGrokInferenceLedger(options.inferenceLedgerPath, registrations) }),
|
|
256
264
|
registrations: registrations.map((entry) => ({
|
|
257
265
|
agentId: entry.agentId,
|
|
@@ -261,8 +269,13 @@ export const renderDaimonGrokServiceConfig = (registrations, options = {}) => ({
|
|
|
261
269
|
profilePath: entry.profilePath,
|
|
262
270
|
eventsPath: entry.eventsPath,
|
|
263
271
|
profileSha256: entry.profileSha256,
|
|
264
|
-
usageLedgerPath: entry.usageLedgerPath,
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}))
|
|
272
|
+
...(options.version === "v3" ? {} : { usageLedgerPath: entry.usageLedgerPath,
|
|
273
|
+
limits: { ...(entry.limits ?? DAIMON_GROK_ENGINE_BROKER.turnLimits.v1Defaults) },
|
|
274
|
+
model: { id: entry.model, reasoningEffort: entry.reasoningEffort } })
|
|
275
|
+
})),
|
|
276
|
+
...(options.version === "v3" ? { slotPolicies: registrations.map(entry => ({
|
|
277
|
+
slot: entry.slot, usageLedgerPath: entry.usageLedgerPath,
|
|
278
|
+
limits: { ...(entry.limits ?? DAIMON_GROK_ENGINE_BROKER.turnLimits.v1Defaults) },
|
|
279
|
+
model: { id: entry.model, reasoningEffort: entry.reasoningEffort }
|
|
280
|
+
})) } : {})
|
|
268
281
|
});
|
|
@@ -5,7 +5,20 @@ export declare const renderDaimonOwnershipProgram: (opaqueTargets: string[], opa
|
|
|
5
5
|
}>, privateDirectories: string[], privateFiles: string[], privateModeDirectories: string[], creatablePrivateDirectories: Array<{
|
|
6
6
|
anchor: string;
|
|
7
7
|
target: string;
|
|
8
|
-
}
|
|
8
|
+
}>,
|
|
9
|
+
/**
|
|
10
|
+
* A brokered Grok worker's sandbox cannot be applied when `/var` is traverse-only.
|
|
11
|
+
* Grok 1.0.34 builds every profile inside bubblewrap and then verifies it from the
|
|
12
|
+
* worker uid; with `/var` at 0711 that verification fails and the worker refuses to
|
|
13
|
+
* start ("could not apply the 'daimon-strict' sandbox profile"), which is every turn
|
|
14
|
+
* of every Grok agent. Bisected on the production host: with `/var` at 0755 the
|
|
15
|
+
* sandbox applies and the turn runs, at 0711 it never does, and the deeper ancestors
|
|
16
|
+
* (`/var/lib`, the worker root) make no difference either way — so only this one
|
|
17
|
+
* level is widened, only for an organization that actually runs a Grok worker, and
|
|
18
|
+
* only to the mode the proven-working training container has always had. Codex- and
|
|
19
|
+
* AGY-only organizations keep the traverse-only `/var` unchanged.
|
|
20
|
+
*/
|
|
21
|
+
grokWorkersPresent?: boolean) => string;
|
|
9
22
|
export declare const resolveDaimonVolumeIdentityFiles: (runtimePlans: RuntimeTargetPlan[]) => Array<{
|
|
10
23
|
path: string;
|
|
11
24
|
identity: string;
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { VOLUME_BOOTSTRAP_MARKER, VOLUME_BOOTSTRAP_MARKER_CONTENT } from "./containerVolumeBootstrap.js";
|
|
3
3
|
const SPAWNFILE_PRIVATE_STATE_ROOT = "/var/lib/spawnfile";
|
|
4
|
-
export const renderDaimonOwnershipProgram = (opaqueTargets, opaqueDescendantRoots, immutableRuntimeRoots, volumeIdentityFiles, privateDirectories, privateFiles, privateModeDirectories, creatablePrivateDirectories
|
|
4
|
+
export const renderDaimonOwnershipProgram = (opaqueTargets, opaqueDescendantRoots, immutableRuntimeRoots, volumeIdentityFiles, privateDirectories, privateFiles, privateModeDirectories, creatablePrivateDirectories,
|
|
5
|
+
/**
|
|
6
|
+
* A brokered Grok worker's sandbox cannot be applied when `/var` is traverse-only.
|
|
7
|
+
* Grok 1.0.34 builds every profile inside bubblewrap and then verifies it from the
|
|
8
|
+
* worker uid; with `/var` at 0711 that verification fails and the worker refuses to
|
|
9
|
+
* start ("could not apply the 'daimon-strict' sandbox profile"), which is every turn
|
|
10
|
+
* of every Grok agent. Bisected on the production host: with `/var` at 0755 the
|
|
11
|
+
* sandbox applies and the turn runs, at 0711 it never does, and the deeper ancestors
|
|
12
|
+
* (`/var/lib`, the worker root) make no difference either way — so only this one
|
|
13
|
+
* level is widened, only for an organization that actually runs a Grok worker, and
|
|
14
|
+
* only to the mode the proven-working training container has always had. Codex- and
|
|
15
|
+
* AGY-only organizations keep the traverse-only `/var` unchanged.
|
|
16
|
+
*/
|
|
17
|
+
grokWorkersPresent = false) => [
|
|
5
18
|
"const fs = require('node:fs');",
|
|
6
19
|
"const constants = fs.constants;",
|
|
7
20
|
"const uid = Number(process.argv[2]);",
|
|
@@ -151,7 +164,7 @@ export const renderDaimonOwnershipProgram = (opaqueTargets, opaqueDescendantRoot
|
|
|
151
164
|
`const volumeBootstrapMarker = ${JSON.stringify(VOLUME_BOOTSTRAP_MARKER)}, volumeBootstrapContent = ${JSON.stringify(`${VOLUME_BOOTSTRAP_MARKER_CONTENT}\n`)};`,
|
|
152
165
|
"const verifyVolumeIdentityFile = (fd, expected, mode, device) => { const before = fs.fstatSync(fd); if (!before.isFile() || before.nlink !== 1 || before.uid !== 0 || before.gid !== 0 || (before.mode & 0o777) !== mode || before.dev !== device || before.size !== Buffer.byteLength(expected)) fail('volume identity anchor is unsafe'); const bytes = Buffer.alloc(before.size); let offset=0; while(offset<bytes.length){const count=fs.readSync(fd,bytes,offset,bytes.length-offset,offset);if(count<1)fail('volume identity anchor read failed');offset+=count;} const after = fs.fstatSync(fd); if (!bytes.equals(Buffer.from(expected)) || after.dev !== before.dev || after.ino !== before.ino || after.size !== before.size || after.mtimeMs !== before.mtimeMs || after.ctimeMs !== before.ctimeMs) fail('volume identity anchor changed'); };",
|
|
153
166
|
"const secureVolumeIdentity = (entry) => { const parentPath = require('node:path').posix.dirname(entry.path); if (entry.path !== `${parentPath}/.spawnfile-resource-identity`) fail('volume identity anchor path is invalid'); const parent = openDirectoryPath(parentPath); let marker, sentinel; try { const parentInfo = fs.fstatSync(parent), parentMode = parentInfo.mode & 0o777, freshParent = parentInfo.uid === 0 && parentInfo.gid === 0 && parentMode === 0o755, establishedParent = parentInfo.uid === uid && parentInfo.gid === uid && parentMode === 0o755; if (!freshParent && !establishedParent) fail('volume identity parent is unsafe'); const names = fs.readdirSync(`/proc/self/fd/${parent}`).sort(), hasSentinel = names.includes('.spawnfile-resource-identity'), hasMarker = names.includes(volumeBootstrapMarker); if (hasSentinel) { sentinel = fs.openSync(`/proc/self/fd/${parent}/.spawnfile-resource-identity`, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK); verifyVolumeIdentityFile(sentinel, `${entry.identity}\n`, 0o644, parentInfo.dev); if (hasMarker) { if (!freshParent || names.length !== 2) fail('volume bootstrap recovery preimage is unsafe'); marker = fs.openSync(`/proc/self/fd/${parent}/${volumeBootstrapMarker}`, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK); verifyVolumeIdentityFile(marker, volumeBootstrapContent, 0o600, parentInfo.dev); fs.fsyncSync(sentinel); fs.fsyncSync(parent); verifyVolumeIdentityFile(sentinel, `${entry.identity}\n`, 0o644, parentInfo.dev); verifyVolumeIdentityFile(marker, volumeBootstrapContent, 0o600, parentInfo.dev); fs.unlinkSync(`/proc/self/fd/${parent}/${volumeBootstrapMarker}`); fs.fsyncSync(parent); } return; } if (!freshParent || names.length !== 1 || !hasMarker) fail('volume bootstrap preimage is unsafe'); marker = fs.openSync(`/proc/self/fd/${parent}/${volumeBootstrapMarker}`, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK); verifyVolumeIdentityFile(marker, volumeBootstrapContent, 0o600, parentInfo.dev); const expected = Buffer.from(`${entry.identity}\n`); try { sentinel = fs.openSync(`/proc/self/fd/${parent}/.spawnfile-resource-identity`, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW | constants.O_NONBLOCK, 0o644); let offset=0; while(offset<expected.length){const written=fs.writeSync(sentinel,expected,offset,expected.length-offset,offset);if(written<1)fail('volume identity anchor write failed');offset+=written;} fs.fchownSync(sentinel,0,0);fs.fchmodSync(sentinel,0o644);fs.fsyncSync(sentinel); } finally { expected.fill(0); } fs.closeSync(sentinel); sentinel=undefined; sentinel=fs.openSync(`/proc/self/fd/${parent}/.spawnfile-resource-identity`,constants.O_RDONLY|constants.O_NOFOLLOW|constants.O_NONBLOCK);verifyVolumeIdentityFile(sentinel,`${entry.identity}\n`,0o644,parentInfo.dev);fs.fsyncSync(parent);verifyVolumeIdentityFile(marker,volumeBootstrapContent,0o600,parentInfo.dev);fs.unlinkSync(`/proc/self/fd/${parent}/${volumeBootstrapMarker}`);fs.fsyncSync(parent); } finally { if(marker!==undefined)fs.closeSync(marker);if(sentinel!==undefined)fs.closeSync(sentinel);fs.closeSync(parent); } };",
|
|
154
|
-
|
|
167
|
+
`for (const target of ${grokWorkersPresent ? "['/var/lib']" : "['/var', '/var/lib']"}) secureFixedTraversalAncestor(target);`,
|
|
155
168
|
`secureSharedStateAncestor('${SPAWNFILE_PRIVATE_STATE_ROOT}');`,
|
|
156
169
|
// `/var/lib/spawnfile/daimon` hosts several independently-owned children
|
|
157
170
|
// (AGY/Grok subscription realms and the wake fuse at organization uid, the
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { DAIMON_RUNTIME_ACCEPTANCE_STORE_MOUNT_ID, DAIMON_WAKE_FUSE_DIRECTORY } from "../runtime/daimon/config.js";
|
|
3
3
|
import { DAIMON_GROK_TURN_USAGE_LEDGER } from "../runtime/daimon/contractManifest.js";
|
|
4
|
+
import { DAIMON_RECORDING_MOUNT_ID_PREFIX } from "../runtime/daimon/recording.js";
|
|
4
5
|
import { MOLTNET_READINESS_DIRECTORY } from "./containerReadinessPaths.js";
|
|
5
6
|
import { createBackedMountGuard } from "./containerBackedMountRender.js";
|
|
6
7
|
import { renderDaimonOwnershipProgram, resolveDaimonVolumeIdentityFiles } from "./containerDaimonOwnershipGuardRender.js";
|
|
@@ -113,18 +114,11 @@ const privateModeDirectories = (runtimePlans, moltnet) => [
|
|
|
113
114
|
.filter((mount) => mount.id === DAIMON_RUNTIME_ACCEPTANCE_STORE_MOUNT_ID
|
|
114
115
|
|| mount.id === DAIMON_AGY_SUBSCRIPTION_REALM_MOUNT_ID
|
|
115
116
|
|| mount.id.startsWith(DAIMON_AGY_RUNTIME_HOME_MOUNT_ID_PREFIX)
|
|
117
|
+
|| mount.id.startsWith(DAIMON_RECORDING_MOUNT_ID_PREFIX)
|
|
116
118
|
|| mount.id.startsWith(DAIMON_PORTABLE_ENGINE_HOME_MOUNT_ID_PREFIX))
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
// this mount, and the ancestor pass below only *chowns* it, so it stayed
|
|
121
|
-
// 0755 and was the one path under `/var/lib/spawnfile` a Grok worker uid
|
|
122
|
-
// could open. Securing it to 0700 2000:2000 backs the acceptance store's
|
|
123
|
-
// sandbox `deny` entry with unix modes as defense in depth (see
|
|
124
|
-
// `containerDaimonGrokWorkerRender.ts`). Nothing loses access: the only thing
|
|
125
|
-
// beneath it is this store, already 0700 2000:2000, so every reader that
|
|
126
|
-
// works today is the organization uid or a `docker exec` root holding
|
|
127
|
-
// CAP_DAC_READ_SEARCH.
|
|
119
|
+
// Secure the acceptance store's parent as well: Docker creates state/ at
|
|
120
|
+
// 0755 and the ancestor pass only chowns it. Mode 0700 prevents Grok worker
|
|
121
|
+
// traversal while retaining organization-uid and privileged exec access.
|
|
128
122
|
.flatMap((mount) => mount.id === DAIMON_RUNTIME_ACCEPTANCE_STORE_MOUNT_ID
|
|
129
123
|
? [mount.mount_path, path.posix.dirname(mount.mount_path)]
|
|
130
124
|
: [mount.mount_path])
|
|
@@ -225,7 +219,7 @@ export const renderDaimonUidEntrypoint = (runtimePlans, persistentMountPaths = [
|
|
|
225
219
|
...createBackedMountGuard(persistentMounts),
|
|
226
220
|
`state_roots=(${ownershipPlan.stateRoots.map(quote).join(" ")})`,
|
|
227
221
|
"node - \"$uid\" \"${state_roots[@]}\" <<'SPAWNFILE_DAIMON_OWNERSHIP'",
|
|
228
|
-
renderDaimonOwnershipProgram(opaqueTargets, ownershipPlan.opaqueDescendantRoots, immutableRuntimeRoots, volumeIdentityFiles, ownershipPlan.privateDirectories, ownershipPlan.privateFiles, ownershipPlan.privateModeDirectories, ownershipPlan.creatablePrivateDirectories),
|
|
222
|
+
renderDaimonOwnershipProgram(opaqueTargets, ownershipPlan.opaqueDescendantRoots, immutableRuntimeRoots, volumeIdentityFiles, ownershipPlan.privateDirectories, ownershipPlan.privateFiles, ownershipPlan.privateModeDirectories, ownershipPlan.creatablePrivateDirectories, resolveDaimonGrokRegistrations(runtimePlans).length > 0),
|
|
229
223
|
"SPAWNFILE_DAIMON_OWNERSHIP",
|
|
230
224
|
`for fixed_uid in ${DAIMON_ORGANIZATION_UID} ${DAIMON_BROKER_UID} ${resolveDaimonGrokRegistrations(runtimePlans).map((entry) => entry.uid).join(" ")}; do`,
|
|
231
225
|
' if ! getent group "$fixed_uid" >/dev/null; then groupadd -K GID_MIN=1 --gid "$fixed_uid" "daimon-$fixed_uid"; fi',
|
|
@@ -22,4 +22,14 @@ export declare const resolveWorkspaceResourceVolumes: (runtimePlans: readonly Ru
|
|
|
22
22
|
resources: ResolvedTargetResourcePlan[];
|
|
23
23
|
mounts: WorkspaceResourcePersistentMount[];
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* One source agent's workspace path inside its runtime target, still in the
|
|
27
|
+
* target's placeholder vocabulary (`<instance-root>`, `<workspace-path>`),
|
|
28
|
+
* which container rendering substitutes once the target's instance paths are
|
|
29
|
+
* known. Mount link paths and MCP `${workspace}` both resolve through here.
|
|
30
|
+
*/
|
|
31
|
+
export declare const expandSourceWorkspacePathTemplate: (meta: RuntimeContainerMeta, source: {
|
|
32
|
+
agentName: string;
|
|
33
|
+
slug: string;
|
|
34
|
+
}) => string;
|
|
25
35
|
export declare const resolveTargetResources: (target: ContainerTarget, inputs: ContainerTargetInput[], instancePaths: RuntimeTargetPlan["instancePaths"], meta: RuntimeContainerMeta, planRoot: string, deploymentLineage?: string) => ResolvedTargetResourcePlan[];
|
|
@@ -2,11 +2,12 @@ import path from "node:path";
|
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { SpawnfileError } from "../shared/index.js";
|
|
4
4
|
import { createExclusiveReattachVolumeName } from "../shared/index.js";
|
|
5
|
-
import { mergeWorkspaceResourcePlans } from "./workspaceResources.js";
|
|
5
|
+
import { mergeWorkspaceResourcePlans, workspaceResourceTargetId } from "./workspaceResources.js";
|
|
6
6
|
const CONFIG_FILE_PLACEHOLDER = "<config-file>";
|
|
7
7
|
const INSTANCE_ROOT_PLACEHOLDER = "<instance-root>";
|
|
8
8
|
const SOURCE_AGENT_PLACEHOLDER = "<agent-name>";
|
|
9
9
|
const SOURCE_SLUG_PLACEHOLDER = "<source-slug>";
|
|
10
|
+
const WORKSPACE_PATH_PLACEHOLDER = "<workspace-path>";
|
|
10
11
|
const digest = (value) => createHash("sha256").update(value).digest("hex");
|
|
11
12
|
export const resolveWorkspaceResourceVolumes = (runtimePlans) => {
|
|
12
13
|
const resources = runtimePlans.flatMap((runtimePlan) => (runtimePlan.resources ?? []));
|
|
@@ -43,19 +44,27 @@ export const resolveWorkspaceResourceVolumes = (runtimePlans) => {
|
|
|
43
44
|
reason: `Workspace ${resource.sharing} resource ${resource.id}`, volume_name: resource.volumeName
|
|
44
45
|
})) };
|
|
45
46
|
};
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
/**
|
|
48
|
+
* One source agent's workspace path inside its runtime target, still in the
|
|
49
|
+
* target's placeholder vocabulary (`<instance-root>`, `<workspace-path>`),
|
|
50
|
+
* which container rendering substitutes once the target's instance paths are
|
|
51
|
+
* known. Mount link paths and MCP `${workspace}` both resolve through here.
|
|
52
|
+
*/
|
|
53
|
+
export const expandSourceWorkspacePathTemplate = (meta, source) => meta.instancePaths.sourceWorkspacePathTemplate
|
|
54
|
+
? meta.instancePaths.sourceWorkspacePathTemplate
|
|
55
|
+
.replaceAll(CONFIG_FILE_PLACEHOLDER, meta.configFileName)
|
|
56
|
+
.replaceAll(SOURCE_AGENT_PLACEHOLDER, source.agentName)
|
|
57
|
+
.replaceAll(SOURCE_SLUG_PLACEHOLDER, source.slug)
|
|
58
|
+
: WORKSPACE_PATH_PLACEHOLDER;
|
|
59
|
+
const resolveSourceWorkspacePath = (input, instancePaths, meta) => {
|
|
48
60
|
const instanceRoot = instancePaths.instanceRoot ?? path.posix.dirname(instancePaths.workspacePath);
|
|
49
|
-
return
|
|
61
|
+
return expandSourceWorkspacePathTemplate(meta, {
|
|
62
|
+
agentName: input.value.kind === "agent" ? input.value.name : input.slug,
|
|
63
|
+
slug: input.slug
|
|
64
|
+
})
|
|
50
65
|
.replaceAll(INSTANCE_ROOT_PLACEHOLDER, instanceRoot)
|
|
51
|
-
.replaceAll(
|
|
52
|
-
.replaceAll(SOURCE_AGENT_PLACEHOLDER, agentName)
|
|
53
|
-
.replaceAll(SOURCE_SLUG_PLACEHOLDER, input.slug);
|
|
66
|
+
.replaceAll(WORKSPACE_PATH_PLACEHOLDER, instancePaths.workspacePath);
|
|
54
67
|
};
|
|
55
|
-
const resolveSourceWorkspacePath = (input, instancePaths, meta) => meta.instancePaths.sourceWorkspacePathTemplate
|
|
56
|
-
? replaceSourceWorkspacePathTemplate(meta.instancePaths.sourceWorkspacePathTemplate, input, instancePaths, meta)
|
|
57
|
-
: instancePaths.workspacePath;
|
|
58
|
-
const sourceTargetId = (target, input, isMergedTarget) => isMergedTarget ? `${target.id}:${input.id}` : target.id;
|
|
59
68
|
const pathsOverlap = (left, right) => left === right || left.startsWith(`${right}/`) || right.startsWith(`${left}/`);
|
|
60
69
|
const dedupeAndAssertResourcePlans = (target, resources) => {
|
|
61
70
|
const byLinkPath = new Map();
|
|
@@ -105,13 +114,12 @@ export const resolveTargetResources = (target, inputs, instancePaths, meta, plan
|
|
|
105
114
|
if (sourceIds.size === 0) {
|
|
106
115
|
return [];
|
|
107
116
|
}
|
|
108
|
-
const isMergedTarget = sourceIds.size > 1;
|
|
109
117
|
const resources = inputs.flatMap((input) => {
|
|
110
118
|
if (!sourceIds.has(input.id) || input.value.kind !== "agent") {
|
|
111
119
|
return [];
|
|
112
120
|
}
|
|
113
121
|
return mergeWorkspaceResourcePlans(input.value.workspaceResources ?? [], `${target.id}/${input.id}`, {
|
|
114
|
-
targetId:
|
|
122
|
+
targetId: workspaceResourceTargetId(target.id, input.id, sourceIds.size),
|
|
115
123
|
workspacePath: resolveSourceWorkspacePath(input, instancePaths, meta)
|
|
116
124
|
}).map((resource) => {
|
|
117
125
|
const canonicalBackingPath = path.posix.normalize(resource.backingPath);
|
|
@@ -104,7 +104,10 @@ export const createWorkspaceResourceShellFunctions = () => [
|
|
|
104
104
|
' local id="$1" link_path="$2" backing_path="$3" archive="$4" identity="$5"',
|
|
105
105
|
' [ -f "$archive" ] || { echo "Workspace bundle $id archive missing" >&2; exit 1; }',
|
|
106
106
|
' local sentinel="$backing_path/.spawnfile-bundle-identity"',
|
|
107
|
-
|
|
107
|
+
// An empty directory is not a materialized bundle: the Grok broker preflight starts before this runs and
|
|
108
|
+
// needs every worker deny target to exist, so the Daimon entrypoint pre-creates missing resource backings
|
|
109
|
+
// empty. Anything with content still has to attest its identity, exactly as a git backing does above.
|
|
110
|
+
' if [ -e "$backing_path" ] && { [ ! -d "$backing_path" ] || [ -L "$backing_path" ] || ! directory_is_empty "$backing_path"; }; then',
|
|
108
111
|
' [ -f "$sentinel" ] && [ "$(cat "$sentinel")" = "$identity" ] || { echo "Workspace bundle $id identity mismatch" >&2; exit 1; }',
|
|
109
112
|
" else",
|
|
110
113
|
' mkdir -p "$backing_path"',
|
package/dist/compiler/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export * from "./dockerBuildContext.js";
|
|
|
10
10
|
export * from "./dockerBuildSkip.js";
|
|
11
11
|
export * from "./initProject.js";
|
|
12
12
|
export * from "./moltnetRoomMemberships.js";
|
|
13
|
+
export * from "./preflightCompilePlan.js";
|
|
13
14
|
export * from "./runProject.js";
|
|
14
15
|
export * from "./syncProjectAuth.js";
|
|
15
16
|
export * from "./types.js";
|
|
@@ -20,3 +21,4 @@ export * from "./upReceipt.js";
|
|
|
20
21
|
export * from "./worldBindings.js";
|
|
21
22
|
export * from "./view/index.js";
|
|
22
23
|
export * from "./training/index.js";
|
|
24
|
+
export * from "./recordingReport.js";
|
package/dist/compiler/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export * from "./dockerBuildContext.js";
|
|
|
10
10
|
export * from "./dockerBuildSkip.js";
|
|
11
11
|
export * from "./initProject.js";
|
|
12
12
|
export * from "./moltnetRoomMemberships.js";
|
|
13
|
+
export * from "./preflightCompilePlan.js";
|
|
13
14
|
export * from "./runProject.js";
|
|
14
15
|
export * from "./syncProjectAuth.js";
|
|
15
16
|
export * from "./types.js";
|
|
@@ -20,3 +21,4 @@ export * from "./upReceipt.js";
|
|
|
20
21
|
export * from "./worldBindings.js";
|
|
21
22
|
export * from "./view/index.js";
|
|
22
23
|
export * from "./training/index.js";
|
|
24
|
+
export * from "./recordingReport.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { McpServer } from "../manifest/index.js";
|
|
2
|
+
import type { CompilePlanNode } from "./types.js";
|
|
3
|
+
export interface McpPlaceholderContext {
|
|
4
|
+
agentId: string;
|
|
5
|
+
agentName: string;
|
|
6
|
+
/** Lazy: only runtimes whose servers use `${workspace}` need a resolvable path. */
|
|
7
|
+
workspace: () => string;
|
|
8
|
+
}
|
|
9
|
+
export declare const resolveMcpServerPlaceholders: (servers: McpServer[], context: McpPlaceholderContext) => McpServer[];
|
|
10
|
+
/** Resolves every agent node's MCP placeholders in place, once node ids and slugs exist. */
|
|
11
|
+
export declare const resolvePlanMcpPlaceholders: (nodes: CompilePlanNode[]) => void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getRuntimeAdapter } from "../runtime/index.js";
|
|
2
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
3
|
+
import { expandSourceWorkspacePathTemplate } from "./containerTargetResources.js";
|
|
4
|
+
/**
|
|
5
|
+
* Compiler-owned placeholders an MCP server may use in `command`, `args` and
|
|
6
|
+
* `env` values. They are resolved per agent after the compile plan assigns
|
|
7
|
+
* node ids, so one `shared.environment.mcp_servers` entry serves every member:
|
|
8
|
+
*
|
|
9
|
+
* - `${workspace}` the agent's workspace path inside its runtime target
|
|
10
|
+
* (the same path `./` workspace resource mounts link under)
|
|
11
|
+
* - `${agent.id}` the agent's compile-plan node id, e.g. `agent:writer`
|
|
12
|
+
* - `${agent.name}` the agent manifest name
|
|
13
|
+
*
|
|
14
|
+
* `${workspace}` and anything under `${agent.` are reserved: an unknown name
|
|
15
|
+
* fails the compile instead of reaching a runtime as a literal string. Other
|
|
16
|
+
* `${...}` text is left untouched.
|
|
17
|
+
*/
|
|
18
|
+
const RESERVED_PLACEHOLDER = /\$\{(workspace|agent\.[^}]*)\}/gu;
|
|
19
|
+
const SUPPORTED = "${workspace}, ${agent.id}, ${agent.name}";
|
|
20
|
+
const fail = (context, server, detail) => {
|
|
21
|
+
throw new SpawnfileError("validation_error", `Agent ${context.agentName} MCP server ${server.name}: ${detail}`);
|
|
22
|
+
};
|
|
23
|
+
const resolveValue = (value, server, context) => value.replace(RESERVED_PLACEHOLDER, (match, name) => {
|
|
24
|
+
if (name === "workspace")
|
|
25
|
+
return context.workspace();
|
|
26
|
+
if (name === "agent.id")
|
|
27
|
+
return context.agentId;
|
|
28
|
+
if (name === "agent.name")
|
|
29
|
+
return context.agentName;
|
|
30
|
+
return fail(context, server, `unknown placeholder ${match}; supported placeholders are ${SUPPORTED}`);
|
|
31
|
+
});
|
|
32
|
+
const hasReservedPlaceholder = (value) => value !== undefined && new RegExp(RESERVED_PLACEHOLDER.source, "u").test(value);
|
|
33
|
+
export const resolveMcpServerPlaceholders = (servers, context) => servers.map((server) => {
|
|
34
|
+
if (hasReservedPlaceholder(server.url) || hasReservedPlaceholder(server.auth?.secret)) {
|
|
35
|
+
fail(context, server, `placeholders (${SUPPORTED}) are only supported in command, args and env values`);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
...server,
|
|
39
|
+
...(server.command === undefined ? {} : { command: resolveValue(server.command, server, context) }),
|
|
40
|
+
...(server.args === undefined ? {} : { args: server.args.map((arg) => resolveValue(arg, server, context)) }),
|
|
41
|
+
...(server.env === undefined ? {} : {
|
|
42
|
+
env: Object.fromEntries(Object.entries(server.env).map(([key, value]) => [key, resolveValue(value, server, context)]))
|
|
43
|
+
})
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
/** Resolves every agent node's MCP placeholders in place, once node ids and slugs exist. */
|
|
47
|
+
export const resolvePlanMcpPlaceholders = (nodes) => {
|
|
48
|
+
for (const node of nodes) {
|
|
49
|
+
if (node.value.kind !== "agent" || node.value.mcpServers.length === 0)
|
|
50
|
+
continue;
|
|
51
|
+
const agent = node.value;
|
|
52
|
+
agent.mcpServers = resolveMcpServerPlaceholders(agent.mcpServers, {
|
|
53
|
+
agentId: node.id,
|
|
54
|
+
agentName: agent.name,
|
|
55
|
+
workspace: () => expandSourceWorkspacePathTemplate(getRuntimeAdapter(node.runtimeName ?? agent.runtime.name).container, { agentName: agent.name, slug: node.slug })
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type McpServer, type McpServerEntry, type SharedMcpServer } from "../manifest/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Resolves an agent's effective MCP servers from its team's
|
|
4
|
+
* `shared.environment.mcp_servers` and its own entries.
|
|
5
|
+
*
|
|
6
|
+
* - A local entry that declares `transport` is a complete server and replaces
|
|
7
|
+
* any inherited server of the same name (SPEC §4.4: member-local wins).
|
|
8
|
+
* - A local entry without `transport` narrows the inherited server of the same
|
|
9
|
+
* name: `tools` replaces the inherited allowlist, `env` merges key by key
|
|
10
|
+
* with local keys winning. Every other field stays inherited.
|
|
11
|
+
* - A bare `{ name }` takes the inherited server unchanged.
|
|
12
|
+
* - A shared server marked `opt_in: true` is inherited only by members that
|
|
13
|
+
* list its name (bare or narrowing). Members never remove an inherited
|
|
14
|
+
* server (SPEC §4.4); an opt-in server is simply not offered by default.
|
|
15
|
+
* - An override with no shared server to narrow is a compile error naming
|
|
16
|
+
* the agent, because there is nothing to complete it from.
|
|
17
|
+
*/
|
|
18
|
+
export declare const resolveInheritedMcpServers: (agentName: string, sharedServers?: SharedMcpServer[], localEntries?: McpServerEntry[]) => McpServer[];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { isMcpServerDeclaration } from "../manifest/index.js";
|
|
2
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolves an agent's effective MCP servers from its team's
|
|
5
|
+
* `shared.environment.mcp_servers` and its own entries.
|
|
6
|
+
*
|
|
7
|
+
* - A local entry that declares `transport` is a complete server and replaces
|
|
8
|
+
* any inherited server of the same name (SPEC §4.4: member-local wins).
|
|
9
|
+
* - A local entry without `transport` narrows the inherited server of the same
|
|
10
|
+
* name: `tools` replaces the inherited allowlist, `env` merges key by key
|
|
11
|
+
* with local keys winning. Every other field stays inherited.
|
|
12
|
+
* - A bare `{ name }` takes the inherited server unchanged.
|
|
13
|
+
* - A shared server marked `opt_in: true` is inherited only by members that
|
|
14
|
+
* list its name (bare or narrowing). Members never remove an inherited
|
|
15
|
+
* server (SPEC §4.4); an opt-in server is simply not offered by default.
|
|
16
|
+
* - An override with no shared server to narrow is a compile error naming
|
|
17
|
+
* the agent, because there is nothing to complete it from.
|
|
18
|
+
*/
|
|
19
|
+
export const resolveInheritedMcpServers = (agentName, sharedServers = [], localEntries = []) => {
|
|
20
|
+
const inherited = new Map();
|
|
21
|
+
const resolved = new Map();
|
|
22
|
+
for (const { opt_in: optIn, ...server } of sharedServers) {
|
|
23
|
+
inherited.set(server.name, server);
|
|
24
|
+
if (optIn !== true)
|
|
25
|
+
resolved.set(server.name, server);
|
|
26
|
+
}
|
|
27
|
+
for (const entry of localEntries) {
|
|
28
|
+
if (isMcpServerDeclaration(entry)) {
|
|
29
|
+
resolved.set(entry.name, entry);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const base = inherited.get(entry.name);
|
|
33
|
+
if (!base) {
|
|
34
|
+
throw new SpawnfileError("validation_error", `Agent ${agentName} overrides MCP server ${entry.name}, but its team declares no shared.environment.mcp_servers entry named ${entry.name}; declare transport to define the server locally`);
|
|
35
|
+
}
|
|
36
|
+
resolved.set(entry.name, {
|
|
37
|
+
...base,
|
|
38
|
+
...(entry.tools === undefined ? {} : { tools: entry.tools }),
|
|
39
|
+
...(entry.env === undefined ? {} : { env: { ...base.env, ...entry.env } })
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return [...resolved.values()];
|
|
43
|
+
};
|
|
@@ -193,6 +193,7 @@ export const generateMoltnetArtifacts = async (plan, deploymentLineage = "compil
|
|
|
193
193
|
path: configPath
|
|
194
194
|
});
|
|
195
195
|
nodePlans.push({
|
|
196
|
+
sourceNodeId: node.id,
|
|
196
197
|
configPath: toContainerRootfsPath(configPath),
|
|
197
198
|
...(clientAuth.credentialAgentId
|
|
198
199
|
? { credentialAgentId: clientAuth.credentialAgentId }
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CompilePlan } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Runs, without emitting anything, the per-agent checks compile would refuse
|
|
4
|
+
* on: runtime-option errors and each adapter's `preflightAgent` (for Daimon:
|
|
5
|
+
* MCP allowlists and absolute commands, engine/model pairing, and the public
|
|
6
|
+
* instruction-size limit). Every failing agent is reported, each named by its
|
|
7
|
+
* node id, so `spawnfile validate` can be an organization's structural check.
|
|
8
|
+
*/
|
|
9
|
+
export declare const preflightCompilePlan: (plan: CompilePlan) => void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { getRuntimeAdapter } from "../runtime/index.js";
|
|
2
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Runs, without emitting anything, the per-agent checks compile would refuse
|
|
5
|
+
* on: runtime-option errors and each adapter's `preflightAgent` (for Daimon:
|
|
6
|
+
* MCP allowlists and absolute commands, engine/model pairing, and the public
|
|
7
|
+
* instruction-size limit). Every failing agent is reported, each named by its
|
|
8
|
+
* node id, so `spawnfile validate` can be an organization's structural check.
|
|
9
|
+
*/
|
|
10
|
+
export const preflightCompilePlan = (plan) => {
|
|
11
|
+
const failures = new Map();
|
|
12
|
+
for (const node of plan.nodes) {
|
|
13
|
+
if (node.value.kind !== "agent")
|
|
14
|
+
continue;
|
|
15
|
+
const runtimeName = node.runtimeName ?? node.value.runtime.name;
|
|
16
|
+
const adapter = getRuntimeAdapter(runtimeName);
|
|
17
|
+
const key = `${node.id} (${runtimeName})`;
|
|
18
|
+
const report = (message) => {
|
|
19
|
+
failures.set(key, (failures.get(key) ?? new Set()).add(message));
|
|
20
|
+
};
|
|
21
|
+
for (const diagnostic of adapter.validateRuntimeOptions?.(node.value.runtime.options) ?? []) {
|
|
22
|
+
if (diagnostic.level === "error")
|
|
23
|
+
report(diagnostic.message);
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
adapter.preflightAgent?.(node.value, node.id);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (!(error instanceof SpawnfileError))
|
|
30
|
+
throw error;
|
|
31
|
+
report(error.message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (failures.size > 0) {
|
|
35
|
+
const lines = [...failures].flatMap(([agent, messages]) => [...messages].map((message) => `- ${agent}: ${message}`));
|
|
36
|
+
throw new SpawnfileError("validation_error", [`Compile would refuse ${failures.size} agent(s):`, ...lines].join("\n"));
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CompileReportWorkspaceGitResource, RecordingAgentReport } from "../report/index.js";
|
|
2
|
+
import type { CompilePlan } from "./types.js";
|
|
3
|
+
/** Only compiled, portable identities: no host sources and no history reads. */
|
|
4
|
+
export declare const resolveRecordingAgentFacts: (plan: CompilePlan, gitPins?: readonly CompileReportWorkspaceGitResource[]) => RecordingAgentReport[];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { resolveMnemeDurableMemoryMountPath } from "../runtime/mnemeMcp.js";
|
|
3
|
+
import { daimonRecordingDirectory } from "../runtime/daimon/recording.js";
|
|
4
|
+
import { recordingKeepMs, SpawnfileError } from "../shared/index.js";
|
|
5
|
+
import { resolveTrainingRecordVolumes } from "./training/plan/index.js";
|
|
6
|
+
/** Only compiled, portable identities: no host sources and no history reads. */
|
|
7
|
+
export const resolveRecordingAgentFacts = (plan, gitPins = []) => plan.nodes.flatMap((node) => {
|
|
8
|
+
if (node.value.kind !== "agent" || node.value.training?.record === undefined)
|
|
9
|
+
return [];
|
|
10
|
+
const agent = node.value;
|
|
11
|
+
const memory = new Map();
|
|
12
|
+
for (const access of agent.memoryAccess ?? []) {
|
|
13
|
+
const declaring = plan.nodes.find((entry) => entry.value.source === access.source);
|
|
14
|
+
if (!declaring)
|
|
15
|
+
throw new SpawnfileError("validation_error", `Recording bank ${access.bank.id} has no declaring node`);
|
|
16
|
+
const home = resolveMnemeDurableMemoryMountPath(access.bank);
|
|
17
|
+
memory.set(`${declaring.id}\0${access.bank.id}`, {
|
|
18
|
+
id: access.bank.id, declared_by: declaring.id,
|
|
19
|
+
ledger_path: home === null ? null : path.posix.join(home, "memory/events.jsonl")
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const resources = agent.workspaceResources ?? [];
|
|
23
|
+
return [{
|
|
24
|
+
node_id: node.id, slug: node.slug, directory: daimonRecordingDirectory(node.slug),
|
|
25
|
+
keep_ms: recordingKeepMs(agent.training.record),
|
|
26
|
+
networks: [...new Set((agent.surfaces?.moltnet ?? []).map((entry) => entry.network))].sort(),
|
|
27
|
+
memory: [...memory.values()].sort((a, b) => `${a.declared_by}:${a.id}`.localeCompare(`${b.declared_by}:${b.id}`)),
|
|
28
|
+
feeds: resources.flatMap((resource) => resource.kind === "volume" && resource.feed
|
|
29
|
+
? [{ id: resource.id, volume_name: resource.name }] : []).sort((a, b) => a.id.localeCompare(b.id)),
|
|
30
|
+
resources: resources.flatMap((resource) => resource.kind === "volume" ? []
|
|
31
|
+
: [{ id: resource.id, kind: gitPins.some((pin) => pin.id === resource.id && pin.agent_node_ids?.includes(node.id)) ? "git" : resource.kind }])
|
|
32
|
+
.sort((a, b) => a.id.localeCompare(b.id)),
|
|
33
|
+
snapshots: resolveTrainingRecordVolumes({ id: node.id, value: agent }).map((resource) => resource.id)
|
|
34
|
+
}];
|
|
35
|
+
}).sort((a, b) => a.node_id.localeCompare(b.node_id));
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type DaimonContractManifest } from "../runtime/daimon/contractManifest.js";
|
|
2
|
+
import type { CompilePlan } from "./types.js";
|
|
3
|
+
/** No runtime lookup, check output, or manifest I/O when recording is absent. */
|
|
4
|
+
export declare const assertRecordingCapability: (plan: CompilePlan, injectedManifest?: DaimonContractManifest) => Promise<void>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { DAIMON_CONTRACT_MANIFEST_SHA256, daimonSupportsWakeMoments, readVerifiedDaimonContractManifest } from "../runtime/daimon/contractManifest.js";
|
|
3
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
4
|
+
/** No runtime lookup, check output, or manifest I/O when recording is absent. */
|
|
5
|
+
export const assertRecordingCapability = async (plan, injectedManifest) => {
|
|
6
|
+
const agents = plan.nodes.filter((node) => node.kind === "agent" && node.value.training?.record !== undefined);
|
|
7
|
+
if (agents.length === 0)
|
|
8
|
+
return;
|
|
9
|
+
for (const agent of agents) {
|
|
10
|
+
if (agent.runtimeName !== "daimon")
|
|
11
|
+
throw new SpawnfileError("validation_error", `Training recording for ${agent.id} requires Daimon; runtime ${agent.runtimeName ?? "unknown"} does not support wake moments`);
|
|
12
|
+
}
|
|
13
|
+
let manifest = injectedManifest;
|
|
14
|
+
if (manifest === undefined) {
|
|
15
|
+
const verified = await readVerifiedDaimonContractManifest(fileURLToPath(new URL("../runtime/daimon/", import.meta.url)));
|
|
16
|
+
if (verified.digest !== DAIMON_CONTRACT_MANIFEST_SHA256)
|
|
17
|
+
throw new SpawnfileError("validation_error", "Pinned Daimon contract manifest does not match the capability-receipt digest");
|
|
18
|
+
manifest = verified.manifest;
|
|
19
|
+
}
|
|
20
|
+
if (!daimonSupportsWakeMoments(manifest))
|
|
21
|
+
throw new SpawnfileError("validation_error", "The pinned Daimon runtime image does not declare the wakeMoments capability; a Daimon release with it and a runtimes.yaml / contract-manifest re-pin are required");
|
|
22
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CompileReport, ContainerMemoryReport, RecordingReport } from "../report/index.js";
|
|
2
|
+
import type { CompilePlan } from "./types.js";
|
|
3
|
+
/** Project effective agent declarations and existing memory access facts only. */
|
|
4
|
+
export declare const resolveRecordingReport: (plan: CompilePlan, memories: readonly ContainerMemoryReport[], gitPins?: CompileReport["workspace_git_resources"]) => RecordingReport | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { maxRecordingKeepMs } from "../shared/index.js";
|
|
2
|
+
import { daimonRecordingMountId } from "../runtime/daimon/recording.js";
|
|
3
|
+
import { resolveRecordingAgentFacts } from "./recordingAgentFacts.js";
|
|
4
|
+
/** Project effective agent declarations and existing memory access facts only. */
|
|
5
|
+
export const resolveRecordingReport = (plan, memories, gitPins = []) => {
|
|
6
|
+
const agents = plan.nodes.filter((node) => node.kind === "agent" && node.value.training?.record !== undefined);
|
|
7
|
+
const keepMs = maxRecordingKeepMs(agents.map((node) => node.value.training?.record));
|
|
8
|
+
if (keepMs === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
const agentIds = new Set(agents.map((node) => node.id));
|
|
11
|
+
const memoryMountIds = memories.flatMap((memory) => memory.store.persistent_mount_id !== undefined && memory.accessible_node_ids.some((id) => agentIds.has(id))
|
|
12
|
+
? [memory.store.persistent_mount_id] : []);
|
|
13
|
+
return {
|
|
14
|
+
keep_ms: keepMs, memory_mount_ids: [...new Set(memoryMountIds)].sort(),
|
|
15
|
+
recording_mount_ids: agents.filter((agent) => agent.runtimeName === "daimon").map((agent) => daimonRecordingMountId(agent.slug)).sort(),
|
|
16
|
+
agents: resolveRecordingAgentFacts(plan, gitPins)
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ResolvedAuthProfile } from "../auth/index.js";
|
|
2
|
-
import { type DockerTargetExecFile } from "../deployment/index.js";
|
|
2
|
+
import { type DeploymentRecord, type DockerTargetExecFile } from "../deployment/index.js";
|
|
3
3
|
import { type CompileProjectOptions, type CompileProjectResult } from "./compileProject.js";
|
|
4
4
|
import { inspectDetachedContainer as recoverDetachedDockerRun, runDockerContainer, type DockerRunInvocation, type DockerRunResult, type DockerRunRunner } from "./runProjectDocker.js";
|
|
5
5
|
export { recoverDetachedDockerRun, runDockerContainer };
|
|
@@ -40,6 +40,7 @@ export declare const createDockerRunInvocation: (compileResult: CompileProjectRe
|
|
|
40
40
|
envFilePath?: string;
|
|
41
41
|
}) => Promise<DockerRunInvocation>;
|
|
42
42
|
interface ResolvedRunDeploymentOptions {
|
|
43
|
+
previousRecord?: DeploymentRecord;
|
|
43
44
|
authProfile?: string;
|
|
44
45
|
containerName?: string;
|
|
45
46
|
deploymentName?: string;
|
|
@@ -153,6 +153,7 @@ export const resolveDetachedDeploymentOptions = async (outputDirectory, options)
|
|
|
153
153
|
});
|
|
154
154
|
}
|
|
155
155
|
return {
|
|
156
|
+
previousRecord: record,
|
|
156
157
|
authProfile: options.authProfile ?? record.auth_profile ?? undefined,
|
|
157
158
|
containerName: options.containerName ?? unit?.container_name ?? undefined,
|
|
158
159
|
deploymentName,
|
|
@@ -212,6 +213,7 @@ export const runProject = async (inputPath, options = {}) => {
|
|
|
212
213
|
const runMetadata = await executeDockerRunWithSupportCleanup(invocation, options.runRunner ?? runDockerContainer);
|
|
213
214
|
const deploymentRecordPath = invocation.detach && invocation.deploymentName
|
|
214
215
|
? await writeDockerDeploymentRecordForRun({
|
|
216
|
+
previousRecord: resolvedOptions.previousRecord,
|
|
215
217
|
authProfileName: authProfile?.name ?? null,
|
|
216
218
|
envFilePath: resolvedOptions.envFilePath,
|
|
217
219
|
imageTag,
|