@plurnk/plurnk-service 1.3.12 → 1.4.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 +84 -77
- package/INSTALL.md +50 -25
- package/README.md +24 -10
- package/SPEC.md +2311 -928
- package/dist/Paths.d.ts +4 -1
- package/dist/Paths.d.ts.map +1 -1
- package/dist/Paths.js +23 -21
- package/dist/Paths.js.map +1 -1
- package/dist/build-info.json +1 -1
- package/dist/content/edit-receipt.d.ts +13 -28
- package/dist/content/edit-receipt.d.ts.map +1 -1
- package/dist/content/edit-receipt.js +285 -104
- package/dist/content/edit-receipt.js.map +1 -1
- package/dist/content/edited-span.d.ts.map +1 -1
- package/dist/content/edited-span.js +2 -5
- package/dist/content/edited-span.js.map +1 -1
- package/dist/content/index.d.ts +3 -3
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +1 -1
- package/dist/content/index.js.map +1 -1
- package/dist/content/line-marker.d.ts +6 -9
- package/dist/content/line-marker.d.ts.map +1 -1
- package/dist/content/line-marker.js +7 -11
- package/dist/content/line-marker.js.map +1 -1
- package/dist/content/matcher.d.ts +14 -25
- package/dist/content/matcher.d.ts.map +1 -1
- package/dist/content/matcher.js +77 -107
- package/dist/content/matcher.js.map +1 -1
- package/dist/content/mimetype-binary.d.ts +2 -2
- package/dist/content/mimetype-binary.d.ts.map +1 -1
- package/dist/content/mimetype-binary.js +10 -10
- package/dist/content/mimetype-binary.js.map +1 -1
- package/dist/content/path-mimetype.js +3 -3
- package/dist/content/path-mimetype.js.map +1 -1
- package/dist/content/read-resolve.d.ts +8 -4
- package/dist/content/read-resolve.d.ts.map +1 -1
- package/dist/content/read-resolve.js +101 -49
- package/dist/content/read-resolve.js.map +1 -1
- package/dist/core/BranchReceipt.d.ts +7 -0
- package/dist/core/BranchReceipt.d.ts.map +1 -0
- package/dist/core/BranchReceipt.js +27 -0
- package/dist/core/BranchReceipt.js.map +1 -0
- package/dist/core/BudgetOverflow.d.ts +23 -0
- package/dist/core/BudgetOverflow.d.ts.map +1 -0
- package/dist/core/BudgetOverflow.js +61 -0
- package/dist/core/BudgetOverflow.js.map +1 -0
- package/dist/core/BudgetReadout.d.ts +8 -0
- package/dist/core/BudgetReadout.d.ts.map +1 -0
- package/dist/core/BudgetReadout.js +79 -0
- package/dist/core/BudgetReadout.js.map +1 -0
- package/dist/core/ChannelWrite.d.ts +28 -9
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/ChannelWrite.js +28 -21
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/ChannelWrite.sql +11 -10
- package/dist/core/CoreSchemeServices.d.ts +10 -4
- package/dist/core/CoreSchemeServices.d.ts.map +1 -1
- package/dist/core/CoreSchemeServices.js +7 -1
- package/dist/core/CoreSchemeServices.js.map +1 -1
- package/dist/core/Dispatcher.d.ts +29 -20
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +1488 -599
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/DurableStatement.d.ts +6 -0
- package/dist/core/DurableStatement.d.ts.map +1 -0
- package/dist/core/DurableStatement.js +51 -0
- package/dist/core/DurableStatement.js.map +1 -0
- package/dist/core/Engine.d.ts +48 -20
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +1208 -789
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +309 -217
- package/dist/core/EnvFlags.js +1 -1
- package/dist/core/EnvFlags.js.map +1 -1
- package/dist/core/ErrorDetail.d.ts +6 -0
- package/dist/core/ErrorDetail.d.ts.map +1 -0
- package/dist/core/ErrorDetail.js +20 -0
- package/dist/core/ErrorDetail.js.map +1 -0
- package/dist/core/ExecutorRegistry.d.ts +14 -3
- package/dist/core/ExecutorRegistry.d.ts.map +1 -1
- package/dist/core/ExecutorRegistry.js +56 -30
- package/dist/core/ExecutorRegistry.js.map +1 -1
- package/dist/core/GitBranch.d.ts +20 -0
- package/dist/core/GitBranch.d.ts.map +1 -0
- package/dist/core/GitBranch.js +110 -0
- package/dist/core/GitBranch.js.map +1 -0
- package/dist/core/JournalTurn.d.ts +9 -0
- package/dist/core/JournalTurn.d.ts.map +1 -0
- package/dist/core/JournalTurn.js +14 -0
- package/dist/core/JournalTurn.js.map +1 -0
- package/dist/core/JournalTurn.sql +10 -0
- package/dist/core/LogBody.d.ts +17 -0
- package/dist/core/LogBody.d.ts.map +1 -0
- package/dist/core/LogBody.js +148 -0
- package/dist/core/LogBody.js.map +1 -0
- package/dist/core/LoopFlagsReader.d.ts +7 -0
- package/dist/core/LoopFlagsReader.d.ts.map +1 -0
- package/dist/core/LoopFlagsReader.js +33 -0
- package/dist/core/LoopFlagsReader.js.map +1 -0
- package/dist/core/LoopLifecycle.d.ts +8 -1
- package/dist/core/LoopLifecycle.d.ts.map +1 -1
- package/dist/core/LoopLifecycle.js +55 -9
- package/dist/core/LoopLifecycle.js.map +1 -1
- package/dist/core/LoopLifecycle.sql +9 -3
- package/dist/core/NoticeChannel.d.ts +13 -0
- package/dist/core/NoticeChannel.d.ts.map +1 -0
- package/dist/core/NoticeChannel.js +40 -0
- package/dist/core/NoticeChannel.js.map +1 -0
- package/dist/core/Owner.d.ts +0 -1
- package/dist/core/Owner.d.ts.map +1 -1
- package/dist/core/Owner.js +2 -5
- package/dist/core/Owner.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts +25 -24
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +313 -375
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/ProblemLog.d.ts +26 -0
- package/dist/core/ProblemLog.d.ts.map +1 -0
- package/dist/core/ProblemLog.js +58 -0
- package/dist/core/ProblemLog.js.map +1 -0
- package/dist/core/ProposalLifecycle.d.ts +15 -21
- package/dist/core/ProposalLifecycle.d.ts.map +1 -1
- package/dist/core/ProposalLifecycle.js +291 -78
- package/dist/core/ProposalLifecycle.js.map +1 -1
- package/dist/core/ProviderInstantiate.d.ts.map +1 -1
- package/dist/core/ProviderInstantiate.js +51 -48
- package/dist/core/ProviderInstantiate.js.map +1 -1
- package/dist/core/SchemeRegistry.d.ts +14 -8
- package/dist/core/SchemeRegistry.d.ts.map +1 -1
- package/dist/core/SchemeRegistry.js +189 -114
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/ServiceTeardown.d.ts +11 -0
- package/dist/core/ServiceTeardown.d.ts.map +1 -0
- package/dist/core/ServiceTeardown.js +70 -0
- package/dist/core/ServiceTeardown.js.map +1 -0
- package/dist/core/StoredPacket.d.ts +29 -0
- package/dist/core/StoredPacket.d.ts.map +1 -0
- package/dist/core/StoredPacket.js +147 -0
- package/dist/core/StoredPacket.js.map +1 -0
- package/dist/core/StrikeRail.d.ts +1 -2
- package/dist/core/StrikeRail.d.ts.map +1 -1
- package/dist/core/StrikeRail.js +25 -55
- package/dist/core/StrikeRail.js.map +1 -1
- package/dist/core/WorkerControlAddress.d.ts +17 -0
- package/dist/core/WorkerControlAddress.d.ts.map +1 -0
- package/dist/core/WorkerControlAddress.js +44 -0
- package/dist/core/WorkerControlAddress.js.map +1 -0
- package/dist/core/WorkerName.d.ts +31 -0
- package/dist/core/WorkerName.d.ts.map +1 -0
- package/dist/core/WorkerName.js +95 -0
- package/dist/core/WorkerName.js.map +1 -0
- package/dist/core/WorkerName.sql +36 -0
- package/dist/core/WorkspaceGate.d.ts +14 -0
- package/dist/core/WorkspaceGate.d.ts.map +1 -0
- package/dist/core/WorkspaceGate.js +155 -0
- package/dist/core/WorkspaceGate.js.map +1 -0
- package/dist/core/caps/CapsResolve.d.ts +1 -1
- package/dist/core/caps/CapsResolve.d.ts.map +1 -1
- package/dist/core/caps/CapsResolve.js.map +1 -1
- package/dist/core/caps/DbChannelCaps.d.ts +5 -11
- package/dist/core/caps/DbChannelCaps.d.ts.map +1 -1
- package/dist/core/caps/DbChannelCaps.js +24 -8
- package/dist/core/caps/DbChannelCaps.js.map +1 -1
- package/dist/core/caps/DbEntryCaps.d.ts +4 -13
- package/dist/core/caps/DbEntryCaps.d.ts.map +1 -1
- package/dist/core/caps/DbEntryCaps.js +15 -6
- 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 +12 -11
- package/dist/core/caps/DbNotifyCaps.js.map +1 -1
- package/dist/core/caps/DbProjectionCaps.d.ts +5 -5
- package/dist/core/caps/DbProjectionCaps.d.ts.map +1 -1
- package/dist/core/caps/DbProjectionCaps.js +21 -4
- package/dist/core/caps/DbProjectionCaps.js.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.d.ts +4 -4
- package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.js +57 -62
- package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
- package/dist/core/caps/DbTagCaps.d.ts +5 -12
- package/dist/core/caps/DbTagCaps.d.ts.map +1 -1
- package/dist/core/caps/DbTagCaps.js +14 -7
- package/dist/core/caps/DbTagCaps.js.map +1 -1
- package/dist/core/content-hash.js +1 -1
- package/dist/core/content-hash.js.map +1 -1
- package/dist/core/env-defaults.d.ts.map +1 -1
- package/dist/core/env-defaults.js.map +1 -1
- package/dist/core/fork.d.ts.map +1 -1
- package/dist/core/fork.js +55 -30
- package/dist/core/fork.js.map +1 -1
- package/dist/core/fork.sql +41 -27
- package/dist/core/git-env.d.ts +2 -0
- package/dist/core/git-env.d.ts.map +1 -1
- package/dist/core/git-env.js +13 -18
- package/dist/core/git-env.js.map +1 -1
- package/dist/core/git-iso.d.ts.map +1 -1
- package/dist/core/git-iso.js +9 -15
- package/dist/core/git-iso.js.map +1 -1
- package/dist/core/git-membership.d.ts +1 -1
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +198 -146
- 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 +10 -11
- package/dist/core/git-state.js.map +1 -1
- package/dist/core/owner.sql +1 -1
- package/dist/core/packet-inject.d.ts.map +1 -1
- package/dist/core/packet-inject.js +7 -11
- package/dist/core/packet-inject.js.map +1 -1
- package/dist/core/packet-wire.d.ts +2 -20
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +242 -368
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/plurnk-uri.d.ts +12 -1
- package/dist/core/plurnk-uri.d.ts.map +1 -1
- package/dist/core/plurnk-uri.js +49 -29
- package/dist/core/plurnk-uri.js.map +1 -1
- package/dist/core/results.d.ts +16 -5
- package/dist/core/results.d.ts.map +1 -1
- package/dist/core/results.js +27 -18
- package/dist/core/results.js.map +1 -1
- package/dist/core/ruler_count.d.ts +4 -0
- package/dist/core/ruler_count.d.ts.map +1 -0
- package/dist/core/ruler_count.js +7 -0
- package/dist/core/ruler_count.js.map +1 -0
- package/dist/core/scheme-types.d.ts +9 -11
- package/dist/core/scheme-types.d.ts.map +1 -1
- package/dist/core/scheme-types.js.map +1 -1
- package/dist/core/search-gate.d.ts.map +1 -1
- package/dist/core/search-gate.js +3 -11
- package/dist/core/search-gate.js.map +1 -1
- package/dist/core/teaching-corpus.d.ts +6 -0
- package/dist/core/teaching-corpus.d.ts.map +1 -0
- package/dist/core/teaching-corpus.js +23 -0
- package/dist/core/teaching-corpus.js.map +1 -0
- package/dist/core/teaching.d.ts +0 -1
- package/dist/core/teaching.d.ts.map +1 -1
- package/dist/core/teaching.js +2 -8
- package/dist/core/teaching.js.map +1 -1
- package/dist/core/token-ruler.d.ts.map +1 -1
- package/dist/core/token-ruler.js +3 -16
- package/dist/core/token-ruler.js.map +1 -1
- package/dist/core/turn-scheduler.d.ts +1 -1
- package/dist/core/turn-scheduler.d.ts.map +1 -1
- package/dist/core/turn-scheduler.js +1 -1
- package/dist/core/turn-scheduler.js.map +1 -1
- package/dist/core/worker-cap.d.ts +2 -4
- package/dist/core/worker-cap.d.ts.map +1 -1
- package/dist/core/worker-cap.js +13 -4
- package/dist/core/worker-cap.js.map +1 -1
- package/dist/core/{run-ops.sql → worker-ops.sql} +11 -11
- package/dist/core/workspace-settings.d.ts.map +1 -1
- package/dist/core/workspace-settings.js +17 -9
- package/dist/core/workspace-settings.js.map +1 -1
- package/dist/digest/Digest.d.ts +2 -1
- package/dist/digest/Digest.d.ts.map +1 -1
- package/dist/digest/Digest.js +337 -138
- package/dist/digest/Digest.js.map +1 -1
- package/dist/digest/digest.sql +19 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/dist/matrix/live-specimen.d.ts +9 -0
- package/dist/matrix/live-specimen.d.ts.map +1 -0
- package/dist/matrix/live-specimen.js +37 -0
- package/dist/matrix/live-specimen.js.map +1 -0
- package/dist/observe/api.d.ts +6 -0
- package/dist/observe/api.d.ts.map +1 -0
- package/dist/observe/api.js +11 -0
- package/dist/observe/api.js.map +1 -0
- package/dist/observe/init.d.ts +7 -0
- package/dist/observe/init.d.ts.map +1 -0
- package/dist/observe/init.js +159 -0
- package/dist/observe/init.js.map +1 -0
- package/dist/observe/metrics.d.ts +6 -0
- package/dist/observe/metrics.d.ts.map +1 -0
- package/dist/observe/metrics.js +15 -0
- package/dist/observe/metrics.js.map +1 -0
- package/dist/observe/spans.d.ts +4 -0
- package/dist/observe/spans.d.ts.map +1 -0
- package/dist/observe/spans.js +51 -0
- package/dist/observe/spans.js.map +1 -0
- package/dist/schemes/EffectPolicy.d.ts +1 -0
- package/dist/schemes/EffectPolicy.d.ts.map +1 -1
- package/dist/schemes/EffectPolicy.js +5 -2
- package/dist/schemes/EffectPolicy.js.map +1 -1
- package/dist/schemes/Exec.d.ts +6 -11
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +364 -247
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.d.ts +8 -7
- package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +48 -9
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/File.d.ts +7 -11
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +279 -142
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts +4 -8
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +475 -208
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/Log.sql +62 -30
- package/dist/schemes/Prompt.d.ts +3 -2
- package/dist/schemes/Prompt.d.ts.map +1 -1
- package/dist/schemes/Prompt.js +9 -6
- package/dist/schemes/Prompt.js.map +1 -1
- package/dist/schemes/Skill.d.ts +1 -1
- package/dist/schemes/Skill.d.ts.map +1 -1
- package/dist/schemes/Skill.js +2 -3
- package/dist/schemes/Skill.js.map +1 -1
- package/dist/schemes/Worker.d.ts +8 -16
- package/dist/schemes/Worker.d.ts.map +1 -1
- package/dist/schemes/Worker.js +179 -69
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/schemes/_entry-chunk.d.ts.map +1 -1
- package/dist/schemes/_entry-chunk.js +12 -5
- package/dist/schemes/_entry-chunk.js.map +1 -1
- package/dist/schemes/_entry-crud.d.ts +10 -9
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js +59 -13
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-crud.sql +20 -8
- package/dist/schemes/_entry-find.d.ts +20 -15
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +339 -174
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-find.sql +20 -8
- package/dist/schemes/_entry-graph.d.ts +4 -2
- package/dist/schemes/_entry-graph.d.ts.map +1 -1
- package/dist/schemes/_entry-graph.js +55 -31
- package/dist/schemes/_entry-graph.js.map +1 -1
- package/dist/schemes/_entry-graph.sql +37 -22
- package/dist/schemes/_entry-manifest.d.ts +10 -15
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-manifest.js +50 -268
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_entry-ops.d.ts +9 -14
- package/dist/schemes/_entry-ops.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.js +149 -77
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_entry-ops.sql +1 -1
- package/dist/schemes/_entry-semantic.d.ts +23 -8
- package/dist/schemes/_entry-semantic.d.ts.map +1 -1
- package/dist/schemes/_entry-semantic.js +141 -60
- package/dist/schemes/_entry-semantic.js.map +1 -1
- package/dist/schemes/_entry-semantic.sql +63 -45
- package/dist/schemes/_entry-send.d.ts +3 -4
- package/dist/schemes/_entry-send.d.ts.map +1 -1
- package/dist/schemes/_entry-send.js +48 -23
- package/dist/schemes/_entry-send.js.map +1 -1
- package/dist/schemes/_path-scope.d.ts +23 -0
- package/dist/schemes/_path-scope.d.ts.map +1 -0
- package/dist/schemes/_path-scope.js +61 -0
- package/dist/schemes/_path-scope.js.map +1 -0
- package/dist/schemes/_search-candidate.d.ts +20 -0
- package/dist/schemes/_search-candidate.d.ts.map +1 -0
- package/dist/schemes/_search-candidate.js +19 -0
- package/dist/schemes/_search-candidate.js.map +1 -0
- package/dist/schemes/_search-exclusion.d.ts +7 -0
- package/dist/schemes/_search-exclusion.d.ts.map +1 -0
- package/dist/schemes/_search-exclusion.js +23 -0
- package/dist/schemes/_search-exclusion.js.map +1 -0
- package/dist/schemes/_search-index.d.ts +6 -0
- package/dist/schemes/_search-index.d.ts.map +1 -0
- package/dist/schemes/_search-index.js +326 -0
- package/dist/schemes/_search-index.js.map +1 -0
- package/dist/schemes/cosine.js +1 -1
- package/dist/schemes/cosine.js.map +1 -1
- package/dist/schemes/exec-abort.js +3 -3
- package/dist/schemes/exec-abort.js.map +1 -1
- package/dist/schemes/exec-env.js +3 -3
- package/dist/schemes/exec-env.js.map +1 -1
- package/dist/server/BranchBatches.d.ts +48 -0
- package/dist/server/BranchBatches.d.ts.map +1 -0
- package/dist/server/BranchBatches.js +591 -0
- package/dist/server/BranchBatches.js.map +1 -0
- package/dist/server/Daemon.d.ts +36 -66
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +920 -446
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DaemonModule.d.ts +31 -0
- package/dist/server/DaemonModule.d.ts.map +1 -0
- package/dist/server/DaemonModule.js +2 -0
- package/dist/server/DaemonModule.js.map +1 -0
- package/dist/server/branch-batch.sql +152 -0
- package/dist/server/client-input.d.ts +12 -0
- package/dist/server/client-input.d.ts.map +1 -1
- package/dist/server/client-input.js +262 -57
- package/dist/server/client-input.js.map +1 -1
- package/dist/server/dispatch-as-plurnk.d.ts +1 -1
- package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
- package/dist/server/dispatch-as-plurnk.js +15 -7
- package/dist/server/dispatch-as-plurnk.js.map +1 -1
- package/dist/server/drain.sql +92 -62
- package/dist/server/envelope.d.ts +2 -5
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +119 -95
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/envelope.sql +19 -23
- package/dist/server/exec-poll-backoff.js +1 -1
- package/dist/server/exec-poll-backoff.js.map +1 -1
- package/dist/server/lifecycle-recovery.sql +79 -2
- package/dist/server/logEntry.d.ts +3 -1
- package/dist/server/logEntry.d.ts.map +1 -1
- package/dist/server/logEntry.js +4 -2
- package/dist/server/logEntry.js.map +1 -1
- package/dist/server/logEntry.sql +1 -1
- package/dist/server/loop-model.d.ts.map +1 -1
- package/dist/server/loop-model.js +22 -9
- package/dist/server/loop-model.js.map +1 -1
- package/dist/server/loopDocs.d.ts.map +1 -1
- package/dist/server/loopDocs.js +5 -4
- package/dist/server/loopDocs.js.map +1 -1
- package/dist/server/seam-entry-read.sql +15 -10
- package/dist/server/seam-log-read.sql +2 -2
- package/dist/server/seam-loop.sql +1 -1
- package/dist/server/seam-proposal-list.sql +17 -7
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +66 -60
- package/dist/service.js.map +1 -1
- package/migrations/001_schema.sql +897 -0
- package/package.json +57 -26
- package/dist/core/PluginLoader.d.ts +0 -20
- package/dist/core/PluginLoader.d.ts.map +0 -1
- package/dist/core/PluginLoader.js +0 -142
- package/dist/core/PluginLoader.js.map +0 -1
- package/dist/core/TelemetryChannel.d.ts +0 -37
- package/dist/core/TelemetryChannel.d.ts.map +0 -1
- package/dist/core/TelemetryChannel.js +0 -80
- package/dist/core/TelemetryChannel.js.map +0 -1
- package/dist/core/path-decode.d.ts +0 -3
- package/dist/core/path-decode.d.ts.map +0 -1
- package/dist/core/path-decode.js +0 -9
- package/dist/core/path-decode.js.map +0 -1
- package/dist/core/plugin-attribution.d.ts +0 -5
- package/dist/core/plugin-attribution.d.ts.map +0 -1
- package/dist/core/plugin-attribution.js +0 -39
- package/dist/core/plugin-attribution.js.map +0 -1
- package/dist/core/world-state.d.ts +0 -10
- package/dist/core/world-state.d.ts.map +0 -1
- package/dist/core/world-state.js +0 -35
- package/dist/core/world-state.js.map +0 -1
- package/dist/core/world-state.sql +0 -35
- package/dist/core/zero-pin.d.ts +0 -3
- package/dist/core/zero-pin.d.ts.map +0 -1
- package/dist/core/zero-pin.js +0 -16
- package/dist/core/zero-pin.js.map +0 -1
- package/dist/server/auto.d.ts +0 -6
- package/dist/server/auto.d.ts.map +0 -1
- package/dist/server/auto.js +0 -63
- package/dist/server/auto.js.map +0 -1
- package/dist/server/clientTurn.d.ts +0 -6
- package/dist/server/clientTurn.d.ts.map +0 -1
- package/dist/server/clientTurn.js +0 -22
- package/dist/server/clientTurn.js.map +0 -1
- package/dist/server/clientTurn.sql +0 -10
- package/dist/server/noProposals.d.ts +0 -6
- package/dist/server/noProposals.d.ts.map +0 -1
- package/dist/server/noProposals.js +0 -37
- package/dist/server/noProposals.js.map +0 -1
- package/dist/server/version-info.d.ts +0 -14
- package/dist/server/version-info.d.ts.map +0 -1
- package/dist/server/version-info.js +0 -69
- package/dist/server/version-info.js.map +0 -1
- package/migrations/0000-00-00.01_schema.sql +0 -536
- package/migrations/0004_loop-provider.sql +0 -3
- package/migrations/0005_subscription-published-channel.sql +0 -3
- package/migrations/0006_loop-max-turns.sql +0 -3
package/dist/schemes/Log.js
CHANGED
|
@@ -1,46 +1,36 @@
|
|
|
1
|
+
import { PathSyntax, } from "@plurnk/plurnk-contracts";
|
|
1
2
|
import { LineMarkerOps } from "../content/index.js";
|
|
2
3
|
import { ReadResolve } from "../content/index.js";
|
|
3
4
|
import Matcher from "../content/matcher.js";
|
|
5
|
+
import { renderFindContent } from "./_entry-find.js";
|
|
4
6
|
import { CoreSchemeAdapterBase } from "../core/CoreSchemeServices.js";
|
|
7
|
+
import Results from "../core/results.js";
|
|
8
|
+
import LogBody from "../core/LogBody.js";
|
|
9
|
+
import EntrySemantic from "./_entry-semantic.js";
|
|
10
|
+
import EntryGraph from "./_entry-graph.js";
|
|
11
|
+
import { resolveSearchCandidates } from "./_search-candidate.js";
|
|
12
|
+
import { pathFolderSummaries, pathScope, pathScopeMatches } from "./_path-scope.js";
|
|
5
13
|
// log:///<loop_seq>/<turn_seq>/<sequence>[/<op>] — the trailing /op segment
|
|
6
14
|
// is wire-rendering self-documentation derived from the row's `op` field;
|
|
7
15
|
// parsing accepts it (or omits it) and identifies the row by coordinate. The op
|
|
8
16
|
// suffix is case-INSENSITIVE: model ops render UPPERCASE (READ/EDIT/FIND) but the
|
|
9
|
-
// engine-minted rows are lowercase (`error`, `model`), and
|
|
10
|
-
// a `[A-Z]+`-only suffix silently rejected FOLD(log:///1/6/2/error), so the model
|
|
11
|
-
// could not reclaim budget by folding its own error rows and spiralled to 413 (jumbo).
|
|
17
|
+
// engine-minted rows are lowercase (`error`, `model`), and both are curatable.
|
|
12
18
|
const COORDINATE = /^(\d+)\/(\d+)\/(\d+)(?:\/([A-Za-z]+))?$/;
|
|
13
|
-
// §log-coordinate-hierarchy — a log coordinate is a HIERARCHICAL PREFIX: `1` selects loop 1's rows,
|
|
19
|
+
// {§log-coordinate-hierarchy} — a log coordinate is a HIERARCHICAL PREFIX: `1` selects loop 1's rows,
|
|
14
20
|
// `1/2` turn 1/2's rows, `1/2/3` the one row. A full coordinate is always 3 parts, so a 1- or 2-part
|
|
15
21
|
// path is unambiguously a prefix — the trailing slash is OPTIONAL (`log:///1/2` ≡ `log:///1/2/`).
|
|
16
22
|
const PARTIAL_COORDINATE = /^\d+(?:\/\d+)?\/?$/;
|
|
17
|
-
//
|
|
18
|
-
// (§find-source-agnostic: the matcher must see exactly the content the model can retrieve).
|
|
19
|
-
// rx.content (with its own mimetype) when the op produced a body; the rx itself as compact JSON
|
|
20
|
-
// otherwise (EDIT/SEND acks — inspectable, matchable); the raw string if the rx isn't JSON.
|
|
21
|
-
const rxProjection = (rawRx) => {
|
|
22
|
-
try {
|
|
23
|
-
const rx = JSON.parse(rawRx);
|
|
24
|
-
if (typeof rx.content === "string") {
|
|
25
|
-
return { content: rx.content, mimetype: typeof rx.mimetype === "string" ? rx.mimetype : "text/plain" };
|
|
26
|
-
}
|
|
27
|
-
return { content: JSON.stringify(rx), mimetype: "application/json" };
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return { content: rawRx, mimetype: "text/plain" };
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
// A log target pathname → the coordinate GLOB it scopes (§log-coordinate-hierarchy): a partial
|
|
23
|
+
// A log target pathname → the coordinate GLOB it scopes ({§log-coordinate-hierarchy}): a partial
|
|
34
24
|
// coordinate (`1`, `1/2`, with or without slash) is a prefix over its descendants; a trailing
|
|
35
25
|
// slash is the folder idiom; a full coordinate/glob passes through. null = malformed.
|
|
36
26
|
const coordinateGlob = (pathname) => {
|
|
37
27
|
if (pathname === "")
|
|
38
|
-
return "
|
|
28
|
+
return "**";
|
|
39
29
|
if (pathname.endsWith("/"))
|
|
40
|
-
return `${pathname}
|
|
30
|
+
return `${pathname}**`;
|
|
41
31
|
if (PARTIAL_COORDINATE.test(pathname))
|
|
42
|
-
return `${pathname}
|
|
43
|
-
if (parseCoordinate(pathname) !== null ||
|
|
32
|
+
return `${pathname}/**`;
|
|
33
|
+
if (parseCoordinate(pathname) !== null || PathSyntax.hasGlob(pathname))
|
|
44
34
|
return pathname;
|
|
45
35
|
return null;
|
|
46
36
|
};
|
|
@@ -54,35 +44,20 @@ const parseCoordinate = (pathname) => {
|
|
|
54
44
|
sequence: Number(match[3]),
|
|
55
45
|
};
|
|
56
46
|
};
|
|
57
|
-
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (first === 0 || first === -1)
|
|
64
|
-
return { status: 200, items: [] };
|
|
65
|
-
if (first > 0 && first <= total)
|
|
66
|
-
return { status: 200, items: [items[first - 1]] };
|
|
67
|
-
return { status: 416 };
|
|
68
|
-
}
|
|
69
|
-
const n = first === 0 ? 1 : first;
|
|
70
|
-
const m = last === -1 ? total : last;
|
|
71
|
-
if (n < 1 || n > total || m < 1 || m > total || n > m)
|
|
72
|
-
return { status: 416 };
|
|
73
|
-
return { status: 200, items: items.slice(n - 1, m) };
|
|
74
|
-
};
|
|
47
|
+
const canonicalCoordinate = (coordinate) => coordinate.replace(/\/[A-Za-z]+$/, "");
|
|
48
|
+
// A rendered log path appends `/OP` to the canonical loop/turn/item coordinate
|
|
49
|
+
// as self-documentation. Selection honors both views: ordinary path globs map
|
|
50
|
+
// the three-level resource tree, while an explicit OP segment can still filter
|
|
51
|
+
// rows (`log:///**/READ`).
|
|
52
|
+
const coordinateScopeMatches = (scope, coordinate) => pathScopeMatches(scope, coordinate) || pathScopeMatches(scope, canonicalCoordinate(coordinate));
|
|
75
53
|
export default class Log extends CoreSchemeAdapterBase {
|
|
76
54
|
static manifest = {
|
|
77
55
|
name: "log",
|
|
78
56
|
channels: {}, // logs render through read(), not channel storage
|
|
79
57
|
defaultChannel: "",
|
|
80
58
|
category: "logging",
|
|
81
|
-
|
|
82
|
-
//
|
|
83
|
-
// model's DB-storage curation lever (plurnk.md:10/:47 + the OP×resource matrix; §model-entry-log-curation).
|
|
84
|
-
// The model clears the gate; Log's handler surface (kill only — no edit/writeEntry) is the
|
|
85
|
-
// op-level truth, so every other mutating op still 501s.
|
|
59
|
+
// Log KILL is model-authorized curation. Other mutations remain unavailable
|
|
60
|
+
// because Log exposes no edit/writeEntry handler. {§model-entry-log-curation}
|
|
86
61
|
writableBy: ["plurnk", "model"],
|
|
87
62
|
volatile: false,
|
|
88
63
|
modelVisible: true,
|
|
@@ -92,106 +67,286 @@ export default class Log extends CoreSchemeAdapterBase {
|
|
|
92
67
|
async read(statement, ctx) {
|
|
93
68
|
const core = this.coreContext(ctx);
|
|
94
69
|
const { db, workerId } = core;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
70
|
+
const failure = (code, status, detail, extensions = {}) => Results.failure("scheme:log", code, status, detail, { content: null, mimetype: null }, extensions);
|
|
71
|
+
if (statement.target === null) {
|
|
72
|
+
return failure("read-target-required", 400, "READ requires a log coordinate.", {
|
|
73
|
+
recovery: "Provide one exact log coordinate.",
|
|
74
|
+
retryable: false,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// READ is exact — one coordinate, one row. Tag recall is OPEN[tag]/FIND[tag]'s job ({§log-region-tagging}),
|
|
98
78
|
// not a filter on a single-row read.
|
|
99
79
|
if (Array.isArray(statement.signal) && statement.signal.length > 0) {
|
|
100
|
-
return
|
|
80
|
+
return failure("tagged-coordinate-not-found", 404, "The exact log row does not carry every requested tag.", {
|
|
81
|
+
recovery: "Remove the tag filter or use a log row carrying those tags.",
|
|
82
|
+
retryable: false,
|
|
83
|
+
});
|
|
101
84
|
}
|
|
102
85
|
const pathname = (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
|
|
103
86
|
const coord = parseCoordinate(pathname);
|
|
104
|
-
if (coord === null)
|
|
105
|
-
return
|
|
87
|
+
if (coord === null) {
|
|
88
|
+
return failure("coordinate-malformed", 400, `The log coordinate '${pathname}' is malformed.`, {
|
|
89
|
+
target: pathname,
|
|
90
|
+
recovery: "Use one exact loop/turn/sequence coordinate.",
|
|
91
|
+
retryable: false,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
106
94
|
const row = await db.log_read_by_coordinate.get({ worker_id: workerId, loop_seq: coord.loopSeq, turn_seq: coord.turnSeq, sequence: coord.sequence });
|
|
107
95
|
if (row === undefined)
|
|
108
|
-
return
|
|
109
|
-
const { content: underlyingContent, mimetype: underlyingMimetype } =
|
|
110
|
-
|
|
96
|
+
return failure("entry-not-found", 404, `No log entry exists at log:///${pathname}.`);
|
|
97
|
+
const { content: underlyingContent, mimetype: underlyingMimetype } = LogBody.resolve({
|
|
98
|
+
op: row.op,
|
|
99
|
+
tx: row.tx,
|
|
100
|
+
rx: row.rx,
|
|
101
|
+
mimetypeTx: row.mimetype_tx,
|
|
102
|
+
mimetypeRx: row.mimetype_rx,
|
|
103
|
+
});
|
|
104
|
+
const resolved = await ReadResolve.resolve({
|
|
111
105
|
content: underlyingContent,
|
|
112
106
|
mimetype: underlyingMimetype,
|
|
113
107
|
lineMarker: statement.lineMarker,
|
|
114
108
|
body: statement.body,
|
|
115
109
|
mimetypes: core.mimetypes,
|
|
116
110
|
});
|
|
111
|
+
if (resolved.status >= 400) {
|
|
112
|
+
if (resolved.problem !== undefined) {
|
|
113
|
+
return Results.assert({
|
|
114
|
+
...resolved,
|
|
115
|
+
content: null,
|
|
116
|
+
mimetype: null,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (resolved.reason === undefined) {
|
|
120
|
+
throw new Error(`Log.read: ReadResolve returned status ${resolved.status} without Problem Details or a diagnostic`);
|
|
121
|
+
}
|
|
122
|
+
return failure(resolved.status === 416
|
|
123
|
+
? "range-not-satisfiable"
|
|
124
|
+
: resolved.status === 501
|
|
125
|
+
? "matcher-unavailable"
|
|
126
|
+
: "read-resolution-failed", resolved.status, resolved.reason, {
|
|
127
|
+
...(resolved.range === undefined ? {} : { range: resolved.range, stage: "projection" }),
|
|
128
|
+
...(statement.body === null || resolved.status === 416
|
|
129
|
+
? {}
|
|
130
|
+
: {
|
|
131
|
+
stage: "matcher",
|
|
132
|
+
dialect: statement.body.dialect,
|
|
133
|
+
recovery: resolved.status === 501
|
|
134
|
+
? "Retry the READ without a content matcher."
|
|
135
|
+
: "Correct or remove the matcher.",
|
|
136
|
+
retryable: false,
|
|
137
|
+
}),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return { ...resolved };
|
|
117
141
|
}
|
|
118
|
-
// §log-uniform-query — FIND over the worker's log rows, on the SAME source-agnostic primitive
|
|
119
|
-
// every entry scheme runs (Matcher.matchCandidates, §find-source-agnostic): candidates are the
|
|
120
|
-
// coordinate-scoped rows
|
|
121
|
-
// dialect works on log BY CONSTRUCTION and FIND(log)
|
|
122
|
-
// ~semantic stays 501 until the pump embeds log rows (epic S5); @graph is 501 (log rows carry
|
|
123
|
-
// no symbol channels — an honest absence, not an exception).
|
|
142
|
+
// {§log-uniform-query} — FIND over the worker's log rows, on the SAME source-agnostic primitive
|
|
143
|
+
// every entry scheme runs (Matcher.matchCandidates, {§find-source-agnostic}): candidates are the
|
|
144
|
+
// coordinate-scoped rows resolved by LogBody exactly as READ shows them, so every content
|
|
145
|
+
// dialect works on log BY CONSTRUCTION and FIND(log)->READ(coordinate) composes like any scheme.
|
|
124
146
|
async find(statement, ctx) {
|
|
125
|
-
|
|
147
|
+
return this.#find(statement, this.coreContext(ctx), true);
|
|
148
|
+
}
|
|
149
|
+
async #find(statement, core, enforceRenderBudget, allowTargetless = false) {
|
|
126
150
|
const { db, workerId, mimetypes } = core;
|
|
127
|
-
const empty = (status
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
151
|
+
const empty = (status, detail, extensions = {}) => {
|
|
152
|
+
const fields = { content: null, mimetype: null, results: [], itemsTokenTotal: 0, pathnames: [], matches: [] };
|
|
153
|
+
if (status >= 400 && detail === undefined) {
|
|
154
|
+
throw new Error(`Log.find: selection returned status ${status} without Problem Details or a diagnostic`);
|
|
155
|
+
}
|
|
156
|
+
return status >= 400
|
|
157
|
+
? Results.failure("scheme:log", status === 416 ? "range-not-satisfiable" : status === 501 ? "matcher-not-implemented" : "find-failed", status, detail, fields, extensions)
|
|
158
|
+
: { status, ...fields };
|
|
159
|
+
};
|
|
160
|
+
if (statement.target === null && !allowTargetless) {
|
|
161
|
+
return empty(400, "FIND requires a log target.", {
|
|
162
|
+
recovery: "Provide a log coordinate, prefix, or glob.",
|
|
163
|
+
retryable: false,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
const pathname = statement.target === null
|
|
167
|
+
? ""
|
|
168
|
+
: (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
|
|
133
169
|
const glob = coordinateGlob(pathname);
|
|
134
|
-
if (glob === null)
|
|
135
|
-
return empty(400
|
|
136
|
-
|
|
170
|
+
if (glob === null) {
|
|
171
|
+
return empty(400, `The log target '${pathname}' is malformed.`, {
|
|
172
|
+
target: pathname,
|
|
173
|
+
recovery: "Use a log coordinate, prefix, or glob.",
|
|
174
|
+
retryable: false,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
const scope = pathScope(glob, false);
|
|
178
|
+
// {§log-region-tagging} — a tag signal AND-filters the candidates ({§find-tag-filter-and-semantics}):
|
|
137
179
|
// a row survives only if it carries EVERY listed tag. No signal → the plain coordinate scope.
|
|
138
180
|
const tags = Array.isArray(statement.signal) ? statement.signal : [];
|
|
139
|
-
const
|
|
140
|
-
? await db.log_find_candidates_tagged.all({ worker_id: workerId,
|
|
141
|
-
: await db.log_find_candidates.all({ worker_id: workerId,
|
|
181
|
+
const candidateRows = tags.length > 0
|
|
182
|
+
? await db.log_find_candidates_tagged.all({ worker_id: workerId, scope_prefix: scope.candidatePrefix, tags: JSON.stringify(tags) })
|
|
183
|
+
: await db.log_find_candidates.all({ worker_id: workerId, scope_prefix: scope.candidatePrefix });
|
|
184
|
+
let rows;
|
|
185
|
+
try {
|
|
186
|
+
rows = candidateRows.filter((row) => coordinateScopeMatches(scope, row.coordinate));
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
return empty(400, `The log glob '${glob}' is malformed.`, {
|
|
190
|
+
target: glob,
|
|
191
|
+
recovery: "Correct the log glob.",
|
|
192
|
+
retryable: false,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
const candidateByCanonicalCoord = new Map(candidateRows.map((row) => [canonicalCoordinate(row.coordinate), row]));
|
|
142
196
|
const byCoord = new Map(rows.map((r) => [r.coordinate, r]));
|
|
143
|
-
const projected = rows.map((r) => ({
|
|
197
|
+
const projected = rows.map((r) => ({
|
|
198
|
+
key: r.coordinate,
|
|
199
|
+
...LogBody.resolve({
|
|
200
|
+
op: r.op,
|
|
201
|
+
tx: r.tx,
|
|
202
|
+
rx: r.rx,
|
|
203
|
+
mimetypeTx: r.mimetype_tx,
|
|
204
|
+
mimetypeRx: r.mimetype_rx,
|
|
205
|
+
}),
|
|
206
|
+
}));
|
|
144
207
|
let matches;
|
|
145
|
-
if (statement.body ===
|
|
146
|
-
|
|
208
|
+
if (statement.body?.dialect === "semantic") {
|
|
209
|
+
if (mimetypes === undefined) {
|
|
210
|
+
return empty(501, "Semantic search requires the mimetypes capability.", {
|
|
211
|
+
stage: "semantic-search",
|
|
212
|
+
retryable: false,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
const candidateSet = resolveSearchCandidates(rows.map(({ coordinate, deep_hash }) => ({ key: coordinate, deepHash: deep_hash })));
|
|
216
|
+
if (candidateSet.state === "incomplete")
|
|
217
|
+
return empty(503, `The persistent search index covers ${candidateSet.indexed} of ${candidateSet.total} selected log results.`, {
|
|
218
|
+
search: candidateSet,
|
|
219
|
+
stage: "search-index",
|
|
220
|
+
recovery: "Wait for search indexing to complete before repeating the search.",
|
|
221
|
+
retryable: false,
|
|
222
|
+
});
|
|
223
|
+
const selection = EntrySemantic.resultSelection(statement.lineMarker);
|
|
224
|
+
const ranked = await EntrySemantic.rankCandidates(db, candidateSet.candidates, mimetypes, statement.body.raw, selection);
|
|
225
|
+
if (ranked.status !== 200) {
|
|
226
|
+
return empty(ranked.status, ranked.status === 501
|
|
227
|
+
? "Similarity-threshold search requires an embedding provider."
|
|
228
|
+
: "The requested similarity threshold is outside the supported range.", {
|
|
229
|
+
stage: "semantic-search",
|
|
230
|
+
...(selection.threshold === null ? {} : { threshold: selection.threshold }),
|
|
231
|
+
recovery: ranked.status === 501
|
|
232
|
+
? "Remove the decimal similarity threshold while embeddings are unavailable."
|
|
233
|
+
: "Use a similarity threshold greater than zero and less than one.",
|
|
234
|
+
retryable: false,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
let selected = ranked.results;
|
|
238
|
+
if (selection.page !== null) {
|
|
239
|
+
const page = LineMarkerOps.page(selected, selection.page);
|
|
240
|
+
if (page.status !== 200) {
|
|
241
|
+
if (page.problem === undefined)
|
|
242
|
+
throw new Error("Log semantic FIND pagination failed without Problem Details");
|
|
243
|
+
return Results.assert({
|
|
244
|
+
status: page.status,
|
|
245
|
+
problem: page.problem,
|
|
246
|
+
content: null,
|
|
247
|
+
mimetype: null,
|
|
248
|
+
results: [],
|
|
249
|
+
itemsTokenTotal: 0,
|
|
250
|
+
pathnames: [],
|
|
251
|
+
matches: [],
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
selected = page.items ?? [];
|
|
255
|
+
}
|
|
256
|
+
const sourceMatches = selected.map(({ key, lineStart, lineEnd }) => ({
|
|
257
|
+
key,
|
|
258
|
+
span: { lineStart, lineEnd },
|
|
259
|
+
}));
|
|
260
|
+
const readable = Matcher.addTextRegions(sourceMatches, projected);
|
|
261
|
+
matches = readable.map(({ key, matches: ranges }) => ({ pathname: key, matches: ranges }));
|
|
262
|
+
}
|
|
263
|
+
else if (statement.body?.dialect === "graph") {
|
|
264
|
+
const candidateSet = resolveSearchCandidates(rows.map(({ coordinate, deep_hash }) => ({ key: coordinate, deepHash: deep_hash })));
|
|
265
|
+
if (candidateSet.state === "incomplete")
|
|
266
|
+
return empty(503, `The persistent search index covers ${candidateSet.indexed} of ${candidateSet.total} selected log results.`, {
|
|
267
|
+
search: candidateSet,
|
|
268
|
+
stage: "search-index",
|
|
269
|
+
recovery: "Wait for search indexing to complete before repeating the search.",
|
|
270
|
+
retryable: false,
|
|
271
|
+
});
|
|
272
|
+
const universeRows = await db.log_find_candidates.all({ worker_id: workerId, scope_prefix: null });
|
|
273
|
+
const universe = resolveSearchCandidates(universeRows.map(({ coordinate, deep_hash }) => ({ key: coordinate, deepHash: deep_hash })));
|
|
274
|
+
if (universe.state === "incomplete")
|
|
275
|
+
return empty(503, `The persistent search index covers ${universe.indexed} of ${universe.total} log results in the relationship universe.`, {
|
|
276
|
+
search: universe,
|
|
277
|
+
stage: "search-index",
|
|
278
|
+
recovery: "Wait for search indexing to complete before repeating the search.",
|
|
279
|
+
retryable: false,
|
|
280
|
+
});
|
|
281
|
+
const graph = await EntryGraph.matchCandidates(db, universe.candidates, candidateSet.candidates, statement.body.raw);
|
|
282
|
+
if (graph.status !== 200) {
|
|
283
|
+
return empty(graph.status, `The graph matcher '${statement.body.raw}' is malformed.`, {
|
|
284
|
+
stage: "matcher",
|
|
285
|
+
dialect: "graph",
|
|
286
|
+
recovery: "Correct or remove the matcher.",
|
|
287
|
+
retryable: false,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
const sourceMatches = graph.matches.map(({ key, lineStart, lineEnd }) => ({
|
|
291
|
+
key,
|
|
292
|
+
span: { lineStart, lineEnd },
|
|
293
|
+
}));
|
|
294
|
+
const readable = Matcher.addTextRegions(sourceMatches, projected);
|
|
295
|
+
matches = readable.map(({ key, matches: ranges }) => ({ pathname: key, matches: ranges }));
|
|
296
|
+
}
|
|
297
|
+
else if (statement.body === null) {
|
|
298
|
+
matches = projected.map(({ key }) => ({ pathname: key, matches: [] }));
|
|
147
299
|
}
|
|
148
300
|
else {
|
|
149
|
-
if (mimetypes === undefined)
|
|
150
|
-
return empty(501
|
|
301
|
+
if (mimetypes === undefined) {
|
|
302
|
+
return empty(501, "Content matching requires the mimetypes capability.", {
|
|
303
|
+
stage: "matcher",
|
|
304
|
+
dialect: statement.body.dialect,
|
|
305
|
+
retryable: false,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
151
308
|
const r = await Matcher.matchCandidates(statement.body, projected, mimetypes);
|
|
152
|
-
if (r.status !== 200)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
309
|
+
if (r.status !== 200) {
|
|
310
|
+
if (r.problem === undefined) {
|
|
311
|
+
throw new Error(`Log.find: matcher returned status ${r.status} without Problem Details`);
|
|
312
|
+
}
|
|
313
|
+
return Results.assert({
|
|
314
|
+
status: r.status,
|
|
315
|
+
problem: r.problem,
|
|
316
|
+
content: null,
|
|
317
|
+
mimetype: null,
|
|
318
|
+
results: [],
|
|
319
|
+
itemsTokenTotal: 0,
|
|
320
|
+
pathnames: [],
|
|
321
|
+
matches: [],
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
matches = r.matches.map(({ key, matches: ranges }) => ({ pathname: key, matches: ranges }));
|
|
163
325
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
326
|
+
const folderSummaries = statement.body === null
|
|
327
|
+
? pathFolderSummaries(scope, candidateRows.map((row) => canonicalCoordinate(row.coordinate)))
|
|
328
|
+
: [];
|
|
329
|
+
if (statement.lineMarker !== null && statement.body?.dialect !== "semantic" && folderSummaries.length === 0) {
|
|
330
|
+
const page = LineMarkerOps.page(matches, statement.lineMarker);
|
|
331
|
+
if (page.status !== 200) {
|
|
332
|
+
if (page.problem === undefined)
|
|
333
|
+
throw new Error("Log FIND pagination failed without Problem Details");
|
|
334
|
+
return Results.assert({
|
|
335
|
+
status: page.status,
|
|
336
|
+
problem: page.problem,
|
|
337
|
+
content: null,
|
|
338
|
+
mimetype: null,
|
|
339
|
+
results: [],
|
|
340
|
+
itemsTokenTotal: 0,
|
|
341
|
+
pathnames: [],
|
|
342
|
+
matches: [],
|
|
343
|
+
});
|
|
344
|
+
}
|
|
168
345
|
matches = page.items ?? [];
|
|
169
346
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
// matcher but skipped its cardinality gate, allowing one matcher over a
|
|
174
|
-
// large READ projection to retain and later fan out tens of thousands
|
|
175
|
-
// of rows. Count-forward here before catalog materialization.
|
|
176
|
-
const budget = Number.parseInt(process.env.PLURNK_SERVICE_FIND_MAX_MATCHES ?? "0", 10);
|
|
177
|
-
if (budget > 0 && matches.length > budget) {
|
|
178
|
-
const unique = new Set(matches.map((m) => m.pathname));
|
|
179
|
-
const itemsTokenTotal = [...unique].reduce((sum, pathname) => sum + (byCoord.get(pathname)?.tokens ?? 0), 0);
|
|
180
|
-
return {
|
|
181
|
-
status: 200,
|
|
182
|
-
content: `${matches.length} entries match, exceeding the render budget (${budget}) — not enumerated.`,
|
|
183
|
-
mimetype: "text/markdown",
|
|
184
|
-
results: [],
|
|
185
|
-
itemsTokenTotal,
|
|
186
|
-
pathnames: [],
|
|
187
|
-
matches: [],
|
|
188
|
-
overflow: matches.length,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
// The result rows mirror the catalog-row shape (§find-result-catalog-rows): one item per
|
|
192
|
-
// match, keyed by the row's self-documenting path, carrying {mimetype, tokens, lines} so
|
|
193
|
-
// the model budgets its READs — uniform with every scheme's FIND.
|
|
194
|
-
const results = [];
|
|
347
|
+
// The result rows mirror the catalog-row shape: one item per selected
|
|
348
|
+
// resource, with optional match coordinates for a surgical READ.
|
|
349
|
+
let results = [];
|
|
195
350
|
const seenPath = [];
|
|
196
351
|
const seen = new Set();
|
|
197
352
|
let itemsTokenTotal = 0;
|
|
@@ -200,63 +355,123 @@ export default class Log extends CoreSchemeAdapterBase {
|
|
|
200
355
|
if (row === undefined)
|
|
201
356
|
continue;
|
|
202
357
|
const path = `log:///${m.pathname}`;
|
|
203
|
-
const proj =
|
|
358
|
+
const proj = LogBody.resolve({
|
|
359
|
+
op: row.op,
|
|
360
|
+
tx: row.tx,
|
|
361
|
+
rx: row.rx,
|
|
362
|
+
mimetypeTx: row.mimetype_tx,
|
|
363
|
+
mimetypeRx: row.mimetype_rx,
|
|
364
|
+
});
|
|
204
365
|
const item = {
|
|
205
366
|
path,
|
|
206
367
|
channels: { [path]: { mimetype: proj.mimetype, tokens: row.tokens, lines: proj.content.length === 0 ? 0 : proj.content.split("\n").length } },
|
|
207
368
|
};
|
|
208
|
-
results.push(m.
|
|
369
|
+
results.push(m.matches.length > 0 ? { ...item, matches: m.matches } : item);
|
|
209
370
|
if (!seen.has(m.pathname)) {
|
|
210
371
|
seen.add(m.pathname);
|
|
211
372
|
seenPath.push(m.pathname);
|
|
212
373
|
itemsTokenTotal += row.tokens;
|
|
213
374
|
}
|
|
214
375
|
}
|
|
376
|
+
for (const folder of folderSummaries) {
|
|
377
|
+
const members = folder.pathnames.map((coordinate) => candidateByCanonicalCoord.get(coordinate)).filter((row) => row !== undefined);
|
|
378
|
+
const item = {
|
|
379
|
+
path: `log:///${folder.selector}`,
|
|
380
|
+
items: members.length,
|
|
381
|
+
tokens: members.reduce((sum, row) => sum + row.tokens, 0),
|
|
382
|
+
};
|
|
383
|
+
results.push(item);
|
|
384
|
+
itemsTokenTotal += item.tokens;
|
|
385
|
+
}
|
|
386
|
+
if (folderSummaries.length > 0) {
|
|
387
|
+
results.sort((a, b) => a.path.localeCompare(b.path));
|
|
388
|
+
if (statement.lineMarker !== null) {
|
|
389
|
+
const page = LineMarkerOps.page(results, statement.lineMarker);
|
|
390
|
+
if (page.status !== 200) {
|
|
391
|
+
if (page.problem === undefined)
|
|
392
|
+
throw new Error("Log FIND pagination failed without Problem Details");
|
|
393
|
+
return Results.assert({
|
|
394
|
+
status: page.status,
|
|
395
|
+
problem: page.problem,
|
|
396
|
+
content: null,
|
|
397
|
+
mimetype: null,
|
|
398
|
+
results: [],
|
|
399
|
+
itemsTokenTotal: 0,
|
|
400
|
+
pathnames: [],
|
|
401
|
+
matches: [],
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
results = page.items ?? [];
|
|
405
|
+
const retained = new Set(results.filter((item) => item.items === undefined).map((item) => item.path.replace(/^log:\/\/\//, "").replace(/^\//, "")));
|
|
406
|
+
matches = matches.filter((match) => retained.has(match.pathname));
|
|
407
|
+
seenPath.splice(0, seenPath.length, ...matches.map((match) => match.pathname).filter((coordinate, i, all) => all.indexOf(coordinate) === i));
|
|
408
|
+
itemsTokenTotal = results.reduce((sum, item) => sum + (item.items === undefined
|
|
409
|
+
? Object.values(item.channels).reduce((channelSum, channel) => channelSum + channel.tokens, 0)
|
|
410
|
+
: item.tokens ?? 0), 0);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
if (results.length === 0)
|
|
414
|
+
return empty(204);
|
|
415
|
+
// {§find-count-not-contents} is source-agnostic. Count the rendered
|
|
416
|
+
// catalog items; a shallow map's folder summaries replace, rather than
|
|
417
|
+
// conceal, their descendants.
|
|
418
|
+
const budget = Number.parseInt(process.env.PLURNK_SERVICE_FIND_MAX_MATCHES ?? "0", 10);
|
|
419
|
+
if (enforceRenderBudget && budget > 0 && results.length > budget) {
|
|
420
|
+
const noun = results.some((item) => item.items !== undefined) ? "catalog items" : "entries";
|
|
421
|
+
return {
|
|
422
|
+
status: 200,
|
|
423
|
+
content: `${results.length} ${noun} match, exceeding the render budget (${budget}) — not enumerated.`,
|
|
424
|
+
mimetype: "text/markdown",
|
|
425
|
+
results: [],
|
|
426
|
+
itemsTokenTotal,
|
|
427
|
+
pathnames: [],
|
|
428
|
+
matches: [],
|
|
429
|
+
omittedItems: results.length,
|
|
430
|
+
maximumItems: budget,
|
|
431
|
+
};
|
|
432
|
+
}
|
|
215
433
|
// matches[].pathname is the fan-out's retarget key — `/loop/turn/seq/OP` re-parses as a
|
|
216
434
|
// coordinate (the /OP suffix is accepted), so READ(log://)<matcher> fan-out delivers rows.
|
|
217
435
|
const fanMatches = matches.map((m) => ({ ...m, pathname: `/${m.pathname}` }));
|
|
218
|
-
return { status: 200, content:
|
|
436
|
+
return { status: 200, content: renderFindContent(results), mimetype: "application/json", results, itemsTokenTotal, pathnames: seenPath.map((p) => `/${p}`), matches: fanMatches };
|
|
219
437
|
}
|
|
220
438
|
async open(statement, ctx) {
|
|
221
439
|
return this.#setExpanded(statement, this.coreContext(ctx), 1);
|
|
222
440
|
}
|
|
223
|
-
// FOLD toggles the expanded bit only — an active subscription stays alive. §subscriptions-fold-keeps-subscription
|
|
441
|
+
// FOLD toggles the expanded bit only — an active subscription stays alive. {§subscriptions-fold-keeps-subscription}
|
|
224
442
|
async fold(statement, ctx) {
|
|
225
443
|
return this.#setExpanded(statement, this.coreContext(ctx), 0);
|
|
226
444
|
}
|
|
227
|
-
// Resolve a log:/// target — a concrete coordinate
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
async #resolveIds(pathname, lineMarker, ctx) {
|
|
445
|
+
// Resolve a log:/// target — a concrete coordinate or path-glob — to the matched row ids.
|
|
446
|
+
// OPEN/FOLD/KILL share this one path selection; log curation has no positional pagination.
|
|
447
|
+
async #resolveIds(pathname, ctx) {
|
|
231
448
|
const { db, workerId } = ctx;
|
|
232
449
|
const coord = parseCoordinate(pathname);
|
|
233
|
-
if (coord !== null
|
|
450
|
+
if (coord !== null) {
|
|
234
451
|
const row = await db.log_id_by_coordinate.get({ worker_id: workerId, loop_seq: coord.loopSeq, turn_seq: coord.turnSeq, sequence: coord.sequence });
|
|
235
452
|
return row === undefined ? { status: 404, ids: [] } : { status: 200, ids: [row.id] };
|
|
236
453
|
}
|
|
237
|
-
// §log-coordinate-hierarchy — one resolution for every consumer (curation here, find below).
|
|
454
|
+
// {§log-coordinate-hierarchy} — one resolution for every consumer (curation here, find below).
|
|
238
455
|
const glob = coordinateGlob(pathname);
|
|
239
456
|
if (glob === null)
|
|
240
|
-
return { status: 400, ids: [], error: `
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
457
|
+
return { status: 400, ids: [], error: `The log target '${pathname}' is malformed.` };
|
|
458
|
+
const scope = pathScope(glob, false);
|
|
459
|
+
const candidates = await db.log_match_coordinates.all({ worker_id: workerId, scope_prefix: scope.candidatePrefix });
|
|
460
|
+
let matched;
|
|
461
|
+
try {
|
|
462
|
+
matched = candidates.filter((row) => coordinateScopeMatches(scope, row.coordinate));
|
|
463
|
+
}
|
|
464
|
+
catch {
|
|
465
|
+
return { status: 400, ids: [], error: `The log glob '${glob}' is malformed.` };
|
|
466
|
+
}
|
|
467
|
+
// {§log-curation-folder-idiom} — a well-formed empty selection is a
|
|
468
|
+
// successful no-op and remains outside the error surface.
|
|
245
469
|
if (matched.length === 0)
|
|
246
470
|
return { status: 204, ids: [] };
|
|
247
|
-
|
|
248
|
-
if (lineMarker !== null) {
|
|
249
|
-
const page = paginate(matched, LineMarkerOps.firstLast(lineMarker));
|
|
250
|
-
if (page.status !== 200)
|
|
251
|
-
return { status: page.status, ids: [] };
|
|
252
|
-
selected = page.items ?? [];
|
|
253
|
-
}
|
|
254
|
-
if (selected.length === 0)
|
|
255
|
-
return { status: 404, ids: [] };
|
|
256
|
-
return { status: 200, ids: selected.map((s) => s.id) };
|
|
471
|
+
return { status: 200, ids: matched.map((row) => row.id) };
|
|
257
472
|
}
|
|
258
|
-
// §log-region-tagging — resolve OPEN[tag] to ids: candidates are the target's glob scope (the
|
|
259
|
-
// whole
|
|
473
|
+
// {§log-region-tagging} — resolve OPEN[tag] to ids: candidates are the target's glob scope (the
|
|
474
|
+
// whole worker log when targetless — a bare OPEN[tag] recalls the entire tagged working-set),
|
|
260
475
|
// AND-filtered to rows carrying EVERY listed tag. Zero matches is a no-op success (204), mirroring
|
|
261
476
|
// #resolveIds — recalling a name that tags nothing steers nothing.
|
|
262
477
|
async #resolveByTags(statement, tags, ctx) {
|
|
@@ -264,86 +479,138 @@ export default class Log extends CoreSchemeAdapterBase {
|
|
|
264
479
|
const pathname = statement.target === null ? "" : (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
|
|
265
480
|
const glob = coordinateGlob(pathname);
|
|
266
481
|
if (glob === null)
|
|
267
|
-
return { status: 400, ids: [], error: `
|
|
268
|
-
const
|
|
482
|
+
return { status: 400, ids: [], error: `The log target '${pathname}' is malformed.` };
|
|
483
|
+
const scope = pathScope(glob, false);
|
|
484
|
+
const candidates = await db.log_match_coordinates_tagged.all({
|
|
485
|
+
worker_id: workerId,
|
|
486
|
+
scope_prefix: scope.candidatePrefix,
|
|
487
|
+
tags: JSON.stringify(tags),
|
|
488
|
+
});
|
|
489
|
+
let matched;
|
|
490
|
+
try {
|
|
491
|
+
matched = candidates.filter((row) => coordinateScopeMatches(scope, row.coordinate));
|
|
492
|
+
}
|
|
493
|
+
catch {
|
|
494
|
+
return { status: 400, ids: [], error: `The log glob '${glob}' is malformed.` };
|
|
495
|
+
}
|
|
269
496
|
if (matched.length === 0)
|
|
270
497
|
return { status: 204, ids: [] };
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
498
|
+
return { status: 200, ids: matched.map((row) => row.id) };
|
|
499
|
+
}
|
|
500
|
+
// A matcher-bearing curation op reuses FIND's complete source-agnostic selector with
|
|
501
|
+
// rendering disabled. OPEN's tags filter candidates; FOLD's tags are withheld until
|
|
502
|
+
// after selection because they apply to the rows being folded.
|
|
503
|
+
async #resolveByMatcher(statement, filterTags, ctx) {
|
|
504
|
+
const selected = await this.#find({
|
|
505
|
+
...statement,
|
|
506
|
+
op: "FIND",
|
|
507
|
+
signal: filterTags ? statement.signal : null,
|
|
508
|
+
lineMarker: null,
|
|
509
|
+
}, ctx, false, filterTags && Array.isArray(statement.signal) && statement.signal.length > 0 && statement.target === null);
|
|
510
|
+
if (selected.status !== 200)
|
|
511
|
+
return { status: selected.status, ids: [], problem: selected.problem };
|
|
512
|
+
const ids = [];
|
|
513
|
+
for (const { pathname } of selected.matches) {
|
|
514
|
+
const coordinate = parseCoordinate(pathname.replace(/^\//, ""));
|
|
515
|
+
if (coordinate === null)
|
|
516
|
+
throw new Error(`Log matcher selected malformed coordinate '${pathname}'`);
|
|
517
|
+
const row = await ctx.db.log_id_by_coordinate.get({
|
|
518
|
+
worker_id: ctx.workerId,
|
|
519
|
+
loop_seq: coordinate.loopSeq,
|
|
520
|
+
turn_seq: coordinate.turnSeq,
|
|
521
|
+
sequence: coordinate.sequence,
|
|
522
|
+
});
|
|
523
|
+
if (row === undefined)
|
|
524
|
+
return { status: 404, ids: [] };
|
|
525
|
+
ids.push(row.id);
|
|
526
|
+
}
|
|
527
|
+
return ids.length === 0 ? { status: 204, ids: [] } : { status: 200, ids };
|
|
528
|
+
}
|
|
529
|
+
async #applyExpanded(ids, expanded, tags, ctx) {
|
|
530
|
+
for (const id of ids)
|
|
531
|
+
await ctx.db.log_set_expanded_by_id.run({ id, expanded });
|
|
532
|
+
if (expanded === 0) {
|
|
533
|
+
for (const id of ids)
|
|
534
|
+
for (const tag of tags)
|
|
535
|
+
await ctx.db.log_write_tag.run({ log_entry_id: id, tag });
|
|
277
536
|
}
|
|
278
|
-
|
|
279
|
-
return { status: 404, ids: [] };
|
|
280
|
-
return { status: 200, ids: selected.map((s) => s.id) };
|
|
537
|
+
return { status: 200, matched: ids.length };
|
|
281
538
|
}
|
|
282
539
|
async #setExpanded(statement, ctx, expanded) {
|
|
283
540
|
const signal = Array.isArray(statement.signal) ? statement.signal : [];
|
|
284
|
-
|
|
541
|
+
if (statement.body !== null) {
|
|
542
|
+
const matched = await this.#resolveByMatcher(statement, expanded === 1, ctx);
|
|
543
|
+
if (matched.status === 204)
|
|
544
|
+
return { status: 204, matched: 0 };
|
|
545
|
+
if (matched.status !== 200) {
|
|
546
|
+
if (matched.problem !== undefined) {
|
|
547
|
+
return Results.assert({ status: matched.status, problem: matched.problem });
|
|
548
|
+
}
|
|
549
|
+
return Results.failure("scheme:log", matched.status === 404 ? "entry-not-found" : "curation-failed", matched.status, "No log entry matches the requested selection.");
|
|
550
|
+
}
|
|
551
|
+
return this.#applyExpanded(matched.ids, expanded, signal, ctx);
|
|
552
|
+
}
|
|
553
|
+
// {§log-region-tagging} — OPEN[tag] is the READ side: recall rows by tag, target optional (a bare
|
|
285
554
|
// OPEN[tag] recalls the whole tagged working-set). FOLD never resolves by tag — it is the WRITE
|
|
286
555
|
// side (it stamps the tag below), always scoped to the target region it folds.
|
|
287
556
|
if (expanded === 1 && signal.length > 0) {
|
|
288
557
|
const rt = await this.#resolveByTags(statement, signal, ctx);
|
|
289
558
|
if (rt.status === 204)
|
|
290
559
|
return { status: 204, matched: 0 };
|
|
291
|
-
if (rt.status !== 200)
|
|
292
|
-
return
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
560
|
+
if (rt.status !== 200) {
|
|
561
|
+
return Results.failure("scheme:log", "open-failed", rt.status, rt.error ?? "No log entry matches the requested selection.", {}, {
|
|
562
|
+
target: statement.target?.raw ?? null,
|
|
563
|
+
...(rt.status === 400
|
|
564
|
+
? {
|
|
565
|
+
recovery: "Use a log coordinate, prefix, or glob.",
|
|
566
|
+
retryable: false,
|
|
567
|
+
}
|
|
568
|
+
: {}),
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
return this.#applyExpanded(rt.ids, 1, signal, ctx);
|
|
572
|
+
}
|
|
573
|
+
if (statement.target === null) {
|
|
574
|
+
return Results.failure("scheme:log", "target-required", 400, `${expanded === 1 ? "OPEN" : "FOLD"} requires a log target.`, {}, {
|
|
575
|
+
recovery: "Provide a log coordinate, prefix, or glob.",
|
|
576
|
+
retryable: false,
|
|
577
|
+
});
|
|
296
578
|
}
|
|
297
|
-
if (statement.target === null)
|
|
298
|
-
return { status: 400 };
|
|
299
579
|
const pathname = (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
|
|
300
|
-
const r = await this.#resolveIds(pathname,
|
|
580
|
+
const r = await this.#resolveIds(pathname, ctx);
|
|
301
581
|
if (r.status === 204)
|
|
302
582
|
return { status: 204, matched: 0 };
|
|
303
|
-
if (r.status !== 200)
|
|
304
|
-
return
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (expanded === 0) {
|
|
314
|
-
const previewIds = new Set();
|
|
315
|
-
for (const id of r.ids) {
|
|
316
|
-
const row = await ctx.db.log_row_target.get({ id });
|
|
317
|
-
if (row?.scheme === "prompt" && row.origin === "plurnk" && row.op === "READ" && row.loop_id === ctx.loopId)
|
|
318
|
-
previewIds.add(id);
|
|
319
|
-
}
|
|
320
|
-
if (previewIds.size > 0) {
|
|
321
|
-
ids = r.ids.filter((id) => !previewIds.has(id));
|
|
322
|
-
if (ids.length === 0)
|
|
323
|
-
return { status: 403, error: "Illegal attempt to FOLD the task preview. Use KILL if you want it removed." };
|
|
324
|
-
}
|
|
583
|
+
if (r.status !== 200) {
|
|
584
|
+
return Results.failure("scheme:log", r.status === 404 ? "entry-not-found" : "curation-failed", r.status, r.error ?? `No log entry matches '${pathname}'.`, {}, {
|
|
585
|
+
target: pathname,
|
|
586
|
+
...(r.status === 400
|
|
587
|
+
? {
|
|
588
|
+
recovery: "Use a log coordinate, prefix, or glob.",
|
|
589
|
+
retryable: false,
|
|
590
|
+
}
|
|
591
|
+
: {}),
|
|
592
|
+
});
|
|
325
593
|
}
|
|
326
|
-
|
|
327
|
-
await ctx.db.log_set_expanded_by_id.run({ id, expanded });
|
|
328
|
-
// §log-region-tagging — FOLD[tag] is the log's write-op: stamp the tags on the folded rows,
|
|
329
|
-
// additively (§edit-tags-additive). Only the rows actually folded are tagged (a preview spared
|
|
330
|
-
// above is neither folded nor tagged). OPEN with a signal never reaches here.
|
|
331
|
-
if (expanded === 0 && signal.length > 0) {
|
|
332
|
-
for (const id of ids)
|
|
333
|
-
for (const tag of signal)
|
|
334
|
-
await ctx.db.log_write_tag.run({ log_entry_id: id, tag });
|
|
335
|
-
}
|
|
336
|
-
return { status: 200, matched: ids.length };
|
|
594
|
+
return this.#applyExpanded(r.ids, expanded, signal, ctx);
|
|
337
595
|
}
|
|
338
|
-
// KILL
|
|
339
|
-
//
|
|
340
|
-
// render; the row persists). Same resolution as OPEN/FOLD, DELETE instead of flip. KILL
|
|
341
|
-
// carries no <L> result slot, so no pagination — a concrete coordinate or a path-glob.
|
|
596
|
+
// KILL shares OPEN/FOLD's address resolution, deletes instead of flipping visibility,
|
|
597
|
+
// and carries no positional scope. {§model-entry-log-curation} {§log-curation-set-selection}
|
|
342
598
|
async kill(pathname, _signal, ctx) {
|
|
343
599
|
const core = this.coreContext(ctx);
|
|
344
|
-
const r = await this.#resolveIds(pathname.replace(/^\//, ""),
|
|
345
|
-
if (r.status
|
|
346
|
-
return { status:
|
|
600
|
+
const r = await this.#resolveIds(pathname.replace(/^\//, ""), core);
|
|
601
|
+
if (r.status === 204)
|
|
602
|
+
return { status: 204 };
|
|
603
|
+
if (r.status !== 200) {
|
|
604
|
+
return Results.failure("scheme:log", r.status === 404 ? "entry-not-found" : "kill-failed", r.status, r.error ?? `No log entry matches '${pathname}'.`, {}, {
|
|
605
|
+
target: pathname,
|
|
606
|
+
...(r.status === 400
|
|
607
|
+
? {
|
|
608
|
+
recovery: "Use a log coordinate, prefix, or glob.",
|
|
609
|
+
retryable: false,
|
|
610
|
+
}
|
|
611
|
+
: {}),
|
|
612
|
+
});
|
|
613
|
+
}
|
|
347
614
|
for (const id of r.ids)
|
|
348
615
|
await core.db.log_delete_by_id.run({ id });
|
|
349
616
|
return { status: 200 };
|