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
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { lstat, readFile, readdir } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { rewindGit } from "./gitProcess.js";
|
|
4
|
+
import { instantNanos } from "./instant.js";
|
|
5
|
+
import { inspectGitIndexTimes, inspectGitWorktree } from "./leakGitPayload.js";
|
|
6
|
+
/** Enumerate every stored object, independently of the materializer's chosen-object list. */
|
|
7
|
+
export const inspectGitBundle = async (repository, input, report) => {
|
|
8
|
+
const add = (detail) => report.findings.push({
|
|
9
|
+
input: { section: input.section, id: input.id, declaredBy: input.declaredBy },
|
|
10
|
+
class: "git-object", path: input.path, detail
|
|
11
|
+
});
|
|
12
|
+
const gitDir = path.join(repository, ".git");
|
|
13
|
+
if (!(await lstat(gitDir)).isDirectory())
|
|
14
|
+
throw new Error("The materialized repository must have its own .git directory");
|
|
15
|
+
const names = new Set(await readdir(gitDir));
|
|
16
|
+
for (const name of ["FETCH_HEAD", "ORIG_HEAD", "logs", "packed-refs", "commondir", "shallow"]) {
|
|
17
|
+
if (names.has(name))
|
|
18
|
+
add(`Forbidden git metadata ${name}`);
|
|
19
|
+
}
|
|
20
|
+
const config = await readFile(path.join(gitDir, "config"), "utf8");
|
|
21
|
+
if (/^\s*\[\s*(?:include|includeif)\b/imu.test(config))
|
|
22
|
+
throw new Error("Git configuration includes are forbidden");
|
|
23
|
+
for (const name of ["objects/info/alternates", "objects/info/http-alternates", "info/grafts"]) {
|
|
24
|
+
const exists = await lstat(path.join(gitDir, name)).catch((error) => {
|
|
25
|
+
if (error.code === "ENOENT")
|
|
26
|
+
return null;
|
|
27
|
+
throw error;
|
|
28
|
+
});
|
|
29
|
+
if (exists)
|
|
30
|
+
throw new Error(`Git object indirection ${name} is forbidden`);
|
|
31
|
+
}
|
|
32
|
+
const localConfig = (await rewindGit(repository, ["config", "--local", "--no-includes", "--list", "--null"]))
|
|
33
|
+
.toString().split("\0").filter(Boolean);
|
|
34
|
+
for (const entry of localConfig) {
|
|
35
|
+
const key = entry.split("\n")[0].toLowerCase();
|
|
36
|
+
if (key.startsWith("remote.") || key === "core.worktree" || key === "extensions.partialclone")
|
|
37
|
+
add(`Forbidden git configuration ${key}`);
|
|
38
|
+
}
|
|
39
|
+
const refs = (await rewindGit(repository, ["for-each-ref", "--format=%(refname) %(objectname)"])).toString().trim().split("\n").filter(Boolean);
|
|
40
|
+
const head = (await readFile(path.join(gitDir, "HEAD"), "utf8")).trim();
|
|
41
|
+
const commit = input.source.commit;
|
|
42
|
+
if (!commit || !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/u.test(commit))
|
|
43
|
+
throw new Error("Missing materialized commit identity");
|
|
44
|
+
if (refs.length !== 1 || !refs[0].startsWith("refs/heads/") || refs[0].split(" ")[1] !== commit
|
|
45
|
+
|| head !== `ref: ${refs[0]?.split(" ")[0]}`)
|
|
46
|
+
add("Exactly one branch and HEAD must name the materialized commit");
|
|
47
|
+
const reachable = new Set((await rewindGit(repository, ["rev-list", "--objects", commit, "--"]))
|
|
48
|
+
.toString().split("\n").filter(Boolean).map((line) => line.split(" ")[0]));
|
|
49
|
+
const objects = (await rewindGit(repository, ["cat-file", "--batch-all-objects", "--batch-check=%(objectname) %(objecttype)"]))
|
|
50
|
+
.toString().trim().split("\n").filter(Boolean);
|
|
51
|
+
report.checked.gitObjects += objects.length;
|
|
52
|
+
for (const row of objects) {
|
|
53
|
+
const [oid, kind] = row.split(" ");
|
|
54
|
+
if (!reachable.has(oid))
|
|
55
|
+
add(`Object ${oid} is not reachable from ${commit}`);
|
|
56
|
+
if (kind !== "commit")
|
|
57
|
+
continue;
|
|
58
|
+
const object = (await rewindGit(repository, ["cat-file", "commit", oid])).toString();
|
|
59
|
+
const headers = object.split("\n\n", 1)[0];
|
|
60
|
+
for (const role of ["author", "committer"]) {
|
|
61
|
+
const match = new RegExp(`^${role} .* (-?\\d+) [+-]\\d{4}$`, "mu").exec(headers);
|
|
62
|
+
if (!match) {
|
|
63
|
+
add(`Commit ${oid} has no valid ${role} date`);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (BigInt(match[1]) * 1000000000n > instantNanos(report.at))
|
|
67
|
+
add(`Commit ${oid} has a future ${role} date`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
for (const inspect of [() => inspectGitWorktree(repository, commit), () => inspectGitIndexTimes(repository, report.at)]) {
|
|
71
|
+
try {
|
|
72
|
+
await inspect();
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
add(error instanceof Error ? error.message : String(error));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Compare against objects in the output repository, never the index or status' cached stat data. */
|
|
2
|
+
export declare const inspectGitWorktree: (repository: string, commit: string) => Promise<void>;
|
|
3
|
+
/** NUL terminates each pathname, so path text cannot masquerade as --debug stat metadata. */
|
|
4
|
+
export declare const inspectGitIndexTimes: (repository: string, at: string) => Promise<void>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { lstat, readFile, readdir, readlink } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { rewindGit } from "./gitProcess.js";
|
|
4
|
+
import { safeCommittedPath } from "./gitTree.js";
|
|
5
|
+
import { instantNanos } from "./instant.js";
|
|
6
|
+
/** Compare against objects in the output repository, never the index or status' cached stat data. */
|
|
7
|
+
export const inspectGitWorktree = async (repository, commit) => {
|
|
8
|
+
const entries = new Map();
|
|
9
|
+
for (const row of (await rewindGit(repository, ["ls-tree", "-rtz", `${commit}^{tree}`])).toString().split("\0").filter(Boolean)) {
|
|
10
|
+
const tab = row.indexOf("\t"), name = safeCommittedPath(row.slice(tab + 1));
|
|
11
|
+
const [mode, kind, oid] = row.slice(0, tab).split(" ");
|
|
12
|
+
entries.set(name, { mode: mode, kind: kind, oid: oid });
|
|
13
|
+
}
|
|
14
|
+
const visit = async (directory, prefix = "") => {
|
|
15
|
+
for (const name of await readdir(directory)) {
|
|
16
|
+
if (!prefix && name === ".git")
|
|
17
|
+
continue;
|
|
18
|
+
const relative = prefix ? `${prefix}/${name}` : name, file = path.join(directory, name);
|
|
19
|
+
const expected = entries.get(relative), stats = await lstat(file);
|
|
20
|
+
if (!expected)
|
|
21
|
+
throw new Error(`Unexpected git worktree entry ${relative}`);
|
|
22
|
+
entries.delete(relative);
|
|
23
|
+
if (expected.kind === "tree" && stats.isDirectory()) {
|
|
24
|
+
await visit(file, relative);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (expected.kind !== "blob" || !["100644", "100755", "120000"].includes(expected.mode)) {
|
|
28
|
+
throw new Error(`Unsupported git worktree entry ${relative}`);
|
|
29
|
+
}
|
|
30
|
+
const bytes = await rewindGit(repository, ["cat-file", "blob", expected.oid]);
|
|
31
|
+
const matches = expected.mode === "120000"
|
|
32
|
+
? stats.isSymbolicLink() && (await readlink(file, { encoding: "buffer" })).equals(bytes)
|
|
33
|
+
: stats.isFile() && Boolean(stats.mode & 0o111) === (expected.mode === "100755") && (await readFile(file)).equals(bytes);
|
|
34
|
+
if (!matches)
|
|
35
|
+
throw new Error(`Git worktree entry mismatch: ${relative}`);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
await visit(repository);
|
|
39
|
+
if (entries.size)
|
|
40
|
+
throw new Error(`Missing git worktree entries: ${[...entries.keys()].join(", ")}`);
|
|
41
|
+
};
|
|
42
|
+
/** NUL terminates each pathname, so path text cannot masquerade as --debug stat metadata. */
|
|
43
|
+
export const inspectGitIndexTimes = async (repository, at) => {
|
|
44
|
+
const debug = (await rewindGit(repository, ["ls-files", "--debug", "-z"])).toString();
|
|
45
|
+
for (let cursor = 0; cursor < debug.length;) {
|
|
46
|
+
const end = debug.indexOf("\0", cursor);
|
|
47
|
+
const metadata = end < 0 ? null : /^ ctime: (\d+):(\d+)\n mtime: (\d+):(\d+)\n dev: [^\n]+\n uid: [^\n]+\n size: [^\n]+\n/u.exec(debug.slice(end + 1));
|
|
48
|
+
if (!metadata)
|
|
49
|
+
throw new Error("Invalid git index stat metadata");
|
|
50
|
+
for (const [label, offset] of [["ctime", 1], ["mtime", 3]]) {
|
|
51
|
+
const nanos = BigInt(metadata[offset]) * 1000000000n + BigInt(metadata[offset + 1]);
|
|
52
|
+
if (nanos > instantNanos(at))
|
|
53
|
+
throw new Error(`Git index ${label} is later than the moment: ${debug.slice(cursor, end)}`);
|
|
54
|
+
}
|
|
55
|
+
cursor = end + 1 + metadata[0].length;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LeakCheck, LeakFinding, MaterializedInput, MaterializedMoment } from "./contract.js";
|
|
2
|
+
import { type History } from "./history.js";
|
|
3
|
+
export declare const addInputFinding: (report: LeakCheck, input: MaterializedInput, kind: LeakFinding["class"], detail: string, file?: string) => void;
|
|
4
|
+
export declare const inspectMemoryBundle: (root: string, input: MaterializedInput, report: LeakCheck) => Promise<void>;
|
|
5
|
+
export declare const inspectFeedBundle: (root: string, input: MaterializedInput, report: LeakCheck, moment?: MaterializedMoment, history?: History) => Promise<void>;
|
|
6
|
+
export declare const inspectMoltnetBundle: (root: string, input: MaterializedInput, report: LeakCheck) => Promise<void>;
|
|
7
|
+
export declare const inspectVolumeBundle: (root: string, input: MaterializedInput, report: LeakCheck, history?: History) => Promise<void>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { lstat, readFile, readdir, readlink, realpath } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { feedIdentityFindings } from "../../../volume/feedRecord.js";
|
|
4
|
+
import { digestDirectory } from "../../../volume/index.js";
|
|
5
|
+
import { assertPreparedFeedRevision, feedGitRevision, verifyPlainFeedTree } from "./feedContent.js";
|
|
6
|
+
import { assertLocalGitRepository } from "./gitHistory.js";
|
|
7
|
+
import { permitsFeedPublicationTime } from "./leakFeed.js";
|
|
8
|
+
import { historyKey, inside, safeSegment } from "./history.js";
|
|
9
|
+
import { compareInstants } from "./instant.js";
|
|
10
|
+
import { diskPath } from "./leakFiles.js";
|
|
11
|
+
import { assertDirectoryEntries } from "./leakLayout.js";
|
|
12
|
+
import { parseMemoryLedger } from "./memory.js";
|
|
13
|
+
import { inspectMoltnetJson } from "./moltnetJson.js";
|
|
14
|
+
import { inspectMoltnetSqlite } from "./moltnetSqlite.js";
|
|
15
|
+
import { readSnapshotManifest, snapshotBytes, snapshotHistoryPath, snapshotTreeFindings } from "./snapshotManifest.js";
|
|
16
|
+
export const addInputFinding = (report, input, kind, detail, file = input.path) => {
|
|
17
|
+
report.findings.push({ input: { section: input.section, id: input.id, declaredBy: input.declaredBy }, class: kind, path: file, detail });
|
|
18
|
+
};
|
|
19
|
+
export const inspectMemoryBundle = async (root, input, report) => {
|
|
20
|
+
const home = await diskPath(root, input.path);
|
|
21
|
+
await assertDirectoryEntries(home, { memory: "directory" });
|
|
22
|
+
await assertDirectoryEntries(path.join(home, "memory"), { "events.jsonl": "file" });
|
|
23
|
+
const ledger = parseMemoryLedger(await readFile(await diskPath(root, `${input.path}/memory/events.jsonl`), "utf8"));
|
|
24
|
+
report.checked.memoryEvents += ledger.events.length;
|
|
25
|
+
let native = false;
|
|
26
|
+
for (const [index, event] of ledger.events.entries()) {
|
|
27
|
+
if (event.seq === undefined ? native : event.seq !== index + 1) {
|
|
28
|
+
addInputFinding(report, input, "memory-event", `Noncontiguous memory sequence at line ${index + 1}`);
|
|
29
|
+
}
|
|
30
|
+
native ||= event.seq !== undefined;
|
|
31
|
+
if (compareInstants(event.createdAt, report.at) > 0)
|
|
32
|
+
addInputFinding(report, input, "memory-event", `Future memory event at line ${index + 1}`);
|
|
33
|
+
if (index > 0 && compareInstants(event.createdAt, ledger.events[index - 1].createdAt) < 0) {
|
|
34
|
+
addInputFinding(report, input, "memory-event", `Memory clock regression at line ${index + 1}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (input.source.seq !== ledger.events.length)
|
|
38
|
+
addInputFinding(report, input, "memory-event", "Ledger length disagrees with the materialized sequence");
|
|
39
|
+
};
|
|
40
|
+
export const inspectFeedBundle = async (root, input, report, moment, history) => {
|
|
41
|
+
const directory = await diskPath(root, input.path);
|
|
42
|
+
if (input.fidelity === "overridden") {
|
|
43
|
+
if ((await readdir(directory)).length)
|
|
44
|
+
addInputFinding(report, input, "feed-identity", "Overridden feed volume must be empty");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const identity = JSON.parse(await readFile(await diskPath(root, `${input.path}/.spawnfile-feed.json`), "utf8"));
|
|
48
|
+
await assertDirectoryEntries(directory, { current: "symlink", ".spawnfile-feed.json": "file", trees: "directory" });
|
|
49
|
+
for (const issue of feedIdentityFindings(identity))
|
|
50
|
+
addInputFinding(report, input, "feed-identity", issue);
|
|
51
|
+
if (compareInstants(identity.landed_at, report.at) > 0 && !(moment && await permitsFeedPublicationTime(identity, input, moment, history))) {
|
|
52
|
+
addInputFinding(report, input, "feed-identity", "Feed landed_at is later than the moment");
|
|
53
|
+
}
|
|
54
|
+
if (identity.resource !== input.id || identity.revision !== input.source.revision) {
|
|
55
|
+
addInputFinding(report, input, "feed-identity", "Feed identity disagrees with the moment input");
|
|
56
|
+
}
|
|
57
|
+
const current = path.join(directory, "current");
|
|
58
|
+
if (!(await lstat(current)).isSymbolicLink())
|
|
59
|
+
throw new Error("Feed current must be a relative symlink");
|
|
60
|
+
const link = await readlink(current);
|
|
61
|
+
if (link !== identity.tree || !/^trees\/[a-f0-9]{64}(?:\.[1-9][0-9]*)?$/u.test(link)
|
|
62
|
+
|| !inside(path.join(directory, "trees"), await realpath(current))) {
|
|
63
|
+
addInputFinding(report, input, "feed-identity", "Feed current does not point to its tree inside the volume");
|
|
64
|
+
}
|
|
65
|
+
else if (!(await lstat(await realpath(current))).isDirectory())
|
|
66
|
+
addInputFinding(report, input, "feed-identity", "Feed tree must be a directory");
|
|
67
|
+
else {
|
|
68
|
+
await assertDirectoryEntries(path.join(directory, "trees"), { [path.basename(link)]: "directory" });
|
|
69
|
+
const prepared = identity.source.prepared !== undefined || input.source.prepared === true;
|
|
70
|
+
if (prepared && (input.fidelity !== "approximate" || !input.notes.includes("prepared output not content-verifiable"))) {
|
|
71
|
+
addInputFinding(report, input, "feed-identity", "Prepared feed must be approximate: prepared output not content-verifiable");
|
|
72
|
+
}
|
|
73
|
+
if (identity.source.prepared)
|
|
74
|
+
assertPreparedFeedRevision(identity.revision, identity.source.prepared);
|
|
75
|
+
if (identity.source.kind === "directory" && !prepared && digestDirectory(await realpath(current)) !== identity.revision) {
|
|
76
|
+
addInputFinding(report, input, "feed-identity", "Directory feed revision disagrees with retained bytes");
|
|
77
|
+
}
|
|
78
|
+
if (identity.source.kind === "git") {
|
|
79
|
+
const repository = await history?.repository(`feeds/${historyKey(input)}/repo`);
|
|
80
|
+
if (!repository)
|
|
81
|
+
throw new Error("Missing feed source history repository for content verification");
|
|
82
|
+
await assertLocalGitRepository(repository, history);
|
|
83
|
+
if (!prepared)
|
|
84
|
+
await verifyPlainFeedTree(repository, identity, await realpath(current));
|
|
85
|
+
else if (identity.source.prepared && feedGitRevision(repository, identity.source.commit, identity.source.ref, identity.source.paths)
|
|
86
|
+
!== identity.source.prepared.source_revision)
|
|
87
|
+
throw new Error("Prepared feed source revision disagrees with selected commit and paths");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
export const inspectMoltnetBundle = async (root, input, report) => {
|
|
92
|
+
const directory = await diskPath(root, input.path);
|
|
93
|
+
const stores = (await readdir(directory)).filter((name) => name === "state.json" || name === "moltnet.sqlite");
|
|
94
|
+
if (stores.length !== 1)
|
|
95
|
+
throw new Error("Expected exactly one Moltnet store");
|
|
96
|
+
await assertDirectoryEntries(directory, { [stores[0]]: "file" });
|
|
97
|
+
const store = await diskPath(root, `${input.path}/${stores[0]}`);
|
|
98
|
+
const result = stores[0] === "state.json" ? await inspectMoltnetJson(store, report.at) : await inspectMoltnetSqlite(store, report.at);
|
|
99
|
+
report.checked.moltnetMessages += result.messages;
|
|
100
|
+
report.checked.moltnetEvents += result.events;
|
|
101
|
+
for (const finding of result.findings)
|
|
102
|
+
addInputFinding(report, input, finding.class, finding.detail, path.relative(root, finding.path));
|
|
103
|
+
};
|
|
104
|
+
export const inspectVolumeBundle = async (root, input, report, history) => {
|
|
105
|
+
const directory = await diskPath(root, input.path);
|
|
106
|
+
if (input.fidelity === "overridden") {
|
|
107
|
+
for (const name of await readdir(directory))
|
|
108
|
+
addInputFinding(report, input, "snapshot", `Unexpected snapshot entry ${name}`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (!history || !input.source.snapshot || !input.source.agentSlug)
|
|
112
|
+
throw new Error("Snapshot verification requires its history, agent slug and selected snapshot");
|
|
113
|
+
if (input.source.snapshot.endsWith(".partial"))
|
|
114
|
+
throw new Error("Selected snapshot is partial");
|
|
115
|
+
const relative = snapshotHistoryPath(input.source.agentSlug, input.id, input.source.snapshot);
|
|
116
|
+
const manifest = await readSnapshotManifest(history, relative, input.id, input.source.snapshot);
|
|
117
|
+
const retained = await history.path(relative);
|
|
118
|
+
if (!manifest || !retained)
|
|
119
|
+
throw new Error("Snapshot tree or manifest is missing");
|
|
120
|
+
if (compareInstants(manifest.started_at, report.at) > 0)
|
|
121
|
+
throw new Error("Selected snapshot is later than the moment");
|
|
122
|
+
const rows = await history.wakeMoments(`recording/${safeSegment(input.source.agentSlug)}/wake-moments.jsonl`);
|
|
123
|
+
if (!rows?.some((row) => compareInstants(row.started_at, manifest.started_at) === 0
|
|
124
|
+
&& row.snapshots.some((entry) => entry.id === input.id && entry.snapshot === input.source.snapshot))) {
|
|
125
|
+
throw new Error("Selected snapshot has no matching wake row");
|
|
126
|
+
}
|
|
127
|
+
report.checked.snapshots++;
|
|
128
|
+
for (const detail of await snapshotTreeFindings(retained, manifest, { retained: true }))
|
|
129
|
+
addInputFinding(report, input, "snapshot", `Retained ${detail}`);
|
|
130
|
+
for (const detail of await snapshotTreeFindings(directory, manifest, {
|
|
131
|
+
readBytes: async (name) => readFile(await diskPath(root, `${input.path}/${name}`)),
|
|
132
|
+
expectedBytes: (name) => snapshotBytes(history, relative, name)
|
|
133
|
+
}))
|
|
134
|
+
addInputFinding(report, input, "snapshot", detail);
|
|
135
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { lstat, readdir } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/** Closed native layouts cannot carry unrelated retained bytes, even when their dates are stamped. */
|
|
4
|
+
export const assertDirectoryEntries = async (directory, expected) => {
|
|
5
|
+
const names = await readdir(directory);
|
|
6
|
+
for (const name of names) {
|
|
7
|
+
if (!Object.hasOwn(expected, name))
|
|
8
|
+
throw new Error(`Unexpected payload entry ${name}`);
|
|
9
|
+
const stat = await lstat(path.join(directory, name)), kind = expected[name];
|
|
10
|
+
if (!(kind === "file" ? stat.isFile() : kind === "directory" ? stat.isDirectory() : stat.isSymbolicLink())) {
|
|
11
|
+
throw new Error(`Payload entry ${name} must be a ${kind}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
for (const name of Object.keys(expected))
|
|
15
|
+
if (!names.includes(name))
|
|
16
|
+
throw new Error(`Missing payload entry ${name}`);
|
|
17
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { LeakCheck, MaterializedInput } from "./contract.js";
|
|
2
|
+
/** Read receipts and source objects afresh; never trust the producer's date guard or stamped files. */
|
|
3
|
+
export declare const inspectInputProvenance: (root: string, input: MaterializedInput, report: LeakCheck, historyDir?: string) => Promise<void>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { mkdtemp, readFile, rm } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { assertLocalGitRepository } from "./gitHistory.js";
|
|
5
|
+
import { rewindGit } from "./gitProcess.js";
|
|
6
|
+
import { historyKey, openHistory } from "./history.js";
|
|
7
|
+
import { instantNanos } from "./instant.js";
|
|
8
|
+
import { diskPath } from "./leakFiles.js";
|
|
9
|
+
import { addInputFinding } from "./leakInputs.js";
|
|
10
|
+
import { verifyRecordedBundle } from "./recordedBundle.js";
|
|
11
|
+
import { digestDirectory } from "../../../volume/index.js";
|
|
12
|
+
import { exportGitTree } from "./gitTree.js";
|
|
13
|
+
const inspectBundleTree = async (repository, commit, directory, input) => {
|
|
14
|
+
if (!input.source.trees?.length)
|
|
15
|
+
throw new Error("Missing bundle source tree selection");
|
|
16
|
+
const scratch = await mkdtemp(path.join(os.tmpdir(), "spawnfile-bundle-check-"));
|
|
17
|
+
try {
|
|
18
|
+
for (const tree of input.source.trees)
|
|
19
|
+
await exportGitTree(repository, commit, scratch, { ...tree, mergeIdentical: true });
|
|
20
|
+
if (digestDirectory(directory) !== digestDirectory(scratch))
|
|
21
|
+
throw new Error("Bundle bytes disagree with selected commit, roots and exclusions");
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
await rm(scratch, { recursive: true, force: true });
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/** Read receipts and source objects afresh; never trust the producer's date guard or stamped files. */
|
|
28
|
+
export const inspectInputProvenance = async (root, input, report, historyDir) => {
|
|
29
|
+
const add = (detail) => addInputFinding(report, input, "git-object", detail);
|
|
30
|
+
try {
|
|
31
|
+
if (input.kind === "bundle" && (input.basis === "record" || input.basis === "deploy-log") && input.source.sha256) {
|
|
32
|
+
await verifyRecordedBundle(await openHistory(historyDir), input.source.sha256, await diskPath(root, input.path));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const commit = input.source.commit;
|
|
36
|
+
if (input.kind === "feed") {
|
|
37
|
+
if (input.fidelity === "overridden")
|
|
38
|
+
return;
|
|
39
|
+
const identity = JSON.parse(await readFile(await diskPath(root, `${input.path}/.spawnfile-feed.json`), "utf8"));
|
|
40
|
+
if (identity.source?.kind === "git") {
|
|
41
|
+
if (!commit || identity.source.commit !== commit)
|
|
42
|
+
add("Feed source commit disagrees with moment provenance");
|
|
43
|
+
}
|
|
44
|
+
else if (!commit)
|
|
45
|
+
return; // Directory feeds have no git provenance.
|
|
46
|
+
}
|
|
47
|
+
else if (input.kind === "bundle" && input.fidelity === "overridden" && !commit && !input.source.repository) {
|
|
48
|
+
return; // Explicit prebuilt tar overrides have no source commit.
|
|
49
|
+
}
|
|
50
|
+
if (!commit || !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/u.test(commit))
|
|
51
|
+
throw new Error("Missing or invalid source commit provenance");
|
|
52
|
+
let repository;
|
|
53
|
+
if (input.source.repository) {
|
|
54
|
+
// Only locally resolved pins/overrides may lack an entry in the history layout.
|
|
55
|
+
if (input.kind === "feed" || input.basis !== "pinned" && input.fidelity !== "overridden"
|
|
56
|
+
|| !path.isAbsolute(input.source.repository))
|
|
57
|
+
throw new Error("Invalid local provenance repository");
|
|
58
|
+
repository = input.source.repository;
|
|
59
|
+
await assertLocalGitRepository(repository);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const history = await openHistory(historyDir);
|
|
63
|
+
const key = input.kind === "feed" ? `feeds/${historyKey(input)}/repo` : `git/${historyKey(input)}`;
|
|
64
|
+
const retained = await history?.repository(key);
|
|
65
|
+
if (!retained)
|
|
66
|
+
throw new Error(`Missing source history repository for provenance: ${key}`);
|
|
67
|
+
repository = retained;
|
|
68
|
+
await assertLocalGitRepository(repository, history);
|
|
69
|
+
}
|
|
70
|
+
const type = (await rewindGit(repository, ["cat-file", "-t", commit])).toString().trim();
|
|
71
|
+
if (type !== "commit")
|
|
72
|
+
throw new Error(`Provenance object ${commit} must be a commit object; found ${type}`);
|
|
73
|
+
const headers = (await rewindGit(repository, ["cat-file", "commit", commit])).toString().split("\n\n", 1)[0];
|
|
74
|
+
report.checked.gitObjects++;
|
|
75
|
+
for (const role of ["author", "committer"]) {
|
|
76
|
+
const match = new RegExp(`^${role} .* (-?\\d+) [+-]\\d{4}$`, "mu").exec(headers);
|
|
77
|
+
if (!match)
|
|
78
|
+
add(`Provenance commit ${commit} has no valid ${role} date`);
|
|
79
|
+
else if (BigInt(match[1]) * 1000000000n > instantNanos(report.at))
|
|
80
|
+
add(`Provenance commit ${commit} has a future ${role} date`);
|
|
81
|
+
}
|
|
82
|
+
if (input.kind === "bundle")
|
|
83
|
+
await inspectBundleTree(repository, commit, await diskPath(root, input.path), input);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
add(error instanceof Error ? error.message : String(error));
|
|
87
|
+
}
|
|
88
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { LoadedTrainingProject, TrainingPlan } from "../plan/index.js";
|
|
2
|
+
import { type MaterializedMoment } from "./contract.js";
|
|
3
|
+
import { type MomentRecord } from "../../../recording/index.js";
|
|
4
|
+
import { type LeakCheckOptions } from "./leakCheck.js";
|
|
5
|
+
import type { RewindInput } from "./types.js";
|
|
6
|
+
export interface MaterializeTrainingMomentOptions {
|
|
7
|
+
plan: TrainingPlan;
|
|
8
|
+
project: LoadedTrainingProject;
|
|
9
|
+
example: string;
|
|
10
|
+
historyDir?: string;
|
|
11
|
+
out: string;
|
|
12
|
+
}
|
|
13
|
+
/** Pure core for a per-trial caller: effective declarations, example identity and matching record. */
|
|
14
|
+
export declare const resolveTrainingMoment: (plan: TrainingPlan, project: LoadedTrainingProject, example: string, records?: MomentRecord[]) => {
|
|
15
|
+
candidateRecords: {
|
|
16
|
+
version: "spawnfile.moment-record.v1";
|
|
17
|
+
agent: string;
|
|
18
|
+
wake: {
|
|
19
|
+
at: string;
|
|
20
|
+
startedAt: string;
|
|
21
|
+
executionId: string;
|
|
22
|
+
deliveries: {
|
|
23
|
+
deliveryId: string;
|
|
24
|
+
kind: string;
|
|
25
|
+
occurredAt: string;
|
|
26
|
+
}[];
|
|
27
|
+
surface?: "moltnet" | undefined;
|
|
28
|
+
room?: string | undefined;
|
|
29
|
+
from?: string | undefined;
|
|
30
|
+
messageId?: string | undefined;
|
|
31
|
+
};
|
|
32
|
+
recordedAt: string;
|
|
33
|
+
exact: boolean;
|
|
34
|
+
resources: ({
|
|
35
|
+
id: string;
|
|
36
|
+
kind: "git";
|
|
37
|
+
commit: string;
|
|
38
|
+
sha256?: string | undefined;
|
|
39
|
+
} | {
|
|
40
|
+
id: string;
|
|
41
|
+
kind: "bundle";
|
|
42
|
+
sha256: string;
|
|
43
|
+
})[];
|
|
44
|
+
feeds: {
|
|
45
|
+
id: string;
|
|
46
|
+
revision: string;
|
|
47
|
+
tree: string;
|
|
48
|
+
landedAt: string;
|
|
49
|
+
commit?: string | undefined;
|
|
50
|
+
ref?: string | undefined;
|
|
51
|
+
paths?: string[] | undefined;
|
|
52
|
+
period?: string | undefined;
|
|
53
|
+
}[];
|
|
54
|
+
memory: {
|
|
55
|
+
id: string;
|
|
56
|
+
declaredBy: string;
|
|
57
|
+
seq: number;
|
|
58
|
+
generation?: number | undefined;
|
|
59
|
+
}[];
|
|
60
|
+
moltnet: {
|
|
61
|
+
network: string;
|
|
62
|
+
cursor: string;
|
|
63
|
+
messageIds?: string[] | undefined;
|
|
64
|
+
}[];
|
|
65
|
+
volumes: {
|
|
66
|
+
id: string;
|
|
67
|
+
snapshot: string;
|
|
68
|
+
}[];
|
|
69
|
+
errors?: string[] | undefined;
|
|
70
|
+
}[];
|
|
71
|
+
record: {
|
|
72
|
+
version: "spawnfile.moment-record.v1";
|
|
73
|
+
agent: string;
|
|
74
|
+
wake: {
|
|
75
|
+
at: string;
|
|
76
|
+
startedAt: string;
|
|
77
|
+
executionId: string;
|
|
78
|
+
deliveries: {
|
|
79
|
+
deliveryId: string;
|
|
80
|
+
kind: string;
|
|
81
|
+
occurredAt: string;
|
|
82
|
+
}[];
|
|
83
|
+
surface?: "moltnet" | undefined;
|
|
84
|
+
room?: string | undefined;
|
|
85
|
+
from?: string | undefined;
|
|
86
|
+
messageId?: string | undefined;
|
|
87
|
+
};
|
|
88
|
+
recordedAt: string;
|
|
89
|
+
exact: boolean;
|
|
90
|
+
resources: ({
|
|
91
|
+
id: string;
|
|
92
|
+
kind: "git";
|
|
93
|
+
commit: string;
|
|
94
|
+
sha256?: string | undefined;
|
|
95
|
+
} | {
|
|
96
|
+
id: string;
|
|
97
|
+
kind: "bundle";
|
|
98
|
+
sha256: string;
|
|
99
|
+
})[];
|
|
100
|
+
feeds: {
|
|
101
|
+
id: string;
|
|
102
|
+
revision: string;
|
|
103
|
+
tree: string;
|
|
104
|
+
landedAt: string;
|
|
105
|
+
commit?: string | undefined;
|
|
106
|
+
ref?: string | undefined;
|
|
107
|
+
paths?: string[] | undefined;
|
|
108
|
+
period?: string | undefined;
|
|
109
|
+
}[];
|
|
110
|
+
memory: {
|
|
111
|
+
id: string;
|
|
112
|
+
declaredBy: string;
|
|
113
|
+
seq: number;
|
|
114
|
+
generation?: number | undefined;
|
|
115
|
+
}[];
|
|
116
|
+
moltnet: {
|
|
117
|
+
network: string;
|
|
118
|
+
cursor: string;
|
|
119
|
+
messageIds?: string[] | undefined;
|
|
120
|
+
}[];
|
|
121
|
+
volumes: {
|
|
122
|
+
id: string;
|
|
123
|
+
snapshot: string;
|
|
124
|
+
}[];
|
|
125
|
+
errors?: string[] | undefined;
|
|
126
|
+
} | null;
|
|
127
|
+
effectiveAt: string;
|
|
128
|
+
inputs: RewindInput[];
|
|
129
|
+
selected: import("./select.js").SelectedExample;
|
|
130
|
+
at: string;
|
|
131
|
+
agentSlug: string;
|
|
132
|
+
};
|
|
133
|
+
/** A separately callable disk acceptance gate, also used to test deliberately broken producers. */
|
|
134
|
+
export declare const finalizeTrainingMoment: (staging: string, out: string, options?: LeakCheckOptions) => Promise<MaterializedMoment>;
|
|
135
|
+
/** Local-only rewind. No compilation artifacts, model invocation, auth, shell or network access. */
|
|
136
|
+
export declare const materializeTrainingMoment: (options: MaterializeTrainingMomentOptions) => Promise<MaterializedMoment>;
|