spawnfile 0.1.14 → 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 +60 -159
- package/dist/audit/checksShared.d.ts +1 -1
- package/dist/auth/importers.d.ts +10 -0
- package/dist/auth/importers.js +46 -5
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/paths.d.ts +1 -1
- package/dist/auth/profileStore.js +13 -10
- package/dist/auth/targetSecretSourceFsIdentity.d.ts +40 -0
- package/dist/auth/targetSecretSourceFsIdentity.js +42 -0
- package/dist/auth/targetSecretSourceFsPublish.d.ts +2 -0
- package/dist/auth/targetSecretSourceFsPublish.js +3 -1
- package/dist/auth/targetSecretSourceFsPublishImmutable.d.ts +2 -1
- package/dist/auth/targetSecretSourceFsPublishImmutable.js +104 -71
- package/dist/auth/targetSecretSourceFsRead.js +5 -14
- package/dist/auth/trainingAuth.d.ts +21 -0
- package/dist/auth/trainingAuth.js +86 -0
- package/dist/auth/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/auth/types.d.ts +1 -1
- package/dist/cli/authCommands.d.ts +1 -1
- package/dist/cli/authCommands.js +18 -5
- package/dist/cli/canaryCutoverCommand.d.ts +2 -0
- package/dist/cli/canaryCutoverCommand.js +30 -0
- package/dist/cli/capabilitiesCommand.d.ts +3 -0
- package/dist/cli/capabilitiesCommand.js +12 -0
- package/dist/cli/capabilitiesReceipt.d.ts +56 -0
- package/dist/cli/capabilitiesReceipt.js +56 -0
- package/dist/cli/compileBuildCommands.js +17 -0
- package/dist/cli/composedLifecycleContractSet.d.ts +21 -0
- package/dist/cli/composedLifecycleContractSet.js +204 -0
- package/dist/cli/devCommands.js +6 -2
- package/dist/cli/downCommand.d.ts +2 -0
- package/dist/cli/downCommand.js +22 -8
- package/dist/cli/envFileOption.d.ts +18 -0
- package/dist/cli/envFileOption.js +20 -0
- package/dist/cli/evidenceExportHelperCommand.d.ts +13 -0
- package/dist/cli/evidenceExportHelperCommand.js +51 -0
- package/dist/cli/index.js +12 -3
- package/dist/cli/lifecycleCommands.d.ts +1 -1
- package/dist/cli/lifecycleCommands.js +3 -1
- package/dist/cli/lifecycleMachine.d.ts +7 -1
- package/dist/cli/lifecycleMachine.js +2 -2
- package/dist/cli/lifecyclePlan.d.ts +1 -0
- package/dist/cli/lifecyclePlan.js +2 -0
- package/dist/cli/paideiaDelegation.d.ts +18 -0
- package/dist/cli/paideiaDelegation.js +211 -0
- package/dist/cli/paideiaSupervisor.d.ts +17 -0
- package/dist/cli/paideiaSupervisor.js +48 -0
- package/dist/cli/productStateCloneCommand.d.ts +2 -0
- package/dist/cli/productStateCloneCommand.js +34 -0
- package/dist/cli/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 +19 -3
- package/dist/cli/runCli.js +43 -10
- package/dist/cli/runPublishCommands.js +5 -3
- package/dist/cli/targetCommands.d.ts +4 -7
- package/dist/cli/targetCommands.js +16 -46
- package/dist/cli/targetConfigPreparedPlan.d.ts +3 -0
- package/dist/cli/targetConfigPreparedPlan.js +74 -0
- package/dist/cli/targetConfigResolver.d.ts +3 -0
- package/dist/cli/targetConfigResolver.js +111 -0
- package/dist/cli/targetConfigResolverCommand.d.ts +6 -0
- package/dist/cli/targetConfigResolverCommand.js +43 -0
- package/dist/cli/targetConfigResolverContracts.d.ts +56 -0
- package/dist/cli/targetConfigResolverContracts.js +30 -0
- package/dist/cli/targetConfigResolverDocker.d.ts +4 -0
- package/dist/cli/targetConfigResolverDocker.js +47 -0
- package/dist/cli/targetConfigResolverValidation.d.ts +10 -0
- package/dist/cli/targetConfigResolverValidation.js +94 -0
- package/dist/cli/targetDefaultAuthorities.d.ts +2 -0
- package/dist/cli/targetDefaultAuthorities.js +3 -0
- package/dist/cli/targetDefaultConfig.d.ts +7 -0
- package/dist/cli/targetDefaultConfig.js +22 -5
- package/dist/cli/targetDefaultConfigStdin.js +7 -1
- package/dist/cli/targetDefaultHandlerFactory.js +23 -2
- package/dist/cli/targetDefaultHandlers.d.ts +2 -2
- package/dist/cli/targetProductionCommands.d.ts +5 -0
- package/dist/cli/targetProductionCommands.js +45 -0
- package/dist/cli/trainCommand.d.ts +3 -0
- package/dist/cli/trainCommand.js +114 -0
- package/dist/cli/upCommand.js +40 -7
- package/dist/cli/upLifecycleRecovery.d.ts +2 -2
- package/dist/cli/upLifecycleRecovery.js +188 -44
- package/dist/cli/usageCommand.d.ts +40 -0
- package/dist/cli/usageCommand.js +284 -0
- package/dist/cli/usageCommandLive.d.ts +84 -0
- package/dist/cli/usageCommandLive.js +95 -0
- package/dist/cli/usageDeploymentSource.d.ts +9 -0
- package/dist/cli/usageDeploymentSource.js +22 -0
- package/dist/cli/volumeCommands.d.ts +8 -0
- package/dist/cli/volumeCommands.js +53 -0
- package/dist/cli/workspaceResourceMigrationCommand.d.ts +8 -0
- package/dist/cli/workspaceResourceMigrationCommand.js +36 -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/buildCompilePlanTeams.d.ts +1 -1
- package/dist/compiler/buildCompilePlanTeams.js +6 -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 +5 -0
- package/dist/compiler/compileProject.d.ts +12 -0
- package/dist/compiler/compileProject.js +33 -3
- package/dist/compiler/compileProjectSupport.js +9 -0
- package/dist/compiler/containerArtifactSummaries.js +1 -0
- package/dist/compiler/containerArtifacts.d.ts +7 -5
- package/dist/compiler/containerArtifacts.js +77 -41
- package/dist/compiler/containerArtifactsPlans.d.ts +1 -1
- package/dist/compiler/containerArtifactsPlans.js +31 -7
- package/dist/compiler/containerArtifactsRender.d.ts +2 -1
- package/dist/compiler/containerArtifactsRender.js +91 -58
- package/dist/compiler/containerArtifactsTypes.d.ts +15 -0
- package/dist/compiler/containerBackedMountRender.d.ts +56 -0
- package/dist/compiler/containerBackedMountRender.js +101 -0
- package/dist/compiler/containerDaimonBrokerRender.d.ts +114 -0
- package/dist/compiler/containerDaimonBrokerRender.js +194 -0
- package/dist/compiler/containerDaimonGrokTaskClock.d.ts +5 -0
- package/dist/compiler/containerDaimonGrokTaskClock.js +29 -0
- package/dist/compiler/containerDaimonGrokWorkerProvisioning.d.ts +38 -0
- package/dist/compiler/containerDaimonGrokWorkerProvisioning.js +130 -0
- package/dist/compiler/containerDaimonGrokWorkerRender.d.ts +197 -0
- package/dist/compiler/containerDaimonGrokWorkerRender.js +281 -0
- package/dist/compiler/containerDaimonOwnershipGuardRender.d.ts +25 -0
- package/dist/compiler/containerDaimonOwnershipGuardRender.js +204 -0
- package/dist/compiler/containerDaimonUidEntrypointRender.d.ts +24 -0
- package/dist/compiler/containerDaimonUidEntrypointRender.js +291 -0
- package/dist/compiler/containerEntrypointRender.d.ts +7 -0
- package/dist/compiler/containerEntrypointRender.js +28 -22
- package/dist/compiler/containerPersistentMounts.d.ts +30 -0
- package/dist/compiler/containerPersistentMounts.js +66 -0
- package/dist/compiler/containerReadinessPaths.d.ts +1 -0
- package/dist/compiler/containerReadinessPaths.js +1 -0
- package/dist/compiler/containerRuntimeLinkMaterializer.d.ts +2 -0
- package/dist/compiler/containerRuntimeLinkMaterializer.js +12 -0
- package/dist/compiler/containerRuntimeReadinessRender.d.ts +7 -0
- package/dist/compiler/containerRuntimeReadinessRender.js +40 -0
- package/dist/compiler/containerStateOwnershipRender.d.ts +4 -0
- package/dist/compiler/containerStateOwnershipRender.js +75 -0
- package/dist/compiler/containerTargetResources.d.ts +32 -1
- package/dist/compiler/containerTargetResources.js +115 -15
- package/dist/compiler/containerVolumeBootstrap.d.ts +3 -0
- package/dist/compiler/containerVolumeBootstrap.js +3 -0
- package/dist/compiler/containerWorkspaceResourceRender.js +52 -1
- package/dist/compiler/daimonTelemetryArtifacts.d.ts +2 -2
- package/dist/compiler/daimonTelemetryArtifacts.js +5 -10
- package/dist/compiler/deploymentLineage.d.ts +40 -0
- package/dist/compiler/deploymentLineage.js +50 -0
- package/dist/compiler/index.d.ts +5 -0
- package/dist/compiler/index.js +5 -0
- package/dist/compiler/initProject.d.ts +2 -0
- package/dist/compiler/initProject.js +39 -1
- package/dist/compiler/localMoltnetAuthority.d.ts +64 -0
- package/dist/compiler/localMoltnetAuthority.js +177 -0
- package/dist/compiler/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/memoryArtifacts.d.ts +1 -1
- package/dist/compiler/memoryArtifacts.js +108 -32
- package/dist/compiler/modelEnv.d.ts +5 -0
- package/dist/compiler/modelEnv.js +8 -2
- package/dist/compiler/moltnetArtifactPaths.d.ts +17 -12
- package/dist/compiler/moltnetArtifactPaths.js +17 -15
- package/dist/compiler/moltnetArtifactTypes.d.ts +11 -0
- package/dist/compiler/moltnetArtifacts.d.ts +1 -1
- package/dist/compiler/moltnetArtifacts.js +53 -12
- package/dist/compiler/moltnetBinaries.d.ts +16 -4
- package/dist/compiler/moltnetBinaries.js +46 -6
- package/dist/compiler/moltnetClientConfig.js +1 -1
- package/dist/compiler/moltnetConfigLowering.d.ts +3 -1
- package/dist/compiler/moltnetConfigLowering.js +30 -6
- package/dist/compiler/moltnetNodeConfig.js +1 -1
- package/dist/compiler/moltnetReleaseAuthority.d.ts +24 -1
- package/dist/compiler/moltnetReleaseAuthority.js +33 -4
- package/dist/compiler/moltnetRepresentativeResolution.d.ts +1 -1
- package/dist/compiler/moltnetRepresentativeResolution.js +2 -2
- package/dist/compiler/moltnetResolution.js +9 -15
- package/dist/compiler/moltnetRoomMemberships.js +20 -5
- package/dist/compiler/moltnetRoomPolicyCompatibility.d.ts +1 -1
- package/dist/compiler/moltnetRoomPolicyCompatibility.js +3 -1
- package/dist/compiler/moltnetRuntimeConfig.d.ts +1 -1
- package/dist/compiler/moltnetRuntimeConfig.js +22 -2
- package/dist/compiler/moltnetServerPlans.js +19 -0
- package/dist/compiler/organizationExternalParticipants.d.ts +3 -0
- package/dist/compiler/organizationExternalParticipants.js +176 -0
- package/dist/compiler/organizationIdentity.d.ts +3 -9
- package/dist/compiler/organizationIdentity.js +37 -270
- package/dist/compiler/organizationIdentityGraph.d.ts +15 -0
- package/dist/compiler/organizationIdentityGraph.js +115 -0
- package/dist/compiler/organizationReadyEvidence.d.ts +8 -0
- package/dist/compiler/organizationReadyEvidence.js +23 -3
- package/dist/compiler/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 +6 -3
- package/dist/compiler/runProject.js +34 -6
- package/dist/compiler/runProjectAuth.d.ts +3 -1
- package/dist/compiler/runProjectAuth.js +19 -3
- package/dist/compiler/runProjectDaimonCodexDocker.d.ts +3 -0
- package/dist/compiler/runProjectDaimonCodexDocker.js +36 -0
- package/dist/compiler/runProjectDocker.d.ts +8 -4
- package/dist/compiler/runProjectDocker.js +43 -18
- package/dist/compiler/runProjectDockerDaimonGuards.d.ts +15 -0
- package/dist/compiler/runProjectDockerDaimonGuards.js +122 -0
- package/dist/compiler/runProjectDockerReservation.d.ts +3 -0
- package/dist/compiler/runProjectDockerReservation.js +118 -0
- package/dist/compiler/runProjectLifecycle.js +1 -1
- package/dist/compiler/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 +47 -0
- package/dist/compiler/training/broker/declaration.js +57 -0
- package/dist/compiler/training/broker/entrypoint.d.ts +39 -0
- package/dist/compiler/training/broker/entrypoint.js +126 -0
- 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 +11 -0
- package/dist/compiler/training/broker/index.js +11 -0
- package/dist/compiler/training/broker/main.d.ts +2 -0
- package/dist/compiler/training/broker/main.js +14 -0
- package/dist/compiler/training/broker/paths.d.ts +236 -0
- package/dist/compiler/training/broker/paths.js +249 -0
- package/dist/compiler/training/broker/processes.d.ts +51 -0
- package/dist/compiler/training/broker/processes.js +102 -0
- package/dist/compiler/training/broker/projection.d.ts +52 -0
- package/dist/compiler/training/broker/projection.js +88 -0
- package/dist/compiler/training/broker/provisioning.d.ts +78 -0
- package/dist/compiler/training/broker/provisioning.js +231 -0
- package/dist/compiler/training/broker/receipt.d.ts +77 -0
- package/dist/compiler/training/broker/receipt.js +110 -0
- package/dist/compiler/training/broker/registration.d.ts +43 -0
- package/dist/compiler/training/broker/registration.js +110 -0
- 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 +22 -0
- package/dist/compiler/training/broker/runtime.js +127 -0
- package/dist/compiler/training/broker/seccompRoutes.d.ts +31 -0
- package/dist/compiler/training/broker/seccompRoutes.js +36 -0
- package/dist/compiler/training/broker/supervisor.d.ts +108 -0
- package/dist/compiler/training/broker/supervisor.js +172 -0
- 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 +54 -0
- package/dist/compiler/training/container/contract.js +51 -0
- 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 +5 -0
- package/dist/compiler/training/container/index.js +3 -0
- package/dist/compiler/training/container/launch.d.ts +21 -0
- package/dist/compiler/training/container/launch.js +264 -0
- 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 +10 -0
- package/dist/compiler/training/container/prepare.js +125 -0
- package/dist/compiler/training/container/process.d.ts +14 -0
- package/dist/compiler/training/container/process.js +70 -0
- package/dist/compiler/training/container/security.d.ts +38 -0
- package/dist/compiler/training/container/security.js +68 -0
- 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 +15 -0
- package/dist/compiler/training/context.js +93 -0
- package/dist/compiler/training/contract.d.ts +144 -0
- package/dist/compiler/training/contract.js +36 -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 +12 -0
- package/dist/compiler/training/index.js +10 -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 +109 -0
- package/dist/compiler/training/preparation/assets/package-lock.json +3787 -0
- package/dist/compiler/training/preparation/broker.d.ts +21 -0
- package/dist/compiler/training/preparation/broker.js +45 -0
- package/dist/compiler/training/preparation/contextModes.d.ts +12 -0
- package/dist/compiler/training/preparation/contextModes.js +38 -0
- package/dist/compiler/training/preparation/contract.d.ts +207 -0
- package/dist/compiler/training/preparation/contract.js +113 -0
- package/dist/compiler/training/preparation/copyAssets.d.ts +1 -0
- package/dist/compiler/training/preparation/copyAssets.js +8 -0
- package/dist/compiler/training/preparation/daimonParent.d.ts +42 -0
- package/dist/compiler/training/preparation/daimonParent.js +114 -0
- package/dist/compiler/training/preparation/files.d.ts +29 -0
- package/dist/compiler/training/preparation/files.js +146 -0
- package/dist/compiler/training/preparation/image.d.ts +28 -0
- package/dist/compiler/training/preparation/image.js +107 -0
- package/dist/compiler/training/preparation/index.d.ts +3 -0
- package/dist/compiler/training/preparation/index.js +2 -0
- package/dist/compiler/training/preparation/inputs.d.ts +24 -0
- package/dist/compiler/training/preparation/inputs.js +101 -0
- package/dist/compiler/training/preparation/prepare.d.ts +38 -0
- package/dist/compiler/training/preparation/prepare.js +223 -0
- package/dist/compiler/training/preparation/scratch.d.ts +8 -0
- package/dist/compiler/training/preparation/scratch.js +114 -0
- package/dist/compiler/training/repair/compatibility.d.ts +11 -0
- package/dist/compiler/training/repair/compatibility.js +34 -0
- package/dist/compiler/training/repair/contract.d.ts +840 -0
- package/dist/compiler/training/repair/contract.js +33 -0
- package/dist/compiler/training/repair/index.d.ts +3 -0
- package/dist/compiler/training/repair/index.js +3 -0
- package/dist/compiler/training/repair/prepare.d.ts +382 -0
- package/dist/compiler/training/repair/prepare.js +78 -0
- package/dist/compiler/training/repair/witness.d.ts +352 -0
- package/dist/compiler/training/repair/witness.js +48 -0
- 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 +7 -2
- package/dist/compiler/upProject.d.ts +27 -1
- package/dist/compiler/upProject.js +135 -180
- package/dist/compiler/upProjectHandoff.d.ts +62 -0
- package/dist/compiler/upProjectHandoff.js +204 -0
- package/dist/compiler/upReceipt.js +49 -4
- package/dist/compiler/updateProjectModels.js +1 -0
- package/dist/compiler/view/types.d.ts +1 -1
- package/dist/compiler/workspaceBundleArtifacts.d.ts +18 -0
- package/dist/compiler/workspaceBundleArtifacts.js +155 -0
- 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 +9 -2
- package/dist/compiler/workspaceResources.js +39 -7
- package/dist/deployment/activation.d.ts +3 -0
- package/dist/deployment/activation.js +12 -0
- package/dist/deployment/artifactsExportPlan.js +51 -1
- package/dist/deployment/canaryCutover.d.ts +42 -0
- package/dist/deployment/canaryCutover.js +140 -0
- package/dist/deployment/candidateDiagnostics.d.ts +15 -0
- package/dist/deployment/candidateDiagnostics.js +90 -0
- package/dist/deployment/candidateRecording.d.ts +8 -0
- package/dist/deployment/candidateRecording.js +22 -0
- package/dist/deployment/dockerLogs.js +4 -1
- package/dist/deployment/dockerManager.d.ts +5 -3
- package/dist/deployment/dockerManager.js +21 -5
- package/dist/deployment/dockerProbeGateway.d.ts +17 -0
- package/dist/deployment/dockerProbeGateway.js +17 -2
- package/dist/deployment/downDeployment.d.ts +7 -0
- package/dist/deployment/downDeployment.js +114 -9
- package/dist/deployment/downReceiptTypes.d.ts +17 -2
- package/dist/deployment/downReceiptTypes.js +17 -2
- package/dist/deployment/homeStore.d.ts +9 -1
- package/dist/deployment/homeStore.js +16 -53
- package/dist/deployment/index.d.ts +10 -0
- package/dist/deployment/index.js +10 -0
- package/dist/deployment/lifecycleCompletionContracts.d.ts +66 -0
- package/dist/deployment/lifecycleCompletionContracts.js +34 -0
- package/dist/deployment/lifecycleCompletionPaths.d.ts +4 -1
- package/dist/deployment/lifecycleCompletionPaths.js +3 -0
- package/dist/deployment/lifecycleCompletionPublication.d.ts +2 -0
- package/dist/deployment/lifecycleCompletionPublication.js +18 -4
- package/dist/deployment/lifecycleCompletionStore.d.ts +1 -1
- package/dist/deployment/lifecycleCompletionStore.js +7 -7
- package/dist/deployment/lifecycleUpRecords.d.ts +11 -0
- package/dist/deployment/lifecycleUpRecords.js +127 -0
- package/dist/deployment/native/AGENTS.md +11 -0
- package/dist/deployment/native/rename-noreplace-arm64 +0 -0
- package/dist/deployment/native/rename-noreplace-arm64.provenance.json +1 -0
- package/dist/deployment/native/rename-noreplace-x64 +0 -0
- package/dist/deployment/native/rename-noreplace-x64.provenance.json +1 -0
- package/dist/deployment/noReplaceActivation.d.ts +17 -0
- package/dist/deployment/noReplaceActivation.js +50 -0
- package/dist/deployment/organizationHandoffAuthorityFsBudget.d.ts +110 -0
- package/dist/deployment/organizationHandoffAuthorityFsBudget.js +156 -0
- package/dist/deployment/organizationHandoffAuthorityFsClient.js +82 -27
- package/dist/deployment/organizationHandoffAuthorityFsElection.d.ts +21 -0
- package/dist/deployment/organizationHandoffAuthorityFsElection.js +57 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorker.js +254 -108
- package/dist/deployment/organizationHandoffAuthorityFsWorkerStall.fixture.d.ts +1 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorkerStall.fixture.js +16 -0
- package/dist/deployment/organizationHandoffAuthorityStore.js +14 -7
- package/dist/deployment/organizationHandoffAuthorityTypes.d.ts +2 -2
- package/dist/deployment/organizationHandoffAuthorityTypes.js +2 -1
- package/dist/deployment/organizationReady.d.ts +2 -0
- package/dist/deployment/organizationReady.js +36 -4
- package/dist/deployment/pidLock.d.ts +25 -0
- package/dist/deployment/pidLock.js +81 -0
- package/dist/deployment/productStateClone.d.ts +43 -0
- package/dist/deployment/productStateClone.js +319 -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/deployment/upLifecycleRecoveryState.d.ts +23 -0
- package/dist/deployment/upLifecycleRecoveryState.js +12 -0
- package/dist/deployment/upReceiptTypes.d.ts +32 -6
- package/dist/deployment/upReceiptTypes.js +29 -2
- package/dist/deployment/workspaceResourceMigration.d.ts +55 -0
- package/dist/deployment/workspaceResourceMigration.js +315 -0
- package/dist/dev/project.d.ts +7 -0
- package/dist/dev/project.js +9 -0
- package/dist/distribution/buildDistributionReport.d.ts +3 -0
- package/dist/distribution/buildDistributionReport.js +5 -0
- package/dist/distribution/consumeImage.d.ts +5 -0
- package/dist/distribution/consumeImage.js +115 -98
- package/dist/distribution/consumeImageDaimonDocker.d.ts +3 -0
- package/dist/distribution/consumeImageDaimonDocker.js +45 -0
- package/dist/distribution/consumeImageLifecycle.d.ts +20 -0
- package/dist/distribution/consumeImageLifecycle.js +242 -0
- package/dist/distribution/consumeImageSupport.d.ts +19 -0
- package/dist/distribution/consumeImageSupport.js +40 -0
- package/dist/distribution/distributionReportSchema.d.ts +58 -1
- package/dist/distribution/distributionReportSchema.js +35 -2
- package/dist/distribution/dockerRunner.d.ts +6 -1
- package/dist/distribution/dockerRunner.js +31 -4
- package/dist/distribution/imageRuntimeAuth.d.ts +9 -1
- package/dist/distribution/imageRuntimeAuth.js +70 -1
- package/dist/distribution/index.d.ts +1 -1
- package/dist/distribution/index.js +1 -1
- package/dist/distribution/preflight.js +5 -1
- package/dist/distribution/renderImageInterface.js +1 -1
- package/dist/distribution/types.d.ts +29 -1
- package/dist/distribution/types.js +3 -0
- package/dist/evidenceExportHelper/boundedExecutor.d.ts +3 -0
- package/dist/evidenceExportHelper/boundedExecutor.js +33 -0
- package/dist/evidenceExportHelper/helperProgram.mjs +156 -0
- package/dist/evidenceExportHelper/index.d.ts +4 -0
- package/dist/evidenceExportHelper/index.js +4 -0
- package/dist/evidenceExportHelper/preparedAuthority.d.ts +64 -0
- package/dist/evidenceExportHelper/preparedAuthority.js +228 -0
- package/dist/evidenceExportHelper/preparedBuilder.d.ts +10 -0
- package/dist/evidenceExportHelper/preparedBuilder.js +183 -0
- package/dist/evidenceExportHelper/preparedBuilderTypes.d.ts +19 -0
- package/dist/evidenceExportHelper/preparedBuilderTypes.js +1 -0
- package/dist/evidenceExportHelper/recipe.d.ts +7 -0
- package/dist/evidenceExportHelper/recipe.js +83 -0
- package/dist/filesystem/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/io.d.ts +2 -0
- package/dist/filesystem/io.js +16 -1
- 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 +47 -0
- package/dist/manifest/executionSchemas.js +31 -2
- 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 +62 -0
- package/dist/manifest/mcpSchemas.js +57 -8
- 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/renderSpawnfileNetworks.js +11 -0
- package/dist/manifest/renderSpawnfileWorkspace.js +10 -1
- package/dist/manifest/scheduleSchemas.d.ts +3 -1
- package/dist/manifest/scheduleSchemas.js +91 -5
- package/dist/manifest/schemas.d.ts +1419 -120
- package/dist/manifest/schemas.js +19 -6
- package/dist/manifest/teamNetworkAccessSchemas.d.ts +5 -1
- package/dist/manifest/teamNetworkAccessSchemas.js +11 -0
- package/dist/manifest/teamNetworkAuthSchemas.d.ts +1 -1
- package/dist/manifest/teamNetworkSchemas.d.ts +18 -4
- package/dist/manifest/teamNetworkSchemas.js +19 -1
- package/dist/manifest/teamNetworkServerSchemas.d.ts +8 -3
- package/dist/manifest/teamNetworkServerSchemas.js +18 -2
- package/dist/manifest/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 +194 -1
- package/dist/manifest/workspaceSchemas.js +117 -2
- 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 +92 -4
- package/dist/runtime/common.d.ts +28 -1
- package/dist/runtime/common.js +33 -3
- package/dist/runtime/container.js +46 -35
- package/dist/runtime/daimon/adapter.d.ts +14 -0
- package/dist/runtime/daimon/adapter.js +254 -0
- package/dist/runtime/daimon/attention.d.ts +8 -0
- package/dist/runtime/daimon/attention.js +32 -0
- package/dist/runtime/daimon/config.d.ts +29 -0
- package/dist/runtime/daimon/config.js +321 -0
- 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 +346 -0
- package/dist/runtime/daimon/contractManifest.js +335 -0
- package/dist/runtime/daimon/grokModel.d.ts +19 -0
- package/dist/runtime/daimon/grokModel.js +33 -0
- package/dist/runtime/daimon/grokTurnLimits.d.ts +25 -0
- package/dist/runtime/daimon/grokTurnLimits.js +51 -0
- package/dist/runtime/daimon/grokWorkerConfigBytes.d.ts +43 -0
- package/dist/runtime/daimon/grokWorkerConfigBytes.js +53 -0
- package/dist/runtime/daimon/grokWorkerContract.d.ts +27 -0
- package/dist/runtime/daimon/grokWorkerContract.js +60 -0
- package/dist/runtime/daimon/memory.d.ts +57 -0
- package/dist/runtime/daimon/memory.js +125 -0
- package/dist/runtime/daimon/recording.d.ts +19 -0
- package/dist/runtime/daimon/recording.js +50 -0
- package/dist/runtime/daimon/runAuth.d.ts +51 -0
- package/dist/runtime/daimon/runAuth.js +279 -0
- package/dist/runtime/daimon/runtimeIdentity.d.ts +22 -0
- package/dist/runtime/daimon/runtimeIdentity.js +22 -0
- package/dist/runtime/daimon/scheduleAuthority.d.ts +11 -0
- package/dist/runtime/daimon/scheduleAuthority.js +31 -0
- 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 +5 -0
- package/dist/runtime/index.js +5 -0
- package/dist/runtime/install.d.ts +5 -0
- package/dist/runtime/install.js +4 -0
- package/dist/runtime/localDaimonAuthority.d.ts +11 -0
- package/dist/runtime/localDaimonAuthority.js +77 -0
- package/dist/runtime/mnemeMcp.d.ts +13 -0
- package/dist/runtime/mnemeMcp.js +26 -0
- package/dist/runtime/openclaw/adapter.js +5 -2
- package/dist/runtime/pi/adapter.d.ts +0 -1
- package/dist/runtime/pi/adapter.js +5 -6
- package/dist/runtime/pi/appCliSource.js +1 -1
- package/dist/runtime/pi/appScheduleSource.js +6 -2
- package/dist/runtime/pi/appTemplateTypes.d.ts +1 -1
- package/dist/runtime/pi/containerTargets.js +6 -0
- package/dist/runtime/picoclaw/adapter.js +5 -2
- package/dist/runtime/registry.d.ts +6 -0
- package/dist/runtime/registry.js +32 -3
- package/dist/runtime/scheduleUtils.d.ts +1 -0
- package/dist/runtime/scheduleUtils.js +5 -1
- package/dist/runtime/types.d.ts +40 -0
- package/dist/runtime/usageLedger.d.ts +158 -0
- package/dist/runtime/usageLedger.js +269 -0
- package/dist/runtime/usageLedgerRead.d.ts +54 -0
- package/dist/runtime/usageLedgerRead.js +102 -0
- package/dist/runtime/usageRequestLedger.d.ts +42 -0
- package/dist/runtime/usageRequestLedger.js +72 -0
- package/dist/shared/daimonCodexDocker.d.ts +32 -0
- package/dist/shared/daimonCodexDocker.js +120 -0
- package/dist/shared/daimonGrokSeccompProfile.d.ts +10 -0
- package/dist/shared/daimonGrokSeccompProfile.js +11 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +3 -0
- package/dist/shared/recording.d.ts +8 -0
- package/dist/shared/recording.js +25 -0
- package/dist/shared/types.d.ts +1 -1
- package/dist/shared/volumeNames.d.ts +6 -0
- package/dist/shared/volumeNames.js +14 -0
- package/dist/target/dockerArtifactsProvider.js +34 -7
- package/dist/target/dockerBaseImage.d.ts +2 -0
- package/dist/target/dockerBaseImage.js +11 -0
- package/dist/target/dockerCommandExecutor.d.ts +11 -0
- package/dist/target/dockerCommandExecutor.js +53 -2
- package/dist/target/dockerCommandExecutorCore.d.ts +2 -1
- package/dist/target/dockerCommandExecutorCore.js +5 -3
- package/dist/target/dockerPublicArtifactSnapshot.d.ts +3 -3
- package/dist/target/dockerPublicArtifactSnapshot.js +17 -33
- package/dist/target/dockerTarget.d.ts +1 -0
- package/dist/target/dockerTargetBinding.d.ts +1 -2
- package/dist/target/dockerTargetBinding.js +4 -4
- package/dist/target/dockerTargetExecFile.d.ts +19 -0
- package/dist/target/dockerTargetExecFile.js +194 -0
- package/dist/target/dockerWorldServiceProvider.d.ts +4 -0
- package/dist/target/dockerWorldServiceProvider.js +13 -1
- package/dist/target/evidenceExport.d.ts +3 -1
- package/dist/target/evidenceExport.js +12 -3
- package/dist/target/evidenceExportOperationsTestKit.js +3 -3
- package/dist/target/evidenceExportProvider.d.ts +2 -0
- package/dist/target/evidenceExportProvider.js +15 -5
- package/dist/target/publicArtifactSnapshot.d.ts +31 -0
- package/dist/target/publicArtifactSnapshot.js +37 -3
- package/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/examples/README.md +45 -0
- package/examples/agent-with-subagents/AGENTS.md +3 -0
- package/examples/agent-with-subagents/Spawnfile +30 -0
- package/examples/agent-with-subagents/subagents/critic/AGENTS.md +3 -0
- package/examples/agent-with-subagents/subagents/critic/Spawnfile +15 -0
- package/examples/agent-with-subagents/subagents/researcher/AGENTS.md +3 -0
- package/examples/agent-with-subagents/subagents/researcher/Spawnfile +17 -0
- package/examples/daimon-org/Spawnfile +68 -0
- package/examples/daimon-org/TEAM.md +4 -0
- package/examples/daimon-org/agents/mapper/AGENTS.md +4 -0
- package/examples/daimon-org/agents/mapper/Spawnfile +37 -0
- package/examples/daimon-org/shared/skills/file-note/SKILL.md +9 -0
- package/examples/daimon-org/teams/review/Spawnfile +53 -0
- package/examples/daimon-org/teams/review/agents/reviewer/AGENTS.md +4 -0
- package/examples/daimon-org/teams/review/agents/reviewer/Spawnfile +37 -0
- package/examples/daimon-public-host/AGENTS.md +3 -0
- package/examples/daimon-public-host/Spawnfile +21 -0
- package/examples/distribution-org/Spawnfile +43 -0
- package/examples/distribution-org/TEAM.md +4 -0
- package/examples/distribution-org/agents/coordinator/AGENTS.md +1 -0
- package/examples/distribution-org/agents/coordinator/Spawnfile +20 -0
- package/examples/distribution-org/agents/researcher/AGENTS.md +1 -0
- package/examples/distribution-org/agents/researcher/Spawnfile +20 -0
- package/examples/jungian-daimon-org/Spawnfile +41 -0
- package/examples/jungian-daimon-org/TEAM.md +21 -0
- package/examples/jungian-daimon-org/teams/luna/Spawnfile +47 -0
- package/examples/jungian-daimon-org/teams/luna/TEAM.md +4 -0
- package/examples/jungian-daimon-org/teams/luna/agents/animus/AGENTS.md +10 -0
- package/examples/jungian-daimon-org/teams/luna/agents/animus/Spawnfile +33 -0
- package/examples/jungian-daimon-org/teams/luna/agents/representative/AGENTS.md +21 -0
- package/examples/jungian-daimon-org/teams/luna/agents/representative/Spawnfile +30 -0
- package/examples/jungian-daimon-org/teams/luna/agents/shadow/AGENTS.md +10 -0
- package/examples/jungian-daimon-org/teams/luna/agents/shadow/Spawnfile +33 -0
- package/examples/jungian-daimon-org/teams/selene/Spawnfile +47 -0
- package/examples/jungian-daimon-org/teams/selene/TEAM.md +4 -0
- package/examples/jungian-daimon-org/teams/selene/agents/animus/AGENTS.md +10 -0
- package/examples/jungian-daimon-org/teams/selene/agents/animus/Spawnfile +33 -0
- package/examples/jungian-daimon-org/teams/selene/agents/representative/AGENTS.md +19 -0
- package/examples/jungian-daimon-org/teams/selene/agents/representative/Spawnfile +33 -0
- package/examples/jungian-daimon-org/teams/selene/agents/shadow/AGENTS.md +10 -0
- package/examples/jungian-daimon-org/teams/selene/agents/shadow/Spawnfile +30 -0
- package/examples/mixed-runtime-org/Spawnfile +71 -0
- package/examples/mixed-runtime-org/TEAM.md +8 -0
- package/examples/mixed-runtime-org/agents/analyst/AGENTS.md +8 -0
- package/examples/mixed-runtime-org/agents/analyst/Spawnfile +27 -0
- package/examples/mixed-runtime-org/agents/conductor/AGENTS.md +8 -0
- package/examples/mixed-runtime-org/agents/conductor/Spawnfile +27 -0
- package/examples/mixed-runtime-org/agents/localist/AGENTS.md +7 -0
- package/examples/mixed-runtime-org/agents/localist/Spawnfile +50 -0
- package/examples/moltnet-team-chat/Spawnfile +43 -0
- package/examples/moltnet-team-chat/TEAM.md +5 -0
- package/examples/moltnet-team-chat/agents/coordinator/AGENTS.md +9 -0
- package/examples/moltnet-team-chat/agents/coordinator/Spawnfile +26 -0
- package/examples/moltnet-team-chat/teams/analysis/Spawnfile +23 -0
- package/examples/moltnet-team-chat/teams/analysis/TEAM.md +3 -0
- package/examples/moltnet-team-chat/teams/analysis/agents/observer/AGENTS.md +5 -0
- package/examples/moltnet-team-chat/teams/analysis/agents/observer/Spawnfile +19 -0
- package/examples/moltnet-team-chat/teams/analysis/agents/representative/AGENTS.md +5 -0
- package/examples/moltnet-team-chat/teams/analysis/agents/representative/Spawnfile +19 -0
- package/examples/moltnet-team-chat/teams/field/Spawnfile +41 -0
- package/examples/moltnet-team-chat/teams/field/TEAM.md +3 -0
- package/examples/moltnet-team-chat/teams/field/agents/observer/AGENTS.md +5 -0
- package/examples/moltnet-team-chat/teams/field/agents/observer/Spawnfile +26 -0
- package/examples/moltnet-team-chat/teams/field/agents/representative/AGENTS.md +11 -0
- package/examples/moltnet-team-chat/teams/field/agents/representative/Spawnfile +26 -0
- package/examples/single-agent/AGENTS.md +3 -0
- package/examples/single-agent/HEARTBEAT.md +3 -0
- package/examples/single-agent/IDENTITY.md +3 -0
- package/examples/single-agent/MEMORY.md +3 -0
- package/examples/single-agent/SOUL.md +3 -0
- package/examples/single-agent/Spawnfile +41 -0
- package/examples/single-agent/skills/web_search/SKILL.md +6 -0
- package/moltnet-releases.json +5 -4
- package/package.json +36 -9
- package/runtimes.yaml +8 -3
- package/dist/cli/targetWorldClockCrossProcess.test-helper.d.ts +0 -13
- package/dist/cli/targetWorldClockCrossProcess.test-helper.js +0 -109
- package/dist/deployment/providerRuntimeBoundaryScanner.test-helper.d.ts +0 -8
- package/dist/deployment/providerRuntimeBoundaryScanner.test-helper.js +0 -60
- package/dist/deployment/simfileFixtureBoundary.test-helper.d.ts +0 -8
- package/dist/deployment/simfileFixtureBoundary.test-helper.js +0 -103
- package/dist/ownership/simfileRunOperatorInputs.d.ts +0 -103
- package/dist/ownership/simfileRunOperatorInputs.js +0 -139
- package/dist/target/cleanupRunDocker.test-helper.d.ts +0 -67
- package/dist/target/cleanupRunDocker.test-helper.js +0 -238
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Moving refs and the freeze: which git ref a refresh lands, decided per refresh from the host's clock,
|
|
2
|
+
// the declared rule and the host's own record -- never from anything inside the volume.
|
|
3
|
+
//
|
|
4
|
+
// WHY A PERIOD AND A REF NAME, NOT A COUNT OF ANYTHING. A freeze exists so readers who already started
|
|
5
|
+
// on this period's content are not moved mid-work. Whether they started cannot be read from the volume
|
|
6
|
+
// (agents can write and delete there, so any marker could freeze a period nobody used or thaw one they
|
|
7
|
+
// did). The host answers it from two things it owns: the period (local date in the freeze time zone) it
|
|
8
|
+
// stamped on the serving revision when it landed, and its clock. A spurious freeze keeps the period on
|
|
9
|
+
// content it already had; a spurious thaw moves content under readers. Both rules err toward the freeze.
|
|
10
|
+
//
|
|
11
|
+
// WHY A MISSING REF IS A WAIT BEFORE THE CUTOFF. A dated ref does not exist until its producer cuts it,
|
|
12
|
+
// so at period start "no such ref" is the normal state, not a failure; a timer that exits non-zero for
|
|
13
|
+
// it every poll trains people to ignore the alarm. Until the freeze cutoff it is a clean wait; after it
|
|
14
|
+
// (or with no freeze) it is a refusal.
|
|
15
|
+
import { spawnSync } from "node:child_process";
|
|
16
|
+
import { FEED_REF_PLACEHOLDER } from "../manifest/index.js";
|
|
17
|
+
import { feedError } from "./feedLayout.js";
|
|
18
|
+
const dateFormats = new Map();
|
|
19
|
+
const clockFormats = new Map();
|
|
20
|
+
const memo = (cache, zone, make) => {
|
|
21
|
+
if (!cache.has(zone))
|
|
22
|
+
cache.set(zone, make());
|
|
23
|
+
return cache.get(zone);
|
|
24
|
+
};
|
|
25
|
+
/** YYYY-MM-DD in `zone` at `now`. */
|
|
26
|
+
export const feedLocalDate = (now, zone) => memo(dateFormats, zone, () => new Intl.DateTimeFormat("en-CA", { day: "2-digit", month: "2-digit", timeZone: zone, year: "numeric" })).format(now);
|
|
27
|
+
/** HH:MM (24-hour, zero-padded, so a string compare orders it) in `zone` at `now`. */
|
|
28
|
+
export const feedLocalClock = (now, zone) => memo(clockFormats, zone, () => new Intl.DateTimeFormat("en-GB", { hour: "2-digit", hourCycle: "h23", minute: "2-digit", timeZone: zone })).format(now);
|
|
29
|
+
export const expandFeedRefTemplate = (template, now) => template.replace(FEED_REF_PLACEHOLDER, (_match, zone) => feedLocalDate(now, zone ?? "UTC"));
|
|
30
|
+
/**
|
|
31
|
+
* The fed paths at `now`: each declared path with its date placeholders expanded at the same instant as the
|
|
32
|
+
* ref, so a dated ref and the dated directory inside it always name the same day. Undefined feeds the whole tree.
|
|
33
|
+
*/
|
|
34
|
+
export const expandFeedPaths = (paths, now) => paths?.map((entry) => expandFeedRefTemplate(entry, now));
|
|
35
|
+
/** The period a landing at `now` belongs to; only a feed that declares a freeze has periods. */
|
|
36
|
+
export const feedPeriod = (target, now) => target.freeze ? feedLocalDate(now, target.freeze.timezone) : undefined;
|
|
37
|
+
const offsetFormats = new Map();
|
|
38
|
+
const offsetMinutes = (instant, zone) => {
|
|
39
|
+
const name = memo(offsetFormats, zone, () => new Intl.DateTimeFormat("en-US", { timeZone: zone, timeZoneName: "longOffset" }))
|
|
40
|
+
.formatToParts(instant).find((part) => part.type === "timeZoneName")?.value ?? "GMT";
|
|
41
|
+
const match = /GMT([+-])(\d{2}):(\d{2})/u.exec(name);
|
|
42
|
+
return match ? (match[1] === "-" ? -1 : 1) * (Number(match[2]) * 60 + Number(match[3])) : 0;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* The INSTANT `after` (HH:MM local) first arrives on `date` in `zone`. An instant, not a wall-clock
|
|
46
|
+
* compare: when clocks fall back the wall clock repeats an hour, and a wall-clock compare would thaw a
|
|
47
|
+
* volume that already froze. An ambiguous local time resolves to its first occurrence and a skipped one
|
|
48
|
+
* to the earlier candidate: both err toward freezing sooner.
|
|
49
|
+
*/
|
|
50
|
+
export const feedCutoffInstant = (date, after, zone) => {
|
|
51
|
+
const naive = Date.parse(`${date}T${after}:00Z`), span = 14 * 3_600_000;
|
|
52
|
+
const candidates = [...new Set([offsetMinutes(new Date(naive - span), zone), offsetMinutes(new Date(naive + span), zone)])]
|
|
53
|
+
.map((offset) => ({ instant: naive - offset * 60_000, offset }));
|
|
54
|
+
const valid = candidates.filter(({ instant, offset }) => offsetMinutes(new Date(instant), zone) === offset);
|
|
55
|
+
return new Date(Math.min(...(valid.length ? valid : candidates).map(({ instant }) => instant)));
|
|
56
|
+
};
|
|
57
|
+
const pastCutoff = (target, now) => target.freeze !== undefined &&
|
|
58
|
+
now.getTime() >= feedCutoffInstant(feedLocalDate(now, target.freeze.timezone), target.freeze.after, target.freeze.timezone).getTime();
|
|
59
|
+
const runRefCommand = (target, command, repo) => {
|
|
60
|
+
const [file, ...args] = command.argv;
|
|
61
|
+
const result = spawnSync(file, args, {
|
|
62
|
+
cwd: command.cwd, encoding: "utf8",
|
|
63
|
+
env: { ...process.env, SPAWNFILE_FEED_REPO: repo, SPAWNFILE_FEED_RESOURCE: target.resourceId },
|
|
64
|
+
maxBuffer: 1024 * 1024, stdio: ["ignore", "pipe", "pipe"], timeout: command.timeoutMs
|
|
65
|
+
});
|
|
66
|
+
if (result.error?.code === "ETIMEDOUT")
|
|
67
|
+
throw feedError(`the feed ref command for ${target.resourceId} did not finish within ${Math.round(command.timeoutMs / 1000)}s`);
|
|
68
|
+
if (result.error)
|
|
69
|
+
throw feedError(`the feed ref command for ${target.resourceId} could not run: ${result.error.message}`);
|
|
70
|
+
if (result.status !== 0)
|
|
71
|
+
throw feedError(`the feed ref command for ${target.resourceId} failed (${result.signal ? `killed by ${result.signal}` : `exit ${result.status}`}): ${String(result.stderr).trim().slice(-300)}`);
|
|
72
|
+
return String(result.stdout).split("\n").map((line) => line.trim()).find((line) => line !== "") ?? null;
|
|
73
|
+
};
|
|
74
|
+
const refExists = (exec, repo, ref) => {
|
|
75
|
+
try {
|
|
76
|
+
exec("git", ["-C", repo, "rev-parse", "--verify", "--quiet", "--end-of-options", `${ref}^{commit}`]);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* The ref this refresh lands: the fixed ref, or the rule's ref when it exists, else its fallback. A rule
|
|
85
|
+
* whose ref and fallback are both missing is a wait before the freeze cutoff and a refusal after it.
|
|
86
|
+
*/
|
|
87
|
+
export const chooseFeedRef = (target, { exec, now }) => {
|
|
88
|
+
const source = target.source, rule = target.refRule;
|
|
89
|
+
if (source.kind !== "git")
|
|
90
|
+
return { kind: "ref", ref: "" };
|
|
91
|
+
if (!rule)
|
|
92
|
+
return { kind: "ref", ref: source.ref };
|
|
93
|
+
const primary = rule.template !== undefined ? expandFeedRefTemplate(rule.template, now) : runRefCommand(target, rule.command, source.repo);
|
|
94
|
+
for (const candidate of [primary, rule.fallback]) {
|
|
95
|
+
if (candidate && refExists(exec, source.repo, candidate))
|
|
96
|
+
return { kind: "ref", ref: candidate };
|
|
97
|
+
}
|
|
98
|
+
const wanted = `${primary ? JSON.stringify(primary) : "the ref command printed no ref"}${rule.fallback ? ` (fallback ${JSON.stringify(rule.fallback)} is missing too)` : ""}`;
|
|
99
|
+
if (target.freeze && !pastCutoff(target, now)) {
|
|
100
|
+
return { kind: "waiting", reason: `waiting for ${wanted} in ${source.repo}: it is ${feedLocalClock(now, target.freeze.timezone)} ${target.freeze.timezone} and it is due by ${target.freeze.after}` };
|
|
101
|
+
}
|
|
102
|
+
throw feedError(`no ref to land for ${target.resourceId}: ${wanted} does not exist in ${source.repo}${target.freeze ? ` and the ${target.freeze.after} ${target.freeze.timezone} cutoff has passed` : ""}`);
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Frozen: the host landed the serving revision in THIS period, the period's cutoff has passed, and the ref
|
|
106
|
+
* and paths chosen now are the ones it was landed from. A new period, a different ref name (the next
|
|
107
|
+
* period's ref appearing) or different expanded paths advance again.
|
|
108
|
+
*/
|
|
109
|
+
export const feedFrozen = (target, record, ref, now, paths) => {
|
|
110
|
+
if (!target.freeze || !record?.period || !pastCutoff(target, now))
|
|
111
|
+
return false;
|
|
112
|
+
if (record.period !== feedLocalDate(now, target.freeze.timezone))
|
|
113
|
+
return false;
|
|
114
|
+
const landed = record.identity.source;
|
|
115
|
+
return landed.kind !== "git" || target.source.kind !== "git"
|
|
116
|
+
|| (landed.ref === ref && JSON.stringify(landed.paths ?? null) === JSON.stringify(paths ?? null));
|
|
117
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type FeedRuntime } from "./feedLand.js";
|
|
2
|
+
import { type FeedTarget } from "./feedTarget.js";
|
|
3
|
+
/** `frozen` and `waiting` are clean holds: the volume keeps serving what it has (see feedRef.ts). */
|
|
4
|
+
export type FeedRefreshStatus = "busy" | "current" | "frozen" | "landed" | "repaired" | "suspended" | "tampered" | "waiting";
|
|
5
|
+
export interface FeedRefreshResult {
|
|
6
|
+
findings: string[];
|
|
7
|
+
previous: string | null;
|
|
8
|
+
revision: string | null;
|
|
9
|
+
status: FeedRefreshStatus;
|
|
10
|
+
}
|
|
11
|
+
/** Clean means nothing needs a human: exit 0. */
|
|
12
|
+
export declare const feedResultClean: (result: FeedRefreshResult) => boolean;
|
|
13
|
+
export declare const refreshVolumeFeed: (target: FeedTarget, runtime?: FeedRuntime) => FeedRefreshResult;
|
|
14
|
+
/** Read-only: reports what a refresh would heal, changes nothing. Taken under the lock so a swap in flight is never misread. */
|
|
15
|
+
export declare const verifyVolumeFeed: (target: FeedTarget, runtime?: Pick<FeedRuntime, "log">) => FeedRefreshResult;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// `spawnfile volume refresh` and `spawnfile volume verify`, under the single-writer lock.
|
|
2
|
+
//
|
|
3
|
+
// A refresh lands a new revision when the source moved. When it did not, it sweeps the volume against
|
|
4
|
+
// the host record and heals what it can: re-lands a drifted tree from the source (beside it, as a new
|
|
5
|
+
// generation), restores the `current` link, republishes the identity record. One revision is re-landed at
|
|
6
|
+
// most `healLimit` times; the count survives clean refreshes and resets only when a new revision lands,
|
|
7
|
+
// so tampering that alternates with quiet periods cannot buy unlimited repairs.
|
|
8
|
+
import { mkdirSync } from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { assertFeedVolumeRoot, assertOutsideVolume, assertSameDevice, auditFeedRoot, feedTreeLink, LINK_OPS, pointCurrent } from "./feedLayout.js";
|
|
11
|
+
import { buildFeedManifest, writeFeedManifest } from "./feedManifest.js";
|
|
12
|
+
import { landFeed } from "./feedLand.js";
|
|
13
|
+
import { publishFeedLanded, ensureFeedLanding } from "./feedLandings.js";
|
|
14
|
+
import { acquireFeedLock } from "./feedLock.js";
|
|
15
|
+
import { resolveFeedContent } from "./feedPrepare.js";
|
|
16
|
+
import { readFeedLanded, writeFeedIdentity } from "./feedRecord.js";
|
|
17
|
+
import { chooseFeedRef, expandFeedPaths, feedFrozen, feedPeriod } from "./feedRef.js";
|
|
18
|
+
import { fetchFeedSource, hostExec } from "./feedSource.js";
|
|
19
|
+
import { feedStagingDir, feedTrashDir } from "./feedTarget.js";
|
|
20
|
+
import { sweepFeed } from "./feedVerify.js";
|
|
21
|
+
/** Clean means nothing needs a human: exit 0. */
|
|
22
|
+
export const feedResultClean = (result) => result.status === "busy" || result.status === "current" || result.status === "frozen" || result.status === "waiting" ||
|
|
23
|
+
(result.status === "landed" && result.findings.length === 0);
|
|
24
|
+
/** Every check that decides where host state may be written runs before anything -- the lock included -- is written. */
|
|
25
|
+
const confine = (target) => {
|
|
26
|
+
assertFeedVolumeRoot(target.volume);
|
|
27
|
+
assertOutsideVolume(target.volume, target.stateDir, "the feed state directory");
|
|
28
|
+
};
|
|
29
|
+
const prepare = (target) => {
|
|
30
|
+
for (const [label, directory] of [["the feed staging directory", feedStagingDir(target)], ["the feed trash directory", feedTrashDir(target)]]) {
|
|
31
|
+
mkdirSync(directory, { mode: 0o700, recursive: true });
|
|
32
|
+
assertSameDevice(target.volume, directory, label);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const withLock = (target, log, run) => {
|
|
36
|
+
confine(target);
|
|
37
|
+
const lock = acquireFeedLock(target.stateDir);
|
|
38
|
+
if (!lock) {
|
|
39
|
+
log(`another writer holds ${path.join(target.stateDir, "lock")}; nothing to do`);
|
|
40
|
+
return { findings: [], previous: null, revision: null, status: "busy" };
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
return run();
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
lock.release();
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const repairable = (sweep) => sweep.drift || sweep.relink || sweep.identity !== null;
|
|
50
|
+
const heal = (target, record, sweep, runtime, { held = false } = {}) => {
|
|
51
|
+
const log = runtime.log ?? (() => undefined);
|
|
52
|
+
const base = { findings: sweep.findings, previous: record.revision, revision: record.revision };
|
|
53
|
+
for (const finding of sweep.findings)
|
|
54
|
+
log(`TAMPER: ${finding}`);
|
|
55
|
+
if (sweep.failed || sweep.planted || sweep.blocked)
|
|
56
|
+
return { ...base, status: "tampered" };
|
|
57
|
+
if (target.record || record.recording)
|
|
58
|
+
ensureFeedLanding(target, record, (runtime.now ?? (() => new Date()))());
|
|
59
|
+
if (sweep.drift) {
|
|
60
|
+
const cycles = record.heals[record.revision] ?? 0;
|
|
61
|
+
if (cycles >= target.healLimit) {
|
|
62
|
+
log(`auto-repair suspended: ${record.revision.slice(0, 12)} was re-landed ${cycles} times and drifted again; it resumes when a new revision lands`);
|
|
63
|
+
return { ...base, status: "suspended" };
|
|
64
|
+
}
|
|
65
|
+
const resolved = resolveFeedContent(target, { exec: runtime.exec ?? hostExec });
|
|
66
|
+
if (resolved.revision !== record.revision) {
|
|
67
|
+
// A held volume never advances, not even to repair itself.
|
|
68
|
+
if (held)
|
|
69
|
+
return { ...base, findings: [...sweep.findings, `the volume is held at ${record.revision.slice(0, 12)} and its source no longer reproduces it (now ${resolved.revision.slice(0, 12)}); not re-landing while held`], status: "tampered" };
|
|
70
|
+
landFeed(target, resolved, record, { period: feedPeriod(target, (runtime.now ?? (() => new Date()))()), runtime });
|
|
71
|
+
return { ...base, revision: resolved.revision, status: "repaired" };
|
|
72
|
+
}
|
|
73
|
+
log(`re-landing ${record.revision.slice(0, 12)} from the source beside the drifted tree`);
|
|
74
|
+
landFeed(target, resolved, record, { exact: held, force: true, heals: { ...record.heals, [record.revision]: cycles + 1 }, ...(record.period ? { period: record.period } : {}), runtime });
|
|
75
|
+
return { ...base, status: "repaired" };
|
|
76
|
+
}
|
|
77
|
+
let switchingAt;
|
|
78
|
+
if (sweep.relink)
|
|
79
|
+
pointCurrent(target.volume, feedTreeLink(record.tree), { ops: runtime.ops ?? LINK_OPS, tmpDir: feedStagingDir(target),
|
|
80
|
+
...(target.record ? { beforeRename: () => { switchingAt = (runtime.now ?? (() => new Date()))().toISOString(); } } : {}) });
|
|
81
|
+
const reestablished = sweep.relink && target.record ? (runtime.now ?? (() => new Date()))() : undefined;
|
|
82
|
+
let next = record;
|
|
83
|
+
if (sweep.identity || reestablished) {
|
|
84
|
+
const identity = reestablished ? { ...record.identity, landed_at: reestablished.toISOString() } : record.identity;
|
|
85
|
+
next = { ...record, identity, identity_sha256: writeFeedIdentity(target.volume, identity, { owner: target.owner, tmpDir: feedStagingDir(target) }) };
|
|
86
|
+
}
|
|
87
|
+
publishFeedLanded(target, next, reestablished ?? (runtime.now ?? (() => new Date()))(), record, switchingAt);
|
|
88
|
+
const after = sweepFeed(target, next);
|
|
89
|
+
if (repairable(after))
|
|
90
|
+
return { findings: [...sweep.findings, ...after.findings.map((finding) => `still after repair: ${finding}`)], previous: record.revision, revision: record.revision, status: "tampered" };
|
|
91
|
+
return { ...base, status: repairable(sweep) && sweep.unknown.length === 0 ? "repaired" : "tampered" };
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Same bytes under a new period or ref name: the serving revision is now this period's content, so its
|
|
95
|
+
* period and provenance are re-stamped (record, then the identity agents read). Without it a ref that
|
|
96
|
+
* moved to identical content would never count as landed this period, and the freeze would never hold.
|
|
97
|
+
*/
|
|
98
|
+
const adopt = (target, record, resolved, period, runtime) => {
|
|
99
|
+
const source = resolved.provenance;
|
|
100
|
+
if (target.record || record.recording)
|
|
101
|
+
ensureFeedLanding(target, record, (runtime.now ?? (() => new Date()))());
|
|
102
|
+
if ((!period && !target.record) || (record.period === period && JSON.stringify(record.identity.source) === JSON.stringify(source))) {
|
|
103
|
+
if (target.record)
|
|
104
|
+
ensureFeedLanding(target, record, (runtime.now ?? (() => new Date()))());
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const now = target.record ? (runtime.now ?? (() => new Date()))() : undefined;
|
|
108
|
+
const identity = { ...record.identity, source, ...(now ? { landed_at: now.toISOString() } : {}) };
|
|
109
|
+
const identitySha = writeFeedIdentity(target.volume, identity, { owner: target.owner, tmpDir: feedStagingDir(target) });
|
|
110
|
+
publishFeedLanded(target, { ...record, identity, identity_sha256: identitySha, period }, now ?? new Date(), record);
|
|
111
|
+
};
|
|
112
|
+
/** A held volume (frozen, or waiting for a ref that does not exist yet) keeps serving what it has; it is still verified and healed. */
|
|
113
|
+
const holdLocked = (target, record, held, runtime) => {
|
|
114
|
+
const sweep = sweepFeed(target, record);
|
|
115
|
+
if (sweep.findings.length)
|
|
116
|
+
return heal(target, record, sweep, runtime, { held: true });
|
|
117
|
+
if (target.record)
|
|
118
|
+
ensureFeedLanding(target, record, (runtime.now ?? (() => new Date()))());
|
|
119
|
+
(runtime.log ?? (() => undefined))(`${held}: serving ${record.revision.slice(0, 12)}`);
|
|
120
|
+
return { findings: [], previous: record.revision, revision: record.revision, status: held };
|
|
121
|
+
};
|
|
122
|
+
const refreshLocked = (target, runtime) => {
|
|
123
|
+
const log = runtime.log ?? (() => undefined), exec = runtime.exec ?? hostExec, now = (runtime.now ?? (() => new Date()))();
|
|
124
|
+
prepare(target);
|
|
125
|
+
fetchFeedSource(target.source, { exec });
|
|
126
|
+
const { reason, record } = readFeedLanded(target.stateDir);
|
|
127
|
+
if (reason)
|
|
128
|
+
log(`ignoring the host record: ${reason}; treating this volume as carrying nothing`);
|
|
129
|
+
const choice = chooseFeedRef(target, { exec, now });
|
|
130
|
+
let concrete = target;
|
|
131
|
+
// Path templates expand at the same instant the ref was chosen from.
|
|
132
|
+
const paths = target.source.kind === "git" ? expandFeedPaths(target.source.paths, now) : undefined;
|
|
133
|
+
if (choice.kind === "waiting") {
|
|
134
|
+
log(choice.reason);
|
|
135
|
+
if (!record)
|
|
136
|
+
return { findings: [], previous: null, revision: null, status: "waiting" };
|
|
137
|
+
}
|
|
138
|
+
else if (target.source.kind === "git")
|
|
139
|
+
concrete = { ...target, source: { ...target.source, ...(paths ? { paths } : {}), ref: choice.ref } };
|
|
140
|
+
const frozen = choice.kind === "ref" && feedFrozen(target, record, choice.ref, now, paths);
|
|
141
|
+
if (record && (choice.kind === "waiting" || frozen)) {
|
|
142
|
+
if (frozen)
|
|
143
|
+
log(`frozen: ${record.revision.slice(0, 12)} was landed this period and the ${target.freeze.after} ${target.freeze.timezone} cutoff has passed`);
|
|
144
|
+
const landed = record.identity.source;
|
|
145
|
+
// Held at its own commit and the paths it landed, so a heal reproduces what is served and never what
|
|
146
|
+
// the ref moved to or what a path template expands to today.
|
|
147
|
+
const held = landed.kind === "git" && target.source.kind === "git"
|
|
148
|
+
? { ...target, source: { fetch: target.source.fetch, kind: "git", label: landed.ref, ...(landed.paths ? { paths: landed.paths } : {}), ref: landed.commit, repo: target.source.repo } } : target;
|
|
149
|
+
return holdLocked(held, record, frozen ? "frozen" : "waiting", runtime);
|
|
150
|
+
}
|
|
151
|
+
const resolved = resolveFeedContent(concrete, { exec });
|
|
152
|
+
const period = feedPeriod(target, now);
|
|
153
|
+
if (!record || record.revision !== resolved.revision) {
|
|
154
|
+
log(`refresh needed: ${record ? `${record.revision.slice(0, 12)} -> ${resolved.revision.slice(0, 12)}` : `nothing landed -> ${resolved.revision.slice(0, 12)}`}`);
|
|
155
|
+
// A new revision does not excuse what else is in the volume: the root is audited on every landing.
|
|
156
|
+
const findings = auditFeedRoot(target.volume);
|
|
157
|
+
const landed = landFeed(concrete, resolved, record, { ...(period ? { period } : {}), runtime });
|
|
158
|
+
findings.push(...landed.unknownTrees.map((name) => `trees/${name} is not a tree this host landed`));
|
|
159
|
+
for (const finding of findings)
|
|
160
|
+
log(`TAMPER: ${finding}`);
|
|
161
|
+
return { findings, previous: record?.revision ?? null, revision: landed.revision, status: "landed" };
|
|
162
|
+
}
|
|
163
|
+
const sweep = sweepFeed(concrete, record);
|
|
164
|
+
if (!sweep.findings.length) {
|
|
165
|
+
// Same bytes, moved mtime: somebody touched the mount without changing content. Re-stamp the manifest.
|
|
166
|
+
if (sweep.touched.length)
|
|
167
|
+
writeFeedManifest(target.stateDir, buildFeedManifest(path.join(target.volume, feedTreeLink(record.tree)), record.tree));
|
|
168
|
+
adopt(concrete, record, resolved, period, runtime);
|
|
169
|
+
log(`already current: ${record.revision.slice(0, 12)}`);
|
|
170
|
+
return { findings: [], previous: record.revision, revision: record.revision, status: "current" };
|
|
171
|
+
}
|
|
172
|
+
const healed = heal(concrete, record, sweep, runtime);
|
|
173
|
+
// A repair of the content this period chose is this period's landing too.
|
|
174
|
+
const after = healed.status === "repaired" ? readFeedLanded(target.stateDir).record : null;
|
|
175
|
+
if (after && after.revision === resolved.revision)
|
|
176
|
+
adopt(concrete, after, resolved, period, runtime);
|
|
177
|
+
return healed;
|
|
178
|
+
};
|
|
179
|
+
export const refreshVolumeFeed = (target, runtime = {}) => withLock(target, runtime.log ?? (() => undefined), () => refreshLocked(target, runtime));
|
|
180
|
+
/** Read-only: reports what a refresh would heal, changes nothing. Taken under the lock so a swap in flight is never misread. */
|
|
181
|
+
export const verifyVolumeFeed = (target, runtime = {}) => withLock(target, runtime.log ?? (() => undefined), () => {
|
|
182
|
+
const { reason, record } = readFeedLanded(target.stateDir);
|
|
183
|
+
if (!record)
|
|
184
|
+
return { findings: [reason ?? "nothing has been landed in this volume yet"], previous: null, revision: null, status: "tampered" };
|
|
185
|
+
const sweep = sweepFeed(target, record);
|
|
186
|
+
return { findings: sweep.findings, previous: record.revision, revision: record.revision, status: sweep.findings.length ? "tampered" : "current" };
|
|
187
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export type FeedSourceSpec =
|
|
2
|
+
/** `label` names the ref in provenance when `ref` is a pinned commit (a held volume re-landing what it serves). */
|
|
3
|
+
{
|
|
4
|
+
fetch: boolean;
|
|
5
|
+
kind: "git";
|
|
6
|
+
label?: string;
|
|
7
|
+
paths?: string[];
|
|
8
|
+
ref: string;
|
|
9
|
+
repo: string;
|
|
10
|
+
} | {
|
|
11
|
+
directory: string;
|
|
12
|
+
kind: "directory";
|
|
13
|
+
};
|
|
14
|
+
/** What `include` and `prepare` added on top of the source; its digest, not the source's, is the revision. */
|
|
15
|
+
export interface FeedPreparedProvenance {
|
|
16
|
+
include: Array<{
|
|
17
|
+
digest: string;
|
|
18
|
+
to: string;
|
|
19
|
+
}>;
|
|
20
|
+
prepare: {
|
|
21
|
+
command: string[];
|
|
22
|
+
image: string | null;
|
|
23
|
+
network: boolean | null;
|
|
24
|
+
platform: string | null;
|
|
25
|
+
} | null;
|
|
26
|
+
source_revision: string;
|
|
27
|
+
}
|
|
28
|
+
export type FeedProvenance = {
|
|
29
|
+
commit: string;
|
|
30
|
+
kind: "git";
|
|
31
|
+
paths: string[] | null;
|
|
32
|
+
prepared?: FeedPreparedProvenance;
|
|
33
|
+
ref: string;
|
|
34
|
+
} | {
|
|
35
|
+
kind: "directory";
|
|
36
|
+
prepared?: FeedPreparedProvenance;
|
|
37
|
+
};
|
|
38
|
+
export interface ResolvedFeedSource {
|
|
39
|
+
provenance: FeedProvenance;
|
|
40
|
+
revision: string;
|
|
41
|
+
}
|
|
42
|
+
export type FeedExec = (command: string, args: string[], options?: {
|
|
43
|
+
cwd?: string;
|
|
44
|
+
input?: Buffer;
|
|
45
|
+
}) => Buffer;
|
|
46
|
+
/**
|
|
47
|
+
* Stdin is closed unless input is given: tar once exited 0 having extracted nothing because its archive
|
|
48
|
+
* was silently discarded, so `stageFeedSource` also refuses an empty extraction.
|
|
49
|
+
*/
|
|
50
|
+
export declare const hostExec: FeedExec;
|
|
51
|
+
/** Sorted (path, kind, executable bit, bytes) of a directory tree; symlinks by their target text. */
|
|
52
|
+
export declare const digestDirectory: (root: string) => string;
|
|
53
|
+
export declare const fetchFeedSource: (spec: FeedSourceSpec, { exec }?: {
|
|
54
|
+
exec?: FeedExec;
|
|
55
|
+
}) => void;
|
|
56
|
+
export declare const resolveFeedSource: (spec: FeedSourceSpec, { exec }?: {
|
|
57
|
+
exec?: FeedExec;
|
|
58
|
+
}) => ResolvedFeedSource;
|
|
59
|
+
/**
|
|
60
|
+
* Copies the source into `stagingDir` (which must exist and be empty) and returns the revision of what
|
|
61
|
+
* was actually staged. For a directory that is re-derived from the copy, so a source edited mid-copy
|
|
62
|
+
* lands as the bytes that were copied, under their own revision, never as a mislabelled mix.
|
|
63
|
+
*/
|
|
64
|
+
export declare const stageFeedSource: (spec: FeedSourceSpec, resolved: ResolvedFeedSource, stagingDir: string, { exec }?: {
|
|
65
|
+
exec?: FeedExec;
|
|
66
|
+
}) => ResolvedFeedSource;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Where a fed volume's content comes from, and how it is copied into a private staging directory.
|
|
2
|
+
//
|
|
3
|
+
// A revision is CONTENT-addressed: a commit that does not change the fed paths, or a directory whose
|
|
4
|
+
// bytes did not move, resolves to the same revision and lands nothing.
|
|
5
|
+
import { execFileSync } from "node:child_process";
|
|
6
|
+
import { cpSync, lstatSync, readFileSync, readdirSync, readlinkSync } from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { feedError } from "./feedLayout.js";
|
|
9
|
+
import { sha256Hex } from "./feedManifest.js";
|
|
10
|
+
/**
|
|
11
|
+
* Stdin is closed unless input is given: tar once exited 0 having extracted nothing because its archive
|
|
12
|
+
* was silently discarded, so `stageFeedSource` also refuses an empty extraction.
|
|
13
|
+
*/
|
|
14
|
+
export const hostExec = (command, args, options = {}) => execFileSync(command, args, {
|
|
15
|
+
cwd: options.cwd,
|
|
16
|
+
input: options.input,
|
|
17
|
+
maxBuffer: 1024 * 1024 * 1024,
|
|
18
|
+
stdio: [options.input === undefined ? "ignore" : "pipe", "pipe", "pipe"]
|
|
19
|
+
});
|
|
20
|
+
const gitOut = (exec, repo, args) => exec("git", ["-C", repo, ...args]).toString().trim();
|
|
21
|
+
/** Sorted (path, kind, executable bit, bytes) of a directory tree; symlinks by their target text. */
|
|
22
|
+
export const digestDirectory = (root) => {
|
|
23
|
+
const lines = [];
|
|
24
|
+
const walk = (directory, prefix) => {
|
|
25
|
+
for (const name of readdirSync(directory).sort()) {
|
|
26
|
+
const full = path.join(directory, name), key = prefix ? `${prefix}/${name}` : name;
|
|
27
|
+
const stat = lstatSync(full);
|
|
28
|
+
if (stat.isSymbolicLink())
|
|
29
|
+
lines.push(`l ${JSON.stringify(key)} ${JSON.stringify(readlinkSync(full))}`);
|
|
30
|
+
else if (stat.isDirectory()) {
|
|
31
|
+
lines.push(`d ${JSON.stringify(key)}`);
|
|
32
|
+
walk(full, key);
|
|
33
|
+
}
|
|
34
|
+
else if (stat.isFile())
|
|
35
|
+
lines.push(`f ${JSON.stringify(key)} ${stat.mode & 0o111 ? "x" : "-"} ${sha256Hex(readFileSync(full))}`);
|
|
36
|
+
else
|
|
37
|
+
throw feedError(`${full} is a special file; a fed volume carries only files, directories and symlinks`);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
walk(root, "");
|
|
41
|
+
return sha256Hex(`directory\n${lines.join("\n")}\n`);
|
|
42
|
+
};
|
|
43
|
+
export const fetchFeedSource = (spec, { exec = hostExec } = {}) => {
|
|
44
|
+
if (spec.kind !== "git" || !spec.fetch)
|
|
45
|
+
return;
|
|
46
|
+
try {
|
|
47
|
+
exec("git", ["-C", spec.repo, "fetch", "--prune", "--quiet", "origin"]);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw feedError(`could not fetch the feed repository ${spec.repo}: ${String(error.message).trim().slice(0, 300)}`);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
export const resolveFeedSource = (spec, { exec = hostExec } = {}) => {
|
|
54
|
+
if (spec.kind === "directory") {
|
|
55
|
+
let stat;
|
|
56
|
+
try {
|
|
57
|
+
stat = lstatSync(spec.directory);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
throw feedError(`feed directory ${spec.directory} does not exist`);
|
|
61
|
+
}
|
|
62
|
+
if (!stat.isDirectory())
|
|
63
|
+
throw feedError(`feed directory ${spec.directory} is not a directory`);
|
|
64
|
+
return { provenance: { kind: "directory" }, revision: digestDirectory(spec.directory) };
|
|
65
|
+
}
|
|
66
|
+
let commit;
|
|
67
|
+
const trees = [];
|
|
68
|
+
try {
|
|
69
|
+
commit = gitOut(exec, spec.repo, ["rev-parse", "--verify", "--end-of-options", `${spec.ref}^{commit}`]);
|
|
70
|
+
for (const entry of spec.paths ?? [""]) {
|
|
71
|
+
const tree = gitOut(exec, spec.repo, ["rev-parse", "--verify", "--end-of-options", entry ? `${commit}:${entry}` : `${commit}^{tree}`]);
|
|
72
|
+
if (gitOut(exec, spec.repo, ["cat-file", "-t", tree]) !== "tree")
|
|
73
|
+
throw new Error(`${entry} is not a directory at ${commit.slice(0, 12)}`);
|
|
74
|
+
trees.push(`${entry}\0${tree}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
throw feedError(`cannot resolve ${spec.ref}${spec.paths ? ` (${spec.paths.join(", ")})` : ""} in ${spec.repo}: ${String(error.message).trim().slice(0, 300)}`);
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
provenance: { commit, kind: "git", paths: spec.paths ?? null, ref: spec.label ?? spec.ref },
|
|
82
|
+
revision: sha256Hex(`git\n${trees.join("\n")}\n`)
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Copies the source into `stagingDir` (which must exist and be empty) and returns the revision of what
|
|
87
|
+
* was actually staged. For a directory that is re-derived from the copy, so a source edited mid-copy
|
|
88
|
+
* lands as the bytes that were copied, under their own revision, never as a mislabelled mix.
|
|
89
|
+
*/
|
|
90
|
+
export const stageFeedSource = (spec, resolved, stagingDir, { exec = hostExec } = {}) => {
|
|
91
|
+
if (spec.kind === "directory") {
|
|
92
|
+
cpSync(spec.directory, stagingDir, { errorOnExist: true, force: false, preserveTimestamps: true, recursive: true, verbatimSymlinks: true });
|
|
93
|
+
if (readdirSync(stagingDir).length === 0)
|
|
94
|
+
throw feedError(`feed directory ${spec.directory} is empty; a fed volume never serves nothing`);
|
|
95
|
+
return { ...resolved, revision: digestDirectory(stagingDir) };
|
|
96
|
+
}
|
|
97
|
+
const provenance = resolved.provenance;
|
|
98
|
+
const archive = exec("git", ["-C", spec.repo, "archive", "--format=tar", provenance.commit, ...(spec.paths ? ["--", ...spec.paths] : [])]);
|
|
99
|
+
exec("tar", ["-x", "-C", stagingDir], { input: archive });
|
|
100
|
+
if (readdirSync(stagingDir).length === 0) {
|
|
101
|
+
throw feedError(`extracting ${provenance.commit.slice(0, 12)} produced an empty tree in ${stagingDir}; a fed volume never serves nothing`);
|
|
102
|
+
}
|
|
103
|
+
return resolved;
|
|
104
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { FeedSourceSpec } from "./feedSource.js";
|
|
2
|
+
export declare const DEFAULT_FEED_KEEP = 1;
|
|
3
|
+
export declare const DEFAULT_FEED_HEAL_LIMIT = 3;
|
|
4
|
+
export declare const DEFAULT_FEED_VALIDATE_TIMEOUT_MS: number;
|
|
5
|
+
export declare const DEFAULT_FEED_PREPARE_TIMEOUT_MS: number;
|
|
6
|
+
export declare const DEFAULT_FEED_REF_COMMAND_TIMEOUT_MS = 60000;
|
|
7
|
+
/** A command run inside the staged tree before validation: in a digest-pinned image on `platform`, or on the host. */
|
|
8
|
+
export type FeedPrepare = {
|
|
9
|
+
command: string[];
|
|
10
|
+
dockerCommand: string;
|
|
11
|
+
image: string;
|
|
12
|
+
kind: "image";
|
|
13
|
+
network: boolean;
|
|
14
|
+
platform: string;
|
|
15
|
+
timeoutMs: number;
|
|
16
|
+
} | {
|
|
17
|
+
command: string[];
|
|
18
|
+
kind: "host";
|
|
19
|
+
timeoutMs: number;
|
|
20
|
+
};
|
|
21
|
+
/** A git ref resolved per refresh: a template expanded at the host clock, or a command printing a ref. */
|
|
22
|
+
export interface FeedRefRule {
|
|
23
|
+
command?: {
|
|
24
|
+
argv: string[];
|
|
25
|
+
cwd: string;
|
|
26
|
+
timeoutMs: number;
|
|
27
|
+
};
|
|
28
|
+
fallback?: string;
|
|
29
|
+
template?: string;
|
|
30
|
+
}
|
|
31
|
+
/** Everything a refresh or verify needs, resolved from the manifest and the host. */
|
|
32
|
+
export interface FeedTarget {
|
|
33
|
+
/** Once local time passes `after`, a volume that already landed this period's ref stops advancing. */
|
|
34
|
+
freeze?: {
|
|
35
|
+
after: string;
|
|
36
|
+
timezone: string;
|
|
37
|
+
};
|
|
38
|
+
/** Re-lands of one revision before auto-repair is suspended. */
|
|
39
|
+
healLimit: number;
|
|
40
|
+
/** Host directories copied into the staged tree at `to` (tree-relative) before `prepare`. */
|
|
41
|
+
include?: Array<{
|
|
42
|
+
from: string;
|
|
43
|
+
to: string;
|
|
44
|
+
}>;
|
|
45
|
+
/** Retired trees kept beside the serving one, so a reader mid-read survives at least one swap. */
|
|
46
|
+
keep: number;
|
|
47
|
+
owner?: string;
|
|
48
|
+
prepare?: FeedPrepare;
|
|
49
|
+
/** Landing-history retention for recording agents consuming this volume; absent means no log I/O. */
|
|
50
|
+
record?: {
|
|
51
|
+
keepMs: number;
|
|
52
|
+
};
|
|
53
|
+
/** Replaces `source.ref` of a git source with a ref chosen on every refresh. */
|
|
54
|
+
refRule?: FeedRefRule;
|
|
55
|
+
resourceId: string;
|
|
56
|
+
source: FeedSourceSpec;
|
|
57
|
+
/** Host state outside the volume, on its filesystem: record, manifests, staging, trash, lock, prepare cache. */
|
|
58
|
+
stateDir: string;
|
|
59
|
+
validate?: {
|
|
60
|
+
command: string[];
|
|
61
|
+
cwd: string;
|
|
62
|
+
timeoutMs: number;
|
|
63
|
+
};
|
|
64
|
+
/** Host path of the volume's content root. */
|
|
65
|
+
volume: string;
|
|
66
|
+
volumeName: string;
|
|
67
|
+
}
|
|
68
|
+
export declare const feedStagingDir: (target: FeedTarget) => string;
|
|
69
|
+
export declare const feedTrashDir: (target: FeedTarget) => string;
|
|
70
|
+
export declare const feedPreparedDir: (target: FeedTarget) => string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
export const DEFAULT_FEED_KEEP = 1;
|
|
3
|
+
export const DEFAULT_FEED_HEAL_LIMIT = 3;
|
|
4
|
+
export const DEFAULT_FEED_VALIDATE_TIMEOUT_MS = 10 * 60_000;
|
|
5
|
+
export const DEFAULT_FEED_PREPARE_TIMEOUT_MS = 30 * 60_000;
|
|
6
|
+
export const DEFAULT_FEED_REF_COMMAND_TIMEOUT_MS = 60_000;
|
|
7
|
+
export const feedStagingDir = (target) => path.join(target.stateDir, "staging");
|
|
8
|
+
export const feedTrashDir = (target) => path.join(target.stateDir, "trash");
|
|
9
|
+
export const feedPreparedDir = (target) => path.join(target.stateDir, "prepared");
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FeedTarget } from "./feedTarget.js";
|
|
2
|
+
export interface FeedFixture {
|
|
3
|
+
cleanup: () => void;
|
|
4
|
+
root: string;
|
|
5
|
+
source: string;
|
|
6
|
+
target: FeedTarget;
|
|
7
|
+
volume: string;
|
|
8
|
+
}
|
|
9
|
+
/** A volume shaped like one a container has initialized: mode 0755 with its resource sentinel. */
|
|
10
|
+
export declare const createFeedFixture: (overrides?: Partial<FeedTarget>) => FeedFixture;
|
|
11
|
+
export declare const writeSourceFiles: (directory: string, files: Record<string, string>) => void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { chmodSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { VOLUME_RESOURCE_SENTINEL } from "./feedLayout.js";
|
|
5
|
+
import { DEFAULT_FEED_HEAL_LIMIT } from "./feedTarget.js";
|
|
6
|
+
/** A volume shaped like one a container has initialized: mode 0755 with its resource sentinel. */
|
|
7
|
+
export const createFeedFixture = (overrides = {}) => {
|
|
8
|
+
const root = mkdtempSync(path.join(tmpdir(), "spawnfile-feed-"));
|
|
9
|
+
const volume = path.join(root, "volume", "_data"), source = path.join(root, "source");
|
|
10
|
+
mkdirSync(volume, { recursive: true });
|
|
11
|
+
chmodSync(volume, 0o755);
|
|
12
|
+
writeFileSync(path.join(volume, VOLUME_RESOURCE_SENTINEL), "sha256:fixture\n", { mode: 0o644 });
|
|
13
|
+
mkdirSync(source);
|
|
14
|
+
writeFileSync(path.join(source, "a.txt"), "alpha\n");
|
|
15
|
+
const target = {
|
|
16
|
+
healLimit: DEFAULT_FEED_HEAL_LIMIT, keep: 1, resourceId: "shared-data", source: { directory: source, kind: "directory" },
|
|
17
|
+
stateDir: path.join(root, "volume", "spawnfile-feed"), volume, volumeName: "shared-data-vol", ...overrides
|
|
18
|
+
};
|
|
19
|
+
const cleanup = () => {
|
|
20
|
+
// Frozen trees are a-w; restore write so the temp root can be removed.
|
|
21
|
+
const thaw = (directory) => {
|
|
22
|
+
try {
|
|
23
|
+
if (!lstatSync(directory).isDirectory())
|
|
24
|
+
return;
|
|
25
|
+
chmodSync(directory, 0o755);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const name of readdirSync(directory))
|
|
31
|
+
thaw(path.join(directory, name));
|
|
32
|
+
};
|
|
33
|
+
thaw(root);
|
|
34
|
+
rmSync(root, { force: true, recursive: true });
|
|
35
|
+
};
|
|
36
|
+
return { cleanup, root, source, target, volume };
|
|
37
|
+
};
|
|
38
|
+
export const writeSourceFiles = (directory, files) => {
|
|
39
|
+
rmSync(directory, { force: true, recursive: true });
|
|
40
|
+
mkdirSync(directory, { recursive: true });
|
|
41
|
+
for (const [name, content] of Object.entries(files)) {
|
|
42
|
+
mkdirSync(path.dirname(path.join(directory, name)), { recursive: true });
|
|
43
|
+
writeFileSync(path.join(directory, name), content);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type FeedLandedRecord } from "./feedRecord.js";
|
|
2
|
+
import type { FeedTarget } from "./feedTarget.js";
|
|
3
|
+
export interface FeedSweep {
|
|
4
|
+
blocked: boolean;
|
|
5
|
+
drift: boolean;
|
|
6
|
+
failed: boolean;
|
|
7
|
+
findings: string[];
|
|
8
|
+
identity: "forged" | "missing" | null;
|
|
9
|
+
planted: boolean;
|
|
10
|
+
relink: boolean;
|
|
11
|
+
touched: string[];
|
|
12
|
+
unknown: string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* NO EXCEPTION LEAVES THIS SWEEP WITHOUT A FINDING. A sweep that throws is a volume nothing verified,
|
|
16
|
+
* and it must read as "not clean", never as a quiet exit.
|
|
17
|
+
*/
|
|
18
|
+
export declare const sweepFeed: (target: FeedTarget, record: FeedLandedRecord) => FeedSweep;
|