spawnfile 0.1.17 → 0.1.19
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/moltnet-releases.json +4 -4
- package/package.json +3 -3
- package/runtimes.yaml +8 -6
|
@@ -6,7 +6,7 @@ import { DAIMON_WORKER_ROOT } from "../../containerDaimonGrokWorkerRender.js";
|
|
|
6
6
|
/**
|
|
7
7
|
* Every container path the broker-capable training container fixes.
|
|
8
8
|
*
|
|
9
|
-
* They are
|
|
9
|
+
* They are deterministic because three parties must agree on them
|
|
10
10
|
* without talking to each other: the root entrypoint that provisions them, the
|
|
11
11
|
* root slot supervisor that wipes and re-provisions them on recycle, and
|
|
12
12
|
* Paideia's native adapter, which writes them into `paideia.daimon-native.launch.v2`
|
|
@@ -14,7 +14,7 @@ import { DAIMON_WORKER_ROOT } from "../../containerDaimonGrokWorkerRender.js";
|
|
|
14
14
|
* resolves a path, so each one must also be canonical and never a symlink; the
|
|
15
15
|
* provisioning program asserts that before a slot is used.
|
|
16
16
|
*
|
|
17
|
-
* Everything under `/run/training/
|
|
17
|
+
* Everything under `/run/training/slots/<i>` is per-trial state on tmpfs — never the
|
|
18
18
|
* Grok realm volume (R2). The realm volume holds only `auth.json` and the
|
|
19
19
|
* broker credential journal, so a recycle can wipe the slot without touching
|
|
20
20
|
* the one durable rotating credential.
|
|
@@ -23,20 +23,8 @@ export const TRAINING_RUN_ROOT = "/run/training/output";
|
|
|
23
23
|
export const TRAINING_SEALED_INPUTS_ROOT = "/run/training/inputs";
|
|
24
24
|
export const TRAINING_PAIDEIA_ROOT = "/run/paideia";
|
|
25
25
|
export const TRAINING_CONTEXT_FILE = `${TRAINING_PAIDEIA_ROOT}/context.json`;
|
|
26
|
-
/** Host-written, read-only `spawnfile.training-broker.
|
|
26
|
+
/** Host-written, read-only `spawnfile.training-broker.v2` declaration the root entrypoint reads. */
|
|
27
27
|
export const TRAINING_BROKER_DECLARATION_FILE = `${TRAINING_PAIDEIA_ROOT}/training-broker.json`;
|
|
28
|
-
export const TRAINING_SLOT_ROOT = "/run/training/slot";
|
|
29
|
-
export const TRAINING_SLOT_WORKSPACE = `${TRAINING_SLOT_ROOT}/workspace`;
|
|
30
|
-
export const TRAINING_SLOT_RUNTIME_HOME = `${TRAINING_SLOT_ROOT}/runtime-home`;
|
|
31
|
-
export const TRAINING_SLOT_STATE_ROOT = `${TRAINING_SLOT_ROOT}/state`;
|
|
32
|
-
export const TRAINING_SLOT_ACCEPTANCE_STORE = `${TRAINING_SLOT_STATE_ROOT}/wake-acceptance`;
|
|
33
|
-
/** Per-slot turn store. On tmpfs on purpose: a replayed turn from trial N must never satisfy trial N+1 (R2). */
|
|
34
|
-
export const TRAINING_SLOT_TURN_STORE = `${TRAINING_SLOT_ROOT}/turns`;
|
|
35
|
-
export const TRAINING_SLOT_USAGE_DIRECTORY = `${TRAINING_SLOT_ROOT}/usage`;
|
|
36
|
-
export const TRAINING_SLOT_USAGE_LEDGER = `${TRAINING_SLOT_USAGE_DIRECTORY}/usage.jsonl`;
|
|
37
|
-
export const TRAINING_SLOT_PREFLIGHT_RECEIPT = `${TRAINING_SLOT_ROOT}/preflight.json`;
|
|
38
|
-
/** Supervisor-owned monotonic generation counter; survives a recycle, never a container restart. */
|
|
39
|
-
export const TRAINING_SLOT_GENERATION_FILE = `${TRAINING_SLOT_ROOT}/generation.json`;
|
|
40
28
|
export const TRAINING_INFERENCE_DIRECTORY = "/run/training/inference";
|
|
41
29
|
export const TRAINING_INFERENCE_LEDGER = `${TRAINING_INFERENCE_DIRECTORY}/inference.jsonl`;
|
|
42
30
|
/** Judge grant homes: `2000:2000 0700`, denied to every worker uid. Paideia reads it as `PAIDEIA_GROK_GRANT_HOME_ROOT`. */
|
|
@@ -58,9 +46,6 @@ export const TRAINING_SUPERVISOR_DIRECTORY = "/run/training/supervisor";
|
|
|
58
46
|
export const TRAINING_SUPERVISOR_SOCKET = `${TRAINING_SUPERVISOR_DIRECTORY}/control.sock`;
|
|
59
47
|
export const TRAINING_SUPERVISOR_LOG = `${TRAINING_SUPERVISOR_DIRECTORY}/supervisor.log`;
|
|
60
48
|
export const TRAINING_WORKER_ROOT = DAIMON_WORKER_ROOT;
|
|
61
|
-
export const TRAINING_SLOT_INDEX = 0;
|
|
62
|
-
export const TRAINING_WORKER_UID = DAIMON_FIRST_WORKER_UID + TRAINING_SLOT_INDEX;
|
|
63
|
-
export const TRAINING_WORKER_HOME = path.posix.join(TRAINING_WORKER_ROOT, String(TRAINING_WORKER_UID));
|
|
64
49
|
/**
|
|
65
50
|
* Paideia's own fixed container paths (`containerPaths` in its native launch
|
|
66
51
|
* schema). They are *not* individual deny entries: Grok 1.0.34 materializes
|
|
@@ -94,63 +79,93 @@ export const TRAINING_CALLER_PROTECTED_PATHS = [
|
|
|
94
79
|
* tagged `context` — the caller-state role — since there is no other way to
|
|
95
80
|
* carry a path through that contract.
|
|
96
81
|
*/
|
|
97
|
-
export const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
{ role: "context", path: path.posix.dirname(DAIMON_GROK_ENGINE_BROKER.controlSocketPath) },
|
|
108
|
-
{ role: "context", path: path.posix.dirname(DAIMON_GROK_ENGINE_BROKER.registrationPath) },
|
|
109
|
-
{ role: "context", path: DAIMON_GROK_TURN_USAGE_LEDGER.directoryPath },
|
|
110
|
-
{ role: "context", path: DAIMON_WAKE_FUSE_DIRECTORY }
|
|
82
|
+
export const TRAINING_SLOTS_FILE = `${TRAINING_PAIDEIA_ROOT}/slots.json`;
|
|
83
|
+
export const TRAINING_SLOTS_VERSION = "spawnfile.training-slots.v1";
|
|
84
|
+
export const TRAINING_DEFAULT_SLOTS = 4;
|
|
85
|
+
export const TRAINING_MAX_SLOTS = 8;
|
|
86
|
+
/** 100 ports per slot: offsets 0=Moltnet, 1=worker control, 2=bridge; 3..99 reserved. */
|
|
87
|
+
export const TRAINING_PORT_BASE = 20_000;
|
|
88
|
+
export const TRAINING_PORT_STRIDE = 100;
|
|
89
|
+
export const TRAINING_BROKER_SOCKET_PATHS = [
|
|
90
|
+
DAIMON_GROK_ENGINE_BROKER.controlSocketPath, DAIMON_GROK_ENGINE_BROKER.backendSocketPath,
|
|
91
|
+
DAIMON_GROK_ENGINE_BROKER.launcherSocketPath
|
|
111
92
|
];
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
93
|
+
export const TRAINING_TURN_STORE_ROOT = "/run/training/turns";
|
|
94
|
+
/** Persistent, broker-only run counter; never part of a slot recycle. */
|
|
95
|
+
export const TRAINING_RUN_REQUEST_STORE = "/run/training/request-budget";
|
|
96
|
+
export const assertTrainingSlotCount = (slots) => {
|
|
97
|
+
if (!Number.isInteger(slots) || slots < 1 || slots > TRAINING_MAX_SLOTS)
|
|
98
|
+
throw Error("Training slots must be an integer from 1 to 8");
|
|
99
|
+
return slots;
|
|
100
|
+
};
|
|
101
|
+
export const trainingSlotPaths = (slot) => {
|
|
102
|
+
if (!Number.isInteger(slot) || slot < 0 || slot >= TRAINING_MAX_SLOTS)
|
|
103
|
+
throw Error("Training slot index must be an integer from 0 to 7");
|
|
104
|
+
const root = `/run/training/slots/${slot}`;
|
|
105
|
+
const workerUid = DAIMON_FIRST_WORKER_UID + slot;
|
|
106
|
+
const workerHome = `${TRAINING_WORKER_ROOT}/${workerUid}`;
|
|
107
|
+
const portBase = TRAINING_PORT_BASE + slot * TRAINING_PORT_STRIDE;
|
|
108
|
+
const clockDirectory = `/run/daimon-engine-broker/task-clock/slot-${slot}`;
|
|
109
|
+
return {
|
|
110
|
+
slot, workerUid, root, workerHome, workspace: `${root}/workspace`, runtimeHome: `${root}/runtime-home`,
|
|
111
|
+
state: `${root}/state`, acceptanceStore: `${root}/state/wake-acceptance`,
|
|
112
|
+
turns: `${TRAINING_TURN_STORE_ROOT}/slot-${slot}`, usageDirectory: `${root}/usage`, usageLedger: `${root}/usage/usage.jsonl`,
|
|
113
|
+
preflightReceipt: `${root}/preflight.json`, generationFile: `${root}/generation.json`,
|
|
114
|
+
sealedInputsAttestation: `${root}/sealed-inputs.json`, privateTmp: `${workerHome}/tmp`,
|
|
115
|
+
clockDirectory, clockFile: `${clockDirectory}/faketime`,
|
|
116
|
+
ports: { base: portBase, stride: TRAINING_PORT_STRIDE, moltnet: portBase, workerControl: portBase + 1, bridge: portBase + 2 }
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
/** The complete additional projection deny set. Sibling roots and homes never nest with own masks. */
|
|
120
|
+
export const trainingEvaluatorPaths = (slot, slots) => {
|
|
121
|
+
assertTrainingSlotCount(slots);
|
|
122
|
+
if (slot >= slots)
|
|
123
|
+
throw Error("Training slot is outside the declared pool");
|
|
124
|
+
const own = trainingSlotPaths(slot);
|
|
125
|
+
return [
|
|
126
|
+
{ role: "run-root", path: TRAINING_RUN_ROOT },
|
|
127
|
+
{ role: "sealed-inputs", path: TRAINING_SEALED_INPUTS_ROOT },
|
|
128
|
+
{ role: "judge-home", path: TRAINING_GRANT_HOME_ROOT },
|
|
129
|
+
{ role: "slot-ledger", path: own.usageDirectory },
|
|
130
|
+
...[TRAINING_PAIDEIA_ROOT, TRAINING_BROKER_TMPDIR, TRAINING_INFERENCE_DIRECTORY,
|
|
131
|
+
TRAINING_TURN_STORE_ROOT, TRAINING_RUN_REQUEST_STORE, TRAINING_SUPERVISOR_DIRECTORY,
|
|
132
|
+
...TRAINING_BROKER_SOCKET_PATHS,
|
|
133
|
+
path.posix.dirname(DAIMON_GROK_ENGINE_BROKER.registrationPath),
|
|
134
|
+
DAIMON_GROK_TURN_USAGE_LEDGER.directoryPath, DAIMON_WAKE_FUSE_DIRECTORY,
|
|
135
|
+
...Array.from({ length: slots }, (_, i) => trainingSlotPaths(i)).filter(p => p.slot !== slot)
|
|
136
|
+
.flatMap(p => [p.root, p.workerHome, p.clockDirectory])
|
|
137
|
+
].map(path => ({ role: "context", path }))
|
|
138
|
+
];
|
|
139
|
+
};
|
|
140
|
+
export const trainingSlotDescriptors = (slots = TRAINING_DEFAULT_SLOTS) => Array.from({ length: assertTrainingSlotCount(slots) }, (_, slot) => ({
|
|
141
|
+
...trainingSlotPaths(slot), evaluatorPaths: trainingEvaluatorPaths(slot, slots),
|
|
142
|
+
containerPaths: TRAINING_CALLER_PROTECTED_PATHS.map(path => ({ path })),
|
|
143
|
+
controlRoot: trainingSlotPaths(slot).state
|
|
144
|
+
}));
|
|
145
|
+
export const trainingSlotsDocument = (slots = TRAINING_DEFAULT_SLOTS) => ({
|
|
146
|
+
schema: TRAINING_SLOTS_VERSION,
|
|
147
|
+
slots: trainingSlotDescriptors(slots).map(p => ({
|
|
148
|
+
index: p.slot, workerUid: p.workerUid,
|
|
149
|
+
// Paideia owns a runtime-neutral lease pool: its strict descriptor carries opaque named paths.
|
|
150
|
+
roots: {
|
|
151
|
+
...Object.fromEntries(Object.entries(p).filter((entry) => typeof entry[1] === "string")),
|
|
152
|
+
home: p.runtimeHome, control: p.state, context: TRAINING_PAIDEIA_ROOT,
|
|
153
|
+
...Object.fromEntries(p.evaluatorPaths.map((entry, index) => [`evaluator:${entry.role}:${index}`, entry.path])),
|
|
154
|
+
...Object.fromEntries(p.containerPaths.map((entry, index) => [`container:${index}`, entry.path]))
|
|
155
|
+
},
|
|
156
|
+
ports: { base: p.ports.base, count: p.ports.stride }
|
|
157
|
+
}))
|
|
158
|
+
});
|
|
159
|
+
/** Both sides derive the descriptor bytes; a stale or edited bind must never certify a different pool. */
|
|
160
|
+
export const assertTrainingSlotsDocument = (value, slots) => {
|
|
161
|
+
if (JSON.stringify(value) !== JSON.stringify(trainingSlotsDocument(slots)))
|
|
162
|
+
throw Error("Training slots manifest differs from the broker declaration");
|
|
163
|
+
};
|
|
164
|
+
/** Shared deny targets exist before worker attestation; no per-slot subtree is touched here. */
|
|
143
165
|
export const TRAINING_OPTIONAL_DENY_DIRECTORIES = [
|
|
144
|
-
TRAINING_BROKER_TMPDIR,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
TRAINING_SLOT_TURN_STORE,
|
|
148
|
-
TRAINING_SUPERVISOR_DIRECTORY,
|
|
149
|
-
TRAINING_GRANT_HOME_ROOT,
|
|
150
|
-
// Denied and unused here — training meters per slot — but the mask still needs an inode. The launch
|
|
151
|
-
// mounts each as tmpfs, so this only creates them when a caller ran the entrypoint without them.
|
|
152
|
-
DAIMON_GROK_TURN_USAGE_LEDGER.directoryPath,
|
|
153
|
-
DAIMON_WAKE_FUSE_DIRECTORY
|
|
166
|
+
TRAINING_BROKER_TMPDIR, TRAINING_INFERENCE_DIRECTORY, TRAINING_TURN_STORE_ROOT,
|
|
167
|
+
TRAINING_SUPERVISOR_DIRECTORY, TRAINING_GRANT_HOME_ROOT,
|
|
168
|
+
DAIMON_GROK_TURN_USAGE_LEDGER.directoryPath, DAIMON_WAKE_FUSE_DIRECTORY
|
|
154
169
|
];
|
|
155
170
|
/**
|
|
156
171
|
* Deny entries a launch may legitimately not have mounted. Everything else must
|
|
@@ -207,7 +222,6 @@ export const TRAINING_HOST_BIND_DENY_PATHS = [TRAINING_RUN_ROOT, DAIMON_GROK_SUB
|
|
|
207
222
|
*/
|
|
208
223
|
export const TRAINING_SEALED_DENY_PATHS = [TRAINING_SEALED_INPUTS_ROOT];
|
|
209
224
|
/** Spawnfile-owned per-route seal attestation, written by provisioning beside the slot preflight receipt. */
|
|
210
|
-
export const TRAINING_SEALED_INPUTS_ATTESTATION = `${TRAINING_SLOT_ROOT}/sealed-inputs.json`;
|
|
211
225
|
/** The image-baked identity of the sealed inputs root, asserted before every slot and never writable at runtime. */
|
|
212
226
|
export const TRAINING_SEALED_INPUTS_IDENTITY = { uid: 0, gid: DAIMON_ORGANIZATION_UID, mode: "750" };
|
|
213
227
|
/**
|
|
@@ -221,21 +235,15 @@ export const TRAINING_SEALED_INPUTS_IDENTITY = { uid: 0, gid: DAIMON_ORGANIZATIO
|
|
|
221
235
|
* anyway, so an undeclared one degrades to "left in place and reported" rather
|
|
222
236
|
* than a failed provision.
|
|
223
237
|
*/
|
|
224
|
-
export const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
];
|
|
232
|
-
|
|
233
|
-
export const TRAINING_CLEAR_TARGETS = [
|
|
234
|
-
TRAINING_SLOT_WORKSPACE,
|
|
235
|
-
TRAINING_SLOT_USAGE_DIRECTORY,
|
|
236
|
-
path.posix.dirname(DAIMON_GROK_ENGINE_BROKER.controlSocketPath),
|
|
237
|
-
path.posix.dirname(DAIMON_GROK_ENGINE_BROKER.registrationPath)
|
|
238
|
-
];
|
|
238
|
+
export const trainingWipeTargets = (slot) => {
|
|
239
|
+
const p = trainingSlotPaths(slot);
|
|
240
|
+
return [p.runtimeHome, p.state, p.preflightReceipt, p.sealedInputsAttestation];
|
|
241
|
+
};
|
|
242
|
+
/** Broker-owned turns and clocks are reset through its control seam, never by filesystem deletion. */
|
|
243
|
+
export const trainingClearTargets = (slot) => {
|
|
244
|
+
const p = trainingSlotPaths(slot);
|
|
245
|
+
return [p.workspace, p.usageDirectory];
|
|
246
|
+
};
|
|
239
247
|
export const TRAINING_REALM_MOUNT = DAIMON_GROK_SUBSCRIPTION_REALM.durableMountPath;
|
|
240
248
|
export const TRAINING_BOOTSTRAP_MOUNT = DAIMON_GROK_SUBSCRIPTION_REALM.bootstrapMountPath;
|
|
241
249
|
export { DAIMON_BROKER_UID, DAIMON_ORGANIZATION_UID };
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
interface SocketIdentity {
|
|
3
|
+
dev: number;
|
|
4
|
+
ino: number;
|
|
5
|
+
ctimeMs: number;
|
|
6
|
+
isSocket(): boolean;
|
|
7
|
+
}
|
|
8
|
+
/** An existing placement socket is not readiness. Its inode (or reuse timestamp) must change. */
|
|
9
|
+
export declare const isStartedBrokerSocket: (current: SocketIdentity | undefined, previous: SocketIdentity | undefined) => boolean;
|
|
2
10
|
export declare const DAIMON_RUNTIME_ROOT = "/opt/spawnfile/runtime-installs/daimon";
|
|
3
11
|
/** `00000000000000c1` = CHOWN|SETGID|SETUID, the launcher's bounding set after `setpriv`. */
|
|
4
12
|
export declare const LAUNCHER_CAPABILITY_BOUND = "00000000000000c1";
|
|
@@ -40,3 +48,4 @@ export interface StartBrokerOptions {
|
|
|
40
48
|
export declare const startBrokerProcesses: (options: StartBrokerOptions) => Promise<BrokerChild[]>;
|
|
41
49
|
/** Graceful stop in reverse start order: relay, backend, launcher. `SIGKILL` only after the grace window. */
|
|
42
50
|
export declare const stopBrokerProcesses: (children: readonly BrokerChild[], log: (line: string) => void, graceMs?: number) => Promise<void>;
|
|
51
|
+
export {};
|
|
@@ -4,6 +4,8 @@ import { setTimeout as pause } from "node:timers/promises";
|
|
|
4
4
|
import { SpawnfileError } from "../../../shared/index.js";
|
|
5
5
|
import { DAIMON_GROK_ENGINE_BROKER } from "../../../runtime/daimon/contractManifest.js";
|
|
6
6
|
import { DAIMON_BROKER_UID, TRAINING_BROKER_TMPDIR } from "./paths.js";
|
|
7
|
+
/** An existing placement socket is not readiness. Its inode (or reuse timestamp) must change. */
|
|
8
|
+
export const isStartedBrokerSocket = (current, previous) => current?.isSocket() === true && (!previous || current.dev !== previous.dev || current.ino !== previous.ino || current.ctimeMs !== previous.ctimeMs);
|
|
7
9
|
export const DAIMON_RUNTIME_ROOT = "/opt/spawnfile/runtime-installs/daimon";
|
|
8
10
|
/** `00000000000000c1` = CHOWN|SETGID|SETUID, the launcher's bounding set after `setpriv`. */
|
|
9
11
|
export const LAUNCHER_CAPABILITY_BOUND = "00000000000000c1";
|
|
@@ -52,6 +54,7 @@ export const startBrokerProcesses = async (options) => {
|
|
|
52
54
|
const deadline = Date.now() + timeoutMs;
|
|
53
55
|
try {
|
|
54
56
|
for (const entry of brokerProcessPlan()) {
|
|
57
|
+
const previousSocket = await stat(entry.socket).catch(() => undefined);
|
|
55
58
|
const child = spawn(entry.argv[0], entry.argv.slice(1), { stdio: ["ignore", "inherit", "inherit"] });
|
|
56
59
|
if (child.pid === undefined)
|
|
57
60
|
throw new SpawnfileError("runtime_error", `${entry.name} did not start`);
|
|
@@ -64,7 +67,7 @@ export const startBrokerProcesses = async (options) => {
|
|
|
64
67
|
if (Date.now() > deadline)
|
|
65
68
|
throw new SpawnfileError("runtime_error", `${entry.name} readiness timed out`);
|
|
66
69
|
const socket = await stat(entry.socket).catch(() => undefined);
|
|
67
|
-
if (socket
|
|
70
|
+
if (isStartedBrokerSocket(socket, previousSocket)) {
|
|
68
71
|
const identity = await processIdentity(child.pid, procRoot);
|
|
69
72
|
if (identity.uid === String(entry.uid) && identity.capBnd === entry.capBnd)
|
|
70
73
|
break;
|
|
@@ -18,6 +18,7 @@ export interface DaimonProjectionModule {
|
|
|
18
18
|
projectionVersion: string;
|
|
19
19
|
slotPreflightVersion: string;
|
|
20
20
|
nativeAbiVersion: number;
|
|
21
|
+
controlProtocolVersion: string;
|
|
21
22
|
};
|
|
22
23
|
}
|
|
23
24
|
export declare const loadDaimonProjectionModule: (load?: () => Promise<unknown>) => Promise<DaimonProjectionModule>;
|
|
@@ -31,13 +32,13 @@ export declare const loadDaimonProjectionModule: (load?: () => Promise<unknown>)
|
|
|
31
32
|
* of peers reach `resolveOrganizationGrokBrokerProjection`, so this minimal
|
|
32
33
|
* config and Paideia's fuller one compute the same projection digest. A peer
|
|
33
34
|
* agent would change Daimon's protected set and the digest with it, which is
|
|
34
|
-
*
|
|
35
|
+
* why each slot resolves its own one-agent projection with explicit sibling deny paths.
|
|
35
36
|
*/
|
|
36
37
|
export declare const trainingOrganizationRuntimeConfig: (declaration: {
|
|
37
38
|
agentId: string;
|
|
38
39
|
model: DaimonGrokBrokerModel;
|
|
39
40
|
reasoningEffort: DaimonGrokBrokerReasoningEffort;
|
|
40
|
-
}) => Record<string, unknown>;
|
|
41
|
+
}, slot?: number) => Record<string, unknown>;
|
|
41
42
|
export interface TrainingGrokProjection {
|
|
42
43
|
projection: Record<string, unknown>;
|
|
43
44
|
projectionSha256: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SpawnfileError } from "../../../shared/index.js";
|
|
2
2
|
import { DAIMON_GROK_ENGINE_BROKER } from "../../../runtime/daimon/contractManifest.js";
|
|
3
|
-
import {
|
|
3
|
+
import { trainingSlotPaths } from "./paths.js";
|
|
4
4
|
/** Indirect specifier: Daimon is an in-image runtime peer of the training container, never a Spawnfile source dependency. */
|
|
5
5
|
const loadRuntime = async () => {
|
|
6
6
|
const packageName = "@noopolis/daimon/runtime";
|
|
@@ -16,6 +16,7 @@ export const loadDaimonProjectionModule = async (load = loadRuntime) => {
|
|
|
16
16
|
}
|
|
17
17
|
if (typeof daimon.resolveOrganizationGrokBrokerProjection !== "function" || typeof daimon.grokBrokerProjectionSha256 !== "function"
|
|
18
18
|
|| daimon.GROK_ENGINE_BROKER?.projectionVersion !== DAIMON_GROK_ENGINE_BROKER.projectionVersion
|
|
19
|
+
|| daimon.GROK_ENGINE_BROKER.controlProtocolVersion !== DAIMON_GROK_ENGINE_BROKER.controlProtocolVersion
|
|
19
20
|
|| daimon.GROK_ENGINE_BROKER.slotPreflightVersion !== DAIMON_GROK_ENGINE_BROKER.slotPreflightVersion
|
|
20
21
|
|| daimon.GROK_ENGINE_BROKER.nativeAbiVersion !== DAIMON_GROK_ENGINE_BROKER.nativeAbiVersion) {
|
|
21
22
|
throw new SpawnfileError("runtime_error", "The installed Daimon Grok broker contract differs from this compiler's vendored manifest");
|
|
@@ -32,17 +33,17 @@ export const loadDaimonProjectionModule = async (load = loadRuntime) => {
|
|
|
32
33
|
* of peers reach `resolveOrganizationGrokBrokerProjection`, so this minimal
|
|
33
34
|
* config and Paideia's fuller one compute the same projection digest. A peer
|
|
34
35
|
* agent would change Daimon's protected set and the digest with it, which is
|
|
35
|
-
*
|
|
36
|
+
* why each slot resolves its own one-agent projection with explicit sibling deny paths.
|
|
36
37
|
*/
|
|
37
|
-
export const trainingOrganizationRuntimeConfig = (declaration) => ({
|
|
38
|
+
export const trainingOrganizationRuntimeConfig = (declaration, slot = 0) => ({
|
|
38
39
|
version: "noopolis.daimon.organization-runtime.v1",
|
|
39
|
-
host: { bindHost: "127.0.0.1", port:
|
|
40
|
+
host: { bindHost: "127.0.0.1", port: trainingSlotPaths(slot).ports.workerControl, controlTokenEnv: "SPAWNFILE_DAIMON_CONTROL_TOKEN" },
|
|
40
41
|
agents: [{
|
|
41
42
|
id: declaration.agentId,
|
|
42
43
|
name: declaration.agentId,
|
|
43
44
|
instructions: "training subject",
|
|
44
|
-
workspacePath:
|
|
45
|
-
runtimeHomePath:
|
|
45
|
+
workspacePath: trainingSlotPaths(slot).workspace,
|
|
46
|
+
runtimeHomePath: trainingSlotPaths(slot).runtimeHome,
|
|
46
47
|
engine: { kind: "grok", model: declaration.model, reasoningEffort: declaration.reasoningEffort }
|
|
47
48
|
}]
|
|
48
49
|
});
|
|
@@ -53,21 +54,32 @@ export const trainingOrganizationRuntimeConfig = (declaration) => ({
|
|
|
53
54
|
* list drifted from the bytes provisioning wrote.
|
|
54
55
|
*/
|
|
55
56
|
export const resolveTrainingGrokProjection = async (declaration, registration, daimon) => {
|
|
56
|
-
const projection = daimon.resolveOrganizationGrokBrokerProjection(trainingOrganizationRuntimeConfig(declaration), declaration.agentId, {
|
|
57
|
+
const projection = daimon.resolveOrganizationGrokBrokerProjection(trainingOrganizationRuntimeConfig(declaration, registration.slot), declaration.agentId, {
|
|
57
58
|
slot: registration.slot,
|
|
59
|
+
workerConfigVariant: "clocked",
|
|
58
60
|
workerUid: registration.uid,
|
|
59
|
-
workerHomePath:
|
|
61
|
+
workerHomePath: registration.home,
|
|
60
62
|
architecture: declaration.architecture,
|
|
61
63
|
usageLedgerPath: registration.usageLedgerPath,
|
|
62
64
|
limits: declaration.limits,
|
|
63
65
|
// The mask that protects the wake-acceptance store is the slot state root it lives in: the store's
|
|
64
66
|
// own parent is `2000:2000 0700`, so bubblewrap could not materialize a deny target inside it as
|
|
65
67
|
// the worker uid. Every party that recomputes this projection must pass the same value.
|
|
66
|
-
acceptanceStorePath:
|
|
68
|
+
acceptanceStorePath: trainingSlotPaths(registration.slot).state,
|
|
67
69
|
denyPaths: registration.denyPaths,
|
|
68
70
|
seccompProfileSha256: declaration.seccompProfileSha256,
|
|
69
71
|
profileSha256: registration.profileSha256
|
|
70
72
|
});
|
|
73
|
+
const clock = DAIMON_GROK_ENGINE_BROKER.worker.taskClock;
|
|
74
|
+
const expectedClock = { ...clock, directoryPath: clock.slotDirectoryPattern.replace("{slot}", String(registration.slot)),
|
|
75
|
+
timestampFilePath: clock.slotFilePattern.replace("{slot}", String(registration.slot)) };
|
|
76
|
+
const actualClock = projection.taskClock;
|
|
77
|
+
if (registration.configVariant !== "clocked" || projection.version !== DAIMON_GROK_ENGINE_BROKER.projectionVersion
|
|
78
|
+
|| projection.profileSha256 !== registration.profileSha256 || actualClock === undefined
|
|
79
|
+
|| Object.entries(expectedClock).some(([key, value]) => actualClock[key] !== value)
|
|
80
|
+
|| projection.workerConfigVariant !== "clocked" || projection.workerConfigSha256 !== registration.configSha256) {
|
|
81
|
+
throw new SpawnfileError("runtime_error", "Daimon's clocked worker config differs from the provisioned registration");
|
|
82
|
+
}
|
|
71
83
|
const denied = [...projection.denyPaths];
|
|
72
84
|
if (denied.length !== registration.denyPaths.length || denied.some((entry, index) => entry !== registration.denyPaths[index])) {
|
|
73
85
|
throw new SpawnfileError("runtime_error", "Daimon's Grok broker projection deny list differs from the provisioned sandbox profile");
|
|
@@ -7,7 +7,7 @@ import type { DaimonGrokRegistration } from "../../containerDaimonGrokWorkerRend
|
|
|
7
7
|
* `2100:2000 2750` uid 2000 — Paideia, DSPy and every judge — cannot read a
|
|
8
8
|
* single subject usage row or inference row it paid for.
|
|
9
9
|
*/
|
|
10
|
-
export declare const trainingSlotDirectories: () => readonly {
|
|
10
|
+
export declare const trainingSlotDirectories: (slot?: number) => readonly {
|
|
11
11
|
path: string;
|
|
12
12
|
mode: string;
|
|
13
13
|
uid: number;
|
|
@@ -22,20 +22,11 @@ export declare const trainingSlotDirectories: () => readonly {
|
|
|
22
22
|
* and the worker uid instead, and this refuses to provision a slot in an image
|
|
23
23
|
* that did not.
|
|
24
24
|
*/
|
|
25
|
-
export declare const renderTrainingIdentities: () => string[];
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
*
|
|
31
|
-
* Everything below the slot skeleton is Daimon's audited production
|
|
32
|
-
* provisioning: the same credential bootstrap and journal recovery, the same
|
|
33
|
-
* `registrations.bin`, the same attested worker `GROK_HOME` layout, the same
|
|
34
|
-
* P1b private worker temp, closed shared temp and setgid spill directory, and
|
|
35
|
-
* the same `service.json` — here v2 with the per-slot usage ledger, the
|
|
36
|
-
* per-slot tmpfs turn store and the evaluator `inferenceLedgerPath`.
|
|
37
|
-
*/
|
|
38
|
-
export declare const renderTrainingBrokerProvisioning: (registration: DaimonGrokRegistration) => string[];
|
|
25
|
+
export declare const renderTrainingIdentities: (slots?: number) => string[];
|
|
26
|
+
/** Full container provisioning runs exactly once, before any broker process starts. */
|
|
27
|
+
export declare const renderTrainingBrokerProvisioning: (input: DaimonGrokRegistration | readonly DaimonGrokRegistration[], maxRunRequests?: number) => string[];
|
|
28
|
+
/** Reuse the audited worker renderer; never touch service config, credentials, shared temps or siblings. */
|
|
29
|
+
export declare const renderTrainingSlotProvisioning: (registration: DaimonGrokRegistration) => string[];
|
|
39
30
|
/**
|
|
40
31
|
* The sealed-inputs seal, asserted and then attacked before any slot is used.
|
|
41
32
|
*
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { renderTrainingTaskClockReset } from "./taskClock.js";
|
|
2
3
|
import { DAIMON_GROK_SECCOMP_PROFILE_SHA256 } from "../../../shared/daimonGrokSeccompProfile.js";
|
|
3
4
|
import { DAIMON_GROK_ENGINE_BROKER, DAIMON_GROK_TURN_USAGE_LEDGER } from "../../../runtime/daimon/contractManifest.js";
|
|
4
5
|
import { DAIMON_WAKE_FUSE_DIRECTORY } from "../../../runtime/daimon/config.js";
|
|
5
|
-
import { renderDaimonBrokerProvisioningProgram } from "../../containerDaimonBrokerRender.js";
|
|
6
|
-
import { renderDaimonGrokHostPreflight } from "../../containerDaimonGrokWorkerProvisioning.js";
|
|
7
|
-
import { DAIMON_BROKER_UID, DAIMON_ORGANIZATION_UID, TRAINING_GRANT_HOME_ROOT, TRAINING_INFERENCE_DIRECTORY, TRAINING_INFERENCE_LEDGER, TRAINING_OPTIONAL_DENY_DIRECTORIES, TRAINING_PAIDEIA_ROOT,
|
|
6
|
+
import { renderDaimonBrokerProvisioningProgram, renderDaimonWorkspaceResourceSecurity } from "../../containerDaimonBrokerRender.js";
|
|
7
|
+
import { renderDaimonGrokHostPreflight, renderDaimonGrokWorkerProvisioning } from "../../containerDaimonGrokWorkerProvisioning.js";
|
|
8
|
+
import { trainingSlotPaths, trainingSlotDescriptors, TRAINING_TURN_STORE_ROOT, TRAINING_RUN_REQUEST_STORE, DAIMON_BROKER_UID, DAIMON_ORGANIZATION_UID, TRAINING_GRANT_HOME_ROOT, TRAINING_INFERENCE_DIRECTORY, TRAINING_INFERENCE_LEDGER, TRAINING_OPTIONAL_DENY_DIRECTORIES, TRAINING_PAIDEIA_ROOT, TRAINING_SEALED_INPUTS_IDENTITY, TRAINING_SEALED_INPUTS_ROOT, TRAINING_SUPERVISOR_DIRECTORY, TRAINING_BROKER_TMPDIR, TRAINING_WORKER_ROOT, } from "./paths.js";
|
|
8
9
|
import { trainingNamespaceDenialMechanism } from "./seccompRoutes.js";
|
|
9
10
|
const quote = (value) => `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
10
11
|
/**
|
|
@@ -28,21 +29,22 @@ const PROVISION_DIRECTORY_HELPER = [
|
|
|
28
29
|
* `2100:2000 2750` uid 2000 — Paideia, DSPy and every judge — cannot read a
|
|
29
30
|
* single subject usage row or inference row it paid for.
|
|
30
31
|
*/
|
|
31
|
-
export const trainingSlotDirectories = () => [
|
|
32
|
+
export const trainingSlotDirectories = (slot = 0) => [
|
|
32
33
|
// `/run/training` itself is deliberately absent: it is a mount-point parent on the read-only
|
|
33
34
|
// image root, and every writable child below it is its own tmpfs or bind.
|
|
34
|
-
{ path:
|
|
35
|
+
{ path: trainingSlotPaths(slot).root, mode: "0711", uid: 0, gid: 0 },
|
|
35
36
|
{ path: TRAINING_PAIDEIA_ROOT, mode: "0750", uid: DAIMON_ORGANIZATION_UID, gid: DAIMON_ORGANIZATION_UID },
|
|
36
37
|
{ path: "/home/training", mode: "0700", uid: DAIMON_ORGANIZATION_UID, gid: DAIMON_ORGANIZATION_UID },
|
|
37
38
|
{ path: "/work", mode: "0700", uid: DAIMON_ORGANIZATION_UID, gid: DAIMON_ORGANIZATION_UID },
|
|
38
|
-
{ path:
|
|
39
|
+
{ path: trainingSlotPaths(slot).workspace, mode: "0750", uid: DAIMON_ORGANIZATION_UID, gid: trainingSlotPaths(slot).workerUid },
|
|
39
40
|
// The agent runtime home is deliberately absent: the shared broker provisioning creates it root-owned,
|
|
40
41
|
// fills its setgid `tool-output/`, and only then narrows it to `2000:<worker> 0710`. Handing it over here
|
|
41
42
|
// would leave root — which holds no `CAP_DAC_OVERRIDE` — unable to create the spill directory inside it.
|
|
42
|
-
{ path:
|
|
43
|
-
{ path:
|
|
44
|
-
{ path:
|
|
45
|
-
{ path:
|
|
43
|
+
{ path: trainingSlotPaths(slot).state, mode: "0700", uid: DAIMON_ORGANIZATION_UID, gid: DAIMON_ORGANIZATION_UID },
|
|
44
|
+
{ path: trainingSlotPaths(slot).acceptanceStore, mode: "0700", uid: DAIMON_ORGANIZATION_UID, gid: DAIMON_ORGANIZATION_UID },
|
|
45
|
+
{ path: TRAINING_TURN_STORE_ROOT, mode: "0700", uid: DAIMON_BROKER_UID, gid: DAIMON_BROKER_UID },
|
|
46
|
+
{ path: TRAINING_RUN_REQUEST_STORE, mode: "0700", uid: DAIMON_BROKER_UID, gid: DAIMON_BROKER_UID },
|
|
47
|
+
{ path: trainingSlotPaths(slot).usageDirectory, mode: "2750", uid: DAIMON_BROKER_UID, gid: DAIMON_ORGANIZATION_UID },
|
|
46
48
|
{ path: TRAINING_INFERENCE_DIRECTORY, mode: "2750", uid: DAIMON_BROKER_UID, gid: DAIMON_ORGANIZATION_UID },
|
|
47
49
|
{ path: TRAINING_GRANT_HOME_ROOT, mode: "0700", uid: DAIMON_ORGANIZATION_UID, gid: DAIMON_ORGANIZATION_UID },
|
|
48
50
|
// Traverse only: the supervisor socket inside it is the uid gate, and a directory nobody but root may
|
|
@@ -66,52 +68,68 @@ export const trainingSlotDirectories = () => [
|
|
|
66
68
|
* and the worker uid instead, and this refuses to provision a slot in an image
|
|
67
69
|
* that did not.
|
|
68
70
|
*/
|
|
69
|
-
export const renderTrainingIdentities = () => [
|
|
70
|
-
`for fixed_uid in ${DAIMON_ORGANIZATION_UID} ${DAIMON_BROKER_UID} ${
|
|
71
|
+
export const renderTrainingIdentities = (slots = 4) => [
|
|
72
|
+
`for fixed_uid in ${DAIMON_ORGANIZATION_UID} ${DAIMON_BROKER_UID} ${trainingSlotDescriptors(slots).map(p => p.workerUid).join(" ")}; do`,
|
|
71
73
|
' getent passwd "$fixed_uid" >/dev/null && getent group "$fixed_uid" >/dev/null || { echo "the training image must bake uid/gid $fixed_uid; the container root is read-only" >&2; exit 1; }',
|
|
72
74
|
"done"
|
|
73
75
|
];
|
|
74
|
-
/**
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
* slot supervisor on every recycle.
|
|
78
|
-
*
|
|
79
|
-
* Everything below the slot skeleton is Daimon's audited production
|
|
80
|
-
* provisioning: the same credential bootstrap and journal recovery, the same
|
|
81
|
-
* `registrations.bin`, the same attested worker `GROK_HOME` layout, the same
|
|
82
|
-
* P1b private worker temp, closed shared temp and setgid spill directory, and
|
|
83
|
-
* the same `service.json` — here v2 with the per-slot usage ledger, the
|
|
84
|
-
* per-slot tmpfs turn store and the evaluator `inferenceLedgerPath`.
|
|
85
|
-
*/
|
|
86
|
-
export const renderTrainingBrokerProvisioning = (registration) => [
|
|
76
|
+
/** Slot-local skeleton, shared by initial provisioning and recycle. */
|
|
77
|
+
const slotDirectories = (slot) => trainingSlotDirectories(slot).filter(entry => entry.path === trainingSlotPaths(slot).root || entry.path.startsWith(`${trainingSlotPaths(slot).root}/`));
|
|
78
|
+
const renderDirectories = (entries, ledgers) => [
|
|
87
79
|
...PROVISION_DIRECTORY_HELPER,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
// its own group, and the setgid directory below is what lets uid 2000 read a row it paid for.
|
|
96
|
-
...[TRAINING_SLOT_USAGE_LEDGER, TRAINING_INFERENCE_LEDGER].map((ledger) => `if [ ! -e ${quote(ledger)} ]; then : > ${quote(ledger)}; fi; chown 0:0 ${quote(ledger)}; chmod 0640 ${quote(ledger)}; chown ${DAIMON_BROKER_UID}:${DAIMON_ORGANIZATION_UID} ${quote(ledger)}`),
|
|
97
|
-
...[...trainingSlotDirectories()].sort((left, right) => right.path.split("/").length - left.path.split("/").length)
|
|
98
|
-
.map((entry) => `provision_dir ${quote(entry.path)} ${entry.mode} ${entry.uid} ${entry.gid}`),
|
|
99
|
-
...renderDaimonGrokHostPreflight(),
|
|
100
|
-
...renderDaimonBrokerProvisioningProgram([registration], [], {
|
|
101
|
-
turnStore: TRAINING_SLOT_TURN_STORE,
|
|
102
|
-
inferenceLedgerPath: TRAINING_INFERENCE_LEDGER
|
|
103
|
-
}, "clear", TRAINING_OPTIONAL_DENY_DIRECTORIES, TRAINING_BROKER_TMPDIR),
|
|
104
|
-
// The shared program leaves the broker's `/etc` root `0555 root:root`, which every uid can list. Training
|
|
105
|
-
// denies that directory to its worker, and a canary can only observe a denial the kernel actually enforces.
|
|
106
|
-
`chmod 0550 /etc/daimon-engine-broker; chown 0:${DAIMON_BROKER_UID} /etc/daimon-engine-broker`,
|
|
107
|
-
`test "$(stat -c '%u:%g %a' ${quote(TRAINING_SLOT_USAGE_DIRECTORY)})" = "${DAIMON_BROKER_UID}:${DAIMON_ORGANIZATION_UID} 2750"`,
|
|
80
|
+
...entries.map(entry => `mkdir -p ${quote(entry.path)}`),
|
|
81
|
+
...ledgers.map(ledger => `if [ ! -e ${quote(ledger)} ]; then : > ${quote(ledger)}; fi; chown 0:0 ${quote(ledger)}; chmod 0640 ${quote(ledger)}; chown ${DAIMON_BROKER_UID}:${DAIMON_ORGANIZATION_UID} ${quote(ledger)}`),
|
|
82
|
+
...[...entries].sort((a, b) => b.path.split("/").length - a.path.split("/").length)
|
|
83
|
+
.map(entry => `provision_dir ${quote(entry.path)} ${entry.mode} ${entry.uid} ${entry.gid}`)
|
|
84
|
+
];
|
|
85
|
+
const renderSlotAssertions = (r) => [
|
|
86
|
+
`test "$(stat -c '%u:%g %a' ${quote(trainingSlotPaths(r.slot).usageDirectory)})" = "${DAIMON_BROKER_UID}:${DAIMON_ORGANIZATION_UID} 2750"`,
|
|
108
87
|
`test "$(stat -c '%u:%g %a' ${quote(TRAINING_INFERENCE_DIRECTORY)})" = "${DAIMON_BROKER_UID}:${DAIMON_ORGANIZATION_UID} 2750"`,
|
|
109
88
|
`test "$(stat -c '%u:%g %a' ${quote(TRAINING_GRANT_HOME_ROOT)})" = "${DAIMON_ORGANIZATION_UID}:${DAIMON_ORGANIZATION_UID} 700"`,
|
|
110
|
-
|
|
111
|
-
`setpriv --clear-groups --reuid ${
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
89
|
+
`setpriv --clear-groups --reuid ${r.uid} --regid ${r.uid} --inh-caps=-all --ambient-caps=-all --bounding-set=-all -- bash -ceu '! test -r ${quote(TRAINING_GRANT_HOME_ROOT)}'`,
|
|
90
|
+
`setpriv --clear-groups --reuid ${DAIMON_ORGANIZATION_UID} --regid ${DAIMON_ORGANIZATION_UID} --inh-caps=-all --ambient-caps=-all --bounding-set=-all -- bash -ceu 'test -r ${quote(r.usageLedgerPath)} && test -r ${quote(TRAINING_INFERENCE_LEDGER)}'`
|
|
91
|
+
];
|
|
92
|
+
/** Full container provisioning runs exactly once, before any broker process starts. */
|
|
93
|
+
export const renderTrainingBrokerProvisioning = (input, maxRunRequests = 1000) => {
|
|
94
|
+
if (!Number.isSafeInteger(maxRunRequests) || maxRunRequests < 1)
|
|
95
|
+
throw new Error("Invalid run request cap");
|
|
96
|
+
const registrations = Array.isArray(input) ? input : [input];
|
|
97
|
+
const directories = [...new Map(registrations.flatMap(r => trainingSlotDirectories(r.slot)).map(d => [d.path, d])).values()];
|
|
98
|
+
return [
|
|
99
|
+
...renderTrainingIdentities(registrations.length),
|
|
100
|
+
...renderTrainingTaskClockReset(),
|
|
101
|
+
...renderDirectories(directories, [...registrations.map(r => r.usageLedgerPath), TRAINING_INFERENCE_LEDGER]),
|
|
102
|
+
...renderDaimonGrokHostPreflight(),
|
|
103
|
+
...renderDaimonBrokerProvisioningProgram(registrations, [], {
|
|
104
|
+
version: "v3", maxRunRequests, runRequestStore: TRAINING_RUN_REQUEST_STORE,
|
|
105
|
+
turnStore: TRAINING_TURN_STORE_ROOT, inferenceLedgerPath: TRAINING_INFERENCE_LEDGER
|
|
106
|
+
}, "clear", TRAINING_OPTIONAL_DENY_DIRECTORIES, TRAINING_BROKER_TMPDIR, [
|
|
107
|
+
`mkdir -p ${quote(DAIMON_GROK_ENGINE_BROKER.worker.taskClock.rootDirectoryPath)}; chmod 0755 ${quote(DAIMON_GROK_ENGINE_BROKER.worker.taskClock.rootDirectoryPath)}`,
|
|
108
|
+
...registrations.flatMap(r => {
|
|
109
|
+
const p = trainingSlotPaths(r.slot);
|
|
110
|
+
return [
|
|
111
|
+
`mkdir -p ${quote(p.clockDirectory)}; chown 0:0 ${quote(p.clockDirectory)}; chmod 0755 ${quote(p.clockDirectory)}`,
|
|
112
|
+
`printf '+0\\n' > ${quote(p.clockFile)}; chmod 0644 ${quote(p.clockFile)}; chown ${DAIMON_BROKER_UID}:${DAIMON_BROKER_UID} ${quote(p.clockFile)}`,
|
|
113
|
+
`chown ${DAIMON_BROKER_UID}:${DAIMON_BROKER_UID} ${quote(p.clockDirectory)}`
|
|
114
|
+
];
|
|
115
|
+
})
|
|
116
|
+
]),
|
|
117
|
+
`chmod 0550 /etc/daimon-engine-broker; chown 0:${DAIMON_BROKER_UID} /etc/daimon-engine-broker`,
|
|
118
|
+
...registrations.flatMap(r => [...renderSlotAssertions(r), ...renderTrainingSealedInputsAssertions(r.uid, r.privateTmp)])
|
|
119
|
+
];
|
|
120
|
+
};
|
|
121
|
+
/** Reuse the audited worker renderer; never touch service config, credentials, shared temps or siblings. */
|
|
122
|
+
export const renderTrainingSlotProvisioning = (registration) => [
|
|
123
|
+
...renderDirectories(slotDirectories(registration.slot), [registration.usageLedgerPath]),
|
|
124
|
+
// Keep worker-home and private-tmp identities stable: sibling turns attest them concurrently.
|
|
125
|
+
`setpriv --clear-groups --reuid=${registration.uid} --regid=${registration.uid} --inh-caps=-all --ambient-caps=-all --bounding-set=-all -- mkdir -p ${quote(registration.grokHome)}`,
|
|
126
|
+
`chown 0:0 ${quote(registration.grokHome)}; chmod 0700 ${quote(registration.grokHome)}`,
|
|
127
|
+
"node <<'SPAWNFILE_TRAINING_SLOT_PROVISION'",
|
|
128
|
+
"const crypto = require('node:crypto'); const fs = require('node:fs');",
|
|
129
|
+
...renderDaimonWorkspaceResourceSecurity([]),
|
|
130
|
+
...renderDaimonGrokWorkerProvisioning([registration], {}, [], "slot"),
|
|
131
|
+
"SPAWNFILE_TRAINING_SLOT_PROVISION",
|
|
132
|
+
...renderSlotAssertions(registration),
|
|
115
133
|
...renderTrainingSealedInputsAssertions(registration.uid, registration.privateTmp)
|
|
116
134
|
];
|
|
117
135
|
/**
|
|
@@ -158,11 +176,11 @@ export const renderTrainingBrokerProvisioning = (registration) => [
|
|
|
158
176
|
* every trial on `namespace-rebind reached no verdict` — the `mkdir` failed, not
|
|
159
177
|
* the seal. The private tmp is also the workspace the subject itself has.
|
|
160
178
|
*/
|
|
161
|
-
export const renderTrainingSealedInputsAssertions = (workerUid =
|
|
179
|
+
export const renderTrainingSealedInputsAssertions = (workerUid = trainingSlotPaths(0).workerUid, privateTmp = trainingSlotPaths(0).privateTmp, mechanism = trainingNamespaceDenialMechanism()) => [
|
|
162
180
|
// Diagnostics go to a file rather than into the verdict: a route's stderr is util-linux prose that
|
|
163
181
|
// would turn every real verdict into "unknown", but a no-verdict refusal with no diagnostic is what
|
|
164
182
|
// made the first live failure unreadable, so the unknown branch prints it back.
|
|
165
|
-
`seal_diagnostic=${quote(`${
|
|
183
|
+
`seal_diagnostic=${quote(`${trainingSlotPaths(workerUid - trainingSlotPaths(0).workerUid).root}/seal-probe.err`)}`,
|
|
166
184
|
`seal_worker() { setpriv --clear-groups --reuid ${workerUid} --regid ${workerUid} --inh-caps=-all --ambient-caps=-all --bounding-set=-all -- /bin/sh -c "$1" 2>"$seal_diagnostic"; }`,
|
|
167
185
|
"seal_rows=''",
|
|
168
186
|
'seal_record() { if [ -n "$seal_rows" ]; then seal_rows="$seal_rows,"; fi; seal_rows="$seal_rows{\\"route\\":\\"$1\\",\\"verdict\\":\\"$2\\"}"; }',
|
|
@@ -198,7 +216,7 @@ export const renderTrainingSealedInputsAssertions = (workerUid = TRAINING_WORKER
|
|
|
198
216
|
// cross-repo `noopolis.daimon.grok-slot-preflight.v2` canary shape is deliberately untouched — its
|
|
199
217
|
// schema lives in Daimon and no consumer here can validate an added member — so the per-route
|
|
200
218
|
// mechanism is recorded here rather than implied by a bare `result: "denied"` there.
|
|
201
|
-
`seal_attestation=${quote(
|
|
219
|
+
`seal_attestation=${quote(trainingSlotPaths(workerUid - trainingSlotPaths(0).workerUid).sealedInputsAttestation)}`,
|
|
202
220
|
`printf '{"version":"spawnfile.training-sealed-inputs.v1","root":"%s","worker_uid":%s,"identity":"%s","pinned_seccomp_profile_sha256":"%s","namespace_routes":"%s","routes":[%s]}\\n' `
|
|
203
221
|
+ `${quote(TRAINING_SEALED_INPUTS_ROOT)} ${workerUid} `
|
|
204
222
|
+ `"$(stat -c '%u:%g %a' ${quote(TRAINING_SEALED_INPUTS_ROOT)})" ${quote(DAIMON_GROK_SECCOMP_PROFILE_SHA256)} `
|