@plurnk/plurnk-service 1.3.12 → 1.5.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.
Files changed (488) hide show
  1. package/.env.defaults +95 -91
  2. package/INSTALL.md +54 -28
  3. package/README.md +25 -10
  4. package/SPEC.md +2426 -942
  5. package/dist/Paths.d.ts +4 -1
  6. package/dist/Paths.d.ts.map +1 -1
  7. package/dist/Paths.js +24 -23
  8. package/dist/Paths.js.map +1 -1
  9. package/dist/build-info.json +1 -1
  10. package/dist/content/edit-receipt.d.ts +13 -28
  11. package/dist/content/edit-receipt.d.ts.map +1 -1
  12. package/dist/content/edit-receipt.js +285 -104
  13. package/dist/content/edit-receipt.js.map +1 -1
  14. package/dist/content/edited-span.d.ts.map +1 -1
  15. package/dist/content/edited-span.js +2 -5
  16. package/dist/content/edited-span.js.map +1 -1
  17. package/dist/content/index.d.ts +4 -3
  18. package/dist/content/index.d.ts.map +1 -1
  19. package/dist/content/index.js +2 -1
  20. package/dist/content/index.js.map +1 -1
  21. package/dist/content/line-marker.d.ts +10 -9
  22. package/dist/content/line-marker.d.ts.map +1 -1
  23. package/dist/content/line-marker.js +8 -11
  24. package/dist/content/line-marker.js.map +1 -1
  25. package/dist/content/matcher.d.ts +15 -26
  26. package/dist/content/matcher.d.ts.map +1 -1
  27. package/dist/content/matcher.js +77 -107
  28. package/dist/content/matcher.js.map +1 -1
  29. package/dist/content/mimetype-binary.d.ts +2 -2
  30. package/dist/content/mimetype-binary.d.ts.map +1 -1
  31. package/dist/content/mimetype-binary.js +10 -10
  32. package/dist/content/mimetype-binary.js.map +1 -1
  33. package/dist/content/path-mimetype.js +3 -3
  34. package/dist/content/path-mimetype.js.map +1 -1
  35. package/dist/content/read-projector.d.ts +14 -0
  36. package/dist/content/read-projector.d.ts.map +1 -0
  37. package/dist/content/read-projector.js +86 -0
  38. package/dist/content/read-projector.js.map +1 -0
  39. package/dist/content/read-resolve.d.ts +6 -7
  40. package/dist/content/read-resolve.d.ts.map +1 -1
  41. package/dist/content/read-resolve.js +36 -59
  42. package/dist/content/read-resolve.js.map +1 -1
  43. package/dist/core/BranchReceipt.d.ts +6 -0
  44. package/dist/core/BranchReceipt.d.ts.map +1 -0
  45. package/dist/core/BranchReceipt.js +24 -0
  46. package/dist/core/BranchReceipt.js.map +1 -0
  47. package/dist/core/BudgetOverflow.d.ts +20 -0
  48. package/dist/core/BudgetOverflow.d.ts.map +1 -0
  49. package/dist/core/BudgetOverflow.js +49 -0
  50. package/dist/core/BudgetOverflow.js.map +1 -0
  51. package/dist/core/BudgetReadout.d.ts +8 -0
  52. package/dist/core/BudgetReadout.d.ts.map +1 -0
  53. package/dist/core/BudgetReadout.js +79 -0
  54. package/dist/core/BudgetReadout.js.map +1 -0
  55. package/dist/core/ChannelWrite.d.ts +31 -9
  56. package/dist/core/ChannelWrite.d.ts.map +1 -1
  57. package/dist/core/ChannelWrite.js +30 -23
  58. package/dist/core/ChannelWrite.js.map +1 -1
  59. package/dist/core/ChannelWrite.sql +14 -12
  60. package/dist/core/CoreSchemeServices.d.ts +18 -4
  61. package/dist/core/CoreSchemeServices.d.ts.map +1 -1
  62. package/dist/core/CoreSchemeServices.js +7 -1
  63. package/dist/core/CoreSchemeServices.js.map +1 -1
  64. package/dist/core/Dispatcher.d.ts +26 -21
  65. package/dist/core/Dispatcher.d.ts.map +1 -1
  66. package/dist/core/Dispatcher.js +1626 -671
  67. package/dist/core/Dispatcher.js.map +1 -1
  68. package/dist/core/DurableStatement.d.ts +6 -0
  69. package/dist/core/DurableStatement.d.ts.map +1 -0
  70. package/dist/core/DurableStatement.js +51 -0
  71. package/dist/core/DurableStatement.js.map +1 -0
  72. package/dist/core/Engine.d.ts +64 -29
  73. package/dist/core/Engine.d.ts.map +1 -1
  74. package/dist/core/Engine.js +1348 -835
  75. package/dist/core/Engine.js.map +1 -1
  76. package/dist/core/Engine.sql +329 -234
  77. package/dist/core/EnvFlags.js +1 -1
  78. package/dist/core/EnvFlags.js.map +1 -1
  79. package/dist/core/ErrorDetail.d.ts +6 -0
  80. package/dist/core/ErrorDetail.d.ts.map +1 -0
  81. package/dist/core/ErrorDetail.js +20 -0
  82. package/dist/core/ErrorDetail.js.map +1 -0
  83. package/dist/core/ExecutorRegistry.d.ts +14 -3
  84. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  85. package/dist/core/ExecutorRegistry.js +56 -30
  86. package/dist/core/ExecutorRegistry.js.map +1 -1
  87. package/dist/core/GitBranch.d.ts +20 -0
  88. package/dist/core/GitBranch.d.ts.map +1 -0
  89. package/dist/core/GitBranch.js +110 -0
  90. package/dist/core/GitBranch.js.map +1 -0
  91. package/dist/core/JournalTurn.d.ts +9 -0
  92. package/dist/core/JournalTurn.d.ts.map +1 -0
  93. package/dist/core/JournalTurn.js +14 -0
  94. package/dist/core/JournalTurn.js.map +1 -0
  95. package/dist/core/JournalTurn.sql +10 -0
  96. package/dist/core/LogBody.d.ts +18 -0
  97. package/dist/core/LogBody.d.ts.map +1 -0
  98. package/dist/core/LogBody.js +180 -0
  99. package/dist/core/LogBody.js.map +1 -0
  100. package/dist/core/LoopFlagsReader.d.ts +7 -0
  101. package/dist/core/LoopFlagsReader.d.ts.map +1 -0
  102. package/dist/core/LoopFlagsReader.js +33 -0
  103. package/dist/core/LoopFlagsReader.js.map +1 -0
  104. package/dist/core/LoopLifecycle.d.ts +8 -2
  105. package/dist/core/LoopLifecycle.d.ts.map +1 -1
  106. package/dist/core/LoopLifecycle.js +54 -11
  107. package/dist/core/LoopLifecycle.js.map +1 -1
  108. package/dist/core/LoopLifecycle.sql +10 -7
  109. package/dist/core/NoticeChannel.d.ts +13 -0
  110. package/dist/core/NoticeChannel.d.ts.map +1 -0
  111. package/dist/core/NoticeChannel.js +40 -0
  112. package/dist/core/NoticeChannel.js.map +1 -0
  113. package/dist/core/Owner.d.ts +0 -1
  114. package/dist/core/Owner.d.ts.map +1 -1
  115. package/dist/core/Owner.js +2 -5
  116. package/dist/core/Owner.js.map +1 -1
  117. package/dist/core/PacketBuilder.d.ts +27 -25
  118. package/dist/core/PacketBuilder.d.ts.map +1 -1
  119. package/dist/core/PacketBuilder.js +321 -383
  120. package/dist/core/PacketBuilder.js.map +1 -1
  121. package/dist/core/ProblemLog.d.ts +26 -0
  122. package/dist/core/ProblemLog.d.ts.map +1 -0
  123. package/dist/core/ProblemLog.js +58 -0
  124. package/dist/core/ProblemLog.js.map +1 -0
  125. package/dist/core/ProposalLifecycle.d.ts +15 -21
  126. package/dist/core/ProposalLifecycle.d.ts.map +1 -1
  127. package/dist/core/ProposalLifecycle.js +291 -78
  128. package/dist/core/ProposalLifecycle.js.map +1 -1
  129. package/dist/core/ProviderInstantiate.d.ts.map +1 -1
  130. package/dist/core/ProviderInstantiate.js +51 -48
  131. package/dist/core/ProviderInstantiate.js.map +1 -1
  132. package/dist/core/SchemeRegistry.d.ts +14 -8
  133. package/dist/core/SchemeRegistry.d.ts.map +1 -1
  134. package/dist/core/SchemeRegistry.js +189 -114
  135. package/dist/core/SchemeRegistry.js.map +1 -1
  136. package/dist/core/ServiceTeardown.d.ts +11 -0
  137. package/dist/core/ServiceTeardown.d.ts.map +1 -0
  138. package/dist/core/ServiceTeardown.js +70 -0
  139. package/dist/core/ServiceTeardown.js.map +1 -0
  140. package/dist/core/StoredPacket.d.ts +29 -0
  141. package/dist/core/StoredPacket.d.ts.map +1 -0
  142. package/dist/core/StoredPacket.js +147 -0
  143. package/dist/core/StoredPacket.js.map +1 -0
  144. package/dist/core/StrikeRail.d.ts +6 -3
  145. package/dist/core/StrikeRail.d.ts.map +1 -1
  146. package/dist/core/StrikeRail.js +27 -56
  147. package/dist/core/StrikeRail.js.map +1 -1
  148. package/dist/core/TerminalResult.d.ts +16 -0
  149. package/dist/core/TerminalResult.d.ts.map +1 -0
  150. package/dist/core/TerminalResult.js +49 -0
  151. package/dist/core/TerminalResult.js.map +1 -0
  152. package/dist/core/WorkerControlAddress.d.ts +17 -0
  153. package/dist/core/WorkerControlAddress.d.ts.map +1 -0
  154. package/dist/core/WorkerControlAddress.js +44 -0
  155. package/dist/core/WorkerControlAddress.js.map +1 -0
  156. package/dist/core/WorkerName.d.ts +31 -0
  157. package/dist/core/WorkerName.d.ts.map +1 -0
  158. package/dist/core/WorkerName.js +95 -0
  159. package/dist/core/WorkerName.js.map +1 -0
  160. package/dist/core/WorkerName.sql +36 -0
  161. package/dist/core/WorkspaceGate.d.ts +14 -0
  162. package/dist/core/WorkspaceGate.d.ts.map +1 -0
  163. package/dist/core/WorkspaceGate.js +155 -0
  164. package/dist/core/WorkspaceGate.js.map +1 -0
  165. package/dist/core/caps/CapsResolve.d.ts +5 -1
  166. package/dist/core/caps/CapsResolve.d.ts.map +1 -1
  167. package/dist/core/caps/CapsResolve.js +8 -4
  168. package/dist/core/caps/CapsResolve.js.map +1 -1
  169. package/dist/core/caps/DbChannelCaps.d.ts +5 -11
  170. package/dist/core/caps/DbChannelCaps.d.ts.map +1 -1
  171. package/dist/core/caps/DbChannelCaps.js +30 -12
  172. package/dist/core/caps/DbChannelCaps.js.map +1 -1
  173. package/dist/core/caps/DbEntryCaps.d.ts +5 -14
  174. package/dist/core/caps/DbEntryCaps.d.ts.map +1 -1
  175. package/dist/core/caps/DbEntryCaps.js +27 -8
  176. package/dist/core/caps/DbEntryCaps.js.map +1 -1
  177. package/dist/core/caps/DbNotifyCaps.d.ts +1 -1
  178. package/dist/core/caps/DbNotifyCaps.d.ts.map +1 -1
  179. package/dist/core/caps/DbNotifyCaps.js +18 -15
  180. package/dist/core/caps/DbNotifyCaps.js.map +1 -1
  181. package/dist/core/caps/DbProjectionCaps.d.ts +5 -5
  182. package/dist/core/caps/DbProjectionCaps.d.ts.map +1 -1
  183. package/dist/core/caps/DbProjectionCaps.js +21 -4
  184. package/dist/core/caps/DbProjectionCaps.js.map +1 -1
  185. package/dist/core/caps/DbSubscriptionCaps.d.ts +4 -6
  186. package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
  187. package/dist/core/caps/DbSubscriptionCaps.js +75 -66
  188. package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
  189. package/dist/core/caps/DbTagCaps.d.ts +5 -12
  190. package/dist/core/caps/DbTagCaps.d.ts.map +1 -1
  191. package/dist/core/caps/DbTagCaps.js +20 -11
  192. package/dist/core/caps/DbTagCaps.js.map +1 -1
  193. package/dist/core/caps/SchemeCtxImpl.d.ts +6 -1
  194. package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
  195. package/dist/core/caps/SchemeCtxImpl.js +6 -6
  196. package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
  197. package/dist/core/content-hash.js +1 -1
  198. package/dist/core/content-hash.js.map +1 -1
  199. package/dist/core/env-defaults.d.ts.map +1 -1
  200. package/dist/core/env-defaults.js.map +1 -1
  201. package/dist/core/fork.d.ts.map +1 -1
  202. package/dist/core/fork.js +55 -30
  203. package/dist/core/fork.js.map +1 -1
  204. package/dist/core/fork.sql +43 -29
  205. package/dist/core/git-env.d.ts +2 -0
  206. package/dist/core/git-env.d.ts.map +1 -1
  207. package/dist/core/git-env.js +13 -18
  208. package/dist/core/git-env.js.map +1 -1
  209. package/dist/core/git-iso.d.ts +3 -2
  210. package/dist/core/git-iso.d.ts.map +1 -1
  211. package/dist/core/git-iso.js +36 -27
  212. package/dist/core/git-iso.js.map +1 -1
  213. package/dist/core/git-membership.d.ts +2 -1
  214. package/dist/core/git-membership.d.ts.map +1 -1
  215. package/dist/core/git-membership.js +276 -162
  216. package/dist/core/git-membership.js.map +1 -1
  217. package/dist/core/git-state.d.ts +8 -1
  218. package/dist/core/git-state.d.ts.map +1 -1
  219. package/dist/core/git-state.js +44 -26
  220. package/dist/core/git-state.js.map +1 -1
  221. package/dist/core/namespace.d.ts +1 -0
  222. package/dist/core/namespace.d.ts.map +1 -1
  223. package/dist/core/namespace.js +20 -0
  224. package/dist/core/namespace.js.map +1 -1
  225. package/dist/core/optimistic-settlement.d.ts +2 -0
  226. package/dist/core/optimistic-settlement.d.ts.map +1 -0
  227. package/dist/core/optimistic-settlement.js +14 -0
  228. package/dist/core/optimistic-settlement.js.map +1 -0
  229. package/dist/core/owner.sql +1 -1
  230. package/dist/core/packet-inject.d.ts.map +1 -1
  231. package/dist/core/packet-inject.js +7 -11
  232. package/dist/core/packet-inject.js.map +1 -1
  233. package/dist/core/packet-wire.d.ts +3 -21
  234. package/dist/core/packet-wire.d.ts.map +1 -1
  235. package/dist/core/packet-wire.js +305 -385
  236. package/dist/core/packet-wire.js.map +1 -1
  237. package/dist/core/plurnk-uri.d.ts +12 -1
  238. package/dist/core/plurnk-uri.d.ts.map +1 -1
  239. package/dist/core/plurnk-uri.js +49 -29
  240. package/dist/core/plurnk-uri.js.map +1 -1
  241. package/dist/core/results.d.ts +18 -5
  242. package/dist/core/results.d.ts.map +1 -1
  243. package/dist/core/results.js +33 -18
  244. package/dist/core/results.js.map +1 -1
  245. package/dist/core/ruler_count.d.ts +4 -0
  246. package/dist/core/ruler_count.d.ts.map +1 -0
  247. package/dist/core/ruler_count.js +7 -0
  248. package/dist/core/ruler_count.js.map +1 -0
  249. package/dist/core/scheme-types.d.ts +3 -17
  250. package/dist/core/scheme-types.d.ts.map +1 -1
  251. package/dist/core/scheme-types.js.map +1 -1
  252. package/dist/core/search-gate.d.ts.map +1 -1
  253. package/dist/core/search-gate.js +3 -11
  254. package/dist/core/search-gate.js.map +1 -1
  255. package/dist/core/teaching-corpus.d.ts +6 -0
  256. package/dist/core/teaching-corpus.d.ts.map +1 -0
  257. package/dist/core/teaching-corpus.js +23 -0
  258. package/dist/core/teaching-corpus.js.map +1 -0
  259. package/dist/core/teaching.d.ts +0 -1
  260. package/dist/core/teaching.d.ts.map +1 -1
  261. package/dist/core/teaching.js +2 -8
  262. package/dist/core/teaching.js.map +1 -1
  263. package/dist/core/token-ruler.d.ts.map +1 -1
  264. package/dist/core/token-ruler.js +3 -16
  265. package/dist/core/token-ruler.js.map +1 -1
  266. package/dist/core/turn-scheduler.d.ts +1 -1
  267. package/dist/core/turn-scheduler.d.ts.map +1 -1
  268. package/dist/core/turn-scheduler.js +1 -1
  269. package/dist/core/turn-scheduler.js.map +1 -1
  270. package/dist/core/worker-cap.d.ts +2 -4
  271. package/dist/core/worker-cap.d.ts.map +1 -1
  272. package/dist/core/worker-cap.js +13 -4
  273. package/dist/core/worker-cap.js.map +1 -1
  274. package/dist/core/{run-ops.sql → worker-ops.sql} +14 -14
  275. package/dist/core/workspace-settings.d.ts.map +1 -1
  276. package/dist/core/workspace-settings.js +17 -9
  277. package/dist/core/workspace-settings.js.map +1 -1
  278. package/dist/digest/Digest.d.ts +2 -1
  279. package/dist/digest/Digest.d.ts.map +1 -1
  280. package/dist/digest/Digest.js +510 -149
  281. package/dist/digest/Digest.js.map +1 -1
  282. package/dist/digest/digest.sql +23 -10
  283. package/dist/index.d.ts.map +1 -1
  284. package/dist/index.js +3 -5
  285. package/dist/index.js.map +1 -1
  286. package/dist/observe/api.d.ts +6 -0
  287. package/dist/observe/api.d.ts.map +1 -0
  288. package/dist/observe/api.js +11 -0
  289. package/dist/observe/api.js.map +1 -0
  290. package/dist/observe/init.d.ts +7 -0
  291. package/dist/observe/init.d.ts.map +1 -0
  292. package/dist/observe/init.js +159 -0
  293. package/dist/observe/init.js.map +1 -0
  294. package/dist/observe/metrics.d.ts +6 -0
  295. package/dist/observe/metrics.d.ts.map +1 -0
  296. package/dist/observe/metrics.js +15 -0
  297. package/dist/observe/metrics.js.map +1 -0
  298. package/dist/observe/spans.d.ts +4 -0
  299. package/dist/observe/spans.d.ts.map +1 -0
  300. package/dist/observe/spans.js +51 -0
  301. package/dist/observe/spans.js.map +1 -0
  302. package/dist/schemes/EffectPolicy.d.ts +1 -0
  303. package/dist/schemes/EffectPolicy.d.ts.map +1 -1
  304. package/dist/schemes/EffectPolicy.js +5 -2
  305. package/dist/schemes/EffectPolicy.js.map +1 -1
  306. package/dist/schemes/Exec.d.ts +9 -14
  307. package/dist/schemes/Exec.d.ts.map +1 -1
  308. package/dist/schemes/Exec.js +402 -262
  309. package/dist/schemes/Exec.js.map +1 -1
  310. package/dist/schemes/ExecOutputScheme.d.ts +9 -9
  311. package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
  312. package/dist/schemes/ExecOutputScheme.js +49 -18
  313. package/dist/schemes/ExecOutputScheme.js.map +1 -1
  314. package/dist/schemes/File.d.ts +7 -13
  315. package/dist/schemes/File.d.ts.map +1 -1
  316. package/dist/schemes/File.js +280 -151
  317. package/dist/schemes/File.js.map +1 -1
  318. package/dist/schemes/Log.d.ts +8 -12
  319. package/dist/schemes/Log.d.ts.map +1 -1
  320. package/dist/schemes/Log.js +402 -233
  321. package/dist/schemes/Log.js.map +1 -1
  322. package/dist/schemes/Log.sql +71 -32
  323. package/dist/schemes/Prompt.d.ts +3 -3
  324. package/dist/schemes/Prompt.d.ts.map +1 -1
  325. package/dist/schemes/Prompt.js +10 -10
  326. package/dist/schemes/Prompt.js.map +1 -1
  327. package/dist/schemes/Skill.d.ts +2 -3
  328. package/dist/schemes/Skill.d.ts.map +1 -1
  329. package/dist/schemes/Skill.js +2 -6
  330. package/dist/schemes/Skill.js.map +1 -1
  331. package/dist/schemes/Worker.d.ts +11 -19
  332. package/dist/schemes/Worker.d.ts.map +1 -1
  333. package/dist/schemes/Worker.js +210 -89
  334. package/dist/schemes/Worker.js.map +1 -1
  335. package/dist/schemes/_entry-chunk.d.ts.map +1 -1
  336. package/dist/schemes/_entry-chunk.js +12 -5
  337. package/dist/schemes/_entry-chunk.js.map +1 -1
  338. package/dist/schemes/_entry-crud.d.ts +11 -9
  339. package/dist/schemes/_entry-crud.d.ts.map +1 -1
  340. package/dist/schemes/_entry-crud.js +72 -13
  341. package/dist/schemes/_entry-crud.js.map +1 -1
  342. package/dist/schemes/_entry-crud.sql +28 -10
  343. package/dist/schemes/_entry-find.d.ts +49 -18
  344. package/dist/schemes/_entry-find.d.ts.map +1 -1
  345. package/dist/schemes/_entry-find.js +348 -195
  346. package/dist/schemes/_entry-find.js.map +1 -1
  347. package/dist/schemes/_entry-find.sql +20 -8
  348. package/dist/schemes/_entry-graph.d.ts +4 -2
  349. package/dist/schemes/_entry-graph.d.ts.map +1 -1
  350. package/dist/schemes/_entry-graph.js +55 -31
  351. package/dist/schemes/_entry-graph.js.map +1 -1
  352. package/dist/schemes/_entry-graph.sql +37 -22
  353. package/dist/schemes/_entry-manifest.d.ts +10 -15
  354. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  355. package/dist/schemes/_entry-manifest.js +50 -268
  356. package/dist/schemes/_entry-manifest.js.map +1 -1
  357. package/dist/schemes/_entry-ops.d.ts +14 -15
  358. package/dist/schemes/_entry-ops.d.ts.map +1 -1
  359. package/dist/schemes/_entry-ops.js +121 -110
  360. package/dist/schemes/_entry-ops.js.map +1 -1
  361. package/dist/schemes/_entry-ops.sql +2 -3
  362. package/dist/schemes/_entry-semantic.d.ts +22 -9
  363. package/dist/schemes/_entry-semantic.d.ts.map +1 -1
  364. package/dist/schemes/_entry-semantic.js +127 -67
  365. package/dist/schemes/_entry-semantic.js.map +1 -1
  366. package/dist/schemes/_entry-semantic.sql +63 -45
  367. package/dist/schemes/_entry-send.d.ts +3 -4
  368. package/dist/schemes/_entry-send.d.ts.map +1 -1
  369. package/dist/schemes/_entry-send.js +48 -23
  370. package/dist/schemes/_entry-send.js.map +1 -1
  371. package/dist/schemes/_path-scope.d.ts +23 -0
  372. package/dist/schemes/_path-scope.d.ts.map +1 -0
  373. package/dist/schemes/_path-scope.js +61 -0
  374. package/dist/schemes/_path-scope.js.map +1 -0
  375. package/dist/schemes/_search-candidate.d.ts +20 -0
  376. package/dist/schemes/_search-candidate.d.ts.map +1 -0
  377. package/dist/schemes/_search-candidate.js +19 -0
  378. package/dist/schemes/_search-candidate.js.map +1 -0
  379. package/dist/schemes/_search-exclusion.d.ts +7 -0
  380. package/dist/schemes/_search-exclusion.d.ts.map +1 -0
  381. package/dist/schemes/_search-exclusion.js +23 -0
  382. package/dist/schemes/_search-exclusion.js.map +1 -0
  383. package/dist/schemes/_search-index.d.ts +6 -0
  384. package/dist/schemes/_search-index.d.ts.map +1 -0
  385. package/dist/schemes/_search-index.js +328 -0
  386. package/dist/schemes/_search-index.js.map +1 -0
  387. package/dist/schemes/cosine.js +1 -1
  388. package/dist/schemes/cosine.js.map +1 -1
  389. package/dist/schemes/exec-abort.js +3 -3
  390. package/dist/schemes/exec-abort.js.map +1 -1
  391. package/dist/schemes/exec-env.js +3 -3
  392. package/dist/schemes/exec-env.js.map +1 -1
  393. package/dist/server/BranchBatches.d.ts +49 -0
  394. package/dist/server/BranchBatches.d.ts.map +1 -0
  395. package/dist/server/BranchBatches.js +592 -0
  396. package/dist/server/BranchBatches.js.map +1 -0
  397. package/dist/server/Daemon.d.ts +39 -71
  398. package/dist/server/Daemon.d.ts.map +1 -1
  399. package/dist/server/Daemon.js +1133 -491
  400. package/dist/server/Daemon.js.map +1 -1
  401. package/dist/server/DaemonModule.d.ts +31 -0
  402. package/dist/server/DaemonModule.d.ts.map +1 -0
  403. package/dist/server/DaemonModule.js +2 -0
  404. package/dist/server/DaemonModule.js.map +1 -0
  405. package/dist/server/branch-batch.sql +154 -0
  406. package/dist/server/client-input.d.ts +13 -0
  407. package/dist/server/client-input.d.ts.map +1 -1
  408. package/dist/server/client-input.js +268 -57
  409. package/dist/server/client-input.js.map +1 -1
  410. package/dist/server/dispatch-as-plurnk.d.ts +1 -1
  411. package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
  412. package/dist/server/dispatch-as-plurnk.js +15 -7
  413. package/dist/server/dispatch-as-plurnk.js.map +1 -1
  414. package/dist/server/drain.sql +96 -65
  415. package/dist/server/envelope.d.ts +4 -7
  416. package/dist/server/envelope.d.ts.map +1 -1
  417. package/dist/server/envelope.js +118 -95
  418. package/dist/server/envelope.js.map +1 -1
  419. package/dist/server/envelope.sql +18 -23
  420. package/dist/server/exec-poll-backoff.js +1 -1
  421. package/dist/server/exec-poll-backoff.js.map +1 -1
  422. package/dist/server/lifecycle-recovery.sql +112 -2
  423. package/dist/server/logEntry.d.ts +4 -2
  424. package/dist/server/logEntry.d.ts.map +1 -1
  425. package/dist/server/logEntry.js +6 -3
  426. package/dist/server/logEntry.js.map +1 -1
  427. package/dist/server/logEntry.sql +1 -1
  428. package/dist/server/loop-model.d.ts.map +1 -1
  429. package/dist/server/loop-model.js +22 -9
  430. package/dist/server/loop-model.js.map +1 -1
  431. package/dist/server/loopDocs.d.ts.map +1 -1
  432. package/dist/server/loopDocs.js +5 -4
  433. package/dist/server/loopDocs.js.map +1 -1
  434. package/dist/server/seam-entry-read.sql +15 -10
  435. package/dist/server/seam-log-read.sql +2 -2
  436. package/dist/server/seam-loop.sql +1 -1
  437. package/dist/server/seam-proposal-list.sql +17 -7
  438. package/dist/service.d.ts.map +1 -1
  439. package/dist/service.js +79 -61
  440. package/dist/service.js.map +1 -1
  441. package/migrations/001_schema.sql +1010 -0
  442. package/package.json +65 -32
  443. package/dist/core/PluginLoader.d.ts +0 -20
  444. package/dist/core/PluginLoader.d.ts.map +0 -1
  445. package/dist/core/PluginLoader.js +0 -142
  446. package/dist/core/PluginLoader.js.map +0 -1
  447. package/dist/core/TelemetryChannel.d.ts +0 -37
  448. package/dist/core/TelemetryChannel.d.ts.map +0 -1
  449. package/dist/core/TelemetryChannel.js +0 -80
  450. package/dist/core/TelemetryChannel.js.map +0 -1
  451. package/dist/core/path-decode.d.ts +0 -3
  452. package/dist/core/path-decode.d.ts.map +0 -1
  453. package/dist/core/path-decode.js +0 -9
  454. package/dist/core/path-decode.js.map +0 -1
  455. package/dist/core/plugin-attribution.d.ts +0 -5
  456. package/dist/core/plugin-attribution.d.ts.map +0 -1
  457. package/dist/core/plugin-attribution.js +0 -39
  458. package/dist/core/plugin-attribution.js.map +0 -1
  459. package/dist/core/world-state.d.ts +0 -10
  460. package/dist/core/world-state.d.ts.map +0 -1
  461. package/dist/core/world-state.js +0 -35
  462. package/dist/core/world-state.js.map +0 -1
  463. package/dist/core/world-state.sql +0 -35
  464. package/dist/core/zero-pin.d.ts +0 -3
  465. package/dist/core/zero-pin.d.ts.map +0 -1
  466. package/dist/core/zero-pin.js +0 -16
  467. package/dist/core/zero-pin.js.map +0 -1
  468. package/dist/server/auto.d.ts +0 -6
  469. package/dist/server/auto.d.ts.map +0 -1
  470. package/dist/server/auto.js +0 -63
  471. package/dist/server/auto.js.map +0 -1
  472. package/dist/server/clientTurn.d.ts +0 -6
  473. package/dist/server/clientTurn.d.ts.map +0 -1
  474. package/dist/server/clientTurn.js +0 -22
  475. package/dist/server/clientTurn.js.map +0 -1
  476. package/dist/server/clientTurn.sql +0 -10
  477. package/dist/server/noProposals.d.ts +0 -6
  478. package/dist/server/noProposals.d.ts.map +0 -1
  479. package/dist/server/noProposals.js +0 -37
  480. package/dist/server/noProposals.js.map +0 -1
  481. package/dist/server/version-info.d.ts +0 -14
  482. package/dist/server/version-info.d.ts.map +0 -1
  483. package/dist/server/version-info.js +0 -69
  484. package/dist/server/version-info.js.map +0 -1
  485. package/migrations/0000-00-00.01_schema.sql +0 -536
  486. package/migrations/0004_loop-provider.sql +0 -3
  487. package/migrations/0005_subscription-published-channel.sql +0 -3
  488. package/migrations/0006_loop-max-turns.sql +0 -3
