@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,15 +1,15 @@
1
- -- Engine SQL. SPEC §arch (architecture), §scheme (op dispatch + log).
1
+ -- Engine SQL. SPEC {§arch} (architecture), {§scheme} (op dispatch + log).
2
2
 
3
3
  -- PREP: engine_loop_status
4
4
  SELECT status FROM loops WHERE id = $loop_id;
5
5
 
6
6
  -- PREP: engine_worker_has_live_child
7
- -- A non-terminal CHILD run (worker:// spawn/fork set parent_worker_id) — a "live thing the worker holds",
8
- -- like an open stream. A SEND[200] while one exists is a premature-terminate (§send-premature-terminate).
7
+ -- A non-terminal child worker (worker:// spawn/fork set parent_worker_id) — a "live thing the worker holds",
8
+ -- like an open stream. A SEND[200] while one exists is a premature-terminate ({§send-premature-terminate}).
9
9
  -- Live = a child whose LATEST loop is still pending/running/parked (100/102/202) — the SAME definition
10
- -- engine_child_workers_live uses for the Child Runs orientation, so the 409 gate and the section the model
10
+ -- engine_child_workers_live uses for the Active Child Workers orientation, so the 409 gate and the section the model
11
11
  -- reads NEVER disagree: a refused termination is always backed by a child the model can SEE and KILL
12
- -- (§child-orientation). An inherited/historical loop (a fork copies the parent's loops) is not the
12
+ -- ({§child-orientation}). An inherited/historical loop (a fork copies the parent's loops) is not the
13
13
  -- latest, so it never makes a concluded child look forever-live.
14
14
  SELECT 1 AS live FROM workers r
15
15
  JOIN loops l ON l.id = (SELECT id FROM loops WHERE worker_id = r.id ORDER BY sequence DESC, id DESC LIMIT 1)
@@ -22,46 +22,34 @@ WHERE r.parent_worker_id = $worker_id AND l.status IN (100, 102, 202) LIMIT 1;
22
22
  SELECT COUNT(*) AS n FROM loops WHERE worker_id = $worker_id AND status = 102;
23
23
 
24
24
  -- PREP: engine_get_loop_flags
25
- -- Loads the loop's persisted flags (json). Default '{}'; auto listener and
26
- -- SchemeRegistry.resolveForLoop merge over DEFAULT_LOOP_FLAGS for missing
27
- -- fields. Migration 014.
25
+ -- Raw persisted partial policy. LoopFlagsReader is the sole runtime expansion
26
+ -- and validation path ({§loop-flags-effective-read}).
28
27
  SELECT flags FROM loops WHERE id = $loop_id;
29
28
 
30
29
  -- PREP: engine_set_loop_flags
31
- -- Updates the loop's persisted flags (json). Called by loop.run RPC handler.
30
+ -- Updates the loop's persisted flags (json). Called by the runLoop seam.
32
31
  UPDATE loops SET flags = $flags WHERE id = $loop_id;
33
32
 
34
- -- PREP: engine_tag_loop_attributions
35
- -- #249 — tag the loop with its active plugins' attribution tags (string[] JSON), write-once: the
36
- -- active set is loop-stable, so the `= '[]'` guard keeps later turns from rewriting it.
37
- UPDATE loops SET attributions = $attributions WHERE id = $loop_id AND attributions = '[]';
38
-
39
33
  -- PREP: engine_set_loop_open_paths
40
- -- #260 — persist the loop.run-passed @file paths (string[] JSON) on the loop before the drain
41
- -- starts, so runTurn foists a turn-0 READ of each (same seam as the #250 AGENTS.md auto-read).
34
+ -- {§methods-loop-run-open-paths}: persist the initial prompt frame's selected
35
+ -- paths (string[] JSON) until turn 1 materializes that frame.
42
36
  UPDATE loops SET open_paths = $open_paths WHERE id = $loop_id;
43
37
 
44
- -- PREP: engine_get_loop_open_paths
45
- -- #260 — runTurn reads the loop's @file foist-paths at turn 0.
46
- SELECT open_paths FROM loops WHERE id = $loop_id;
47
-
48
38
  -- PREP: engine_get_loop_prompt
49
- -- Loop's prompt + sequence — runTurn reads it on turn 1 to foist a
50
- -- system-origin EDIT against plurnk://prompt/<run>/<loop>/1 (§packet), at the
51
- -- turn's first action sequence. Prompts are first-class log entries
52
- -- (no synthetic / shim layer).
53
- SELECT prompt, sequence FROM loops WHERE id = $loop_id;
39
+ -- Initial prompt frame. On turn 1, runTurn stores the owner-keyed
40
+ -- prompt:///<loop>/1 entry with its selected paths and publishes it.
41
+ SELECT prompt, sequence, open_paths FROM loops WHERE id = $loop_id;
54
42
 
55
43
  -- PREP: engine_reclaim_queued_loop
56
- -- §worker-lifecycle-wake-requeue-not-terminal — atomic 100→102 re-claim by loop id. A wake
44
+ -- {§worker-lifecycle-wake-requeue-not-terminal} — atomic 100→102 re-claim by loop id. A wake
57
45
  -- re-queued this loop while ITS OWN live drain was between turns; the drain re-claims and
58
46
  -- keeps running (the injected prompt is already the next turn). Conditional so a racing
59
47
  -- claimant can never double-claim.
60
48
  UPDATE loops SET status = 102 WHERE id = $loop_id AND status = 100;
61
49
 
62
50
  -- PREP: workspace_get_settings
63
- -- #231 — the workspace's client-chosen open-context bag ({ manifestItems?, mdDocs? }),
64
- -- read at turn-0 with precedence over env.
51
+ -- {§operator-config} — the workspace's validated client settings bag, read at
52
+ -- each owning use site with its declared composition semantics.
65
53
  SELECT settings FROM workspaces WHERE id = $workspace_id;
66
54
 
67
55
  -- PREP: engine_target_diverged_this_turn
@@ -75,26 +63,29 @@ WHERE worker_id = $worker_id AND turn_id = $turn_id
75
63
  AND scheme IS $scheme AND pathname = $pathname
76
64
  LIMIT 1;
77
65
 
78
- -- PREP: engine_list_workspace_entry_tags
79
- -- #note13 — every (entry, tag) in the workspace, for the manifest catalog's tags field.
80
- SELECT et.entry_id, et.tag
81
- FROM entry_tags et
82
- JOIN entries e ON e.id = et.entry_id
83
- WHERE e.workspace_id = $workspace_id
84
- ORDER BY et.entry_id, et.tag;
85
-
86
- -- PREP: engine_list_worker_entries
66
+ -- PREP: engine_list_owner_entries
87
67
  -- {§entry-owner} — one principal's entries (catalogRowsFor source for an owner-scoped FIND/foist):
88
68
  -- the commons, a worker's own space, or a named space — exactly one owner's rows, its perspective.
89
69
  SELECT e.id AS entry_id, e.scheme, e.pathname, ec.name AS channel, ec.content, ec.mimetype, ec.tokens AS tokens, e.deep_hash,
90
- CAST(unixepoch('now') - unixepoch(s.opened_at) AS INTEGER) AS seconds
70
+ s.id AS subscription_id,
71
+ CASE WHEN s.closed_at IS NULL
72
+ THEN CAST(unixepoch('now') - unixepoch(s.opened_at) AS INTEGER)
73
+ ELSE NULL
74
+ END AS seconds,
75
+ s.close_status
91
76
  FROM entries e
92
77
  JOIN entry_channels ec ON ec.entry_id = e.id
93
- LEFT JOIN subscriptions s ON s.entry_id = e.id AND s.closed_at IS NULL
78
+ LEFT JOIN subscriptions s ON s.id = (
79
+ SELECT latest.id
80
+ FROM subscriptions latest
81
+ WHERE latest.entry_id = e.id
82
+ ORDER BY latest.id DESC
83
+ LIMIT 1
84
+ )
94
85
  WHERE e.workspace_id = $workspace_id AND e.owner_id = $owner_id
95
86
  ORDER BY e.updated_at ASC, e.id ASC, ec.name;
96
87
 
97
- -- PREP: engine_list_worker_entry_tags
88
+ -- PREP: engine_list_owner_entry_tags
98
89
  -- {§entry-owner} — (entry, tag) for one principal's entries (the owner-scoped catalog's tags field).
99
90
  SELECT et.entry_id, et.tag
100
91
  FROM entry_tags et
@@ -102,33 +93,62 @@ JOIN entries e ON e.id = et.entry_id
102
93
  WHERE e.workspace_id = $workspace_id AND e.owner_id = $owner_id
103
94
  ORDER BY et.entry_id, et.tag;
104
95
 
105
- -- PREP: engine_worker_scratch_count
106
- -- §worker-scheme — distinct entry count owned by the building worker, to decide whether the
107
- -- turn-0 catalog foists a FIND(worker://~/**) (a worker with no private space foists nothing).
108
- SELECT COUNT(DISTINCT e.id) AS entries
109
- FROM entries e
110
- WHERE e.workspace_id = $workspace_id AND e.owner_id = $owner_id;
111
-
112
96
  -- PREP: engine_next_turn_sequence
113
97
  SELECT COALESCE(MAX(sequence), 0) + 1 AS next FROM turns WHERE loop_id = $loop_id;
114
98
 
115
99
  -- PREP: engine_loop_usage
116
- -- Per-loop usage totals — SUM the loop's turns (§tokenomics stores usage per turn).
117
- -- Surfaced on loop.run + loop/terminated (#197). `context` is the LAST turn's prompt tokens — the
118
- -- honest window-occupancy numerator (#263), distinct from the summed `prompt` (which overcounts a
119
- -- context that grows across turns).
100
+ -- Per-loop usage totals and latest-turn gauge ({§tokenomics-client-gauge}),
101
+ -- surfaced on {§notifications-loop-terminated}. `context` is the latest
102
+ -- provider attempt on the latest turn, distinct from summed billed `prompt`.
120
103
  SELECT COALESCE(SUM(usage_prompt), 0) AS prompt,
121
104
  COALESCE(SUM(usage_completion), 0) AS completion,
122
- COALESCE(SUM(usage_cost_usd), 0) AS cost_usd,
123
- (SELECT usage_prompt FROM turns WHERE loop_id = $loop_id ORDER BY sequence DESC LIMIT 1) AS context,
124
- -- #274 — the LAST turn's model window (denominator), so numerator + denominator come from
125
- -- the same loop/model; NULL when the provider reports no window.
105
+ COALESCE(SUM(usage_reasoning), 0) AS reasoning,
106
+ COALESCE(SUM(usage_cached), 0) AS cached,
107
+ (SELECT cost_usd FROM loop_costs WHERE id = $loop_id) AS cost_usd,
108
+ COALESCE((
109
+ SELECT json_group_array(json(cost.value))
110
+ FROM turns charged, json_each(charged.usage_cost) AS cost
111
+ WHERE charged.loop_id = $loop_id
112
+ ), '[]') AS costs,
113
+ (
114
+ SELECT a.usage_prompt
115
+ FROM turn_attempts a
116
+ WHERE a.turn_id = (
117
+ SELECT latest.id
118
+ FROM turns latest
119
+ WHERE latest.loop_id = $loop_id
120
+ ORDER BY latest.sequence DESC
121
+ LIMIT 1
122
+ )
123
+ AND a.state = 'response'
124
+ ORDER BY a.sequence DESC
125
+ LIMIT 1
126
+ ) AS context,
127
+ -- Latest turn's effective packet allowance; NULL when uncapped or unknown.
128
+ -- {§tokenomics-client-gauge}
126
129
  (SELECT usage_prompt_budget FROM turns WHERE loop_id = $loop_id ORDER BY sequence DESC LIMIT 1) AS context_size,
127
- -- #252 — the opaque provider meta blob from the LATEST turn (for example, a
128
- -- point-in-time snapshot; latest wins). Service-unenforced passthrough to the client.
130
+ -- Latest turn's opaque provider metadata. {§meta-passthrough}
129
131
  (SELECT meta FROM turns WHERE loop_id = $loop_id ORDER BY sequence DESC LIMIT 1) AS meta
130
132
  FROM turns WHERE loop_id = $loop_id;
131
133
 
134
+ -- PREP: engine_loop_attributions
135
+ -- {§attribution} — derive the loop projection from exact response-attempt
136
+ -- evidence plus each turn's latest request (which also covers a call that
137
+ -- failed without response evidence).
138
+ SELECT attribution
139
+ FROM (
140
+ SELECT value AS attribution
141
+ FROM turns t, json_each(t.packet, '$.attributions')
142
+ WHERE t.loop_id = $loop_id
143
+ UNION
144
+ SELECT value AS attribution
145
+ FROM turn_attempts a
146
+ JOIN turns t ON t.id = a.turn_id,
147
+ json_each(a.attributions)
148
+ WHERE t.loop_id = $loop_id
149
+ )
150
+ ORDER BY attribution;
151
+
132
152
  -- PREP: engine_loop_turn_seqs
133
153
  -- Look up (loop_seq, turn_seq) for a given (loop_id, turn_id). Used by
134
154
  -- #writeLog when an op needs to address itself or its output by log
@@ -138,109 +158,193 @@ FROM loops l, turns t
138
158
  WHERE l.id = $loop_id AND t.id = $turn_id;
139
159
 
140
160
  -- PREP: engine_open_turn
141
- -- Turn-as-container model: insert a turn row at runTurn open with a
142
- -- placeholder packet and status=102 (in-progress). Pre-model writes
143
- -- (the user prompt; later, system signals/telemetry events) land into
161
+ -- Turn-as-container model: insert a turn row at runTurn open with no assembled
162
+ -- model request and status=102 (in-progress). Pre-model writes
163
+ -- (the user prompt; later, system signals/notices) land into
144
164
  -- this row before the provider is called. The turn is then "closed"
145
165
  -- via engine_close_turn with the final packet + status + usage stats
146
166
  -- after dispatch completes.
147
- INSERT INTO turns (loop_id, sequence, status, packet)
148
- VALUES ($loop_id, $sequence, 102, '{}')
167
+ INSERT INTO turns (loop_id, sequence, status)
168
+ VALUES ($loop_id, $sequence, 102)
149
169
  RETURNING id;
150
170
 
151
171
  -- PREP: engine_close_turn
152
- -- Updates the turn with the response packet, terminal status, and
153
- -- provider usage stats once dispatch is complete. Paired with
154
- -- engine_open_turn at runTurn boundaries.
172
+ -- Updates the turn with the response packet and terminal metadata once dispatch
173
+ -- is complete. Provider attempts own and materialize usage/cost above this path.
155
174
  UPDATE turns SET
156
175
  status = $status,
157
176
  packet = $packet,
177
+ usage_prompt_budget = $usage_prompt_budget,
178
+ finish_reason = $finish_reason,
179
+ model = $model,
180
+ meta = $meta
181
+ WHERE id = $id;
182
+
183
+ -- PREP: engine_open_turn_attempt
184
+ -- Identity and request attribution become durable before provider I/O.
185
+ INSERT INTO turn_attempts (turn_id, sequence, attributions, model)
186
+ VALUES ($turn_id, $sequence, $attributions, $model)
187
+ RETURNING id;
188
+
189
+ -- PREP: engine_observe_turn_attempt_response
190
+ -- Preserve the response and provider usage before parser/cost classification.
191
+ -- Unknown is the safe monetary evidence until the following classification.
192
+ UPDATE turn_attempts SET
193
+ state = 'response',
194
+ response = $response,
158
195
  usage_prompt = $usage_prompt,
159
196
  usage_completion = $usage_completion,
160
197
  usage_reasoning = $usage_reasoning,
161
198
  usage_cached = $usage_cached,
162
- usage_cost_usd = $usage_cost_usd,
163
- usage_prompt_budget = $usage_prompt_budget,
199
+ usage_cost = $usage_cost,
200
+ usage_cost_usd = NULL,
164
201
  finish_reason = $finish_reason,
165
202
  model = $model,
166
- meta = $meta
167
- WHERE id = $id;
203
+ completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
204
+ WHERE id = $id AND state = 'pending';
205
+
206
+ -- PREP: engine_classify_turn_attempt_response
207
+ UPDATE turn_attempts SET
208
+ accepted = $accepted,
209
+ parse_errors = $parse_errors,
210
+ failure = $failure,
211
+ usage_cost = $usage_cost,
212
+ usage_cost_usd = $usage_cost_usd
213
+ WHERE id = $id AND state = 'response';
214
+
215
+ -- PREP: engine_fail_turn_attempt
216
+ UPDATE turn_attempts SET
217
+ state = 'error',
218
+ failure = $failure,
219
+ usage_prompt = 0,
220
+ usage_completion = 0,
221
+ usage_reasoning = 0,
222
+ usage_cached = 0,
223
+ usage_cost = $usage_cost,
224
+ usage_cost_usd = NULL,
225
+ completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
226
+ WHERE id = $id AND state = 'pending';
168
227
 
169
228
  -- PREP: engine_list_workspace_entries
170
- -- Every entry of a workspace — all schemes, all channels — the source behind the entry
171
- -- catalog (catalogRowsFor / FIND) and the per-turn derivation pump (maintainDerivations).
172
- -- Workspace-scoped (persists across runs); FOLD doesn't drop from the catalog.
173
- -- `seconds` is the live age of an active stream: now − the open subscription's
174
- -- opened_at (closed_at IS NULL). NULL for static entries. unixepoch parses the
175
- -- stored '...%fZ' timestamp directly; re-evaluated every render like tokens.
229
+ -- Every owner-held entry of a workspace — all schemes, all channels — for
230
+ -- internal indexing and aggregate inspection. Addressable catalogs use the
231
+ -- owner-filtered statements above.
232
+ -- The latest subscription carries stream lifecycle into the catalog. `seconds`
233
+ -- is the live age of an open stream; close_status is the exact terminal status
234
+ -- of a closed one. Entries with no subscription remain ordinary static entries.
176
235
  SELECT e.id AS entry_id, e.scheme, e.pathname, ec.name AS channel, ec.content, ec.mimetype, ec.tokens AS tokens, e.deep_hash,
177
- CAST(unixepoch('now') - unixepoch(s.opened_at) AS INTEGER) AS seconds
236
+ s.id AS subscription_id,
237
+ CASE WHEN s.closed_at IS NULL
238
+ THEN CAST(unixepoch('now') - unixepoch(s.opened_at) AS INTEGER)
239
+ ELSE NULL
240
+ END AS seconds,
241
+ s.close_status
178
242
  FROM entries e
179
243
  JOIN entry_channels ec ON ec.entry_id = e.id
180
- LEFT JOIN subscriptions s ON s.entry_id = e.id AND s.closed_at IS NULL
181
- -- entries are workspace-scoped, shared across runs — §machine-processes-one-filesystem
244
+ LEFT JOIN subscriptions s ON s.id = (
245
+ SELECT latest.id
246
+ FROM subscriptions latest
247
+ WHERE latest.entry_id = e.id
248
+ ORDER BY latest.id DESC
249
+ LIMIT 1
250
+ )
182
251
  WHERE e.workspace_id = $workspace_id
183
252
  -- User Note 5 — mtime-ascending: dormant entries hold the stable prompt-cache prefix; churn clusters at the tail.
184
253
  ORDER BY e.updated_at ASC, e.id ASC, ec.name;
185
254
 
186
255
  -- PREP: engine_scheme_catalog_summary
187
- -- Per-scheme entry tally (distinct count; scheme=null → file). Sources the turn-0 per-scheme
188
- -- foist so the model sees which schemes hold content without running FIND(known://**) itself;
189
- -- the foist FIND carries each scheme's live token weight.
256
+ -- Per-scheme entry tally plus one-level catalog-row count (direct entries and
257
+ -- distinct first-segment `dir/**` summaries). The engine uses the latter to
258
+ -- encode a valid first-N file preview range without guessing how many rows the
259
+ -- shallow projection will produce.
190
260
  SELECT e.scheme AS scheme,
191
- COUNT(DISTINCT e.id) AS entries
261
+ COUNT(DISTINCT e.id) AS entries,
262
+ COUNT(DISTINCT CASE
263
+ WHEN instr(ltrim(e.pathname, '/'), '/') = 0
264
+ THEN 'entry:' || ltrim(e.pathname, '/')
265
+ ELSE 'scope:' || substr(ltrim(e.pathname, '/'), 1, instr(ltrim(e.pathname, '/'), '/'))
266
+ END) AS shallow_items
192
267
  FROM entries e
193
268
  JOIN entry_channels ec ON ec.entry_id = e.id
194
269
  WHERE e.workspace_id = $workspace_id
195
270
  GROUP BY e.scheme
196
271
  ORDER BY e.scheme;
197
272
 
198
- -- PREP: engine_worker_prior_turn_time
199
- -- §env-delta — timestamp of this worker's most recent turn BEFORE the current one
200
- -- (the "since I last looked" boundary). NULL on the worker's first turn → no deltas.
201
- SELECT MAX(t.timestamp) AS since
202
- FROM turns t JOIN loops l ON l.id = t.loop_id
203
- WHERE l.worker_id = $worker_id AND t.id != $turn_id;
204
-
205
- -- PREP: engine_pull_env_deltas
206
- -- §env-delta — other actors' resolved EDITs on shared entries since this worker last
207
- -- looked. Real edits (origin model/client) AND the plurnk worker's fs-sync fictions
208
- -- (origin=plurnk on the reserved 'plurnk' run); excludes this worker's own rows and
209
- -- other workers' already-materialized deltas (origin=plurnk on a real run). plurnk:///
210
- -- entries (manifest/prompt/doc) never surface. This is the environment door (§actor-boundary-two-doors); the voice door is inject.
211
- SELECT le.worker_id, le.scheme, le.pathname, le.rx, le.source, le.attrs
212
- FROM log_entries le
213
- JOIN workers r ON r.id = le.worker_id
214
- WHERE r.workspace_id = $workspace_id
215
- AND le.op = 'EDIT'
216
- AND le.state = 'resolved'
217
- AND le.status_rx IN (200, 201)
218
- AND (le.scheme IS NULL OR le.scheme != 'plurnk')
219
- AND le.worker_id != $worker_id
220
- AND le.at > $since
221
- AND (le.origin != 'plurnk'
222
- OR le.worker_id = (SELECT id FROM workers WHERE workspace_id = $workspace_id AND name = 'plurnk'))
223
- ORDER BY le.at;
224
-
225
- -- PREP: engine_insert_env_delta
226
- -- §env-delta — materialize a pulled cross-actor edit as a FOLDED delta (expanded=0)
227
- -- in this worker's log. origin=plurnk; source carries the cause (sibling worker id or
228
- -- 'file'); rx reuses the originating row's result span (§edit-result-render).
273
+ -- PREP: engine_initialize_ambient_cursor
274
+ -- A worker's first packet reads current shared state directly, so pre-existing
275
+ -- occurrences are its baseline rather than historical deltas. The NULL guard
276
+ -- makes this safe on every turn and preserves a fork's inherited progress.
277
+ UPDATE workers
278
+ SET ambient_event_cursor = COALESCE((
279
+ SELECT MAX(ae.id) FROM ambient_events ae WHERE ae.workspace_id = $workspace_id
280
+ ), 0)
281
+ WHERE id = $worker_id
282
+ AND workspace_id = $workspace_id
283
+ AND ambient_event_cursor IS NULL
284
+ RETURNING ambient_event_cursor;
285
+
286
+ -- PREP: engine_pull_ambient_events
287
+ -- One SQLite snapshot captures both ends of the closed observation window.
288
+ -- The LEFT JOIN returns the boundary even when the window contains no event.
289
+ WITH observation AS (
290
+ SELECT w.ambient_event_cursor AS cursor,
291
+ COALESCE(
292
+ (SELECT MAX(ae.id) FROM ambient_events ae WHERE ae.workspace_id = $workspace_id),
293
+ w.ambient_event_cursor,
294
+ 0
295
+ ) AS boundary
296
+ FROM workers w
297
+ WHERE w.id = $worker_id AND w.workspace_id = $workspace_id
298
+ )
299
+ SELECT o.cursor, o.boundary,
300
+ ae.id AS event_id, ae.producer_worker_id, producer.name AS producer_worker_name,
301
+ ae.kind, ae.source,
302
+ ae.op, ae.scheme, ae.hostname, ae.pathname, ae.rx, ae.attrs,
303
+ ae.status_rx, ae.terminated_by
304
+ FROM observation o
305
+ LEFT JOIN ambient_events ae
306
+ ON ae.workspace_id = $workspace_id
307
+ AND ae.id > o.cursor
308
+ AND ae.id <= o.boundary
309
+ AND ae.producer_worker_id != $worker_id
310
+ LEFT JOIN workers producer ON producer.id = ae.producer_worker_id
311
+ ORDER BY ae.id;
312
+
313
+ -- PREP: engine_insert_ambient_delta
314
+ -- Materialize one occurrence into the observer's self-contained log. The
315
+ -- targeted conflict rule makes crash replay idempotent without swallowing any
316
+ -- unrelated sequence, FK, or shape violation.
229
317
  INSERT INTO log_entries (
230
- worker_id, loop_id, turn_id, sequence, origin, source,
231
- op, scheme, pathname, tx, mimetype_tx, rx, mimetype_rx, status_rx, expanded, attrs
318
+ worker_id, loop_id, turn_id, sequence, origin, source, ambient_event_id,
319
+ op, scheme, hostname, pathname, tx, mimetype_tx,
320
+ rx, mimetype_rx, status_rx, expanded, attrs
232
321
  ) VALUES (
233
- $worker_id, $loop_id, $turn_id, $sequence, 'plurnk', $source,
234
- 'EDIT', $scheme, $pathname, '', 'text/plain', $rx, 'application/json', 200, 0, $attrs
235
- );
322
+ $worker_id, $loop_id, $turn_id, $sequence, 'plurnk', $source, $event_id,
323
+ $op, $scheme, $hostname, $pathname, '', 'text/plain',
324
+ $rx, $mimetype_rx, $status, $expanded, $attrs
325
+ )
326
+ ON CONFLICT(worker_id, ambient_event_id) WHERE ambient_event_id IS NOT NULL DO NOTHING
327
+ RETURNING id;
328
+
329
+ -- PREP: engine_advance_ambient_cursor
330
+ -- Advance only from the snapshot that was actually materialized. A concurrent
331
+ -- pull winning the CAS is safe; a loser replays idempotently on its next turn.
332
+ UPDATE workers
333
+ SET ambient_event_cursor = $boundary
334
+ WHERE id = $worker_id
335
+ AND workspace_id = $workspace_id
336
+ AND ambient_event_cursor IS $cursor
337
+ AND $boundary >= ambient_event_cursor
338
+ RETURNING ambient_event_cursor;
236
339
 
237
340
  -- PREP: engine_worker_stream_channels
238
- -- §exec-stream — every stream channel the worker owns (an EXEC's stdout/stderr live on the
239
- -- runtime-tag entry), with content + state + coordinate, so the per-turn injector can emit the
240
- -- channel's unshown byte-delta. Stays listed until its last delta is shown (cursor == content len).
341
+ -- {§exec-stream} — every stream channel the worker owns (an EXEC's stdout/stderr live on the
342
+ -- runtime-tag entry), with content + mimetype + state + coordinate, so the per-turn injector can
343
+ -- publish the channel's next complete unit. Stays listed until its terminal observation is shown.
241
344
  SELECT s.id AS subscription_id, e.scheme AS runtime, e.pathname AS coord,
242
- ec.name AS channel, ec.content AS content, ec.state AS state, s.close_status AS close_status,
243
- s.published_channel AS published_channel
345
+ ec.name AS channel, ec.content AS content, ec.mimetype AS mimetype,
346
+ ec.state AS state, s.close_status AS close_status,
347
+ s.close_result AS close_result, s.published_channel AS published_channel
244
348
  FROM subscriptions s
245
349
  JOIN entries e ON e.id = s.entry_id
246
350
  JOIN entry_channels ec ON ec.entry_id = s.entry_id
@@ -249,8 +353,8 @@ WHERE s.worker_id = $worker_id
249
353
  ORDER BY s.id, ec.name;
250
354
 
251
355
  -- PREP: engine_stream_cursor
252
- -- §exec-stream — bytes of this channel already shown to the worker: the streamEnd recorded on its
253
- -- latest foisted delta (the caller defaults to 0 when none exists yet).
356
+ -- {§exec-stream} — content offset already shown to the worker: the streamEnd recorded on its latest
357
+ -- foisted observation (the caller defaults to 0 when none exists yet).
254
358
  SELECT attrs
255
359
  FROM log_entries
256
360
  WHERE worker_id = $worker_id AND origin = 'plurnk' AND op = 'READ'
@@ -258,44 +362,16 @@ WHERE worker_id = $worker_id AND origin = 'plurnk' AND op = 'READ'
258
362
  ORDER BY id DESC LIMIT 1;
259
363
 
260
364
  -- PREP: engine_insert_stream_delta
261
- -- §exec-stream / §env-delta — materialize a channel's unshown byte-delta as a
262
- -- foisted READ@200 row (the model READs the stream it never typed). origin=plurnk; fragment is
263
- -- the channel; attrs.streamEnd is the next turn's cursor; expanded=1 when the channel has CLOSED
264
- -- (the terminal delta auto-OPENs), 0 while it streams (ongoing deltas fold). §exec-stream
365
+ -- {§exec-stream} / {§env-delta} — materialize a channel's next publishable content as a
366
+ -- foisted READ row (the model READs the stream it never typed). origin=plurnk; fragment is
367
+ -- the channel; attrs.streamEnd is the next turn's cursor; expanded=1 for a terminal
368
+ -- observation, 0 for an ongoing observation. {§exec-stream}
265
369
  INSERT INTO log_entries (
266
370
  worker_id, loop_id, turn_id, sequence, origin, source,
267
371
  op, scheme, pathname, fragment, tx, mimetype_tx, rx, mimetype_rx, status_rx, attrs, expanded
268
372
  ) VALUES (
269
373
  $worker_id, $loop_id, $turn_id, $sequence, 'plurnk', NULL,
270
- 'READ', $scheme, $pathname, $fragment, '', 'text/plain', $rx, 'application/json', 200, $attrs, $expanded
271
- );
272
-
273
- -- PREP: engine_pull_loop_terminations
274
- -- §worker-scheme — sibling runs' loops that reached a terminal status since this worker last
275
- -- looked (the loop-termination ambient delta). Carries terminal_message — the SEND[200]
276
- -- deliverable or the abandonment reason — plus terminated_by so a cancellation renders
277
- -- its marker (#379). Excludes this worker's own loops.
278
- SELECT l.worker_id, r.name AS worker_name, l.status, l.prompt, l.terminal_message, l.terminated_by
279
- FROM loops l
280
- JOIN workers r ON r.id = l.worker_id
281
- WHERE r.workspace_id = $workspace_id
282
- AND l.terminated_at IS NOT NULL
283
- AND l.terminated_at > $since
284
- AND l.worker_id != $worker_id
285
- ORDER BY l.terminated_at;
286
-
287
- -- PREP: engine_insert_loop_termination_delta
288
- -- §worker-scheme — materialize a sibling's loop-termination as a delta: a SEND from
289
- -- worker:///<name> carrying the terminal status + message (the deliverable). origin=plurnk,
290
- -- source=the terminated run — uniform with the env-delta. Born OPEN for a 2xx deliverable
291
- -- (a child's success must reach the parent open + awakening), folded otherwise.
292
- INSERT INTO log_entries (
293
- worker_id, loop_id, turn_id, sequence, origin, source,
294
- op, scheme, pathname, tx, mimetype_tx, rx, mimetype_rx, status_rx, expanded
295
- ) VALUES (
296
- $worker_id, $loop_id, $turn_id, $sequence, 'plurnk', $source,
297
- 'SEND', 'worker', $pathname, '', 'text/plain', $rx, 'text/markdown', $status,
298
- CASE WHEN $status >= 200 AND $status < 300 THEN 1 ELSE 0 END
374
+ 'READ', $scheme, $pathname, $fragment, '', 'text/plain', $rx, 'application/json', $status, $attrs, $expanded
299
375
  );
300
376
 
301
377
  -- PREP: engine_entry_tags
@@ -303,7 +379,7 @@ SELECT tag FROM entry_tags WHERE entry_id = $entry_id ORDER BY tag;
303
379
 
304
380
  -- PREP: engine_child_workers_live
305
381
  -- The worker's LIVE child workers — latest loop non-terminal (100 pending / 102 processing / 202 parked).
306
- -- Powers the Child Runs orienting section (§child-orientation): terse `* <status> worker://<name>`
382
+ -- Powers the Active Child Workers orienting section ({§child-orientation}): terse `* <status> worker://<name>`
307
383
  -- pointers so the model SEES what it holds live and reasons for itself (READ/KILL), never told to.
308
384
  -- Empty → section omitted.
309
385
  SELECT r.name, l.status
@@ -314,7 +390,7 @@ ORDER BY r.name;
314
390
 
315
391
  -- PREP: engine_child_streams_open
316
392
  -- The worker's OPEN streams (subscriptions not yet closed) — their addressable coord. Powers the Child
317
- -- Streams orienting section (§child-orientation): terse `* active <runtime>:///<coord>` pointers the
393
+ -- Streams orienting section ({§child-orientation}): terse `* active <runtime>:///<coord>` pointers the
318
394
  -- model OPENs/READs/KILLs. Empty → section omitted.
319
395
  SELECT s.scheme, e.pathname
320
396
  FROM subscriptions s
@@ -322,14 +398,14 @@ JOIN entries e ON e.id = s.entry_id
322
398
  WHERE s.worker_id = $worker_id AND s.closed_at IS NULL
323
399
  ORDER BY e.pathname;
324
400
 
325
- -- PREP: engine_render_telemetry_errors
326
- -- SPEC §telemetry: 4xx/5xx log rows are mirrored into the packet's telemetry as
401
+ -- PREP: engine_render_errors
402
+ -- SPEC {§operation-results}: 4xx/5xx log rows are indexed in the packet's errors as
327
403
  -- LogCoordinate pointers, forcing the model to confront failures instead of letting
328
404
  -- them rot in log:///. Window = the current turn AND the immediately-prior one
329
405
  -- (>= current_turn_seq - 1): prior-turn for action failures the model just caused,
330
406
  -- current-turn so a same-turn engine error (the grinder's budget-overflow row, minted
331
407
  -- pre-generate then re-derived) surfaces THIS turn rather than a turn late.
332
- -- §telemetry-uniform-error-channel
408
+ -- {§operation-result-uniform-error-channel}
333
409
  SELECT
334
410
  le.op, le.sequence, le.status_rx, le.rx, le.mimetype_rx,
335
411
  le.scheme, le.pathname,
@@ -339,94 +415,96 @@ JOIN turns t ON t.id = le.turn_id
339
415
  JOIN loops l ON l.id = le.loop_id
340
416
  WHERE le.loop_id = $loop_id
341
417
  AND le.status_rx >= 400
342
- -- §log-row-self-explains: every >=400 row points at ITSELF — the op row carries its failure
418
+ -- {§log-row-self-explains}: every >=400 row points at ITSELF — the op row carries its failure
343
419
  -- message on its meta line (packet-wire), so the pointer leads to a record that states its why.
344
420
  AND t.sequence >= $current_turn_seq - 1
345
421
  ORDER BY t.sequence, le.sequence;
346
422
 
347
- -- PREP: engine_grinder_fold_newest_turn
348
- -- §grinder-layer1-rollback — THE DOCTRINE: the log is the model's memory and the model ALONE
423
+ -- TX: engine_grinder_fold_newest_turn
424
+ -- {§grinder-layer1-rollback} — THE DOCTRINE: the log is the model's memory and the model ALONE
349
425
  -- curates it (FOLD/KILL). The grinder never touches history — it only blocks NEW memories from
350
426
  -- landing when there is no room: one set-op folds the still-open rows of the newest turn
351
427
  -- boundary — the immediately-prior turn's emissions and the current turn's pre-model rows
352
428
  -- (foists, wake surfaces). Turn 1 is the same rule (no prior turn; its foists are the newest).
353
- -- Folded, never deleted; THREE exemptions (§grinder-errors-exempt): op='error' rows, the
354
- -- user PROMPT (#382 — the task frame the engine foisted is not the model's curatable memory;
355
- -- the engine never reclaims the definition of the task it set), and PLAN rows (#465, owner
356
- -- ruling — the checklist is the model's orientation surface at exactly the moment the grinder
357
- -- fires; plans are concise by rule, so exempting them reclaims almost nothing and preserves
358
- -- the reasoning thread a recovery turn steers by).
359
- UPDATE log_entries SET expanded = 0
360
- WHERE loop_id = $loop_id AND expanded = 1 AND op NOT IN ('error', 'PLAN')
361
- AND COALESCE(scheme, '') != 'prompt' -- the task frame ({§prompt-self-only}); NULL-safe: a model row's scheme is NULL
429
+ -- Folded, never deleted; THREE exemptions ({§grinder-errors-exempt}): op='error',
430
+ -- the user prompt, and PLAN. The temporary set captures the
431
+ -- selection once so folding and additive `overflow` tagging cannot diverge.
432
+ CREATE TEMP TABLE IF NOT EXISTS engine_grinder_fold_set (id INTEGER PRIMARY KEY);
433
+ DELETE FROM engine_grinder_fold_set;
434
+ INSERT INTO engine_grinder_fold_set (id)
435
+ SELECT id FROM log_entries
436
+ WHERE loop_id = $loop_id AND expanded = 1 AND COALESCE(op, '') NOT IN ('error', 'PLAN')
437
+ AND COALESCE(scheme, '') != 'prompt' -- the task frame ({§prompt-self-only}); NULL-safe: a model-emission row's scheme is NULL
362
438
  AND (turn_id = $turn_id
363
439
  OR turn_id = (SELECT MAX(id) FROM turns WHERE loop_id = $loop_id AND id < $turn_id));
364
440
 
441
+ UPDATE log_entries SET expanded = 0
442
+ WHERE id IN (SELECT id FROM engine_grinder_fold_set);
443
+
444
+ INSERT OR IGNORE INTO log_tags (log_entry_id, tag)
445
+ SELECT id, 'overflow' FROM engine_grinder_fold_set;
446
+
447
+ DELETE FROM engine_grinder_fold_set;
448
+
365
449
  -- PREP: engine_fold_log_entry
366
- -- §prompt-fold (User Note 6): fold a single log row by id — collapse to its
367
- -- coordinate, body elided in the render, re-OPENable. Used for the foisted prompt
368
- -- EDIT, which duplicates packet.user.prompt: logged for forensics, born folded.
450
+ -- Fold one known log row by id. Model-emission rows use this after insertion so
451
+ -- the complete admitted emission remains available without opening by default.
369
452
  UPDATE log_entries SET expanded = 0 WHERE id = $id;
370
453
 
371
454
  -- PREP: engine_render_log
372
- -- Render-time log assembly (SPEC §packet packet.system.log).
373
- -- Yields log_entries for the whole RUN — the conversation's working
374
- -- memory carries across loops within a workspace's run, not just the
375
- -- current loop. Coordinate is log:///<loop_seq>/<turn_seq>/<sequence>/<op>.
455
+ -- Render-time log-section assembly ({§body-projection}).
456
+ -- Yields log_entries for the whole worker — the conversation's working
457
+ -- memory carries across loops within a worker, not just the
458
+ -- current loop. Coordinates append /<op> only for rows that represent an operation.
376
459
  -- Status 202 entries in state='proposed' are model-invisible until resolved.
377
460
  -- `expanded = 0` rows are FOLDED — listed but collapsed to their coordinate
378
- -- (FOLD); the renderer elides the body. §open-fold: folded rows stay listed, re-OPENable.
461
+ -- (FOLD); the renderer elides the body. {§open-fold}: folded rows stay listed, re-OPENable.
379
462
  SELECT
463
+ le.id,
380
464
  l.sequence AS loop_seq,
381
465
  t.sequence AS turn_seq,
382
466
  le.sequence,
383
- -- le.origin is attribution, never a render filter; the worker's actor — §actor-boundary-origin-not-filter §machine-processes-worker-origin
467
+ -- le.origin is attribution, never a render filter; the worker's actor — {§actor-boundary-origin-not-filter} {§machine-processes-worker-origin}
384
468
  le.origin,
385
469
  le.op, le.suffix, le.signal,
386
470
  le.scheme, le.username, le.password,
387
471
  le.hostname, le.port, le.pathname,
388
- le.params, le.fragment,
472
+ le.query, le.fragment,
389
473
  le.status_rx, le.rx, le.mimetype_rx,
390
474
  le.tx, le.mimetype_tx,
391
475
  le.state, le.outcome, le.expanded, le.source, le.attrs
392
476
  FROM log_entries le
393
477
  JOIN turns t ON t.id = le.turn_id
394
478
  JOIN loops l ON l.id = le.loop_id
395
- -- WHERE renders exactly one worker's log — §actor-boundary-isolation §machine-processes-worker-is-its-log
396
- -- the AND NOT clauses keep proposed (202) rows hidden until resolved (§proposal-proposed-hidden),
397
- -- and SUCCESSFUL log-curation receipts out of the packet (#382 — recorded in the DB for forensics,
398
- -- suppressed from materialization so a curation act rents zero packet space; the successful fold
399
- -- that hid the task frame in run43 left NO trace, the database dig). Two receipts, one principle:
400
- -- OPEN/FOLD — render directives, always log-targeted, suppressed on success.
401
- -- KILL of a LOG item — a real deletion whose tombstone is spent once executed; suppressed on
402
- -- success too (run61: a floor model KILLed log rows ~2000×, and the tombstones — bodyless, but
403
- -- ~130-char meta-lines apiece — became 95% of its packet, a self-growing curation trap). SCOPED
404
- -- to le.scheme='log': a KILL of a worker:// note / sh:// stream is a world mutation, NOT log
405
- -- housekeeping, and stays visible. A FAILED op of any kind still renders — errors are signals
406
- -- (§telemetry-uniform-error-channel).
479
+ -- WHERE renders exactly one worker's log — {§actor-boundary-isolation} {§machine-processes-worker-is-its-log}
480
+ -- the AND NOT clauses keep proposed (202) rows hidden until resolved ({§proposal-proposed-hidden}),
481
+ -- and successful log-curation receipts out of the packet. OPEN/FOLD follow
482
+ -- {§fold-open-meta-operations}; only log-target KILL follows
483
+ -- {§kill-log-receipt-suppressed}. Every failed operation remains visible through
484
+ -- {§operation-result-uniform-error-channel}.
407
485
  WHERE le.worker_id = $worker_id
408
486
  AND NOT (le.status_rx = 202 AND le.state = 'proposed')
409
- AND NOT (le.op IN ('OPEN', 'FOLD') AND le.status_rx < 400)
410
- AND NOT (le.op = 'KILL' AND le.scheme = 'log' AND le.status_rx < 400)
487
+ AND NOT (COALESCE(le.op, '') IN ('OPEN', 'FOLD') AND le.status_rx < 400)
488
+ AND NOT (COALESCE(le.op, '') = 'KILL' AND le.scheme = 'log' AND le.status_rx < 400)
411
489
  ORDER BY l.sequence, t.sequence, le.sequence;
412
490
 
413
491
  -- PREP: engine_insert_log_entry
414
492
  -- Default state='resolved' covers the common path (non-proposing schemes
415
493
  -- return their final status immediately). Status 202 + state='proposed'
416
494
  -- triggers the proposal lifecycle (engine pauses dispatch; client resolves
417
- -- via loop/resolve RPC; entry transitions through engine_resolve_log_entry).
495
+ -- via proposal resolution; entry transitions through engine_resolve_log_entry).
418
496
  INSERT INTO log_entries (
419
497
  worker_id, loop_id, turn_id, sequence, origin, source,
420
498
  op, suffix, signal,
421
499
  scheme, username, password, hostname, port,
422
- pathname, params, fragment, lineMarker,
500
+ pathname, query, fragment, lineMarker,
423
501
  tx, mimetype_tx, rx, mimetype_rx, status_rx, tokens,
424
502
  state, outcome, attrs
425
503
  ) VALUES (
426
504
  $worker_id, $loop_id, $turn_id, $sequence, $origin, $source,
427
505
  $op, $suffix, $signal,
428
506
  $scheme, $username, $password, $hostname, $port,
429
- $pathname, $params, $fragment, $lineMarker,
507
+ $pathname, $query, $fragment, $lineMarker,
430
508
  $tx, $mimetype_tx, $rx, $mimetype_rx, $status_rx, $tokens,
431
509
  $state, $outcome, $attrs
432
510
  )
@@ -434,18 +512,32 @@ RETURNING id;
434
512
 
435
513
  -- PREP: engine_resolve_log_entry
436
514
  -- Transitions a proposed log entry to its terminal state. Used by the
437
- -- proposal lifecycle (loop/resolve RPC, auto resolution, timeout, abort).
515
+ -- proposal lifecycle (client resolution, auto resolution, timeout, abort).
438
516
  -- Updates status_rx + rx + state + outcome atomically.
439
517
  UPDATE log_entries
440
518
  SET state = $state,
441
519
  outcome = $outcome,
442
520
  status_rx = $status_rx,
443
- rx = $rx
521
+ rx = $rx,
522
+ deep_hash = NULL
444
523
  WHERE id = $id
445
524
  AND state = 'proposed';
446
525
 
526
+ -- PREP: engine_log_entry_coordinate
527
+ -- Resolve a durable operation occurrence after a proposal settles so a
528
+ -- Problem Details instance names the same model-facing log URI as every
529
+ -- immediately failed operation.
530
+ SELECT l.sequence AS loop_seq,
531
+ t.sequence AS turn_seq,
532
+ le.sequence AS sequence,
533
+ le.op AS op
534
+ FROM log_entries le
535
+ JOIN turns t ON t.id = le.turn_id
536
+ JOIN loops l ON l.id = le.loop_id
537
+ WHERE le.id = $id;
538
+
447
539
  -- PREP: engine_turn_retrievals
448
- -- §send-premature-terminate — the pending set's retrieval leg: THIS turn's READ/FIND/OPEN rows,
540
+ -- {§send-premature-terminate} — the pending set's retrieval leg: THIS turn's READ/FIND/OPEN rows,
449
541
  -- whose results the model cannot have seen (they fold back next packet). A [200] over them is
450
542
  -- discarding answers it asked for.
451
543
  SELECT id FROM log_entries
@@ -475,36 +567,38 @@ WHERE s.worker_id = $worker_id
475
567
  LIMIT 1;
476
568
 
477
569
  -- PREP: engine_turn_failures
478
- -- §send-200-failed-ops — THIS turn's failed op results (the model's own ops, status >= 400), whose
479
- -- errors the model cannot have seen (they land next packet). A [200] over them concludes blind
480
- -- past a failure — refused 409; [499] abandons regardless (declaring failure IS weighing it).
481
- -- op='error' rows are EXCLUDED: the error CHANNEL is already-surfaced signal (the grinder's
482
- -- overflow row mints pre-packet — the recovery turn SAW it; §grinder-hard-413-recovery's
483
- -- concluding-is-legitimate stands), and the current emission's parse errors ride the threaded
484
- -- count instead (they mint as rows only after dispatch).
570
+ -- {§send-premature-terminate} — THIS turn's failed op results (the model's own ops, status >= 400), whose
571
+ -- errors the model cannot have seen (they land next packet). A [200] or already-drained [202] over
572
+ -- them concludes blind past a failure — refused 409; [499] abandons regardless (declaring failure
573
+ -- IS weighing it).
574
+ -- Actionless engine errors are excluded: the grinder's overflow row mints pre-packet, so the
575
+ -- recovery turn already saw it ({§grinder-hard-413-recovery}). A model-authored statement that
576
+ -- failed grammar parsing is different: source='grammar' records a bounded operation failure
577
+ -- from the accepted emission, unseen until the next packet, so it gates completion like every
578
+ -- other failed model operation.
485
579
  SELECT id FROM log_entries
486
- WHERE turn_id = $turn_id AND origin = 'model' AND status_rx >= 400 AND op != 'error';
487
-
488
- -- PREP: engine_demote_turn_status
489
- -- §send-premature-terminate — a terminal REFUSED at dispatch (the pending-set 409) demotes the
490
- -- turn to a continue AFTER the close already persisted the provisional status (the close writes
491
- -- packet+usage as soon as the model responds; ops dispatch after). The record must match the
492
- -- truth the return value carries: the loop never went terminal, so the turn didn't either.
580
+ WHERE turn_id = $turn_id
581
+ AND origin = 'model'
582
+ AND status_rx >= 400
583
+ AND (op != 'error' OR source = 'grammar');
584
+
585
+ -- PREP: engine_reconcile_turn_status
586
+ -- A SEND's signal is only provisional until dispatch adjudicates live obligations and failures.
587
+ -- The close writes packet+usage before ops dispatch, so reconcile the persisted turn whenever
588
+ -- dispatch changes that disposition (for example refused 200 -> 102 or drained 202 -> 200).
493
589
  UPDATE turns SET status = $status WHERE id = $id;
494
590
 
495
591
 
496
592
 
497
593
  -- PREP: engine_loop_sequence
498
- -- The loop's PER-RUN sequence — the model-facing coordinate (prompt/<run>/<loop-seq>/<turn-seq>,
594
+ -- The loop's per-worker sequence — the model-facing coordinate (prompt/<worker>/<loop-seq>/<turn-seq>,
499
595
  -- matching the log's loop-relative numbering). The raw db id leaked into prompt paths and the
500
596
  -- model's first loop read as prompt/2/1 (the docs loop holds id 1). Owner: minor but annoying.
501
597
  SELECT sequence FROM loops WHERE id = $loop_id;
502
598
 
503
599
  -- PREP: engine_worker_lineage_root
504
- -- #522 — the PRIMARY worker: the no-parent root the lineage descends from (walk parent_worker_id
505
- -- up). A worker with no parent returns ITSELF (the primary's own turns stamp Worker-Primary ==
506
- -- Worker-Id). The endpoint routes primary→strong, spawned→cheap by equality, so this is the
507
- -- root-of-tree grouping key. Always resolvable (the chain is finite + acyclic — parent != id CHECK).
600
+ -- The no-parent root of a worker lineage; a root worker returns itself.
601
+ -- {§worker-primary}
508
602
  WITH RECURSIVE lineage(id, parent_worker_id) AS (
509
603
  SELECT id, parent_worker_id FROM workers WHERE id = $worker_id
510
604
  UNION ALL
@@ -513,14 +607,15 @@ WITH RECURSIVE lineage(id, parent_worker_id) AS (
513
607
  SELECT id FROM lineage WHERE parent_worker_id IS NULL;
514
608
 
515
609
  -- PREP: engine_worker_has_undelivered_child_term
516
- -- A child worker whose loop TERMINATED after the current turn's timestamp — its deliverable
517
- -- (the §worker-scheme collect delta) is queued for the NEXT packet build and has not been seen.
518
- -- The 1ms-wide fan-out race: workers concluding DURING the parent's generation are not "live"
519
- -- (the wait's J leg misses them) but their results are pending — concluding or ∅-collapsing
520
- -- over them silently discards deliverables the model spawned. {§send-undelivered-child-term}
521
- SELECT 1 AS pending FROM loops l
522
- JOIN workers r ON r.id = l.worker_id
523
- WHERE r.parent_worker_id = $worker_id
524
- AND l.terminated_at IS NOT NULL
525
- AND l.terminated_at > (SELECT timestamp FROM turns WHERE id = $turn_id)
610
+ -- A child conclusion newer than the parent's observation cursor is complete but
611
+ -- not delivered. This is the same durable boundary the next packet consumes,
612
+ -- not a second timestamp race. {§send-undelivered-child-term}
613
+ SELECT 1 AS pending
614
+ FROM ambient_events ae
615
+ JOIN workers child ON child.id = ae.producer_worker_id
616
+ JOIN workers parent ON parent.id = $worker_id
617
+ WHERE ae.workspace_id = parent.workspace_id
618
+ AND ae.kind = 'loop_termination'
619
+ AND child.parent_worker_id = parent.id
620
+ AND ae.id > COALESCE(parent.ambient_event_cursor, 0)
526
621
  LIMIT 1;