@plurnk/plurnk-service 1.16.4 → 1.17.0
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/.env.defaults +122 -246
- package/INSTALL.md +84 -138
- package/README.md +9 -5
- package/SPEC.md +1710 -1015
- package/dist/Paths.d.ts +2 -0
- package/dist/Paths.d.ts.map +1 -1
- package/dist/Paths.js +2 -0
- package/dist/Paths.js.map +1 -1
- package/dist/build-info.d.ts.map +1 -1
- package/dist/build-info.js +7 -1
- package/dist/build-info.js.map +1 -1
- package/dist/build-info.json +1 -1
- package/dist/content/body-preview.d.ts +8 -0
- package/dist/content/body-preview.d.ts.map +1 -0
- package/dist/content/body-preview.js +39 -0
- package/dist/content/body-preview.js.map +1 -0
- package/dist/content/byte-view.d.ts +1 -4
- package/dist/content/byte-view.d.ts.map +1 -1
- package/dist/content/byte-view.js.map +1 -1
- package/dist/content/edit-collision.d.ts.map +1 -1
- package/dist/content/edit-collision.js +3 -4
- package/dist/content/edit-collision.js.map +1 -1
- package/dist/content/line-anchors.d.ts +2 -2
- package/dist/content/line-anchors.d.ts.map +1 -1
- package/dist/content/line-anchors.js +4 -3
- package/dist/content/line-anchors.js.map +1 -1
- package/dist/content/line-selection.d.ts +9 -0
- package/dist/content/line-selection.d.ts.map +1 -0
- package/dist/content/line-selection.js +29 -0
- package/dist/content/line-selection.js.map +1 -0
- package/dist/content/matcher.d.ts +0 -1
- package/dist/content/matcher.d.ts.map +1 -1
- package/dist/content/matcher.js +2 -3
- package/dist/content/matcher.js.map +1 -1
- package/dist/content/pattern-edits.d.ts +39 -0
- package/dist/content/pattern-edits.d.ts.map +1 -0
- package/dist/content/pattern-edits.js +121 -0
- package/dist/content/pattern-edits.js.map +1 -0
- package/dist/content/read-projector.d.ts +18 -9
- package/dist/content/read-projector.d.ts.map +1 -1
- package/dist/content/read-projector.js +132 -35
- package/dist/content/read-projector.js.map +1 -1
- package/dist/content/read-resolve.d.ts +3 -1
- package/dist/content/read-resolve.d.ts.map +1 -1
- package/dist/content/read-resolve.js +39 -7
- package/dist/content/read-resolve.js.map +1 -1
- package/dist/core/AdmittedTurnExecutor.d.ts +3 -5
- package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
- package/dist/core/AdmittedTurnExecutor.js +91 -83
- package/dist/core/AdmittedTurnExecutor.js.map +1 -1
- package/dist/core/BareBatchRunner.d.ts +6 -1
- package/dist/core/BareBatchRunner.d.ts.map +1 -1
- package/dist/core/BareBatchRunner.js +20 -5
- package/dist/core/BareBatchRunner.js.map +1 -1
- package/dist/core/BudgetReadout.d.ts +2 -3
- package/dist/core/BudgetReadout.d.ts.map +1 -1
- package/dist/core/BudgetReadout.js +23 -32
- package/dist/core/BudgetReadout.js.map +1 -1
- package/dist/core/CapabilityPolicies.d.ts +3 -8
- package/dist/core/CapabilityPolicies.d.ts.map +1 -1
- package/dist/core/CapabilityPolicies.js +2 -28
- package/dist/core/CapabilityPolicies.js.map +1 -1
- package/dist/core/CapabilityResolver.d.ts +10 -10
- package/dist/core/CapabilityResolver.d.ts.map +1 -1
- package/dist/core/CapabilityResolver.js +87 -65
- package/dist/core/CapabilityResolver.js.map +1 -1
- package/dist/core/ChannelWrite.d.ts +14 -11
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/ChannelWrite.js +11 -12
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/ChannelWrite.sql +99 -9
- package/dist/core/ClientInteractions.d.ts.map +1 -1
- package/dist/core/ClientInteractions.js +7 -0
- package/dist/core/ClientInteractions.js.map +1 -1
- package/dist/core/CoreSchemeServices.d.ts +13 -10
- package/dist/core/CoreSchemeServices.d.ts.map +1 -1
- package/dist/core/CoreSchemeServices.js +13 -5
- package/dist/core/CoreSchemeServices.js.map +1 -1
- package/dist/core/DataStatementRunner.d.ts +2 -2
- package/dist/core/DataStatementRunner.d.ts.map +1 -1
- package/dist/core/DataStatementRunner.js +36 -39
- package/dist/core/DataStatementRunner.js.map +1 -1
- package/dist/core/Dispatcher.d.ts +19 -26
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +369 -219
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/Dispatcher.sql +66 -0
- package/dist/core/DurableStatement.d.ts.map +1 -1
- package/dist/core/DurableStatement.js +2 -1
- package/dist/core/DurableStatement.js.map +1 -1
- package/dist/core/EditMutations.d.ts +14 -18
- package/dist/core/EditMutations.d.ts.map +1 -1
- package/dist/core/EditMutations.js +211 -280
- package/dist/core/EditMutations.js.map +1 -1
- package/dist/core/EditMutations.sql +15 -0
- package/dist/core/EditSequence.d.ts +13 -0
- package/dist/core/EditSequence.d.ts.map +1 -0
- package/dist/core/EditSequence.js +73 -0
- package/dist/core/EditSequence.js.map +1 -0
- package/dist/core/Engine.d.ts +17 -23
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +73 -163
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +0 -724
- package/dist/core/EntryAddressBinding.d.ts +7 -17
- package/dist/core/EntryAddressBinding.d.ts.map +1 -1
- package/dist/core/EntryAddressBinding.js +12 -72
- package/dist/core/EntryAddressBinding.js.map +1 -1
- package/dist/core/ExecutionOutputs.d.ts +9 -0
- package/dist/core/ExecutionOutputs.d.ts.map +1 -0
- package/dist/core/ExecutionOutputs.js +36 -0
- package/dist/core/ExecutionOutputs.js.map +1 -0
- package/dist/core/ExecutionOutputs.sql +13 -0
- package/dist/core/ExecutorRegistry.d.ts +7 -5
- package/dist/core/ExecutorRegistry.d.ts.map +1 -1
- package/dist/core/ExecutorRegistry.js +36 -32
- package/dist/core/ExecutorRegistry.js.map +1 -1
- package/dist/core/HostPaths.d.ts +1 -0
- package/dist/core/HostPaths.d.ts.map +1 -1
- package/dist/core/HostPaths.js +4 -0
- package/dist/core/HostPaths.js.map +1 -1
- package/dist/core/InferenceCall.d.ts.map +1 -1
- package/dist/core/InferenceCall.js +1 -2
- package/dist/core/InferenceCall.js.map +1 -1
- package/dist/core/InferenceCall.sql +29 -0
- package/dist/core/KillHandler.d.ts +1 -0
- package/dist/core/KillHandler.d.ts.map +1 -1
- package/dist/core/KillHandler.js +24 -21
- package/dist/core/KillHandler.js.map +1 -1
- package/dist/core/LogBody.d.ts +8 -1
- package/dist/core/LogBody.d.ts.map +1 -1
- package/dist/core/LogBody.js +42 -11
- package/dist/core/LogBody.js.map +1 -1
- package/dist/core/LogEntryProjection.d.ts +1 -0
- package/dist/core/LogEntryProjection.d.ts.map +1 -1
- package/dist/core/LogEntryProjection.js +18 -10
- package/dist/core/LogEntryProjection.js.map +1 -1
- package/dist/core/LogVisibility.d.ts +1 -0
- package/dist/core/LogVisibility.d.ts.map +1 -1
- package/dist/core/LogVisibility.js +3 -0
- package/dist/core/LogVisibility.js.map +1 -1
- package/dist/core/LogWriter.d.ts +2 -3
- package/dist/core/LogWriter.d.ts.map +1 -1
- package/dist/core/LogWriter.js +25 -32
- package/dist/core/LogWriter.js.map +1 -1
- package/dist/core/LogWriter.sql +23 -0
- package/dist/core/LoopDriver.d.ts +11 -8
- package/dist/core/LoopDriver.d.ts.map +1 -1
- package/dist/core/LoopDriver.js +163 -189
- package/dist/core/LoopDriver.js.map +1 -1
- package/dist/core/LoopDriver.sql +11 -0
- package/dist/core/LoopLifecycle.d.ts +32 -2
- package/dist/core/LoopLifecycle.d.ts.map +1 -1
- package/dist/core/LoopLifecycle.js +88 -4
- package/dist/core/LoopLifecycle.js.map +1 -1
- package/dist/core/LoopLifecycle.sql +145 -28
- package/dist/core/LoopPolicyReader.sql +6 -0
- package/dist/core/MembershipMaterialization.d.ts.map +1 -1
- package/dist/core/MembershipMaterialization.js +6 -28
- package/dist/core/MembershipMaterialization.js.map +1 -1
- package/dist/core/ModelCall.sql +70 -0
- package/dist/core/MutationEffects.d.ts +5 -3
- package/dist/core/MutationEffects.d.ts.map +1 -1
- package/dist/core/MutationEffects.js +10 -28
- package/dist/core/MutationEffects.js.map +1 -1
- package/dist/core/NativeContent.d.ts +6 -0
- package/dist/core/NativeContent.d.ts.map +1 -0
- package/dist/core/NativeContent.js +16 -0
- package/dist/core/NativeContent.js.map +1 -0
- package/dist/core/NativeContent.sql +6 -0
- package/dist/core/NoticeChannel.js +1 -1
- package/dist/core/NoticeChannel.js.map +1 -1
- package/dist/core/OperatorConfig.js +5 -5
- package/dist/core/OperatorConfig.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts +8 -5
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +117 -81
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/PacketBuilder.sql +146 -0
- package/dist/core/PatternSelection.d.ts +28 -0
- package/dist/core/PatternSelection.d.ts.map +1 -0
- package/dist/core/PatternSelection.js +42 -0
- package/dist/core/PatternSelection.js.map +1 -0
- package/dist/core/ProblemLog.d.ts.map +1 -1
- package/dist/core/ProblemLog.js +0 -1
- package/dist/core/ProblemLog.js.map +1 -1
- package/dist/core/PromptFrames.d.ts +12 -0
- package/dist/core/PromptFrames.d.ts.map +1 -0
- package/dist/core/PromptFrames.js +28 -0
- package/dist/core/PromptFrames.js.map +1 -0
- package/dist/core/ProposalLifecycle.d.ts +0 -1
- package/dist/core/ProposalLifecycle.d.ts.map +1 -1
- package/dist/core/ProposalLifecycle.js +20 -19
- package/dist/core/ProposalLifecycle.js.map +1 -1
- package/dist/core/ProposalLifecycle.sql +33 -0
- package/dist/core/ProviderInstantiate.d.ts +1 -1
- package/dist/core/ProviderInstantiate.d.ts.map +1 -1
- package/dist/core/ProviderInstantiate.js +7 -14
- package/dist/core/ProviderInstantiate.js.map +1 -1
- package/dist/core/ReasoningView.d.ts +9 -0
- package/dist/core/ReasoningView.d.ts.map +1 -0
- package/dist/core/ReasoningView.js +47 -0
- package/dist/core/ReasoningView.js.map +1 -0
- package/dist/core/ResourceBindings.d.ts +16 -0
- package/dist/core/ResourceBindings.d.ts.map +1 -0
- package/dist/core/ResourceBindings.js +45 -0
- package/dist/core/ResourceBindings.js.map +1 -0
- package/dist/core/ResourceMutations.d.ts +5 -8
- package/dist/core/ResourceMutations.d.ts.map +1 -1
- package/dist/core/ResourceMutations.js +6 -7
- package/dist/core/ResourceMutations.js.map +1 -1
- package/dist/core/ResourceSelector.d.ts +2 -2
- package/dist/core/ResourceSelector.d.ts.map +1 -1
- package/dist/core/ResourceSelector.js +122 -62
- package/dist/core/ResourceSelector.js.map +1 -1
- package/dist/core/ResourceTransfers.d.ts +4 -2
- package/dist/core/ResourceTransfers.d.ts.map +1 -1
- package/dist/core/ResourceTransfers.js +95 -26
- package/dist/core/ResourceTransfers.js.map +1 -1
- package/dist/core/RuntimeWorker.d.ts +5 -0
- package/dist/core/RuntimeWorker.d.ts.map +1 -0
- package/dist/core/RuntimeWorker.js +10 -0
- package/dist/core/RuntimeWorker.js.map +1 -0
- package/dist/core/RuntimeWorker.sql +5 -0
- package/dist/core/SchemeRegistry.d.ts +12 -16
- package/dist/core/SchemeRegistry.d.ts.map +1 -1
- package/dist/core/SchemeRegistry.js +58 -84
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/StoredPacket.d.ts +6 -1
- package/dist/core/StoredPacket.d.ts.map +1 -1
- package/dist/core/StoredPacket.js +30 -10
- package/dist/core/StoredPacket.js.map +1 -1
- package/dist/core/StrikeRail.d.ts +9 -6
- package/dist/core/StrikeRail.d.ts.map +1 -1
- package/dist/core/StrikeRail.js +60 -113
- package/dist/core/StrikeRail.js.map +1 -1
- package/dist/core/StrikeRail.sql +12 -0
- package/dist/core/TerminalResult.d.ts +1 -1
- package/dist/core/TerminalResult.d.ts.map +1 -1
- package/dist/core/TerminalResult.js +2 -2
- package/dist/core/TerminalResult.js.map +1 -1
- package/dist/core/TokenCalibration.d.ts +1 -6
- package/dist/core/TokenCalibration.d.ts.map +1 -1
- package/dist/core/TokenCalibration.js +13 -9
- package/dist/core/TokenCalibration.js.map +1 -1
- package/dist/core/TokenCalibration.sql +15 -0
- package/dist/core/ToolInputSchema.d.ts +6 -0
- package/dist/core/ToolInputSchema.d.ts.map +1 -0
- package/dist/core/ToolInputSchema.js +43 -0
- package/dist/core/ToolInputSchema.js.map +1 -0
- package/dist/core/ToolResources.d.ts.map +1 -1
- package/dist/core/ToolResources.js +76 -52
- package/dist/core/ToolResources.js.map +1 -1
- package/dist/core/Turn.d.ts +5 -2
- package/dist/core/Turn.d.ts.map +1 -1
- package/dist/core/Turn.js +13 -11
- package/dist/core/Turn.js.map +1 -1
- package/dist/core/Turn.sql +25 -39
- package/dist/core/{SendBroadcastHandler.d.ts → TurnDispositionHandler.d.ts} +25 -17
- package/dist/core/TurnDispositionHandler.d.ts.map +1 -0
- package/dist/core/TurnDispositionHandler.js +198 -0
- package/dist/core/TurnDispositionHandler.js.map +1 -0
- package/dist/core/TurnMaterialization.d.ts +2 -3
- package/dist/core/TurnMaterialization.d.ts.map +1 -1
- package/dist/core/TurnMaterialization.js +40 -15
- package/dist/core/TurnMaterialization.js.map +1 -1
- package/dist/core/TurnMaterialization.sql +44 -0
- package/dist/core/TurnOps.d.ts.map +1 -1
- package/dist/core/TurnOps.js +8 -64
- package/dist/core/TurnOps.js.map +1 -1
- package/dist/core/TurnRunner.d.ts +9 -12
- package/dist/core/TurnRunner.d.ts.map +1 -1
- package/dist/core/TurnRunner.js +232 -408
- package/dist/core/TurnRunner.js.map +1 -1
- package/dist/core/TurnRunner.sql +74 -0
- package/dist/core/TurnSources.sql +39 -0
- package/dist/core/WorkerControlAddress.d.ts +1 -0
- package/dist/core/WorkerControlAddress.d.ts.map +1 -1
- package/dist/core/WorkerControlAddress.js +5 -0
- package/dist/core/WorkerControlAddress.js.map +1 -1
- package/dist/core/WorkerControlHandler.d.ts +1 -3
- package/dist/core/WorkerControlHandler.d.ts.map +1 -1
- package/dist/core/WorkerControlHandler.js +41 -48
- package/dist/core/WorkerControlHandler.js.map +1 -1
- package/dist/core/WorkerName.d.ts +8 -6
- package/dist/core/WorkerName.d.ts.map +1 -1
- package/dist/core/WorkerName.js +33 -24
- package/dist/core/WorkerName.js.map +1 -1
- package/dist/core/WorkerName.sql +7 -10
- package/dist/core/WorkspaceGate.d.ts +1 -1
- package/dist/core/WorkspaceGate.d.ts.map +1 -1
- package/dist/core/WorkspaceGate.js +29 -6
- package/dist/core/WorkspaceGate.js.map +1 -1
- package/dist/core/ambient.sql +236 -0
- package/dist/core/attachments.d.ts +2 -1
- package/dist/core/attachments.d.ts.map +1 -1
- package/dist/core/attachments.js +5 -4
- package/dist/core/attachments.js.map +1 -1
- package/dist/core/caps/CapsResolve.d.ts +2 -3
- package/dist/core/caps/CapsResolve.d.ts.map +1 -1
- package/dist/core/caps/CapsResolve.js +5 -5
- package/dist/core/caps/CapsResolve.js.map +1 -1
- package/dist/core/caps/DbChannelCaps.d.ts +1 -1
- package/dist/core/caps/DbChannelCaps.d.ts.map +1 -1
- package/dist/core/caps/DbChannelCaps.js +4 -6
- package/dist/core/caps/DbChannelCaps.js.map +1 -1
- package/dist/core/caps/DbEntryCaps.d.ts +2 -1
- package/dist/core/caps/DbEntryCaps.d.ts.map +1 -1
- package/dist/core/caps/DbEntryCaps.js +11 -17
- package/dist/core/caps/DbEntryCaps.js.map +1 -1
- package/dist/core/caps/DbNotifyCaps.d.ts +1 -1
- package/dist/core/caps/DbNotifyCaps.d.ts.map +1 -1
- package/dist/core/caps/DbNotifyCaps.js +3 -5
- package/dist/core/caps/DbNotifyCaps.js.map +1 -1
- package/dist/core/caps/DbProjectionCaps.js +1 -1
- package/dist/core/caps/DbProjectionCaps.js.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.d.ts +1 -1
- package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.js +5 -7
- package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.d.ts +0 -2
- package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.js +4 -20
- package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
- package/dist/core/env-defaults.d.ts.map +1 -1
- package/dist/core/env-defaults.js +4 -2
- package/dist/core/env-defaults.js.map +1 -1
- package/dist/core/file-materialization.d.ts +4 -1
- package/dist/core/file-materialization.d.ts.map +1 -1
- package/dist/core/file-materialization.js +14 -0
- package/dist/core/file-materialization.js.map +1 -1
- package/dist/core/fork.d.ts +1 -6
- package/dist/core/fork.d.ts.map +1 -1
- package/dist/core/fork.js +9 -153
- package/dist/core/fork.js.map +1 -1
- package/dist/core/fork.sql +162 -185
- package/dist/core/git-env.d.ts +1 -0
- package/dist/core/git-env.d.ts.map +1 -1
- package/dist/core/git-env.js +39 -2
- package/dist/core/git-env.js.map +1 -1
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +64 -48
- package/dist/core/git-membership.js.map +1 -1
- package/dist/core/git-state.d.ts.map +1 -1
- package/dist/core/git-state.js +25 -19
- package/dist/core/git-state.js.map +1 -1
- package/dist/core/glob_match.d.ts +4 -0
- package/dist/core/glob_match.d.ts.map +1 -0
- package/dist/core/glob_match.js +7 -0
- package/dist/core/glob_match.js.map +1 -0
- package/dist/core/maintenance.sql +6 -0
- package/dist/core/mutation-types.d.ts +7 -28
- package/dist/core/mutation-types.d.ts.map +1 -1
- package/dist/core/packet-inject.d.ts.map +1 -1
- package/dist/core/packet-inject.js +2 -3
- package/dist/core/packet-inject.js.map +1 -1
- package/dist/core/packet-wire.d.ts +8 -6
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +131 -163
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/plurnk-uri.d.ts +1 -1
- package/dist/core/plurnk-uri.d.ts.map +1 -1
- package/dist/core/plurnk-uri.js +5 -12
- package/dist/core/plurnk-uri.js.map +1 -1
- package/dist/core/scheme-types.d.ts +3 -3
- package/dist/core/scheme-types.d.ts.map +1 -1
- package/dist/core/scheme-types.js.map +1 -1
- package/dist/core/sha256.d.ts +4 -0
- package/dist/core/sha256.d.ts.map +1 -0
- package/dist/core/sha256.js +6 -0
- package/dist/core/sha256.js.map +1 -0
- package/dist/core/teaching.js +1 -1
- package/dist/core/teaching.js.map +1 -1
- package/dist/core/turn-scheduler.d.ts.map +1 -1
- package/dist/core/turn-scheduler.js +5 -18
- package/dist/core/turn-scheduler.js.map +1 -1
- package/dist/core/turn-signals.d.ts +0 -6
- package/dist/core/turn-signals.d.ts.map +1 -1
- package/dist/core/turn-signals.js +1 -7
- package/dist/core/turn-signals.js.map +1 -1
- package/dist/core/worker-ops.sql +15 -22
- package/dist/core/workspace-settings.d.ts.map +1 -1
- package/dist/core/workspace-settings.js +18 -2
- package/dist/core/workspace-settings.js.map +1 -1
- package/dist/core/workspace-settings.sql +6 -0
- package/dist/digest/Digest.d.ts.map +1 -1
- package/dist/digest/Digest.js +27 -90
- package/dist/digest/Digest.js.map +1 -1
- package/dist/digest/DigestRender.d.ts.map +1 -1
- package/dist/digest/DigestRender.js +14 -54
- package/dist/digest/DigestRender.js.map +1 -1
- package/dist/digest/digest-rows.d.ts +10 -32
- package/dist/digest/digest-rows.d.ts.map +1 -1
- package/dist/digest/digest.sql +43 -18
- package/dist/schemes/Exec.d.ts +6 -12
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +256 -188
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.d.ts +8 -6
- package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +33 -61
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/ExecutionInput.d.ts +12 -0
- package/dist/schemes/ExecutionInput.d.ts.map +1 -0
- package/dist/schemes/ExecutionInput.js +94 -0
- package/dist/schemes/ExecutionInput.js.map +1 -0
- package/dist/schemes/File.d.ts +5 -2
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +62 -92
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +84 -79
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/Log.sql +183 -15
- package/dist/schemes/Prompt.d.ts.map +1 -1
- package/dist/schemes/Prompt.js +3 -12
- package/dist/schemes/Prompt.js.map +1 -1
- package/dist/schemes/QuestionTool.d.ts +5 -0
- package/dist/schemes/QuestionTool.d.ts.map +1 -1
- package/dist/schemes/QuestionTool.js +6 -14
- package/dist/schemes/QuestionTool.js.map +1 -1
- package/dist/schemes/Skill.d.ts +12 -7
- package/dist/schemes/Skill.d.ts.map +1 -1
- package/dist/schemes/Skill.js +149 -21
- package/dist/schemes/Skill.js.map +1 -1
- package/dist/schemes/TurnSource.d.ts +12 -0
- package/dist/schemes/TurnSource.d.ts.map +1 -0
- package/dist/schemes/TurnSource.js +116 -0
- package/dist/schemes/TurnSource.js.map +1 -0
- package/dist/schemes/Worker.d.ts +3 -3
- package/dist/schemes/Worker.d.ts.map +1 -1
- package/dist/schemes/Worker.js +61 -208
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/schemes/_entry-crud.d.ts +12 -15
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js +63 -63
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-crud.sql +142 -46
- package/dist/schemes/_entry-find.d.ts +1 -3
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +111 -112
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-find.sql +22 -14
- package/dist/schemes/_entry-fts.d.ts +14 -0
- package/dist/schemes/_entry-fts.d.ts.map +1 -0
- package/dist/schemes/_entry-fts.js +82 -0
- package/dist/schemes/_entry-fts.js.map +1 -0
- package/dist/schemes/_entry-fts.sql +31 -0
- package/dist/schemes/_entry-graph.d.ts.map +1 -1
- package/dist/schemes/_entry-graph.js +6 -14
- package/dist/schemes/_entry-graph.js.map +1 -1
- package/dist/schemes/_entry-graph.sql +29 -44
- package/dist/schemes/_entry-manifest.d.ts +2 -1
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-manifest.js +15 -12
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_entry-manifest.sql +26 -0
- package/dist/schemes/_entry-ops.d.ts +3 -5
- package/dist/schemes/_entry-ops.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.js +30 -43
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_entry-ops.sql +5 -6
- package/dist/schemes/_entry-readable.d.ts +8 -0
- package/dist/schemes/_entry-readable.d.ts.map +1 -0
- package/dist/schemes/_entry-readable.js +38 -0
- package/dist/schemes/_entry-readable.js.map +1 -0
- package/dist/schemes/_entry-send.d.ts +1 -1
- package/dist/schemes/_entry-send.d.ts.map +1 -1
- package/dist/schemes/_entry-send.js +3 -3
- package/dist/schemes/_entry-send.js.map +1 -1
- package/dist/schemes/_search-index.d.ts +1 -3
- package/dist/schemes/_search-index.d.ts.map +1 -1
- package/dist/schemes/_search-index.js +79 -110
- package/dist/schemes/_search-index.js.map +1 -1
- package/dist/schemes/_search-index.sql +30 -0
- package/dist/schemes/exec-runtime.d.ts +1 -1
- package/dist/schemes/exec-runtime.d.ts.map +1 -1
- package/dist/schemes/exec-runtime.js.map +1 -1
- package/dist/server/ClientReads.d.ts +2 -2
- package/dist/server/ClientReads.d.ts.map +1 -1
- package/dist/server/ClientReads.js +5 -8
- package/dist/server/ClientReads.js.map +1 -1
- package/dist/server/Daemon.d.ts +14 -21
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +135 -156
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DaemonModule.d.ts +23 -21
- package/dist/server/DaemonModule.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.d.ts +8 -21
- package/dist/server/DrainSupervisor.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.js +278 -306
- package/dist/server/DrainSupervisor.js.map +1 -1
- package/dist/server/Functionality.d.ts +11 -12
- package/dist/server/Functionality.d.ts.map +1 -1
- package/dist/server/Functionality.js +129 -101
- package/dist/server/Functionality.js.map +1 -1
- package/dist/server/FunctionalityManager.d.ts +3 -5
- package/dist/server/FunctionalityManager.d.ts.map +1 -1
- package/dist/server/FunctionalityManager.js +20 -58
- package/dist/server/FunctionalityManager.js.map +1 -1
- package/dist/server/MembersFunctionality.d.ts +5 -4
- package/dist/server/MembersFunctionality.d.ts.map +1 -1
- package/dist/server/MembersFunctionality.js +24 -37
- package/dist/server/MembersFunctionality.js.map +1 -1
- package/dist/server/PlurnkSkill.d.ts +11 -0
- package/dist/server/PlurnkSkill.d.ts.map +1 -0
- package/dist/server/PlurnkSkill.js +41 -0
- package/dist/server/PlurnkSkill.js.map +1 -0
- package/dist/server/Retention.d.ts +22 -0
- package/dist/server/Retention.d.ts.map +1 -0
- package/dist/server/Retention.js +54 -0
- package/dist/server/Retention.js.map +1 -0
- package/dist/server/Retention.sql +36 -0
- package/dist/server/ServiceModules.d.ts +5 -0
- package/dist/server/ServiceModules.d.ts.map +1 -0
- package/dist/server/ServiceModules.js +10 -0
- package/dist/server/ServiceModules.js.map +1 -0
- package/dist/server/SkillsFunctionality.d.ts +14 -19
- package/dist/server/SkillsFunctionality.d.ts.map +1 -1
- package/dist/server/SkillsFunctionality.js +97 -104
- package/dist/server/SkillsFunctionality.js.map +1 -1
- package/dist/server/WorkerModelResolver.d.ts +4 -0
- package/dist/server/WorkerModelResolver.d.ts.map +1 -1
- package/dist/server/WorkerModelResolver.js +72 -39
- package/dist/server/WorkerModelResolver.js.map +1 -1
- package/dist/server/WorkspaceCapabilities.d.ts +21 -0
- package/dist/server/WorkspaceCapabilities.d.ts.map +1 -0
- package/dist/server/{WorkerCapabilities.js → WorkspaceCapabilities.js} +40 -40
- package/dist/server/WorkspaceCapabilities.js.map +1 -0
- package/dist/server/WorkspaceResidency.d.ts +36 -0
- package/dist/server/WorkspaceResidency.d.ts.map +1 -0
- package/dist/server/WorkspaceResidency.js +199 -0
- package/dist/server/WorkspaceResidency.js.map +1 -0
- package/dist/server/client-input.d.ts +1 -4
- package/dist/server/client-input.d.ts.map +1 -1
- package/dist/server/client-input.js +4 -45
- package/dist/server/client-input.js.map +1 -1
- package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
- package/dist/server/dispatch-as-plurnk.js +4 -22
- package/dist/server/dispatch-as-plurnk.js.map +1 -1
- package/dist/server/drain.sql +65 -42
- package/dist/server/envelope.d.ts +8 -0
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +9 -7
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/envelope.sql +49 -13
- package/dist/server/lifecycle-recovery.sql +14 -17
- package/dist/server/logEntry.d.ts +1 -1
- package/dist/server/logEntry.d.ts.map +1 -1
- package/dist/server/logEntry.js +4 -1
- package/dist/server/logEntry.js.map +1 -1
- package/dist/server/logEntry.sql +25 -1
- package/dist/server/loopDocs.d.ts +2 -2
- package/dist/server/loopDocs.d.ts.map +1 -1
- package/dist/server/loopDocs.js +38 -31
- package/dist/server/loopDocs.js.map +1 -1
- package/dist/server/loopDocs.sql +1 -3
- package/dist/server/model-catalog.d.ts.map +1 -1
- package/dist/server/model-catalog.js +2 -1
- package/dist/server/model-catalog.js.map +1 -1
- package/dist/server/model-route.d.ts +1 -1
- package/dist/server/model-route.d.ts.map +1 -1
- package/dist/server/model-route.js +4 -2
- package/dist/server/model-route.js.map +1 -1
- package/dist/server/seam-entry-read.sql +3 -4
- package/dist/server/seam-loop.sql +2 -9
- package/dist/server/workspace-capabilities.sql +19 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +5 -17
- package/dist/service.js.map +1 -1
- package/docs/members.md +83 -0
- package/docs/skills.md +50 -0
- package/migrations/001_workspaces.sql +53 -0
- package/migrations/002_workers.sql +183 -0
- package/migrations/003_loops.sql +326 -0
- package/migrations/004_inference.sql +360 -0
- package/migrations/005_entries.sql +207 -0
- package/migrations/006_log.sql +578 -0
- package/migrations/007_subscriptions.sql +175 -0
- package/migrations/008_interactions.sql +29 -0
- package/package.json +33 -40
- package/digest-sql/channel-dispositions/dispositions.sql +0 -15
- package/digest-sql/channel-state/state.sql +0 -6
- package/digest-sql/curation/curation.sql +0 -6
- package/digest-sql/derivations/derivations.sql +0 -4
- package/digest-sql/embeddings/embeddings.sql +0 -4
- package/digest-sql/entry-dispositions/dispositions.sql +0 -15
- package/digest-sql/entry-state/state.sql +0 -6
- package/digest-sql/token-counts/token-counts.sql +0 -2
- package/dist/core/EmbeddingCall.d.ts +0 -23
- package/dist/core/EmbeddingCall.d.ts.map +0 -1
- package/dist/core/EmbeddingCall.js +0 -149
- package/dist/core/EmbeddingCall.js.map +0 -1
- package/dist/core/OverflowTurn.d.ts +0 -11
- package/dist/core/OverflowTurn.d.ts.map +0 -1
- package/dist/core/OverflowTurn.js +0 -80
- package/dist/core/OverflowTurn.js.map +0 -1
- package/dist/core/Owner.d.ts +0 -8
- package/dist/core/Owner.d.ts.map +0 -1
- package/dist/core/Owner.js +0 -46
- package/dist/core/Owner.js.map +0 -1
- package/dist/core/SendBroadcastHandler.d.ts.map +0 -1
- package/dist/core/SendBroadcastHandler.js +0 -159
- package/dist/core/SendBroadcastHandler.js.map +0 -1
- package/dist/core/VectorPump.d.ts +0 -28
- package/dist/core/VectorPump.d.ts.map +0 -1
- package/dist/core/VectorPump.js +0 -130
- package/dist/core/VectorPump.js.map +0 -1
- package/dist/core/owner.sql +0 -11
- package/dist/core/worker-settings.d.ts +0 -10
- package/dist/core/worker-settings.d.ts.map +0 -1
- package/dist/core/worker-settings.js +0 -53
- package/dist/core/worker-settings.js.map +0 -1
- package/dist/schemes/_entry-chunk.d.ts +0 -14
- package/dist/schemes/_entry-chunk.d.ts.map +0 -1
- package/dist/schemes/_entry-chunk.js +0 -165
- package/dist/schemes/_entry-chunk.js.map +0 -1
- package/dist/schemes/_entry-semantic.d.ts +0 -63
- package/dist/schemes/_entry-semantic.d.ts.map +0 -1
- package/dist/schemes/_entry-semantic.js +0 -299
- package/dist/schemes/_entry-semantic.js.map +0 -1
- package/dist/schemes/_entry-semantic.sql +0 -99
- package/dist/schemes/cosine.d.ts +0 -4
- package/dist/schemes/cosine.d.ts.map +0 -1
- package/dist/schemes/cosine.js +0 -9
- package/dist/schemes/cosine.js.map +0 -1
- package/dist/server/WorkerCapabilities.d.ts +0 -21
- package/dist/server/WorkerCapabilities.d.ts.map +0 -1
- package/dist/server/WorkerCapabilities.js.map +0 -1
- package/dist/server/WorkerResidency.d.ts +0 -40
- package/dist/server/WorkerResidency.d.ts.map +0 -1
- package/dist/server/WorkerResidency.js +0 -283
- package/dist/server/WorkerResidency.js.map +0 -1
- package/dist/server/seam-log-read.sql +0 -21
- package/dist/server/worker-capabilities.sql +0 -28
- package/migrations/001_schema.sql +0 -2207
package/dist/core/Dispatcher.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
var _a;
|
|
2
|
-
import {
|
|
2
|
+
import { PlurnkParser, TurnDisposition, parsePath } from "@plurnk/plurnk-contracts";
|
|
3
|
+
import { foldAuthorityIntoPath, promptLoopPrefix, renderAddress, renderTarget, schemeNameOf } from "./plurnk-uri.js";
|
|
3
4
|
import { PathSyntax } from "@plurnk/plurnk-contracts";
|
|
4
5
|
import Namespace from "./namespace.js";
|
|
5
6
|
import CapabilityResolver from "./CapabilityResolver.js";
|
|
7
|
+
import LoopPolicyReader from "./LoopPolicyReader.js";
|
|
6
8
|
import SchemeCtxImpl from "./caps/SchemeCtxImpl.js";
|
|
7
|
-
import LoopLifecycle from "./LoopLifecycle.js";
|
|
8
9
|
import Results from "./results.js";
|
|
9
10
|
import { OperationFailureError } from "./results.js";
|
|
10
11
|
import EffectPolicy from "../schemes/EffectPolicy.js";
|
|
@@ -14,11 +15,15 @@ import ResourceMutations from "./ResourceMutations.js";
|
|
|
14
15
|
import { primaryTargetOf } from "./statement-primary.js";
|
|
15
16
|
import LogBody from "./LogBody.js";
|
|
16
17
|
import LogVisibility from "./LogVisibility.js";
|
|
18
|
+
import EntryAddressBinding from "./EntryAddressBinding.js";
|
|
17
19
|
import WorkerControlHandler from "./WorkerControlHandler.js";
|
|
20
|
+
import WorkerControlAddress from "./WorkerControlAddress.js";
|
|
18
21
|
import KillHandler from "./KillHandler.js";
|
|
19
|
-
import
|
|
22
|
+
import TurnDispositionHandler from "./TurnDispositionHandler.js";
|
|
20
23
|
import LogWriter from "./LogWriter.js";
|
|
24
|
+
import LogEntryProjection from "./LogEntryProjection.js";
|
|
21
25
|
import DataStatementRunner from "./DataStatementRunner.js";
|
|
26
|
+
import ResourceBindings from "./ResourceBindings.js";
|
|
22
27
|
// SPEC {§scheme-surface}: writer must be in target scheme's manifest.writableBy.
|
|
23
28
|
// READ/FIND are not gated — they read, never mutating an entry.
|
|
24
29
|
const MUTATING_OPS = new Set(["EDIT", "SEND", "COPY", "MOVE", "EXEC", "KILL", "FORK", "WORK"]);
|
|
@@ -47,17 +52,12 @@ class Dispatcher {
|
|
|
47
52
|
// {§relation-indexed-dialects} — the engine's derivation pump, awaited by a scheme whose
|
|
48
53
|
// indexed dialect met a still-deriving index.
|
|
49
54
|
#settleDerivations;
|
|
50
|
-
#settleVectors;
|
|
51
55
|
#streamEventNotify;
|
|
52
56
|
#wakeWorkerNotify;
|
|
53
57
|
#injectWorker;
|
|
54
58
|
#cancelWorker;
|
|
55
59
|
#cancelDescendants;
|
|
56
|
-
// {§send-premature-terminate}/SEND signal 202 with scope — the engine-owned park-deadline registry (loopId → seconds;
|
|
57
|
-
// -1 = indefinite). The dispatcher WRITES at park; the daemon's drain park-exit consumes.
|
|
58
|
-
#parkDeadlines;
|
|
59
60
|
// Per-turn running-worker READ obligations. {§join-blocking-collect}
|
|
60
|
-
#joinTargets;
|
|
61
61
|
#liveSubscriptions;
|
|
62
62
|
#lifecycle;
|
|
63
63
|
#resourceMutations;
|
|
@@ -65,10 +65,10 @@ class Dispatcher {
|
|
|
65
65
|
#capabilities;
|
|
66
66
|
#workerControl;
|
|
67
67
|
#kill;
|
|
68
|
-
#
|
|
68
|
+
#disposition;
|
|
69
69
|
#logWriter;
|
|
70
70
|
#dataRun;
|
|
71
|
-
constructor({ db, schemes, mimetypes, weigh, notices, proposals, interactions, executors, loopSignal, settleDerivations,
|
|
71
|
+
constructor({ db, lifecycle, schemes, mimetypes, weigh, notices, proposals, interactions, executors, loopSignal, settleDerivations, streamEventNotify, wakeWorkerNotify, injectWorker, cancelWorker, cancelDescendants, liveSubscriptions, entryAddresses }) {
|
|
72
72
|
this.#db = db;
|
|
73
73
|
this.#schemes = schemes;
|
|
74
74
|
this.#mimetypes = mimetypes;
|
|
@@ -79,24 +79,21 @@ class Dispatcher {
|
|
|
79
79
|
this.#executors = executors;
|
|
80
80
|
this.#loopSignal = loopSignal;
|
|
81
81
|
this.#settleDerivations = settleDerivations;
|
|
82
|
-
this.#settleVectors = settleVectors;
|
|
83
82
|
this.#streamEventNotify = streamEventNotify;
|
|
84
83
|
this.#wakeWorkerNotify = wakeWorkerNotify;
|
|
85
84
|
this.#injectWorker = injectWorker;
|
|
86
85
|
this.#cancelWorker = cancelWorker;
|
|
87
86
|
this.#cancelDescendants = cancelDescendants;
|
|
88
|
-
this.#parkDeadlines = parkDeadlines ?? new Map();
|
|
89
|
-
this.#joinTargets = joinTargets ?? new Set();
|
|
90
87
|
this.#liveSubscriptions = liveSubscriptions;
|
|
91
88
|
this.#entryAddresses = entryAddresses;
|
|
92
89
|
this.#capabilities = new CapabilityResolver(db, schemes, executors);
|
|
93
|
-
this.#lifecycle =
|
|
90
|
+
this.#lifecycle = lifecycle;
|
|
94
91
|
this.#resourceMutations = new ResourceMutations({
|
|
95
92
|
schemes,
|
|
96
93
|
liveSubscriptions,
|
|
97
94
|
run: (schemeName, statement, ctx) => this.#dataRun.run(schemeName, statement, ctx),
|
|
98
|
-
checkWritable: (statement, origin,
|
|
99
|
-
checkCapabilities: (statement,
|
|
95
|
+
checkWritable: (statement, origin, workspaceId) => this.#checkWritable(statement, origin, workspaceId),
|
|
96
|
+
checkCapabilities: (statement, ctx) => this.#checkCapabilities(statement, ctx),
|
|
100
97
|
editTargetIdentity: (statement, workspaceId, workerId) => this.#editTargetIdentity(statement, workspaceId, workerId),
|
|
101
98
|
canonicalFilePath: (pathname, workspaceId) => this.#canonicalFilePath(pathname, workspaceId),
|
|
102
99
|
prepareDataRepresentation: (args) => this.#prepareDataRepresentation({
|
|
@@ -109,11 +106,11 @@ class Dispatcher {
|
|
|
109
106
|
deleteChannel: (scheme, address, channel, ctx) => this.#deleteChannel(scheme, address, channel, ctx),
|
|
110
107
|
applyProposal: (statement, result, resolution, ids) => this.#proposals.workerApply(statement, result, resolution, ids),
|
|
111
108
|
});
|
|
112
|
-
this.#workerControl = new WorkerControlHandler({ db: this.#db,
|
|
109
|
+
this.#workerControl = new WorkerControlHandler({ db: this.#db, failure: _a.#failure });
|
|
113
110
|
this.#kill = new KillHandler({ db: this.#db, schemes: this.#schemes, liveSubscriptions: this.#liveSubscriptions, cancelWorker: this.#cancelWorker, resolveDataEntryAddress: this.#resolveDataEntryAddress.bind(this), boundEntryContext: this.#boundEntryContext.bind(this), handlerContext: this.#handlerContext.bind(this), deleteEntry: this.#deleteEntry.bind(this), failure: _a.#failure });
|
|
114
|
-
this.#
|
|
111
|
+
this.#disposition = new TurnDispositionHandler({ db: this.#db, cancelDescendants: this.#cancelDescendants, lifecycle: this.#lifecycle, nextPacketBoundaries: this.#nextPacketBoundaries.bind(this), unobservedFailureCount: this.#unobservedFailureCount.bind(this), pendingSet: this.#pendingSet.bind(this), hasLiveWork: this.hasLiveWork.bind(this), failure: _a.#failure, statusResult: _a.#statusResult, unobservedFailures: _a.#unobservedFailures });
|
|
115
112
|
this.#logWriter = new LogWriter({ db: this.#db, weighContent: this.#weighContent, extractTarget: this.#extractTarget.bind(this), canonColumns: this.#canonColumns.bind(this), signalToJson: this.#signalToJson.bind(this), isProposal: _a.#isProposal });
|
|
116
|
-
this.#dataRun = new DataStatementRunner({ schemes: this.#schemes, liveSubscriptions: this.#liveSubscriptions, resolveDataEntryAddress: this.#resolveDataEntryAddress.bind(this),
|
|
113
|
+
this.#dataRun = new DataStatementRunner({ schemes: this.#schemes, liveSubscriptions: this.#liveSubscriptions, resolveDataEntryAddress: this.#resolveDataEntryAddress.bind(this), prepareDataRepresentation: this.#prepareDataRepresentation.bind(this), failure: _a.#failure });
|
|
117
114
|
}
|
|
118
115
|
// workspace → project_root, memoized: {§fs-namespace} fixes the root immutably at
|
|
119
116
|
// workspace creation, so a process-lifetime cache can never go stale.
|
|
@@ -121,36 +118,31 @@ class Dispatcher {
|
|
|
121
118
|
evictWorkspaceCache(workspaceId) {
|
|
122
119
|
this.#rootCache.delete(workspaceId);
|
|
123
120
|
}
|
|
124
|
-
async #fixedEntryOwnerId(manifest, ctx) {
|
|
125
|
-
return this.#entryAddresses.fixedOwnerId(manifest, ctx);
|
|
126
|
-
}
|
|
127
121
|
async #handlerContext(scheme, ctx, authority = "") {
|
|
128
|
-
const manifest = this.#schemes.manifestFor(scheme, ctx.
|
|
122
|
+
const manifest = this.#schemes.manifestFor(scheme, ctx.workspaceId);
|
|
129
123
|
return manifest === undefined
|
|
130
124
|
? null
|
|
131
125
|
: new SchemeCtxImpl(ctx, scheme, manifest, this.#liveSubscriptions, {
|
|
132
126
|
authority,
|
|
133
|
-
ownerId: await this.#fixedEntryOwnerId(manifest, ctx),
|
|
134
127
|
});
|
|
135
128
|
}
|
|
136
129
|
#boundEntryContext(routedScheme, address, ctx) {
|
|
137
|
-
const manifest = this.#schemes.manifestFor(routedScheme, ctx.
|
|
130
|
+
const manifest = this.#schemes.manifestFor(routedScheme, ctx.workspaceId);
|
|
138
131
|
return manifest?.category === "data"
|
|
139
132
|
? new SchemeCtxImpl(ctx, address.scheme, manifest, this.#liveSubscriptions, {
|
|
140
133
|
authority: address.authority,
|
|
141
|
-
ownerId: address.ownerId,
|
|
142
134
|
})
|
|
143
135
|
: null;
|
|
144
136
|
}
|
|
145
|
-
#coreCrud(scheme,
|
|
146
|
-
const handler = this.#schemes.get(scheme,
|
|
137
|
+
#coreCrud(scheme, workspaceId) {
|
|
138
|
+
const handler = this.#schemes.get(scheme, workspaceId);
|
|
147
139
|
return handler instanceof CoreSchemeAdapterBase
|
|
148
140
|
? handler
|
|
149
141
|
: undefined;
|
|
150
142
|
}
|
|
151
143
|
async #readEntry(scheme, address, ctx) {
|
|
152
144
|
const { pathname } = address;
|
|
153
|
-
const handler = this.#coreCrud(scheme, ctx.
|
|
145
|
+
const handler = this.#coreCrud(scheme, ctx.workspaceId);
|
|
154
146
|
const handlerCtx = this.#boundEntryContext(scheme, address, ctx);
|
|
155
147
|
if (typeof handler?.readEntry === "function" && handlerCtx !== null) {
|
|
156
148
|
return Results.assert(await handler.readEntry(pathname, handlerCtx));
|
|
@@ -180,7 +172,7 @@ class Dispatcher {
|
|
|
180
172
|
}
|
|
181
173
|
async #writeEntry(scheme, address, entry, ctx) {
|
|
182
174
|
const { pathname } = address;
|
|
183
|
-
const handler = this.#coreCrud(scheme, ctx.
|
|
175
|
+
const handler = this.#coreCrud(scheme, ctx.workspaceId);
|
|
184
176
|
const handlerCtx = this.#boundEntryContext(scheme, address, ctx);
|
|
185
177
|
if (typeof handler?.writeEntry === "function" && handlerCtx !== null) {
|
|
186
178
|
return Results.assert(await handler.writeEntry(pathname, entry, handlerCtx));
|
|
@@ -198,7 +190,7 @@ class Dispatcher {
|
|
|
198
190
|
}
|
|
199
191
|
async #deleteEntry(scheme, address, ctx) {
|
|
200
192
|
const { pathname } = address;
|
|
201
|
-
const handler = this.#coreCrud(scheme, ctx.
|
|
193
|
+
const handler = this.#coreCrud(scheme, ctx.workspaceId);
|
|
202
194
|
const handlerCtx = this.#boundEntryContext(scheme, address, ctx);
|
|
203
195
|
if (typeof handler?.deleteEntry === "function" && handlerCtx !== null) {
|
|
204
196
|
return Results.assert(await handler.deleteEntry(pathname, handlerCtx));
|
|
@@ -216,7 +208,7 @@ class Dispatcher {
|
|
|
216
208
|
}
|
|
217
209
|
async #deleteChannel(scheme, address, channel, ctx) {
|
|
218
210
|
const { pathname } = address;
|
|
219
|
-
const handler = this.#coreCrud(scheme, ctx.
|
|
211
|
+
const handler = this.#coreCrud(scheme, ctx.workspaceId);
|
|
220
212
|
const handlerCtx = this.#boundEntryContext(scheme, address, ctx);
|
|
221
213
|
if (typeof handler?.deleteChannel === "function" && handlerCtx !== null) {
|
|
222
214
|
return Results.assert(await handler.deleteChannel(pathname, channel, handlerCtx));
|
|
@@ -254,31 +246,23 @@ class Dispatcher {
|
|
|
254
246
|
async #canonicalFilePath(pathname, workspaceId) {
|
|
255
247
|
return Namespace.canonicalizeSpelling(pathname, await this.#workspaceRoot(workspaceId));
|
|
256
248
|
}
|
|
257
|
-
async #editTargetIdentity(statement, workspaceId,
|
|
258
|
-
const target = this.#extractTarget(statement.target,
|
|
249
|
+
async #editTargetIdentity(statement, workspaceId, _workerId) {
|
|
250
|
+
const target = this.#extractTarget(statement.target, workspaceId);
|
|
259
251
|
await this.#canonColumns(target, workspaceId);
|
|
260
|
-
return
|
|
261
|
-
key: JSON.stringify([
|
|
262
|
-
schemeNameOf(statement.target),
|
|
263
|
-
target.scheme,
|
|
264
|
-
target.hostname,
|
|
265
|
-
target.pathname,
|
|
266
|
-
target.fragment,
|
|
267
|
-
]),
|
|
268
|
-
identity: renderTarget(target),
|
|
269
|
-
};
|
|
252
|
+
return renderTarget(target);
|
|
270
253
|
}
|
|
271
254
|
// {§kill-scope-entry} — a scoped KILL on an entry-bearing scheme is one EDIT with an empty
|
|
272
255
|
// body over the same marker: prepared, gated, and merged as an EDIT while its log row
|
|
273
256
|
// records the model's KILL. Schemes that implement kill() (streams) take the scope themselves;
|
|
274
257
|
// the log's scoped KILL is curation.
|
|
275
258
|
#scopedEntryEdits = new WeakMap();
|
|
276
|
-
#scopedEntryEdit(statement,
|
|
259
|
+
#scopedEntryEdit(statement, workspaceId) {
|
|
277
260
|
if (statement.op === "EDIT")
|
|
278
261
|
return statement;
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
|
|
262
|
+
// {§kill-scope-entry} a scoped KILL of an entry empties the span; {§kill-pattern} a KILL with
|
|
263
|
+
// a matcher removes every whole line the pattern selects, inside its scope when one is given.
|
|
264
|
+
// Both are emptying EDITs; the log and every scheme with its own kill() keep their own path.
|
|
265
|
+
if (statement.op !== "KILL" || (statement.lineMarker === null && statement.matcher === null))
|
|
282
266
|
return null;
|
|
283
267
|
const cached = this.#scopedEntryEdits.get(statement);
|
|
284
268
|
if (cached !== undefined)
|
|
@@ -286,33 +270,29 @@ class Dispatcher {
|
|
|
286
270
|
const schemeName = schemeNameOf(statement.target);
|
|
287
271
|
if (schemeName === null || schemeName === "log")
|
|
288
272
|
return null;
|
|
289
|
-
const handler = this.#schemes.get(schemeName,
|
|
273
|
+
const handler = this.#schemes.get(schemeName, workspaceId);
|
|
290
274
|
if (handler === undefined || typeof handler.kill === "function")
|
|
291
275
|
return null;
|
|
292
276
|
const edit = {
|
|
293
277
|
op: "EDIT",
|
|
294
|
-
|
|
295
|
-
annotation: statement.annotation,
|
|
278
|
+
aside: statement.aside,
|
|
296
279
|
metadata: statement.metadata,
|
|
297
280
|
target: statement.target,
|
|
298
281
|
lineMarker: statement.lineMarker,
|
|
282
|
+
matcher: statement.matcher,
|
|
299
283
|
body: "",
|
|
300
284
|
position: statement.position,
|
|
301
285
|
};
|
|
302
286
|
this.#scopedEntryEdits.set(statement, edit);
|
|
287
|
+
if (statement.matcher !== null)
|
|
288
|
+
this.#resourceMutations.markLineDeletion(edit);
|
|
303
289
|
return edit;
|
|
304
290
|
}
|
|
305
|
-
async prepareEditBatches(statements, context) {
|
|
306
|
-
const { workspaceId, workerId, functionalityWorkerId, loopId, turnId, origin } = context;
|
|
307
|
-
const schemeCtx = this.#buildSchemeCtx({ workspaceId, workerId, functionalityWorkerId, loopId, turnId, origin });
|
|
308
|
-
const edits = statements.flatMap((statement) => {
|
|
309
|
-
const edit = this.#scopedEntryEdit(statement, schemeCtx.functionalityWorkerId);
|
|
310
|
-
return edit === null ? [] : [edit];
|
|
311
|
-
});
|
|
312
|
-
await this.#resourceMutations.prepareEditBatches(edits, context, schemeCtx);
|
|
313
|
-
}
|
|
314
291
|
async dispatch(context) {
|
|
315
|
-
|
|
292
|
+
if (context.statement.op === "READ" && _a.#globTarget(context.statement.target)) {
|
|
293
|
+
return this.#fanOutRead(context, context.statement);
|
|
294
|
+
}
|
|
295
|
+
let result = await ResourceBindings.using(this.#schemes, this.#buildSchemeCtx(context), (ctx) => this.#dispatchOne(context, ctx));
|
|
316
296
|
const edit = context.statement.op === "EDIT" ? context.statement : this.#scopedEntryEdits.get(context.statement);
|
|
317
297
|
if (edit !== undefined) {
|
|
318
298
|
// {§edit-batch-merges} — a proposal's apply result replaces the projected one; the
|
|
@@ -322,15 +302,65 @@ class Dispatcher {
|
|
|
322
302
|
}
|
|
323
303
|
return result;
|
|
324
304
|
}
|
|
325
|
-
|
|
305
|
+
static #globTarget(target) {
|
|
306
|
+
return target !== null && PathSyntax.hasGlob(target.kind === "url" ? target.pathname : target.raw);
|
|
307
|
+
}
|
|
308
|
+
// {§read-fan-out} — a READ over a glob reads every matching path: the paths come from the
|
|
309
|
+
// ordinary FIND over the same target (unlogged; a matcher FIND when there is one, the catalog
|
|
310
|
+
// otherwise; its resource page bounds the fan-out), and each is read as an ordinary exact READ
|
|
311
|
+
// with the authored scope and matcher and its own receipt row, so every rendered line keeps its
|
|
312
|
+
// path, ordinal and anchor. No path: one 204 receipt on the authored glob. A resource dialect
|
|
313
|
+
// (`~`, `&`) selects resources, not lines, so that READ is the FIND survey.
|
|
314
|
+
async #fanOutRead(context, statement) {
|
|
315
|
+
const survey = {
|
|
316
|
+
op: "FIND", aside: statement.aside, target: statement.target, metadata: statement.metadata,
|
|
317
|
+
matcher: statement.matcher, lineMarker: null, body: null, position: statement.position,
|
|
318
|
+
};
|
|
319
|
+
if (statement.matcher?.dialect === "fts" || statement.matcher?.dialect === "graph") {
|
|
320
|
+
return this.dispatch({ ...context, statement: survey });
|
|
321
|
+
}
|
|
322
|
+
const found = await ResourceBindings.using(this.#schemes, this.#buildSchemeCtx(context), (ctx) => this.#dataRun.run(schemeNameOf(statement.target), survey, ctx));
|
|
323
|
+
const paths = found.status < 300
|
|
324
|
+
? (found.results ?? []).flatMap((item) => Array.isArray(item) && !("items" in item[0]) ? [item[0].path] : [])
|
|
325
|
+
: [];
|
|
326
|
+
if (paths.length === 0) {
|
|
327
|
+
const result = found.status >= 400 ? found : Results.assert(statement.matcher === null
|
|
328
|
+
? { status: 204, detail: `No path matched ${statement.target.raw}.` }
|
|
329
|
+
: { status: 204, matched: 0, matcher: statement.matcher.raw, detail: `No line under ${statement.target.raw} matched the pattern.` });
|
|
330
|
+
const logEntryId = await this.#logWriter.writeLog({
|
|
331
|
+
statement, result, workspaceId: context.workspaceId, workerId: context.workerId, loopId: context.loopId,
|
|
332
|
+
turnId: context.turnId, sequence: context.sequence, origin: context.origin, curationPlan: null, modelCallId: null,
|
|
333
|
+
});
|
|
334
|
+
context.onDispatch?.(logEntryId);
|
|
335
|
+
return result;
|
|
336
|
+
}
|
|
337
|
+
const results = [];
|
|
338
|
+
for (const [index, path] of paths.entries()) {
|
|
339
|
+
const target = parsePath(path);
|
|
340
|
+
if (target === null)
|
|
341
|
+
throw new InvalidOperationResultError(`FIND named an unparseable path: ${path}`);
|
|
342
|
+
results.push(await this.dispatch({ ...context, statement: { ...statement, target }, sequence: context.sequence + index }));
|
|
343
|
+
}
|
|
344
|
+
const matchingPathCount = typeof found.matchingPathCount === "number" ? found.matchingPathCount : paths.length;
|
|
345
|
+
if (matchingPathCount > paths.length) {
|
|
346
|
+
this.#notices.push(context.workspaceId, context.workerId, context.loopId, {
|
|
347
|
+
source: "engine:dispatcher",
|
|
348
|
+
kind: "read_fanout_bounded",
|
|
349
|
+
level: "warn",
|
|
350
|
+
message: `READ ${statement.target.raw} matched ${matchingPathCount} paths; the first ${paths.length} were read. Narrow the glob, or FIND first.`,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
return Results.assert({ ...(results.find(({ status }) => status >= 400) ?? results[results.length - 1]), rowsWritten: results.length });
|
|
354
|
+
}
|
|
355
|
+
async #dispatchOne(context, schemeCtx) {
|
|
326
356
|
const { statement, workspaceId, workerId, loopId, turnId, sequence, origin, onDispatch, onSettled, } = context;
|
|
327
|
-
const schemeCtx = this.#buildSchemeCtx({ workspaceId, workerId, functionalityWorkerId: context.functionalityWorkerId, loopId, turnId, origin });
|
|
328
|
-
const { functionalityWorkerId } = schemeCtx;
|
|
329
357
|
let result;
|
|
330
358
|
let curationPlan = null;
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
359
|
+
// {§send-prompt-acceptance} — a model SEND addressed to one of this loop's own prompts
|
|
360
|
+
// means what an untargeted SEND means; the address the packet showed it is accepted.
|
|
361
|
+
const ownPrompt = statement.op === "SEND" && origin === "model" && await this.#isOwnPromptAddress(statement.target, workerId, loopId);
|
|
362
|
+
const denial = ownPrompt ? null : (this.#checkWritable(statement, origin, workspaceId)
|
|
363
|
+
?? await this.#checkCapabilities(statement, schemeCtx));
|
|
334
364
|
if (denial !== null) {
|
|
335
365
|
result = denial;
|
|
336
366
|
}
|
|
@@ -342,16 +372,20 @@ class Dispatcher {
|
|
|
342
372
|
// those are system failures.
|
|
343
373
|
try {
|
|
344
374
|
if (statement.op === "EDIT") {
|
|
345
|
-
result = await this.#resourceMutations.
|
|
375
|
+
result = await this.#resourceMutations.edit(statement, schemeCtx, context.editSequence);
|
|
376
|
+
}
|
|
377
|
+
else if (statement.op === "SEND" && (statement.target === null || ownPrompt)) {
|
|
378
|
+
result = await this.#respond(statement, schemeCtx, origin, workerId, loopId);
|
|
346
379
|
}
|
|
347
|
-
else if (
|
|
348
|
-
result = await this.#
|
|
380
|
+
else if (TurnDisposition.is(statement)) {
|
|
381
|
+
result = await this.#disposition.handle(statement, {
|
|
349
382
|
workspaceId,
|
|
350
383
|
workerId,
|
|
351
384
|
loopId,
|
|
352
385
|
turnId,
|
|
353
386
|
sequence,
|
|
354
387
|
origin,
|
|
388
|
+
allowUnobservedRetrievalCompletion: context.allowUnobservedRetrievalCompletion,
|
|
355
389
|
});
|
|
356
390
|
}
|
|
357
391
|
else if (statement.op === "KILL" && schemeNameOf(statement.target) === "log") {
|
|
@@ -360,7 +394,9 @@ class Dispatcher {
|
|
|
360
394
|
curationPlan = curation.plan;
|
|
361
395
|
}
|
|
362
396
|
else if (statement.op === "FORK" || statement.op === "WORK") {
|
|
363
|
-
|
|
397
|
+
// {§worker-spawn-prompt-resource} — a non-address path is the child's prompt resource.
|
|
398
|
+
const seeded = await this.#seedSpawnPrompt(statement, schemeCtx);
|
|
399
|
+
result = "result" in seeded ? seeded.result : await this.#workerControl.handleWorkerControl(seeded.statement, schemeCtx);
|
|
364
400
|
}
|
|
365
401
|
else if (statement.op === "COPY") {
|
|
366
402
|
result = await this.#resourceMutations.handleCopy(statement, schemeCtx);
|
|
@@ -368,15 +404,12 @@ class Dispatcher {
|
|
|
368
404
|
else if (statement.op === "MOVE") {
|
|
369
405
|
result = await this.#resourceMutations.handleMove(statement, schemeCtx);
|
|
370
406
|
}
|
|
371
|
-
else if (statement.op === "KILL" && this.#
|
|
372
|
-
result = await this.#resourceMutations.
|
|
407
|
+
else if (statement.op === "KILL" && this.#scopedEntryEdit(statement, workspaceId) !== null) {
|
|
408
|
+
result = await this.#resourceMutations.edit(this.#scopedEntryEdits.get(statement), schemeCtx, context.editSequence);
|
|
373
409
|
}
|
|
374
410
|
else if (statement.op === "KILL") {
|
|
375
411
|
result = await this.#kill.handleKill(statement, schemeCtx);
|
|
376
412
|
}
|
|
377
|
-
else if (statement.op === "PLAN") {
|
|
378
|
-
result = this.#handlePlan(statement);
|
|
379
|
-
}
|
|
380
413
|
else if (statement.op === "EXEC") {
|
|
381
414
|
// EXEC routes unconditionally to its operation owner after
|
|
382
415
|
// the shared capability resolver admits its runtime/tool.
|
|
@@ -395,7 +428,7 @@ class Dispatcher {
|
|
|
395
428
|
else {
|
|
396
429
|
const scheme = schemeNameOf(primaryTargetOf(statement));
|
|
397
430
|
console.error(`Scheme '${scheme ?? "unknown"}' ${statement.op} threw outside its operation result contract:`, err);
|
|
398
|
-
result = _a.#failure("scheme-handler-threw", 500, `The '${scheme ?? "unknown"}' scheme did not produce a ${statement.op}
|
|
431
|
+
result = _a.#failure("scheme-handler-threw", 500, `The '${scheme ?? "unknown"}' scheme did not produce a result for ${statement.op}.`, {}, {
|
|
399
432
|
stage: "scheme-dispatch",
|
|
400
433
|
scheme,
|
|
401
434
|
operation: statement.op,
|
|
@@ -407,12 +440,9 @@ class Dispatcher {
|
|
|
407
440
|
// successful receipts while the exact state effects remain durable.
|
|
408
441
|
// A running-worker READ arms this turn's blocking collect.
|
|
409
442
|
// {§join-blocking-collect}
|
|
410
|
-
if (typeof result.awaitWorker === "string")
|
|
411
|
-
this.#joinTargets.add(loopId);
|
|
412
443
|
const logEntryId = await this.#logWriter.writeLog({
|
|
413
444
|
statement,
|
|
414
445
|
result,
|
|
415
|
-
functionalityWorkerId,
|
|
416
446
|
workspaceId,
|
|
417
447
|
workerId,
|
|
418
448
|
loopId,
|
|
@@ -424,8 +454,8 @@ class Dispatcher {
|
|
|
424
454
|
});
|
|
425
455
|
onDispatch?.(logEntryId);
|
|
426
456
|
// Proposal lifecycle (SPEC.md {§engine-rails} + {§methods-proposal-resolve}; {§proposal-202-pauses}). When a
|
|
427
|
-
// side-effecting op returns status 202 (a
|
|
428
|
-
//
|
|
457
|
+
// side-effecting op returns status 202 (a waiting TASK parks rather
|
|
458
|
+
// than proposing — #isProposal), the entry is written
|
|
429
459
|
// state='proposed'; dispatch then PAUSES on a per-entry waiter until
|
|
430
460
|
// resolution arrives via Engine.resolveProposal (from a client-interface resume,
|
|
431
461
|
// core-owned disposition, or timeout). The post-resolution status replaces 202 in the
|
|
@@ -436,20 +466,21 @@ class Dispatcher {
|
|
|
436
466
|
// that exact fact here; no human gate or loop/proposal notification.
|
|
437
467
|
const effect = result.attrs?.effect;
|
|
438
468
|
let autoAccept = false;
|
|
439
|
-
if (statement.op === "EXEC"
|
|
469
|
+
if (statement.op === "EXEC" || (statement.op === "SEND"
|
|
470
|
+
&& this.#schemes.isRuntimeScheme(schemeNameOf(statement.target) ?? "", workspaceId))) {
|
|
440
471
|
if (!EffectPolicy.isEffect(effect)) {
|
|
441
|
-
throw new InvalidOperationResultError("
|
|
472
|
+
throw new InvalidOperationResultError("Execution proposal omitted its canonical effect fact.");
|
|
442
473
|
}
|
|
443
474
|
autoAccept = EffectPolicy.decide(effect) === "auto";
|
|
444
475
|
}
|
|
445
476
|
if (autoAccept) {
|
|
446
|
-
const initialSettlement = await this.#proposals.workerApply(statement, result, { decision: "accept" }, { workspaceId, workerId,
|
|
477
|
+
const initialSettlement = await this.#proposals.workerApply(statement, result, { decision: "accept" }, { workspaceId, workerId, loopId, turnId });
|
|
447
478
|
const effective = await this.#resourceMutations.settleProposal({
|
|
448
479
|
statement,
|
|
449
480
|
result,
|
|
450
481
|
settlement: initialSettlement,
|
|
451
482
|
ctx: schemeCtx,
|
|
452
|
-
ids: { workspaceId, workerId,
|
|
483
|
+
ids: { workspaceId, workerId, loopId, turnId },
|
|
453
484
|
});
|
|
454
485
|
const post = await this.#proposals.applyResolution(logEntryId, effective);
|
|
455
486
|
await onSettled?.(logEntryId);
|
|
@@ -481,13 +512,13 @@ class Dispatcher {
|
|
|
481
512
|
// file, spawns the process, etc.). Its operation result is
|
|
482
513
|
// preserved: an apply failure keeps its original status and
|
|
483
514
|
// Problem Details instead of masquerading as a client rejection.
|
|
484
|
-
const initialSettlement = await this.#proposals.workerApply(statement, result, resolution, { workspaceId, workerId,
|
|
515
|
+
const initialSettlement = await this.#proposals.workerApply(statement, result, resolution, { workspaceId, workerId, loopId, turnId });
|
|
485
516
|
const effective = await this.#resourceMutations.settleProposal({
|
|
486
517
|
statement,
|
|
487
518
|
result,
|
|
488
519
|
settlement: initialSettlement,
|
|
489
520
|
ctx: schemeCtx,
|
|
490
|
-
ids: { workspaceId, workerId,
|
|
521
|
+
ids: { workspaceId, workerId, loopId, turnId },
|
|
491
522
|
});
|
|
492
523
|
const post = await this.#proposals.applyResolution(logEntryId, effective);
|
|
493
524
|
await onSettled?.(logEntryId);
|
|
@@ -506,14 +537,21 @@ class Dispatcher {
|
|
|
506
537
|
if (statement.op !== "READ")
|
|
507
538
|
throw new Error(`look resolves READ only; got ${statement.op}`);
|
|
508
539
|
// turnId is a write-time FK only — a look writes no row, so 0 (no turn) is inert.
|
|
509
|
-
const schemeCtx = this.#buildSchemeCtx({ workspaceId, workerId,
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
540
|
+
const schemeCtx = this.#buildSchemeCtx({ workspaceId, workerId, loopId, turnId: 0, origin });
|
|
541
|
+
return ResourceBindings.using(this.#schemes, schemeCtx, async (ctx) => {
|
|
542
|
+
try {
|
|
543
|
+
const denial = await this.#checkCapabilities(statement, ctx);
|
|
544
|
+
return denial ?? await this.#dataRun.run(schemeNameOf(statement.target), statement, ctx);
|
|
545
|
+
}
|
|
546
|
+
catch (error) {
|
|
547
|
+
if (error instanceof OperationFailureError)
|
|
548
|
+
return error.result;
|
|
549
|
+
throw error;
|
|
550
|
+
}
|
|
551
|
+
});
|
|
514
552
|
}
|
|
515
|
-
capabilityProjection(workspaceId
|
|
516
|
-
return this.#capabilities.projection(workspaceId
|
|
553
|
+
capabilityProjection(workspaceId) {
|
|
554
|
+
return this.#capabilities.projection(workspaceId);
|
|
517
555
|
}
|
|
518
556
|
// Resolve the client selector through the owning scheme before persistence
|
|
519
557
|
// is consulted. Public schemes choose a semantic owner; core-owned authority
|
|
@@ -523,7 +561,6 @@ class Dispatcher {
|
|
|
523
561
|
const coreCtx = this.#buildSchemeCtx({
|
|
524
562
|
workspaceId,
|
|
525
563
|
workerId,
|
|
526
|
-
functionalityWorkerId: context.functionalityWorkerId,
|
|
527
564
|
loopId: 0,
|
|
528
565
|
turnId: 0,
|
|
529
566
|
origin: "client",
|
|
@@ -539,7 +576,6 @@ class Dispatcher {
|
|
|
539
576
|
if (rendered === null)
|
|
540
577
|
throw new TypeError("Resolved entry target did not render.");
|
|
541
578
|
return {
|
|
542
|
-
ownerId: resolved.address.ownerId,
|
|
543
579
|
scheme: resolved.address.scheme,
|
|
544
580
|
authority: resolved.address.authority,
|
|
545
581
|
pathname: resolved.address.pathname,
|
|
@@ -550,23 +586,32 @@ class Dispatcher {
|
|
|
550
586
|
const routedScheme = schemeNameOf(target);
|
|
551
587
|
if (routedScheme === null)
|
|
552
588
|
return null;
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
589
|
+
return ResourceBindings.using(this.#schemes, ctx, async (boundCtx) => {
|
|
590
|
+
try {
|
|
591
|
+
const binding = await ResourceBindings.resolve(target, boundCtx);
|
|
592
|
+
if (binding?.manifest.category !== "data")
|
|
593
|
+
return null;
|
|
594
|
+
return this.#resolveDataEntryAddress({ target, routedScheme,
|
|
595
|
+
handler: binding.handler, manifest: binding.manifest, ctx: boundCtx });
|
|
596
|
+
}
|
|
597
|
+
catch (error) {
|
|
598
|
+
if (error instanceof OperationFailureError)
|
|
599
|
+
return { address: null, result: error.result };
|
|
600
|
+
throw error;
|
|
601
|
+
}
|
|
602
|
+
});
|
|
558
603
|
}
|
|
559
|
-
async #resolveDataEntryAddress({ target, routedScheme, handler, manifest, ctx, }) {
|
|
604
|
+
async #resolveDataEntryAddress({ target, routedScheme, handler, manifest, ctx, access = "read", }) {
|
|
560
605
|
if (manifest.category !== "data") {
|
|
561
606
|
throw new TypeError(`Scheme '${routedScheme}' is not entry-bearing.`);
|
|
562
607
|
}
|
|
563
|
-
return this.#entryAddresses.resolve({ target, routedScheme, handler, manifest, ctx });
|
|
608
|
+
return this.#entryAddresses.resolve({ target, routedScheme, handler, manifest, ctx, access });
|
|
564
609
|
}
|
|
565
610
|
async #prepareDataRepresentation({ target, metadata, routedScheme, handler, manifest, ctx, publishedChannel, resolved: priorResolution, }) {
|
|
566
611
|
if (metadata !== null && manifest.metadataModifier !== true) {
|
|
567
612
|
return {
|
|
568
613
|
address: null,
|
|
569
|
-
result: _a.#failure("scheme-metadata-unsupported", 400, `Scheme '${routedScheme}' does not accept the
|
|
614
|
+
result: _a.#failure("scheme-metadata-unsupported", 400, `Scheme '${routedScheme}' does not accept the [metadata] modifier.`, {}, { scheme: routedScheme, retryable: false }),
|
|
570
615
|
};
|
|
571
616
|
}
|
|
572
617
|
const resolved = priorResolution ?? await this.#resolveDataEntryAddress({
|
|
@@ -587,7 +632,6 @@ class Dispatcher {
|
|
|
587
632
|
: target;
|
|
588
633
|
const preparationCtx = new SchemeCtxImpl(ctx, target.kind === "url" ? target.scheme : routedScheme, manifest, this.#liveSubscriptions, {
|
|
589
634
|
authority: address.authority,
|
|
590
|
-
ownerId: address.ownerId,
|
|
591
635
|
publishedChannel,
|
|
592
636
|
});
|
|
593
637
|
const prepared = Results.assertRepresentationPreparation(await handler.prepareRepresentation({
|
|
@@ -604,16 +648,37 @@ class Dispatcher {
|
|
|
604
648
|
// An accepted EXEC reads a non-file source through the same registered
|
|
605
649
|
// handler and addressed context as an authored READ. {§exec-target-routing}
|
|
606
650
|
async readExecSource(statement, ctx) {
|
|
651
|
+
return ResourceBindings.using(this.#schemes, ctx, (boundCtx) => this.#readExecSource(statement, boundCtx));
|
|
652
|
+
}
|
|
653
|
+
async #readExecSource(statement, ctx) {
|
|
607
654
|
const schemeName = schemeNameOf(statement.target);
|
|
608
|
-
const
|
|
655
|
+
const binding = await ResourceBindings.resolve(statement.target, ctx);
|
|
656
|
+
const manifest = binding?.manifest;
|
|
609
657
|
if (manifest !== undefined && manifest.category !== "data") {
|
|
610
|
-
return _a.#failure("exec-source-not-data", 501, `Scheme '${schemeName}' is not a data source for EXEC.`, {}, {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
658
|
+
return { nativePath: null, result: _a.#failure("exec-source-not-data", 501, `Scheme '${schemeName}' is not a data source for EXEC.`, {}, {
|
|
659
|
+
scheme: schemeName,
|
|
660
|
+
category: manifest.category,
|
|
661
|
+
retryable: false,
|
|
662
|
+
}) };
|
|
615
663
|
}
|
|
616
|
-
|
|
664
|
+
const result = Results.assertReadResult(await this.#dataRun.run(schemeName, statement, ctx));
|
|
665
|
+
const target = statement.target;
|
|
666
|
+
const handler = binding?.handler;
|
|
667
|
+
const selectedChannel = target?.fragment ?? null;
|
|
668
|
+
if (result.status !== 200 || target === null || handler === undefined || manifest?.category !== "data"
|
|
669
|
+
|| (selectedChannel !== null && selectedChannel !== manifest.defaultChannel)) {
|
|
670
|
+
return { result, nativePath: null };
|
|
671
|
+
}
|
|
672
|
+
const resolved = await this.#resolveDataEntryAddress({ target, routedScheme: schemeName, handler, manifest, ctx });
|
|
673
|
+
if (resolved.result !== null)
|
|
674
|
+
return { result: resolved.result, nativePath: null };
|
|
675
|
+
const source = resolved.address === null ? undefined : handler.byteSource?.(resolved.address, EntryAddressBinding.addressContext(ctx));
|
|
676
|
+
if (source?.nativePath === undefined)
|
|
677
|
+
return { result, nativePath: null };
|
|
678
|
+
const nativePath = await source.nativePath();
|
|
679
|
+
if (nativePath === null)
|
|
680
|
+
return { nativePath: null, result: _a.#failure("entry-not-found", 404, "The EXEC source file no longer exists.", {}, { target: target.raw }) };
|
|
681
|
+
return { result, nativePath };
|
|
617
682
|
}
|
|
618
683
|
// The one place per-dispatch coordinates are built; a caller that carries no
|
|
619
684
|
// explicit Functionality coordinate acts in its own Worker's
|
|
@@ -621,10 +686,9 @@ class Dispatcher {
|
|
|
621
686
|
// PlurnkSchemeContext and never re-derive.
|
|
622
687
|
#buildSchemeCtx(ids) {
|
|
623
688
|
const { workspaceId, workerId, loopId, turnId, origin } = ids;
|
|
624
|
-
const functionalityWorkerId = ids.functionalityWorkerId ?? workerId;
|
|
625
689
|
const context = {
|
|
626
690
|
db: this.#db,
|
|
627
|
-
workspaceId, workerId,
|
|
691
|
+
workspaceId, workerId, loopId, turnId,
|
|
628
692
|
writer: origin,
|
|
629
693
|
signal: this.#loopSignal(loopId),
|
|
630
694
|
streamEventNotify: this.#streamEventNotify,
|
|
@@ -634,11 +698,10 @@ class Dispatcher {
|
|
|
634
698
|
weigh: this.#weighContent,
|
|
635
699
|
// {§exec-stream} — a runtime scheme's default channel is its own (stdout), never the
|
|
636
700
|
// catalog fallback `body`; resolved through the same registry the writable gate reads.
|
|
637
|
-
defaultChannelFor: (scheme) => this.#schemes.defaultChannelFor(scheme,
|
|
701
|
+
defaultChannelFor: (scheme) => this.#schemes.defaultChannelFor(scheme, context.workspaceId),
|
|
638
702
|
settleDerivations: () => this.#settleDerivations(context),
|
|
639
|
-
settleVectors: (hashes) => this.#settleVectors(context, hashes),
|
|
640
703
|
pushNotice: (notice) => this.#notices.push(workspaceId, workerId, loopId, notice),
|
|
641
|
-
requestInteraction: (request) => this.#interactions.request(request, { workspaceId, workerId, loopId, turnId },
|
|
704
|
+
requestInteraction: (request, signal = this.#loopSignal(loopId)) => this.#interactions.request(request, { workspaceId, workerId, loopId, turnId }, signal),
|
|
642
705
|
executors: this.#executors(),
|
|
643
706
|
};
|
|
644
707
|
return context;
|
|
@@ -649,40 +712,38 @@ class Dispatcher {
|
|
|
649
712
|
// - SEND broadcast (path=null) has no target scheme; not gated.
|
|
650
713
|
// - COPY: dst scheme writableBy applies.
|
|
651
714
|
// - MOVE: both src (delete) and dst (write) schemes' writableBy apply.
|
|
652
|
-
#checkWritable(statement, origin,
|
|
653
|
-
const workerId = functionalityWorkerId;
|
|
715
|
+
#checkWritable(statement, origin, workspaceId) {
|
|
654
716
|
if (!MUTATING_OPS.has(statement.op))
|
|
655
717
|
return null;
|
|
656
|
-
if (statement.op === "SEND" && statement.target === null)
|
|
718
|
+
if (TurnDisposition.is(statement) || statement.op === "SEND" && statement.target === null)
|
|
657
719
|
return null;
|
|
658
720
|
// EXEC's operation authority always belongs to the exec scheme;
|
|
659
721
|
// runtime-specific resource authority is gated separately below.
|
|
660
722
|
if (statement.op === "EXEC") {
|
|
661
|
-
return this.#denyIfDisallowed("exec", origin,
|
|
723
|
+
return this.#denyIfDisallowed("exec", origin, workspaceId);
|
|
662
724
|
}
|
|
663
|
-
// {§stream-control}
|
|
664
|
-
//
|
|
665
|
-
|
|
666
|
-
if (statement.op === "KILL") {
|
|
725
|
+
// {§stream-control}, {§exec-input}: process control is not a write to
|
|
726
|
+
// stored output. The workspace execution binding owns KILL and SEND.
|
|
727
|
+
if (statement.op === "KILL" || statement.op === "SEND") {
|
|
667
728
|
const target = schemeNameOf(statement.target);
|
|
668
|
-
if (target !== null && this.#schemes.isRuntimeScheme(target,
|
|
729
|
+
if (target !== null && this.#schemes.isRuntimeScheme(target, workspaceId))
|
|
669
730
|
return null;
|
|
670
731
|
}
|
|
671
732
|
// Worker control (FORK/WORK → worker://<name>, spawn or fork) is gated by worker://'s writableBy — its
|
|
672
733
|
// body is a seed prompt, not a dst path, so the entry-COPY dst-parse below doesn't apply.
|
|
673
734
|
// {§machine-processes}
|
|
674
735
|
if (this.#isWorkerControl(statement))
|
|
675
|
-
return this.#denyIfDisallowed("worker", origin,
|
|
736
|
+
return this.#denyIfDisallowed("worker", origin, workspaceId);
|
|
676
737
|
if (statement.op === "COPY" || statement.op === "MOVE") {
|
|
677
738
|
const dst = statement.destination.target;
|
|
678
739
|
const dstScheme = schemeNameOf(dst);
|
|
679
|
-
const dstDenial = this.#denyIfDisallowed(dstScheme, origin,
|
|
740
|
+
const dstDenial = this.#denyIfDisallowed(dstScheme, origin, workspaceId);
|
|
680
741
|
if (dstDenial !== null)
|
|
681
742
|
return dstDenial;
|
|
682
743
|
if (statement.op === "MOVE") {
|
|
683
744
|
const srcScheme = schemeNameOf(statement.source.target);
|
|
684
745
|
if (srcScheme !== dstScheme) {
|
|
685
|
-
const srcDenial = this.#denyIfDisallowed(srcScheme, origin,
|
|
746
|
+
const srcDenial = this.#denyIfDisallowed(srcScheme, origin, workspaceId);
|
|
686
747
|
if (srcDenial !== null)
|
|
687
748
|
return srcDenial;
|
|
688
749
|
}
|
|
@@ -690,7 +751,7 @@ class Dispatcher {
|
|
|
690
751
|
return null;
|
|
691
752
|
}
|
|
692
753
|
const target = schemeNameOf(statement.target);
|
|
693
|
-
const denial = this.#denyIfDisallowed(target, origin,
|
|
754
|
+
const denial = this.#denyIfDisallowed(target, origin, workspaceId);
|
|
694
755
|
// {§send-target-recipient} — SEND addresses recipients, not otherwise
|
|
695
756
|
// read-only resources. State that boundary without guessing whether the
|
|
696
757
|
// model intended a reply, deletion, or directed message.
|
|
@@ -704,13 +765,13 @@ class Dispatcher {
|
|
|
704
765
|
}
|
|
705
766
|
return denial;
|
|
706
767
|
}
|
|
707
|
-
#denyIfDisallowed(schemeName, origin,
|
|
768
|
+
#denyIfDisallowed(schemeName, origin, workspaceId) {
|
|
708
769
|
if (schemeName === null)
|
|
709
770
|
return null;
|
|
710
|
-
const handler = this.#schemes.get(schemeName,
|
|
771
|
+
const handler = this.#schemes.get(schemeName, workspaceId);
|
|
711
772
|
if (handler === undefined)
|
|
712
773
|
return null;
|
|
713
|
-
const manifest = this.#schemes.manifestFor(schemeName,
|
|
774
|
+
const manifest = this.#schemes.manifestFor(schemeName, workspaceId);
|
|
714
775
|
if (manifest === undefined)
|
|
715
776
|
throw new Error(`registered scheme '${schemeName}' has no manifest`);
|
|
716
777
|
if (manifest.writableBy.includes(origin))
|
|
@@ -725,8 +786,9 @@ class Dispatcher {
|
|
|
725
786
|
// {§capability-admission} — one resolver gates every operation route before
|
|
726
787
|
// execution or proposal handling. Unknown routes continue to their ordinary
|
|
727
788
|
// owner; a known policy denial is one factual, non-presumptuous 403.
|
|
728
|
-
async #checkCapabilities(statement,
|
|
729
|
-
|
|
789
|
+
async #checkCapabilities(statement, ctx) {
|
|
790
|
+
await LoopPolicyReader.read(this.#db, ctx.loopId);
|
|
791
|
+
const denied = await this.#capabilities.denial(statement, ctx.workspaceId, ctx.writer, async (target) => (await ResourceBindings.resolve(target, ctx))?.manifest);
|
|
730
792
|
if (denied === null)
|
|
731
793
|
return null;
|
|
732
794
|
const { descriptor, scope } = denied;
|
|
@@ -742,19 +804,23 @@ class Dispatcher {
|
|
|
742
804
|
retryable: false,
|
|
743
805
|
});
|
|
744
806
|
}
|
|
807
|
+
capabilityDenial(statement, ctx) {
|
|
808
|
+
return ResourceBindings.using(this.#schemes, ctx, (boundCtx) => this.#checkCapabilities(statement, boundCtx));
|
|
809
|
+
}
|
|
745
810
|
// Worker control is FORK/WORK (grammar 0.74.55), not COPY — its body
|
|
746
811
|
// is the new worker's seed prompt, not a destination path. The COPY gates and ResourceMutations.handleCopy
|
|
747
812
|
// branch on this so they never parse the prompt as a dst path.
|
|
748
813
|
#isWorkerControl(statement) {
|
|
749
814
|
return statement.op === "FORK" || statement.op === "WORK"; // worker control targets worker://<name> (grammar 0.74.55)
|
|
750
815
|
}
|
|
751
|
-
|
|
752
|
-
|
|
816
|
+
// {§rejected-emission-entry} — rejected provider bytes, never an admitted program.
|
|
817
|
+
async writeEmissionAttempt({ verbatim, workerId, loopId, turnId, sequence, modelCallId }) {
|
|
818
|
+
const durableAttrs = { kind: "emissionAttempt" };
|
|
753
819
|
const rx = JSON.stringify({ content: verbatim, mimetype: "text/vnd.plurnk" });
|
|
754
820
|
const row = await this.#db.engine_insert_log_entry.get({
|
|
755
821
|
worker_id: workerId, loop_id: loopId, turn_id: turnId, sequence,
|
|
756
|
-
origin, source: null, model_call_id: modelCallId,
|
|
757
|
-
op: null,
|
|
822
|
+
origin: "model", source: null, model_call_id: modelCallId,
|
|
823
|
+
op: null, signal: null,
|
|
758
824
|
scheme: null, username: null, password: null, hostname: null, port: null,
|
|
759
825
|
pathname: null, query: null, fragment: null, lineMarker: null,
|
|
760
826
|
tx: "", mimetype_tx: "text/vnd.plurnk",
|
|
@@ -771,49 +837,82 @@ class Dispatcher {
|
|
|
771
837
|
}, this.#weighContent),
|
|
772
838
|
state: "resolved", outcome: null,
|
|
773
839
|
attrs: JSON.stringify(durableAttrs),
|
|
774
|
-
initial_folded: LogVisibility.serialize(
|
|
840
|
+
initial_folded: LogVisibility.serialize(LogVisibility.FOLDED),
|
|
775
841
|
});
|
|
776
842
|
if (row === undefined)
|
|
777
|
-
throw new Error("Dispatcher
|
|
843
|
+
throw new Error("Dispatcher.writeEmissionAttempt: insert returned no row");
|
|
778
844
|
return row.id;
|
|
779
845
|
}
|
|
780
|
-
// {§
|
|
781
|
-
//
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
846
|
+
// {§worker-spawn-prompt-resource} WORK and FORK overload their slot by scheme: a `worker://`
|
|
847
|
+
// path is always the child's address (and keeps the address rules); a path of any other scheme
|
|
848
|
+
// is read whole and becomes the child's prompt, composed with the body as BARE's combined form.
|
|
849
|
+
// The durable row keeps the authored statement; only the handler sees the composed one, with no
|
|
850
|
+
// target, so the child is auto-named exactly as when the slot is empty.
|
|
851
|
+
async #seedSpawnPrompt(statement, ctx) {
|
|
852
|
+
if (statement.target === null || WorkerControlAddress.isWorkerScheme(statement.target))
|
|
853
|
+
return { statement };
|
|
854
|
+
const read = { ...statement, op: "READ", matcher: null, body: null, lineMarker: { marks: [1, -1] } };
|
|
855
|
+
const denial = await this.#checkCapabilities(read, ctx);
|
|
856
|
+
if (denial !== null)
|
|
857
|
+
return { result: denial };
|
|
858
|
+
const result = Results.assertReadResult(await this.#dataRun.run(schemeNameOf(read.target), read, ctx));
|
|
859
|
+
if (result.status !== 200 && result.status !== 204)
|
|
860
|
+
return { result };
|
|
861
|
+
if (result.content !== null && typeof result.content !== "string") {
|
|
862
|
+
throw new InvalidOperationResultError(`${statement.op} prompt resource READ returned non-text content.`);
|
|
863
|
+
}
|
|
864
|
+
const prompt = [result.content ?? "", statement.body ?? ""].filter((part) => part !== "").join("\n\n");
|
|
865
|
+
if (prompt.trim() === "") {
|
|
866
|
+
return { result: _a.#failure("spawn-prompt-empty", 422, `${statement.op} has no prompt text: the resource is empty and there is no body.`, {}, { retryable: false }) };
|
|
867
|
+
}
|
|
868
|
+
return { statement: { ...statement, target: null, body: prompt } };
|
|
790
869
|
}
|
|
791
|
-
// {§
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
870
|
+
// {§bare-inference} Reuse exact READ projection without its log/presentation layer.
|
|
871
|
+
async prepareBarePrompt(context) {
|
|
872
|
+
return ResourceBindings.using(this.#schemes, this.#buildSchemeCtx(context), async (ctx) => {
|
|
873
|
+
try {
|
|
874
|
+
return await this.#prepareBarePrompt(context.statement, ctx);
|
|
875
|
+
}
|
|
876
|
+
catch (error) {
|
|
877
|
+
if (error instanceof OperationFailureError)
|
|
878
|
+
return { result: error.result };
|
|
879
|
+
throw error;
|
|
880
|
+
}
|
|
800
881
|
});
|
|
801
882
|
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
883
|
+
async #prepareBarePrompt(statement, ctx) {
|
|
884
|
+
const denial = await this.#checkCapabilities(statement, ctx);
|
|
885
|
+
if (denial !== null)
|
|
886
|
+
return { result: denial };
|
|
887
|
+
let resource = "";
|
|
888
|
+
if (statement.target !== null) {
|
|
889
|
+
const read = {
|
|
890
|
+
...statement,
|
|
891
|
+
op: "READ",
|
|
892
|
+
matcher: null,
|
|
893
|
+
body: null,
|
|
894
|
+
lineMarker: { marks: [1, -1] },
|
|
895
|
+
};
|
|
896
|
+
const result = Results.assertReadResult(await this.#dataRun.run(schemeNameOf(read.target), read, ctx));
|
|
897
|
+
if (result.status !== 200 && result.status !== 204)
|
|
898
|
+
return { result };
|
|
899
|
+
if (typeof result.content === "string")
|
|
900
|
+
resource = result.content;
|
|
901
|
+
else if (result.content !== null) {
|
|
902
|
+
throw new InvalidOperationResultError("BARE source READ returned non-text content.");
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
const prompt = [resource, statement.body].filter((part) => part !== "").join("\n\n");
|
|
906
|
+
if (prompt.trim() === "") {
|
|
907
|
+
return { result: _a.#failure("bare-prompt-empty", 422, "BARE has no prompt text.", {}, { retryable: false }) };
|
|
908
|
+
}
|
|
909
|
+
return { prompt };
|
|
809
910
|
}
|
|
810
|
-
// {§bare-inference} Provider work
|
|
811
|
-
// dispatcher owns only the ordinary operation-result commit and notification.
|
|
911
|
+
// {§bare-inference} Provider work runs concurrently; receipts commit in authored order.
|
|
812
912
|
async recordBareResult(context, result, modelCallId) {
|
|
813
913
|
Results.assert(result);
|
|
814
914
|
const logEntryId = await this.#logWriter.writeLog({
|
|
815
915
|
...context,
|
|
816
|
-
functionalityWorkerId: context.functionalityWorkerId ?? context.workerId,
|
|
817
916
|
result,
|
|
818
917
|
curationPlan: null,
|
|
819
918
|
modelCallId,
|
|
@@ -822,41 +921,103 @@ class Dispatcher {
|
|
|
822
921
|
await context.onSettled?.(logEntryId);
|
|
823
922
|
return result;
|
|
824
923
|
}
|
|
825
|
-
// {§send-
|
|
826
|
-
//
|
|
827
|
-
//
|
|
828
|
-
//
|
|
829
|
-
//
|
|
830
|
-
//
|
|
831
|
-
//
|
|
924
|
+
// {§send-prompt-acceptance} `prompt://<this worker>/<this loop>/<id>` names a prompt the loop
|
|
925
|
+
// contains; a SEND to it is the response, exactly as if untargeted. Another worker's or
|
|
926
|
+
// another loop's prompt is not a recipient and keeps the ordinary refusal.
|
|
927
|
+
// {§send-response-receipt} — a response names the prompts it answers, so the receipt
|
|
928
|
+
// says where the text went. {§send-looks-like-operation} — a model response whose first
|
|
929
|
+
// line is an operation heading is a mis-fenced operation, not a reply: the 2026-09-11
|
|
930
|
+
// dogfood put four operations on the line after their fences, delivered all four to the
|
|
931
|
+
// user as 200 replies, then waited fifteen minutes for receipts that could never come.
|
|
932
|
+
async #respond(statement, schemeCtx, origin, workerId, loopId) {
|
|
933
|
+
if (origin === "model") {
|
|
934
|
+
const heading = this.#operationHeading(statement.body?.raw ?? "", schemeCtx);
|
|
935
|
+
if (heading !== null) {
|
|
936
|
+
return _a.#failure("send-looks-like-operation", 400, `The response begins with the operation heading \`${heading}\`; nothing ran and nothing was delivered.`, {}, {
|
|
937
|
+
heading,
|
|
938
|
+
stage: "dispatch",
|
|
939
|
+
recovery: `An operation goes on the fence line (\`\`\`\`${heading}); a quoted example goes inside a SEND body.`,
|
|
940
|
+
retryable: false,
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
return { status: 200, recipients: await this.#activePrompts(workerId, loopId) };
|
|
945
|
+
}
|
|
946
|
+
// The first non-blank line, when it parses alone as one clean heading naming an operation
|
|
947
|
+
// this worker could perform: a Plurnk operation, or a registered executor or MCP service.
|
|
948
|
+
#operationHeading(body, schemeCtx) {
|
|
949
|
+
const line = body.split("\n").find((candidate) => candidate.trim().length > 0)?.trim();
|
|
950
|
+
if (line === undefined || line.startsWith("`"))
|
|
951
|
+
return null;
|
|
952
|
+
const parsed = PlurnkParser.parseStatements(PlurnkParser.frame(line, null), {
|
|
953
|
+
executors: schemeCtx.executors?.availableRuntimes(schemeCtx.workspaceId) ?? [],
|
|
954
|
+
});
|
|
955
|
+
if (parsed.unparsedTail !== undefined || parsed.items.length !== 1 || parsed.items[0].kind !== "statement")
|
|
956
|
+
return null;
|
|
957
|
+
const { statement } = parsed.items[0];
|
|
958
|
+
// {§naked-pattern} lifts prose after the path on FIND, READ and KILL as a literal matcher;
|
|
959
|
+
// on a reply's first line a multi-word literal is prose, not a mis-fenced operation.
|
|
960
|
+
if ("matcher" in statement && statement.matcher?.dialect === "glob" && /\s/u.test(statement.matcher.raw))
|
|
961
|
+
return null;
|
|
962
|
+
if (statement.op !== "EXEC")
|
|
963
|
+
return line;
|
|
964
|
+
const executor = statement.executor;
|
|
965
|
+
if (executor === null || schemeCtx.executors?.entry(executor, schemeCtx.workspaceId) === undefined)
|
|
966
|
+
return null;
|
|
967
|
+
return line;
|
|
968
|
+
}
|
|
969
|
+
// The loop's Active Prompts, oldest first, exactly as the packet lists them.
|
|
970
|
+
async #activePrompts(workerId, loopId) {
|
|
971
|
+
const worker = await this.#db.worker_get.get({ id: workerId });
|
|
972
|
+
if (worker === undefined)
|
|
973
|
+
throw new Error(`worker ${workerId} does not exist`);
|
|
974
|
+
const loopSeq = (await this.#db.engine_loop_sequence.get({ loop_id: loopId }))?.sequence ?? loopId;
|
|
975
|
+
const prefix = promptLoopPrefix(loopSeq);
|
|
976
|
+
const rows = await this.#db.drain_get_all_prompt_bodies_for_loop.all({
|
|
977
|
+
worker_id: workerId,
|
|
978
|
+
pattern: `${prefix}%`,
|
|
979
|
+
prefix_len: prefix.length,
|
|
980
|
+
});
|
|
981
|
+
return rows.map((row) => `prompt://${worker.name}${row.pathname}`);
|
|
982
|
+
}
|
|
983
|
+
async #isOwnPromptAddress(target, workerId, loopId) {
|
|
984
|
+
if (target === null || target.kind !== "url" || target.scheme !== "prompt")
|
|
985
|
+
return false;
|
|
986
|
+
const worker = await this.#db.worker_get.get({ id: workerId });
|
|
987
|
+
if (worker === undefined || target.hostname !== worker.name)
|
|
988
|
+
return false;
|
|
989
|
+
const loopSeq = (await this.#db.engine_loop_sequence.get({ loop_id: loopId }))?.sequence ?? loopId;
|
|
990
|
+
return target.pathname.startsWith(promptLoopPrefix(loopSeq));
|
|
991
|
+
}
|
|
992
|
+
// {§send-premature-terminate} The pending set is judged at TASK's dispatch point,
|
|
993
|
+
// after earlier operations have executed. Every non-SEND/TASK/KILL model operation
|
|
994
|
+
// requires a new packet, independently of its result or log visibility.
|
|
832
995
|
async #pendingSet(workerId, turnId) {
|
|
833
996
|
const pending = [];
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
if (
|
|
997
|
+
// {§worker-obligations} — the stream and child legs are one durable row.
|
|
998
|
+
const held = await this.#db.worker_live_obligations.get({ worker_id: workerId });
|
|
999
|
+
if (held === undefined)
|
|
1000
|
+
throw new Error(`worker ${workerId} does not exist`);
|
|
1001
|
+
if (held.streams === 1)
|
|
839
1002
|
pending.push("streams");
|
|
840
|
-
|
|
841
|
-
if (liveChild !== undefined)
|
|
1003
|
+
if (held.workers === 1)
|
|
842
1004
|
pending.push("workers");
|
|
843
1005
|
const boundaries = await this.#nextPacketBoundaries(workerId, turnId);
|
|
844
|
-
|
|
1006
|
+
const receipts = [...new Set(boundaries.operations
|
|
1007
|
+
.filter(({ op }) => op !== "KILL")
|
|
1008
|
+
.map((row) => LogEntryProjection.leaf(row)))];
|
|
1009
|
+
if (boundaries.streamTerminations.length > 0)
|
|
1010
|
+
receipts.push("stream completion");
|
|
1011
|
+
if (receipts.length > 0)
|
|
845
1012
|
pending.push("receipts");
|
|
846
|
-
//
|
|
847
|
-
// success is legitimate and its output stays in the Log. A failed close is an unseen
|
|
848
|
-
// failure — named exactly (bench#5 requiem #9) so the model reads it, not guesses.
|
|
1013
|
+
// The final-strike escape hatch cannot discard an unobserved failure.
|
|
849
1014
|
if (boundaries.streamTerminations.some(({ closeStatus }) => closeStatus >= 400))
|
|
850
1015
|
pending.push("failed-stream-results");
|
|
851
1016
|
if (boundaries.childTerminations)
|
|
852
1017
|
pending.push("worker-results");
|
|
853
|
-
return pending;
|
|
1018
|
+
return { pending, receipts };
|
|
854
1019
|
}
|
|
855
|
-
//
|
|
856
|
-
// successful log-curation effects likewise become useful through the curated next packet.
|
|
857
|
-
// Keep every next-packet boundary in one classifier while letting the callers apply
|
|
858
|
-
// their distinct contracts: retrievals block explicit completion, whereas log curation only
|
|
859
|
-
// prevents an empty wait from being inferred as completion.
|
|
1020
|
+
// {§wait-obligation-matrix}: completion and an empty wait use the same execution evidence.
|
|
860
1021
|
async #nextPacketBoundaries(workerId, turnId) {
|
|
861
1022
|
const [turnBoundaries, streamTerminations, childTermination] = await Promise.all([
|
|
862
1023
|
this.#db.engine_turn_packet_boundaries.all({ turn_id: turnId }),
|
|
@@ -866,10 +1027,7 @@ class Dispatcher {
|
|
|
866
1027
|
.get({ worker_id: workerId }),
|
|
867
1028
|
]);
|
|
868
1029
|
return {
|
|
869
|
-
|
|
870
|
-
// blocks an explicit (TERM); every other boundary row is a retrieval receipt.
|
|
871
|
-
retrievals: turnBoundaries.some(({ op }) => op !== "KILL"),
|
|
872
|
-
curations: turnBoundaries.some(({ op }) => op === "KILL"),
|
|
1030
|
+
operations: turnBoundaries,
|
|
873
1031
|
streamTerminations,
|
|
874
1032
|
childTerminations: childTermination !== undefined,
|
|
875
1033
|
};
|
|
@@ -883,25 +1041,18 @@ class Dispatcher {
|
|
|
883
1041
|
return failedRows.length;
|
|
884
1042
|
}
|
|
885
1043
|
static #unobservedFailures(failCount) {
|
|
886
|
-
return _a.#failure("unobserved-failures", 409, `
|
|
1044
|
+
return _a.#failure("unobserved-failures", 409, `Completion deferred: ${failCount} operation${failCount === 1 ? "" : "s"} failed in the same turn. The failure${failCount === 1 ? " is" : "s are"} in this packet; address ${failCount === 1 ? "it" : "them"} or complete with a TASK now.`, {}, {
|
|
887
1045
|
failures: failCount,
|
|
888
1046
|
stage: "completion",
|
|
889
|
-
retryable:
|
|
1047
|
+
retryable: true,
|
|
890
1048
|
});
|
|
891
1049
|
}
|
|
892
|
-
//
|
|
1050
|
+
// A live obligation to wait on: a spawned child or an open stream (not retrievals, which land
|
|
893
1051
|
// next turn regardless). The wait-side twin of #pendingSet's stream+child legs ({§wait-obligation-matrix}).
|
|
894
1052
|
async hasLiveWork(workerId) {
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
.filter(({ id }) => execHandler?.isDetachedSpawn?.(id) !== true);
|
|
899
|
-
if (openSubs.length > 0)
|
|
900
|
-
return true;
|
|
901
|
-
if (execHandler?.hasActiveSpawns?.(workerId) === true)
|
|
902
|
-
return true;
|
|
903
|
-
const liveChild = await this.#db.engine_worker_has_live_child.get({ worker_id: workerId });
|
|
904
|
-
return liveChild !== undefined;
|
|
1053
|
+
// {§worker-obligations} — one durable row answers both legs.
|
|
1054
|
+
const held = await this.#db.worker_live_obligations.get({ worker_id: workerId });
|
|
1055
|
+
return held !== undefined && (held.streams === 1 || held.workers === 1);
|
|
905
1056
|
}
|
|
906
1057
|
async #runLogCuration(statement, ctx, admittedMaxId) {
|
|
907
1058
|
const addressedScheme = schemeNameOf(statement.target);
|
|
@@ -926,27 +1077,26 @@ class Dispatcher {
|
|
|
926
1077
|
if (maxId === undefined) {
|
|
927
1078
|
throw new Error(`log selection boundary could not be resolved for worker ${ctx.workerId}`);
|
|
928
1079
|
}
|
|
929
|
-
const schemeCtx = new SchemeCtxImpl(ctx, "log", manifest, this.#liveSubscriptions, {
|
|
1080
|
+
const schemeCtx = new SchemeCtxImpl(ctx, "log", manifest, this.#liveSubscriptions, {});
|
|
930
1081
|
const outcome = await handler.curate(statement, schemeCtx, maxId);
|
|
931
1082
|
return { result: Results.assert(outcome.result), plan: outcome.plan };
|
|
932
1083
|
}
|
|
933
|
-
// {§proposal}/{§send} —
|
|
934
|
-
// SEND signal 202, which parks the loop. The operation disambiguates the status.
|
|
1084
|
+
// {§proposal}/{§send} — native dispositions park; other 202 results propose.
|
|
935
1085
|
static #isProposal(statement, result) {
|
|
936
1086
|
if (result.status !== 202)
|
|
937
1087
|
return false;
|
|
938
|
-
return !(statement
|
|
1088
|
+
return !TurnDisposition.is(statement);
|
|
939
1089
|
}
|
|
940
1090
|
// Normalize a parsed target for log storage. Bare paths and `file:///...`
|
|
941
1091
|
// inputs collapse to scheme=null in log target metadata because both render
|
|
942
1092
|
// as bare paths. Addressable file entries separately persist under the
|
|
943
1093
|
// reserved `file` identity scheme ({§entry-identity-no-null}).
|
|
944
|
-
#extractTarget(path,
|
|
1094
|
+
#extractTarget(path, workspaceId) {
|
|
945
1095
|
if (path === null)
|
|
946
1096
|
return { scheme: null, username: null, password: null, hostname: null, port: null, pathname: null, query: null, fragment: null };
|
|
947
1097
|
// `local` (bare path) carries no URL parts — store the raw text as the pathname for the log record, scheme=null.
|
|
948
1098
|
if (path.kind === "local")
|
|
949
|
-
return { scheme: null, username: null, password: null, hostname: null, port: null, pathname: PathSyntax.decodeParens(path.raw), query: null, fragment: null }; // {§path-parentheses}
|
|
1099
|
+
return { scheme: null, username: null, password: null, hostname: null, port: null, pathname: PathSyntax.decodeParens(path.raw), query: null, fragment: path.fragment ?? null }; // {§path-parentheses} {§local-path-fragment}
|
|
950
1100
|
const scheme = path.scheme === "file" ? null : path.scheme;
|
|
951
1101
|
// The registered scheme owns authority disposition. Namespace authority
|
|
952
1102
|
// is path syntax; resource and owner authorities remain explicit in the
|
|
@@ -954,7 +1104,7 @@ class Dispatcher {
|
|
|
954
1104
|
const routedScheme = schemeNameOf(path);
|
|
955
1105
|
const manifest = routedScheme === null
|
|
956
1106
|
? undefined
|
|
957
|
-
: this.#schemes.manifestFor(routedScheme,
|
|
1107
|
+
: this.#schemes.manifestFor(routedScheme, workspaceId);
|
|
958
1108
|
const foldNs = scheme !== null
|
|
959
1109
|
&& manifest !== undefined
|
|
960
1110
|
&& (manifest.authority ?? "namespace") === "namespace";
|