@@ -1,46 +1,35 @@
1
- import { LineMarkerOps } from "../content/index.js";
2
- import { ReadResolve } from "../content/index.js";
1
+ import { PathSyntax, } from "@plurnk/plurnk-contracts";
3
2
  import Matcher from "../content/matcher.js";
3
+ import { emptyFindFields, projectFindResult } from "./_entry-find.js";
4
4
  import { CoreSchemeAdapterBase } from "../core/CoreSchemeServices.js";
5
+ import Results from "../core/results.js";
6
+ import LogBody from "../core/LogBody.js";
7
+ import EntrySemantic from "./_entry-semantic.js";
8
+ import EntryGraph from "./_entry-graph.js";
9
+ import { resolveSearchCandidates } from "./_search-candidate.js";
10
+ import { pathFolderSummaries, pathScope, pathScopeMatches } from "./_path-scope.js";
5
11
  // log:///<loop_seq>/<turn_seq>/<sequence>[/<op>] — the trailing /op segment
6
12
  // is wire-rendering self-documentation derived from the row's `op` field;
7
13
  // parsing accepts it (or omits it) and identifies the row by coordinate. The op
8
- // suffix is case-INSENSITIVE: model ops render UPPERCASE (READ/EDIT/FIND) but the
9
- // engine-minted rows are lowercase (`error`, `model`), and those are curatable too —
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).
14
+ // suffix is case-INSENSITIVE: model ops render UPPERCASE (READ/EDIT/FIND) while
15
+ // engine-minted selectors such as `error` are lowercase. An actionless model
16
+ // emission has no suffix at all.
12
17
  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,
18
+ // {§log-coordinate-hierarchy} — a log coordinate is a HIERARCHICAL PREFIX: `1` selects loop 1's rows,
14
19
  // `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
20
  // path is unambiguously a prefix — the trailing slash is OPTIONAL (`log:///1/2` ≡ `log:///1/2/`).
16
21
  const PARTIAL_COORDINATE = /^\d+(?:\/\d+)?\/?$/;
17
- // The ONE content projection of a stored rx — what READ shows and therefore what FIND matches
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
22
+ // A log target pathname → the coordinate GLOB it scopes ({§log-coordinate-hierarchy}): a partial
34
23
  // coordinate (`1`, `1/2`, with or without slash) is a prefix over its descendants; a trailing
35
24
  // slash is the folder idiom; a full coordinate/glob passes through. null = malformed.
36
25
  const coordinateGlob = (pathname) => {
37
26
  if (pathname === "")
38
- return "*";
27
+ return "**";
39
28
  if (pathname.endsWith("/"))
40
- return `${pathname}*`;
29
+ return `${pathname}**`;
41
30
  if (PARTIAL_COORDINATE.test(pathname))
42
- return `${pathname}/*`;
43
- if (parseCoordinate(pathname) !== null || pathname.includes("*"))
31
+ return `${pathname}/**`;
32
+ if (parseCoordinate(pathname) !== null || PathSyntax.hasGlob(pathname))
44
33
  return pathname;
45
34
  return null;
46
35
  };
@@ -54,209 +43,322 @@ const parseCoordinate = (pathname) => {
54
43
  sequence: Number(match[3]),
55
44
  };
56
45
  };
57
- // <L> over a matched row set (mirrors EntryFind.#paginate): <N> picks the Nth,
58
- // <N,M> the range; 0→1, -1→last; out-of-range → 416.
59
- const paginate = (items, marker) => {
60
- const total = items.length;
61
- const { first, last } = marker;
62
- if (last === null) {
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
- };
46
+ const canonicalCoordinate = (coordinate) => coordinate.replace(/\/[A-Za-z]+$/, "");
47
+ // A rendered log path appends `/OP` to the canonical loop/turn/item coordinate
48
+ // as self-documentation. Selection honors both views: ordinary path globs map
49
+ // the three-level resource tree, while an explicit OP segment can still filter
50
+ // rows (`log:///**/READ`).
51
+ const coordinateScopeMatches = (scope, coordinate) => pathScopeMatches(scope, coordinate) || pathScopeMatches(scope, canonicalCoordinate(coordinate));
75
52
  export default class Log extends CoreSchemeAdapterBase {
76
53
  static manifest = {
77
54
  name: "log",
78
- channels: {}, // logs render through read(), not channel storage
55
+ channels: {},
79
56
  defaultChannel: "",
80
57
  category: "logging",
81
- scope: "workspace",
82
- // Engine-only WRITES — but KILL ∈ MUTATING_OPS rides this same gate, and log-KILL is the
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.
58
+ // Log KILL is model-authorized curation. Other mutations remain unavailable
59
+ // because Log exposes no edit/writeEntry handler. {§model-entry-log-curation}
86
60
  writableBy: ["plurnk", "model"],
87
61
  volatile: false,
88
62
  modelVisible: true,
89
63
  folderScopes: true,
90
64
  example: "<<READ(log:///1/2/3)::READ",
91
65
  };
92
- async read(statement, ctx) {
66
+ async resolveCoreRepresentation(target, ctx) {
93
67
  const core = this.coreContext(ctx);
94
68
  const { db, workerId } = core;
95
- if (statement.target === null)
96
- return { status: 400, content: null, mimetype: null };
97
- // READ is exact — one coordinate, one row. Tag recall is OPEN[tag]/FIND[tag]'s job (§log-region-tagging),
98
- // not a filter on a single-row read.
99
- if (Array.isArray(statement.signal) && statement.signal.length > 0) {
100
- return { status: 404, content: null, mimetype: null };
69
+ const failure = (code, status, detail, extensions = {}) => ({
70
+ result: Results.failure("scheme:log", code, status, detail, { content: null, mimetype: null, channel: null }, extensions),
71
+ });
72
+ if (target === null) {
73
+ return failure("read-target-required", 400, "READ requires a log coordinate.", {
74
+ recovery: "Provide one exact log coordinate.",
75
+ retryable: false,
76
+ });
101
77
  }
102
- const pathname = (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
78
+ const pathname = (target.kind === "url" ? target.pathname : target.raw).replace(/^\//, "");
103
79
  const coord = parseCoordinate(pathname);
104
- if (coord === null)
105
- return { status: 400, content: null, mimetype: null };
80
+ if (coord === null) {
81
+ return failure("coordinate-malformed", 400, `The log coordinate '${pathname}' is malformed.`, {
82
+ target: pathname,
83
+ recovery: "Use one exact loop/turn/sequence coordinate.",
84
+ retryable: false,
85
+ });
86
+ }
106
87
  const row = await db.log_read_by_coordinate.get({ worker_id: workerId, loop_seq: coord.loopSeq, turn_seq: coord.turnSeq, sequence: coord.sequence });
107
88
  if (row === undefined)
108
- return { status: 404, content: null, mimetype: null };
109
- const { content: underlyingContent, mimetype: underlyingMimetype } = rxProjection(row.rx);
110
- return ReadResolve.resolve({
111
- content: underlyingContent,
112
- mimetype: underlyingMimetype,
113
- lineMarker: statement.lineMarker,
114
- body: statement.body,
115
- mimetypes: core.mimetypes,
89
+ return failure("entry-not-found", 404, `No log entry exists at log:///${pathname}.`);
90
+ const { content: underlyingContent, mimetype: underlyingMimetype } = LogBody.resolve({
91
+ op: row.op,
92
+ attrs: row.attrs,
93
+ tx: row.tx,
94
+ rx: row.rx,
95
+ mimetypeTx: row.mimetype_tx,
96
+ mimetypeRx: row.mimetype_rx,
116
97
  });
98
+ const tags = JSON.parse(row.tags);
99
+ if (!Array.isArray(tags) || !tags.every((tag) => typeof tag === "string")) {
100
+ throw new TypeError(`Log row ${pathname} contains invalid tag storage.`);
101
+ }
102
+ return {
103
+ representation: {
104
+ channels: {
105
+ "": {
106
+ content: underlyingContent,
107
+ mimetype: underlyingMimetype,
108
+ state: "static",
109
+ },
110
+ },
111
+ tags,
112
+ },
113
+ };
117
114
  }
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 projected exactly as READ shows them (rxProjection), so every content
121
- // dialect works on log BY CONSTRUCTION and FIND(log)→READ(coordinate) composes like any scheme.
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).
115
+ // {§log-uniform-query} — FIND over the worker's log rows, on the SAME source-agnostic primitive
116
+ // every entry scheme runs (Matcher.matchCandidates, {§find-source-agnostic}): candidates are the
117
+ // coordinate-scoped rows resolved by LogBody exactly as READ shows them, so every content
118
+ // dialect works on log BY CONSTRUCTION and FIND(log)->READ(coordinate) composes like any scheme.
124
119
  async find(statement, ctx) {
125
- const core = this.coreContext(ctx);
120
+ return this.#find(statement, this.coreContext(ctx));
121
+ }
122
+ async #find(statement, core, allowTargetless = false) {
126
123
  const { db, workerId, mimetypes } = core;
127
- const empty = (status) => ({ status, content: null, mimetype: null, results: [], itemsTokenTotal: 0, pathnames: [], matches: [] });
128
- if (statement.target === null)
129
- return empty(400);
130
- if (statement.body !== null && (statement.body.dialect === "semantic" || statement.body.dialect === "graph"))
131
- return empty(501);
132
- const pathname = (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
124
+ const empty = (status, detail, extensions = {}) => {
125
+ const fields = emptyFindFields();
126
+ if (status >= 400 && detail === undefined) {
127
+ throw new Error(`Log.find: selection returned status ${status} without Problem Details or a diagnostic`);
128
+ }
129
+ return status >= 400
130
+ ? Results.failure("scheme:log", status === 404 ? "entry-not-found" : status === 416 ? "range-not-satisfiable" : status === 501 ? "matcher-not-implemented" : "find-failed", status, detail, fields, extensions)
131
+ : { status, ...fields };
132
+ };
133
+ if (statement.target === null && !allowTargetless) {
134
+ return empty(400, "FIND requires a log target.", {
135
+ recovery: "Provide a log coordinate, prefix, or glob.",
136
+ retryable: false,
137
+ });
138
+ }
139
+ const pathname = statement.target === null
140
+ ? ""
141
+ : (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
133
142
  const glob = coordinateGlob(pathname);
134
- if (glob === null)
135
- return empty(400);
136
- // §log-region-tagging — a tag signal AND-filters the candidates (§find-tag-filter-and-semantics):
143
+ if (glob === null) {
144
+ return empty(400, `The log target '${pathname}' is malformed.`, {
145
+ target: pathname,
146
+ recovery: "Use a log coordinate, prefix, or glob.",
147
+ retryable: false,
148
+ });
149
+ }
150
+ const scope = pathScope(glob, false);
151
+ if (scope.kind === "exact") {
152
+ const coordinate = parseCoordinate(scope.pathname);
153
+ if (coordinate === null)
154
+ throw new Error(`Exact log scope has a malformed coordinate ${JSON.stringify(scope.pathname)}`);
155
+ const exact = await db.log_id_by_coordinate.get({
156
+ worker_id: workerId,
157
+ loop_seq: coordinate.loopSeq,
158
+ turn_seq: coordinate.turnSeq,
159
+ sequence: coordinate.sequence,
160
+ });
161
+ if (exact === undefined) {
162
+ return empty(404, `No log entry exists at ${statement.target?.raw ?? `log:///${scope.pathname}`}.`, { target: statement.target?.raw ?? `log:///${scope.pathname}` });
163
+ }
164
+ }
165
+ // {§log-region-tagging} — a tag signal AND-filters the candidates ({§find-tag-filter-and-semantics}):
137
166
  // a row survives only if it carries EVERY listed tag. No signal → the plain coordinate scope.
138
167
  const tags = Array.isArray(statement.signal) ? statement.signal : [];
139
- const rows = tags.length > 0
140
- ? await db.log_find_candidates_tagged.all({ worker_id: workerId, glob, tags: JSON.stringify(tags) })
141
- : await db.log_find_candidates.all({ worker_id: workerId, glob });
168
+ const candidateRows = tags.length > 0
169
+ ? await db.log_find_candidates_tagged.all({ worker_id: workerId, scope_prefix: scope.candidatePrefix, tags: JSON.stringify(tags) })
170
+ : await db.log_find_candidates.all({ worker_id: workerId, scope_prefix: scope.candidatePrefix });
171
+ let rows;
172
+ try {
173
+ rows = candidateRows.filter((row) => coordinateScopeMatches(scope, row.coordinate));
174
+ }
175
+ catch {
176
+ return empty(400, `The log glob '${glob}' is malformed.`, {
177
+ target: glob,
178
+ recovery: "Correct the log glob.",
179
+ retryable: false,
180
+ });
181
+ }
182
+ const candidateByCanonicalCoord = new Map(candidateRows.map((row) => [canonicalCoordinate(row.coordinate), row]));
142
183
  const byCoord = new Map(rows.map((r) => [r.coordinate, r]));
143
- const projected = rows.map((r) => ({ key: r.coordinate, ...rxProjection(r.rx) }));
184
+ const projected = rows.map((r) => ({
185
+ key: r.coordinate,
186
+ ...LogBody.resolve({
187
+ op: r.op,
188
+ attrs: r.attrs,
189
+ tx: r.tx,
190
+ rx: r.rx,
191
+ mimetypeTx: r.mimetype_tx,
192
+ mimetypeRx: r.mimetype_rx,
193
+ }),
194
+ }));
144
195
  let matches;
145
- if (statement.body === null) {
146
- matches = projected.map((c) => ({ pathname: c.key, span: null }));
196
+ if (statement.body?.dialect === "semantic") {
197
+ if (mimetypes === undefined) {
198
+ return empty(501, "Semantic search requires the mimetypes capability.", {
199
+ stage: "semantic-search",
200
+ retryable: false,
201
+ });
202
+ }
203
+ const candidateSet = resolveSearchCandidates(rows.map(({ coordinate, deep_hash }) => ({ key: coordinate, deepHash: deep_hash })));
204
+ if (candidateSet.state === "incomplete")
205
+ return empty(503, `The persistent search index covers ${candidateSet.indexed} of ${candidateSet.total} selected log results.`, {
206
+ search: candidateSet,
207
+ stage: "search-index",
208
+ recovery: "Wait for search indexing to complete before repeating the search.",
209
+ retryable: false,
210
+ });
211
+ const selection = EntrySemantic.resultSelection(statement.lineMarker);
212
+ const ranked = await EntrySemantic.rankCandidates(db, candidateSet.candidates, mimetypes, statement.body.raw, selection);
213
+ if (ranked.status !== 200) {
214
+ return empty(ranked.status, ranked.status === 501
215
+ ? "Similarity-threshold search requires an embedding provider."
216
+ : "The requested similarity threshold is outside the supported range.", {
217
+ stage: "semantic-search",
218
+ ...(selection.threshold === null ? {} : { threshold: selection.threshold }),
219
+ recovery: ranked.status === 501
220
+ ? "Remove the decimal similarity threshold while embeddings are unavailable."
221
+ : "Use a similarity threshold greater than zero and less than one.",
222
+ retryable: false,
223
+ });
224
+ }
225
+ const sourceMatches = ranked.results.map(({ key, lineStart, lineEnd }) => ({
226
+ key,
227
+ span: { lineStart, lineEnd },
228
+ }));
229
+ const readable = Matcher.addTextRegions(sourceMatches, projected);
230
+ matches = readable.map(({ key, matches: ranges }) => ({ pathname: key, matches: ranges }));
147
231
  }
148
- else {
149
- if (mimetypes === undefined)
150
- return empty(501);
151
- const r = await Matcher.matchCandidates(statement.body, projected, mimetypes);
152
- if (r.status !== 200)
153
- return empty(r.status);
154
- matches = r.matches.map((m) => ({
155
- pathname: m.key,
156
- span: m.span === null ? null : {
157
- ...m.span,
158
- rowStart: m.span.lineStart,
159
- rowEnd: m.span.lineEnd,
160
- },
161
- ...(m.path !== undefined ? { path: m.path } : {}),
232
+ else if (statement.body?.dialect === "graph") {
233
+ const candidateSet = resolveSearchCandidates(rows.map(({ coordinate, deep_hash }) => ({ key: coordinate, deepHash: deep_hash })));
234
+ if (candidateSet.state === "incomplete")
235
+ return empty(503, `The persistent search index covers ${candidateSet.indexed} of ${candidateSet.total} selected log results.`, {
236
+ search: candidateSet,
237
+ stage: "search-index",
238
+ recovery: "Wait for search indexing to complete before repeating the search.",
239
+ retryable: false,
240
+ });
241
+ const universeRows = await db.log_find_candidates.all({ worker_id: workerId, scope_prefix: null });
242
+ const universe = resolveSearchCandidates(universeRows.map(({ coordinate, deep_hash }) => ({ key: coordinate, deepHash: deep_hash })));
243
+ if (universe.state === "incomplete")
244
+ return empty(503, `The persistent search index covers ${universe.indexed} of ${universe.total} log results in the relationship universe.`, {
245
+ search: universe,
246
+ stage: "search-index",
247
+ recovery: "Wait for search indexing to complete before repeating the search.",
248
+ retryable: false,
249
+ });
250
+ const graph = await EntryGraph.matchCandidates(db, universe.candidates, candidateSet.candidates, statement.body.raw);
251
+ if (graph.status !== 200) {
252
+ return empty(graph.status, `The graph matcher '${statement.body.raw}' is malformed.`, {
253
+ stage: "matcher",
254
+ dialect: "graph",
255
+ recovery: "Correct or remove the matcher.",
256
+ retryable: false,
257
+ });
258
+ }
259
+ const sourceMatches = graph.matches.map(({ key, lineStart, lineEnd }) => ({
260
+ key,
261
+ span: { lineStart, lineEnd },
162
262
  }));
263
+ const readable = Matcher.addTextRegions(sourceMatches, projected);
264
+ matches = readable.map(({ key, matches: ranges }) => ({ pathname: key, matches: ranges }));
163
265
  }
164
- if (statement.lineMarker !== null) {
165
- const page = paginate(matches, LineMarkerOps.firstLast(statement.lineMarker));
166
- if (page.status !== 200)
167
- return empty(page.status);
168
- matches = page.items ?? [];
266
+ else if (statement.body === null) {
267
+ matches = projected.map(({ key }) => ({ pathname: key, matches: [] }));
169
268
  }
170
- if (matches.length === 0)
171
- return empty(204);
172
- // §find-count-not-contents is source-agnostic. Log used the shared
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
- };
269
+ else {
270
+ if (mimetypes === undefined) {
271
+ return empty(501, "Content matching requires the mimetypes capability.", {
272
+ stage: "matcher",
273
+ dialect: statement.body.dialect,
274
+ retryable: false,
275
+ });
276
+ }
277
+ const r = await Matcher.matchCandidates(statement.body, projected, mimetypes);
278
+ if (r.status !== 200) {
279
+ if (r.problem === undefined) {
280
+ throw new Error(`Log.find: matcher returned status ${r.status} without Problem Details`);
281
+ }
282
+ return Results.assert({
283
+ status: r.status,
284
+ problem: r.problem,
285
+ ...emptyFindFields(),
286
+ });
287
+ }
288
+ matches = r.matches.map(({ key, matches: ranges }) => ({ pathname: key, matches: ranges }));
190
289
  }
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 = [];
195
- const seenPath = [];
196
- const seen = new Set();
197
- let itemsTokenTotal = 0;
290
+ const folderSummaries = statement.body === null
291
+ ? pathFolderSummaries(scope, candidateRows.map((row) => canonicalCoordinate(row.coordinate)))
292
+ : [];
293
+ const resources = [];
198
294
  for (const m of matches) {
199
295
  const row = byCoord.get(m.pathname);
200
296
  if (row === undefined)
201
297
  continue;
202
298
  const path = `log:///${m.pathname}`;
203
- const proj = rxProjection(row.rx);
299
+ const proj = LogBody.resolve({
300
+ op: row.op,
301
+ attrs: row.attrs,
302
+ tx: row.tx,
303
+ rx: row.rx,
304
+ mimetypeTx: row.mimetype_tx,
305
+ mimetypeRx: row.mimetype_rx,
306
+ });
204
307
  const item = {
205
308
  path,
206
309
  channels: { [path]: { mimetype: proj.mimetype, tokens: row.tokens, lines: proj.content.length === 0 ? 0 : proj.content.split("\n").length } },
207
310
  };
208
- results.push(m.span !== null ? { ...item, matchSpan: m.span, ...(m.path !== undefined ? { matchPath: m.path } : {}) } : item);
209
- if (!seen.has(m.pathname)) {
210
- seen.add(m.pathname);
211
- seenPath.push(m.pathname);
212
- itemsTokenTotal += row.tokens;
213
- }
311
+ resources.push({ item, match: m });
214
312
  }
215
- // matches[].pathname is the fan-out's retarget key — `/loop/turn/seq/OP` re-parses as a
216
- // coordinate (the /OP suffix is accepted), so READ(log://)<matcher> fan-out delivers rows.
217
- const fanMatches = matches.map((m) => ({ ...m, pathname: `/${m.pathname}` }));
218
- return { status: 200, content: JSON.stringify(results), mimetype: "application/json", results, itemsTokenTotal, pathnames: seenPath.map((p) => `/${p}`), matches: fanMatches };
313
+ const scopes = [];
314
+ for (const folder of folderSummaries) {
315
+ const members = folder.pathnames.map((coordinate) => candidateByCanonicalCoord.get(coordinate)).filter((row) => row !== undefined);
316
+ const item = {
317
+ path: `log:///${folder.selector}`,
318
+ items: members.length,
319
+ tokens: members.reduce((sum, row) => sum + row.tokens, 0),
320
+ };
321
+ scopes.push(item);
322
+ }
323
+ return projectFindResult(statement, scope, resources, scopes);
219
324
  }
220
325
  async open(statement, ctx) {
221
326
  return this.#setExpanded(statement, this.coreContext(ctx), 1);
222
327
  }
223
- // FOLD toggles the expanded bit only — an active subscription stays alive. §subscriptions-fold-keeps-subscription
328
+ // FOLD toggles the expanded bit only — an active subscription stays alive. {§subscriptions-fold-keeps-subscription}
224
329
  async fold(statement, ctx) {
225
330
  return this.#setExpanded(statement, this.coreContext(ctx), 0);
226
331
  }
227
- // Resolve a log:/// target — a concrete coordinate, or a path-glob optionally paginated
228
- // by <L> (OPEN/FOLD only) — to the matched row ids. The ONE resolution OPEN/FOLD and
229
- // KILL share: fold flips `expanded` on the ids, kill deletes them.
230
- async #resolveIds(pathname, lineMarker, ctx) {
332
+ // Resolve a log:/// target — a concrete coordinate or path-glob — to the matched row ids.
333
+ // OPEN/FOLD/KILL share this one path selection; log curation has no positional pagination.
334
+ async #resolveIds(pathname, ctx) {
231
335
  const { db, workerId } = ctx;
232
336
  const coord = parseCoordinate(pathname);
233
- if (coord !== null && lineMarker === null) {
337
+ if (coord !== null) {
234
338
  const row = await db.log_id_by_coordinate.get({ worker_id: workerId, loop_seq: coord.loopSeq, turn_seq: coord.turnSeq, sequence: coord.sequence });
235
339
  return row === undefined ? { status: 404, ids: [] } : { status: 200, ids: [row.id] };
236
340
  }
237
- // §log-coordinate-hierarchy — one resolution for every consumer (curation here, find below).
341
+ // {§log-coordinate-hierarchy} — one resolution for every consumer (curation here, find below).
238
342
  const glob = coordinateGlob(pathname);
239
343
  if (glob === null)
240
- return { status: 400, ids: [], error: `malformed log target '${pathname}' — a coordinate (1/2/3), a prefix (1 or 1/2), or a glob (**/READ)` };
241
- const matched = await db.log_match_coordinates.all({ worker_id: workerId, glob });
242
- // Zero matches on a well-formed glob is a NO-OP SUCCESS, not an error (owner ruling): a
243
- // curation sweep that found nothing to curate steers nothing — 204 keeps it out of the
244
- // errors surface (>= 400), and the rx carries matched: 0, clearly shown.
344
+ return { status: 400, ids: [], error: `The log target '${pathname}' is malformed.` };
345
+ const scope = pathScope(glob, false);
346
+ const candidates = await db.log_match_coordinates.all({ worker_id: workerId, scope_prefix: scope.candidatePrefix });
347
+ let matched;
348
+ try {
349
+ matched = candidates.filter((row) => coordinateScopeMatches(scope, row.coordinate));
350
+ }
351
+ catch {
352
+ return { status: 400, ids: [], error: `The log glob '${glob}' is malformed.` };
353
+ }
354
+ // {§log-curation-folder-idiom} — a well-formed empty selection is a
355
+ // successful no-op and remains outside the error surface.
245
356
  if (matched.length === 0)
246
357
  return { status: 204, ids: [] };
247
- let selected = matched;
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) };
358
+ return { status: 200, ids: matched.map((row) => row.id) };
257
359
  }
258
- // §log-region-tagging — resolve OPEN[tag] to ids: candidates are the target's glob scope (the
259
- // whole run when targetless — a bare OPEN[tag] recalls the entire tagged working-set),
360
+ // {§log-region-tagging} — resolve OPEN[tag] to ids: candidates are the target's glob scope (the
361
+ // whole worker log when targetless — a bare OPEN[tag] recalls the entire tagged working-set),
260
362
  // AND-filtered to rows carrying EVERY listed tag. Zero matches is a no-op success (204), mirroring
261
363
  // #resolveIds — recalling a name that tags nothing steers nothing.
262
364
  async #resolveByTags(statement, tags, ctx) {
@@ -264,86 +366,153 @@ export default class Log extends CoreSchemeAdapterBase {
264
366
  const pathname = statement.target === null ? "" : (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
265
367
  const glob = coordinateGlob(pathname);
266
368
  if (glob === null)
267
- return { status: 400, ids: [], error: `malformed log target '${pathname}' — a coordinate (1/2/3), a prefix (1 or 1/2), or a glob (**/READ)` };
268
- const matched = await db.log_match_coordinates_tagged.all({ worker_id: workerId, glob, tags: JSON.stringify(tags) });
369
+ return { status: 400, ids: [], error: `The log target '${pathname}' is malformed.` };
370
+ const scope = pathScope(glob, false);
371
+ const candidates = await db.log_match_coordinates_tagged.all({
372
+ worker_id: workerId,
373
+ scope_prefix: scope.candidatePrefix,
374
+ tags: JSON.stringify(tags),
375
+ });
376
+ let matched;
377
+ try {
378
+ matched = candidates.filter((row) => coordinateScopeMatches(scope, row.coordinate));
379
+ }
380
+ catch {
381
+ return { status: 400, ids: [], error: `The log glob '${glob}' is malformed.` };
382
+ }
269
383
  if (matched.length === 0)
270
384
  return { status: 204, ids: [] };
271
- let selected = matched;
272
- if (statement.lineMarker !== null) {
273
- const page = paginate(matched, LineMarkerOps.firstLast(statement.lineMarker));
274
- if (page.status !== 200)
275
- return { status: page.status, ids: [] };
276
- selected = page.items ?? [];
385
+ return { status: 200, ids: matched.map((row) => row.id) };
386
+ }
387
+ // A matcher-bearing curation op reuses FIND's complete source-agnostic selector with
388
+ // explicit all-results pagination. OPEN's tags filter candidates; FOLD's tags are withheld until
389
+ // after selection because they apply to the rows being folded.
390
+ async #resolveByMatcher(statement, filterTags, ctx) {
391
+ const selected = await this.#find({
392
+ ...statement,
393
+ op: "FIND",
394
+ signal: filterTags ? statement.signal : null,
395
+ lineMarker: { marks: [1, -1] },
396
+ }, ctx, filterTags && Array.isArray(statement.signal) && statement.signal.length > 0 && statement.target === null);
397
+ if (selected.status !== 200)
398
+ return { status: selected.status, ids: [], problem: selected.problem };
399
+ let selectedPaths = selected.results.flatMap((item) => typeof item.path === "string" ? [item.path] : []);
400
+ if (selectedPaths.length === 0) {
401
+ if (statement.target === null) {
402
+ throw new Error("A successful broad log matcher selection returned no resource paths");
403
+ }
404
+ const pathname = (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
405
+ const glob = coordinateGlob(pathname);
406
+ if (glob === null)
407
+ throw new Error(`Log matcher selected malformed target ${JSON.stringify(pathname)}`);
408
+ const scope = pathScope(glob, false);
409
+ if (scope.kind !== "exact") {
410
+ throw new Error("A successful broad log matcher selection returned no resource paths");
411
+ }
412
+ selectedPaths = [scope.pathname];
413
+ }
414
+ const ids = [];
415
+ for (const pathname of selectedPaths) {
416
+ const coordinate = parseCoordinate(pathname.replace(/^log:\/\/\//, "").replace(/^\//, ""));
417
+ if (coordinate === null)
418
+ throw new Error(`Log matcher selected malformed coordinate '${pathname}'`);
419
+ const row = await ctx.db.log_id_by_coordinate.get({
420
+ worker_id: ctx.workerId,
421
+ loop_seq: coordinate.loopSeq,
422
+ turn_seq: coordinate.turnSeq,
423
+ sequence: coordinate.sequence,
424
+ });
425
+ if (row === undefined)
426
+ return { status: 404, ids: [] };
427
+ ids.push(row.id);
428
+ }
429
+ return ids.length === 0 ? { status: 204, ids: [] } : { status: 200, ids };
430
+ }
431
+ async #applyExpanded(ids, expanded, tags, ctx) {
432
+ for (const id of ids)
433
+ await ctx.db.log_set_expanded_by_id.run({ id, expanded });
434
+ if (expanded === 0) {
435
+ for (const id of ids)
436
+ for (const tag of tags)
437
+ await ctx.db.log_write_tag.run({ log_entry_id: id, tag });
277
438
  }
278
- if (selected.length === 0)
279
- return { status: 404, ids: [] };
280
- return { status: 200, ids: selected.map((s) => s.id) };
439
+ return { status: 200, matched: ids.length };
281
440
  }
282
441
  async #setExpanded(statement, ctx, expanded) {
283
442
  const signal = Array.isArray(statement.signal) ? statement.signal : [];
284
- // §log-region-tagging — OPEN[tag] is the READ side: recall rows by tag, target optional (a bare
443
+ if (statement.body !== null) {
444
+ const matched = await this.#resolveByMatcher(statement, expanded === 1, ctx);
445
+ if (matched.status === 204)
446
+ return { status: 204, matched: 0 };
447
+ if (matched.status !== 200) {
448
+ if (matched.problem !== undefined) {
449
+ return Results.assert({ status: matched.status, problem: matched.problem });
450
+ }
451
+ return Results.failure("scheme:log", matched.status === 404 ? "entry-not-found" : "curation-failed", matched.status, "No log entry matches the requested selection.");
452
+ }
453
+ return this.#applyExpanded(matched.ids, expanded, signal, ctx);
454
+ }
455
+ // {§log-region-tagging} — OPEN[tag] is the READ side: recall rows by tag, target optional (a bare
285
456
  // OPEN[tag] recalls the whole tagged working-set). FOLD never resolves by tag — it is the WRITE
286
457
  // side (it stamps the tag below), always scoped to the target region it folds.
287
458
  if (expanded === 1 && signal.length > 0) {
288
459
  const rt = await this.#resolveByTags(statement, signal, ctx);
289
460
  if (rt.status === 204)
290
461
  return { status: 204, matched: 0 };
291
- if (rt.status !== 200)
292
- return { status: rt.status, ...(rt.error !== undefined ? { error: rt.error } : {}) };
293
- for (const id of rt.ids)
294
- await ctx.db.log_set_expanded_by_id.run({ id, expanded: 1 });
295
- return { status: 200, matched: rt.ids.length };
462
+ if (rt.status !== 200) {
463
+ return Results.failure("scheme:log", "open-failed", rt.status, rt.error ?? "No log entry matches the requested selection.", {}, {
464
+ target: statement.target?.raw ?? null,
465
+ ...(rt.status === 400
466
+ ? {
467
+ recovery: "Use a log coordinate, prefix, or glob.",
468
+ retryable: false,
469
+ }
470
+ : {}),
471
+ });
472
+ }
473
+ return this.#applyExpanded(rt.ids, 1, signal, ctx);
474
+ }
475
+ if (statement.target === null) {
476
+ return Results.failure("scheme:log", "target-required", 400, `${expanded === 1 ? "OPEN" : "FOLD"} requires a log target.`, {}, {
477
+ recovery: "Provide a log coordinate, prefix, or glob.",
478
+ retryable: false,
479
+ });
296
480
  }
297
- if (statement.target === null)
298
- return { status: 400 };
299
481
  const pathname = (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
300
- const r = await this.#resolveIds(pathname, statement.lineMarker, ctx);
482
+ const r = await this.#resolveIds(pathname, ctx);
301
483
  if (r.status === 204)
302
484
  return { status: 204, matched: 0 };
303
- if (r.status !== 200)
304
- return { status: r.status, ...(r.error !== undefined ? { error: r.error } : {}) };
305
- let ids = r.ids;
306
- // §prompt-fold-illegal (#382, owner) — the task frame stays visible: the CURRENT loop's
307
- // foisted preview READ (prompt target, origin plurnk, op READ) refuses FOLD (run43: a weak
308
- // model folded its own task in a housekeeping turn and lost the plot). Every other
309
- // prompt-target row — the born-folded EDIT foist, the model's own deeper prompt READs,
310
- // prior loops' previews — is ordinary curatable memory; KILL still DELETES deliberately.
311
- // A glob sweep silently spares the preview and folds the rest; an explicit fold whose
312
- // whole target IS the preview gets the steer.
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
- }
485
+ if (r.status !== 200) {
486
+ return Results.failure("scheme:log", r.status === 404 ? "entry-not-found" : "curation-failed", r.status, r.error ?? `No log entry matches '${pathname}'.`, {}, {
487
+ target: pathname,
488
+ ...(r.status === 400
489
+ ? {
490
+ recovery: "Use a log coordinate, prefix, or glob.",
491
+ retryable: false,
492
+ }
493
+ : {}),
494
+ });
325
495
  }
326
- for (const id of ids)
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 };
496
+ return this.#applyExpanded(r.ids, expanded, signal, ctx);
337
497
  }
338
- // KILL erases log items (plurnk.md:36, :98) — the model's DB-storage curation lever and
339
- // the only way to shed accumulated log rows in a long workspace (FOLD only collapses the
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.
498
+ // KILL shares OPEN/FOLD's address resolution, deletes instead of flipping visibility,
499
+ // and carries no positional scope. {§model-entry-log-curation} {§log-curation-set-selection}
342
500
  async kill(pathname, _signal, ctx) {
343
501
  const core = this.coreContext(ctx);
344
- const r = await this.#resolveIds(pathname.replace(/^\//, ""), null, core);
345
- if (r.status !== 200)
346
- return { status: r.status };
502
+ const r = await this.#resolveIds(pathname.replace(/^\//, ""), core);
503
+ if (r.status === 204)
504
+ return { status: 204 };
505
+ if (r.status !== 200) {
506
+ return Results.failure("scheme:log", r.status === 404 ? "entry-not-found" : "kill-failed", r.status, r.error ?? `No log entry matches '${pathname}'.`, {}, {
507
+ target: pathname,
508
+ ...(r.status === 400
509
+ ? {
510
+ recovery: "Use a log coordinate, prefix, or glob.",
511
+ retryable: false,
512
+ }
513
+ : {}),
514
+ });
515
+ }
347
516
  for (const id of r.ids)
348
517
  await core.db.log_delete_by_id.run({ id });
349
518
  return { status: 200 };