@plurnk/plurnk-service 1.3.12 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (469) hide show
  1. package/.env.defaults +84 -77
  2. package/INSTALL.md +50 -25
  3. package/README.md +24 -10
  4. package/SPEC.md +2311 -928
  5. package/dist/Paths.d.ts +4 -1
  6. package/dist/Paths.d.ts.map +1 -1
  7. package/dist/Paths.js +23 -21
  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 +3 -3
  18. package/dist/content/index.d.ts.map +1 -1
  19. package/dist/content/index.js +1 -1
  20. package/dist/content/index.js.map +1 -1
  21. package/dist/content/line-marker.d.ts +6 -9
  22. package/dist/content/line-marker.d.ts.map +1 -1
  23. package/dist/content/line-marker.js +7 -11
  24. package/dist/content/line-marker.js.map +1 -1
  25. package/dist/content/matcher.d.ts +14 -25
  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-resolve.d.ts +8 -4
  36. package/dist/content/read-resolve.d.ts.map +1 -1
  37. package/dist/content/read-resolve.js +101 -49
  38. package/dist/content/read-resolve.js.map +1 -1
  39. package/dist/core/BranchReceipt.d.ts +7 -0
  40. package/dist/core/BranchReceipt.d.ts.map +1 -0
  41. package/dist/core/BranchReceipt.js +27 -0
  42. package/dist/core/BranchReceipt.js.map +1 -0
  43. package/dist/core/BudgetOverflow.d.ts +23 -0
  44. package/dist/core/BudgetOverflow.d.ts.map +1 -0
  45. package/dist/core/BudgetOverflow.js +61 -0
  46. package/dist/core/BudgetOverflow.js.map +1 -0
  47. package/dist/core/BudgetReadout.d.ts +8 -0
  48. package/dist/core/BudgetReadout.d.ts.map +1 -0
  49. package/dist/core/BudgetReadout.js +79 -0
  50. package/dist/core/BudgetReadout.js.map +1 -0
  51. package/dist/core/ChannelWrite.d.ts +28 -9
  52. package/dist/core/ChannelWrite.d.ts.map +1 -1
  53. package/dist/core/ChannelWrite.js +28 -21
  54. package/dist/core/ChannelWrite.js.map +1 -1
  55. package/dist/core/ChannelWrite.sql +11 -10
  56. package/dist/core/CoreSchemeServices.d.ts +10 -4
  57. package/dist/core/CoreSchemeServices.d.ts.map +1 -1
  58. package/dist/core/CoreSchemeServices.js +7 -1
  59. package/dist/core/CoreSchemeServices.js.map +1 -1
  60. package/dist/core/Dispatcher.d.ts +29 -20
  61. package/dist/core/Dispatcher.d.ts.map +1 -1
  62. package/dist/core/Dispatcher.js +1488 -599
  63. package/dist/core/Dispatcher.js.map +1 -1
  64. package/dist/core/DurableStatement.d.ts +6 -0
  65. package/dist/core/DurableStatement.d.ts.map +1 -0
  66. package/dist/core/DurableStatement.js +51 -0
  67. package/dist/core/DurableStatement.js.map +1 -0
  68. package/dist/core/Engine.d.ts +48 -20
  69. package/dist/core/Engine.d.ts.map +1 -1
  70. package/dist/core/Engine.js +1208 -789
  71. package/dist/core/Engine.js.map +1 -1
  72. package/dist/core/Engine.sql +309 -217
  73. package/dist/core/EnvFlags.js +1 -1
  74. package/dist/core/EnvFlags.js.map +1 -1
  75. package/dist/core/ErrorDetail.d.ts +6 -0
  76. package/dist/core/ErrorDetail.d.ts.map +1 -0
  77. package/dist/core/ErrorDetail.js +20 -0
  78. package/dist/core/ErrorDetail.js.map +1 -0
  79. package/dist/core/ExecutorRegistry.d.ts +14 -3
  80. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  81. package/dist/core/ExecutorRegistry.js +56 -30
  82. package/dist/core/ExecutorRegistry.js.map +1 -1
  83. package/dist/core/GitBranch.d.ts +20 -0
  84. package/dist/core/GitBranch.d.ts.map +1 -0
  85. package/dist/core/GitBranch.js +110 -0
  86. package/dist/core/GitBranch.js.map +1 -0
  87. package/dist/core/JournalTurn.d.ts +9 -0
  88. package/dist/core/JournalTurn.d.ts.map +1 -0
  89. package/dist/core/JournalTurn.js +14 -0
  90. package/dist/core/JournalTurn.js.map +1 -0
  91. package/dist/core/JournalTurn.sql +10 -0
  92. package/dist/core/LogBody.d.ts +17 -0
  93. package/dist/core/LogBody.d.ts.map +1 -0
  94. package/dist/core/LogBody.js +148 -0
  95. package/dist/core/LogBody.js.map +1 -0
  96. package/dist/core/LoopFlagsReader.d.ts +7 -0
  97. package/dist/core/LoopFlagsReader.d.ts.map +1 -0
  98. package/dist/core/LoopFlagsReader.js +33 -0
  99. package/dist/core/LoopFlagsReader.js.map +1 -0
  100. package/dist/core/LoopLifecycle.d.ts +8 -1
  101. package/dist/core/LoopLifecycle.d.ts.map +1 -1
  102. package/dist/core/LoopLifecycle.js +55 -9
  103. package/dist/core/LoopLifecycle.js.map +1 -1
  104. package/dist/core/LoopLifecycle.sql +9 -3
  105. package/dist/core/NoticeChannel.d.ts +13 -0
  106. package/dist/core/NoticeChannel.d.ts.map +1 -0
  107. package/dist/core/NoticeChannel.js +40 -0
  108. package/dist/core/NoticeChannel.js.map +1 -0
  109. package/dist/core/Owner.d.ts +0 -1
  110. package/dist/core/Owner.d.ts.map +1 -1
  111. package/dist/core/Owner.js +2 -5
  112. package/dist/core/Owner.js.map +1 -1
  113. package/dist/core/PacketBuilder.d.ts +25 -24
  114. package/dist/core/PacketBuilder.d.ts.map +1 -1
  115. package/dist/core/PacketBuilder.js +313 -375
  116. package/dist/core/PacketBuilder.js.map +1 -1
  117. package/dist/core/ProblemLog.d.ts +26 -0
  118. package/dist/core/ProblemLog.d.ts.map +1 -0
  119. package/dist/core/ProblemLog.js +58 -0
  120. package/dist/core/ProblemLog.js.map +1 -0
  121. package/dist/core/ProposalLifecycle.d.ts +15 -21
  122. package/dist/core/ProposalLifecycle.d.ts.map +1 -1
  123. package/dist/core/ProposalLifecycle.js +291 -78
  124. package/dist/core/ProposalLifecycle.js.map +1 -1
  125. package/dist/core/ProviderInstantiate.d.ts.map +1 -1
  126. package/dist/core/ProviderInstantiate.js +51 -48
  127. package/dist/core/ProviderInstantiate.js.map +1 -1
  128. package/dist/core/SchemeRegistry.d.ts +14 -8
  129. package/dist/core/SchemeRegistry.d.ts.map +1 -1
  130. package/dist/core/SchemeRegistry.js +189 -114
  131. package/dist/core/SchemeRegistry.js.map +1 -1
  132. package/dist/core/ServiceTeardown.d.ts +11 -0
  133. package/dist/core/ServiceTeardown.d.ts.map +1 -0
  134. package/dist/core/ServiceTeardown.js +70 -0
  135. package/dist/core/ServiceTeardown.js.map +1 -0
  136. package/dist/core/StoredPacket.d.ts +29 -0
  137. package/dist/core/StoredPacket.d.ts.map +1 -0
  138. package/dist/core/StoredPacket.js +147 -0
  139. package/dist/core/StoredPacket.js.map +1 -0
  140. package/dist/core/StrikeRail.d.ts +1 -2
  141. package/dist/core/StrikeRail.d.ts.map +1 -1
  142. package/dist/core/StrikeRail.js +25 -55
  143. package/dist/core/StrikeRail.js.map +1 -1
  144. package/dist/core/WorkerControlAddress.d.ts +17 -0
  145. package/dist/core/WorkerControlAddress.d.ts.map +1 -0
  146. package/dist/core/WorkerControlAddress.js +44 -0
  147. package/dist/core/WorkerControlAddress.js.map +1 -0
  148. package/dist/core/WorkerName.d.ts +31 -0
  149. package/dist/core/WorkerName.d.ts.map +1 -0
  150. package/dist/core/WorkerName.js +95 -0
  151. package/dist/core/WorkerName.js.map +1 -0
  152. package/dist/core/WorkerName.sql +36 -0
  153. package/dist/core/WorkspaceGate.d.ts +14 -0
  154. package/dist/core/WorkspaceGate.d.ts.map +1 -0
  155. package/dist/core/WorkspaceGate.js +155 -0
  156. package/dist/core/WorkspaceGate.js.map +1 -0
  157. package/dist/core/caps/CapsResolve.d.ts +1 -1
  158. package/dist/core/caps/CapsResolve.d.ts.map +1 -1
  159. package/dist/core/caps/CapsResolve.js.map +1 -1
  160. package/dist/core/caps/DbChannelCaps.d.ts +5 -11
  161. package/dist/core/caps/DbChannelCaps.d.ts.map +1 -1
  162. package/dist/core/caps/DbChannelCaps.js +24 -8
  163. package/dist/core/caps/DbChannelCaps.js.map +1 -1
  164. package/dist/core/caps/DbEntryCaps.d.ts +4 -13
  165. package/dist/core/caps/DbEntryCaps.d.ts.map +1 -1
  166. package/dist/core/caps/DbEntryCaps.js +15 -6
  167. package/dist/core/caps/DbEntryCaps.js.map +1 -1
  168. package/dist/core/caps/DbNotifyCaps.d.ts +1 -1
  169. package/dist/core/caps/DbNotifyCaps.d.ts.map +1 -1
  170. package/dist/core/caps/DbNotifyCaps.js +12 -11
  171. package/dist/core/caps/DbNotifyCaps.js.map +1 -1
  172. package/dist/core/caps/DbProjectionCaps.d.ts +5 -5
  173. package/dist/core/caps/DbProjectionCaps.d.ts.map +1 -1
  174. package/dist/core/caps/DbProjectionCaps.js +21 -4
  175. package/dist/core/caps/DbProjectionCaps.js.map +1 -1
  176. package/dist/core/caps/DbSubscriptionCaps.d.ts +4 -4
  177. package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
  178. package/dist/core/caps/DbSubscriptionCaps.js +57 -62
  179. package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
  180. package/dist/core/caps/DbTagCaps.d.ts +5 -12
  181. package/dist/core/caps/DbTagCaps.d.ts.map +1 -1
  182. package/dist/core/caps/DbTagCaps.js +14 -7
  183. package/dist/core/caps/DbTagCaps.js.map +1 -1
  184. package/dist/core/content-hash.js +1 -1
  185. package/dist/core/content-hash.js.map +1 -1
  186. package/dist/core/env-defaults.d.ts.map +1 -1
  187. package/dist/core/env-defaults.js.map +1 -1
  188. package/dist/core/fork.d.ts.map +1 -1
  189. package/dist/core/fork.js +55 -30
  190. package/dist/core/fork.js.map +1 -1
  191. package/dist/core/fork.sql +41 -27
  192. package/dist/core/git-env.d.ts +2 -0
  193. package/dist/core/git-env.d.ts.map +1 -1
  194. package/dist/core/git-env.js +13 -18
  195. package/dist/core/git-env.js.map +1 -1
  196. package/dist/core/git-iso.d.ts.map +1 -1
  197. package/dist/core/git-iso.js +9 -15
  198. package/dist/core/git-iso.js.map +1 -1
  199. package/dist/core/git-membership.d.ts +1 -1
  200. package/dist/core/git-membership.d.ts.map +1 -1
  201. package/dist/core/git-membership.js +198 -146
  202. package/dist/core/git-membership.js.map +1 -1
  203. package/dist/core/git-state.d.ts.map +1 -1
  204. package/dist/core/git-state.js +10 -11
  205. package/dist/core/git-state.js.map +1 -1
  206. package/dist/core/owner.sql +1 -1
  207. package/dist/core/packet-inject.d.ts.map +1 -1
  208. package/dist/core/packet-inject.js +7 -11
  209. package/dist/core/packet-inject.js.map +1 -1
  210. package/dist/core/packet-wire.d.ts +2 -20
  211. package/dist/core/packet-wire.d.ts.map +1 -1
  212. package/dist/core/packet-wire.js +242 -368
  213. package/dist/core/packet-wire.js.map +1 -1
  214. package/dist/core/plurnk-uri.d.ts +12 -1
  215. package/dist/core/plurnk-uri.d.ts.map +1 -1
  216. package/dist/core/plurnk-uri.js +49 -29
  217. package/dist/core/plurnk-uri.js.map +1 -1
  218. package/dist/core/results.d.ts +16 -5
  219. package/dist/core/results.d.ts.map +1 -1
  220. package/dist/core/results.js +27 -18
  221. package/dist/core/results.js.map +1 -1
  222. package/dist/core/ruler_count.d.ts +4 -0
  223. package/dist/core/ruler_count.d.ts.map +1 -0
  224. package/dist/core/ruler_count.js +7 -0
  225. package/dist/core/ruler_count.js.map +1 -0
  226. package/dist/core/scheme-types.d.ts +9 -11
  227. package/dist/core/scheme-types.d.ts.map +1 -1
  228. package/dist/core/scheme-types.js.map +1 -1
  229. package/dist/core/search-gate.d.ts.map +1 -1
  230. package/dist/core/search-gate.js +3 -11
  231. package/dist/core/search-gate.js.map +1 -1
  232. package/dist/core/teaching-corpus.d.ts +6 -0
  233. package/dist/core/teaching-corpus.d.ts.map +1 -0
  234. package/dist/core/teaching-corpus.js +23 -0
  235. package/dist/core/teaching-corpus.js.map +1 -0
  236. package/dist/core/teaching.d.ts +0 -1
  237. package/dist/core/teaching.d.ts.map +1 -1
  238. package/dist/core/teaching.js +2 -8
  239. package/dist/core/teaching.js.map +1 -1
  240. package/dist/core/token-ruler.d.ts.map +1 -1
  241. package/dist/core/token-ruler.js +3 -16
  242. package/dist/core/token-ruler.js.map +1 -1
  243. package/dist/core/turn-scheduler.d.ts +1 -1
  244. package/dist/core/turn-scheduler.d.ts.map +1 -1
  245. package/dist/core/turn-scheduler.js +1 -1
  246. package/dist/core/turn-scheduler.js.map +1 -1
  247. package/dist/core/worker-cap.d.ts +2 -4
  248. package/dist/core/worker-cap.d.ts.map +1 -1
  249. package/dist/core/worker-cap.js +13 -4
  250. package/dist/core/worker-cap.js.map +1 -1
  251. package/dist/core/{run-ops.sql → worker-ops.sql} +11 -11
  252. package/dist/core/workspace-settings.d.ts.map +1 -1
  253. package/dist/core/workspace-settings.js +17 -9
  254. package/dist/core/workspace-settings.js.map +1 -1
  255. package/dist/digest/Digest.d.ts +2 -1
  256. package/dist/digest/Digest.d.ts.map +1 -1
  257. package/dist/digest/Digest.js +337 -138
  258. package/dist/digest/Digest.js.map +1 -1
  259. package/dist/digest/digest.sql +19 -10
  260. package/dist/index.d.ts.map +1 -1
  261. package/dist/index.js +3 -5
  262. package/dist/index.js.map +1 -1
  263. package/dist/matrix/live-specimen.d.ts +9 -0
  264. package/dist/matrix/live-specimen.d.ts.map +1 -0
  265. package/dist/matrix/live-specimen.js +37 -0
  266. package/dist/matrix/live-specimen.js.map +1 -0
  267. package/dist/observe/api.d.ts +6 -0
  268. package/dist/observe/api.d.ts.map +1 -0
  269. package/dist/observe/api.js +11 -0
  270. package/dist/observe/api.js.map +1 -0
  271. package/dist/observe/init.d.ts +7 -0
  272. package/dist/observe/init.d.ts.map +1 -0
  273. package/dist/observe/init.js +159 -0
  274. package/dist/observe/init.js.map +1 -0
  275. package/dist/observe/metrics.d.ts +6 -0
  276. package/dist/observe/metrics.d.ts.map +1 -0
  277. package/dist/observe/metrics.js +15 -0
  278. package/dist/observe/metrics.js.map +1 -0
  279. package/dist/observe/spans.d.ts +4 -0
  280. package/dist/observe/spans.d.ts.map +1 -0
  281. package/dist/observe/spans.js +51 -0
  282. package/dist/observe/spans.js.map +1 -0
  283. package/dist/schemes/EffectPolicy.d.ts +1 -0
  284. package/dist/schemes/EffectPolicy.d.ts.map +1 -1
  285. package/dist/schemes/EffectPolicy.js +5 -2
  286. package/dist/schemes/EffectPolicy.js.map +1 -1
  287. package/dist/schemes/Exec.d.ts +6 -11
  288. package/dist/schemes/Exec.d.ts.map +1 -1
  289. package/dist/schemes/Exec.js +364 -247
  290. package/dist/schemes/Exec.js.map +1 -1
  291. package/dist/schemes/ExecOutputScheme.d.ts +8 -7
  292. package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
  293. package/dist/schemes/ExecOutputScheme.js +48 -9
  294. package/dist/schemes/ExecOutputScheme.js.map +1 -1
  295. package/dist/schemes/File.d.ts +7 -11
  296. package/dist/schemes/File.d.ts.map +1 -1
  297. package/dist/schemes/File.js +279 -142
  298. package/dist/schemes/File.js.map +1 -1
  299. package/dist/schemes/Log.d.ts +4 -8
  300. package/dist/schemes/Log.d.ts.map +1 -1
  301. package/dist/schemes/Log.js +475 -208
  302. package/dist/schemes/Log.js.map +1 -1
  303. package/dist/schemes/Log.sql +62 -30
  304. package/dist/schemes/Prompt.d.ts +3 -2
  305. package/dist/schemes/Prompt.d.ts.map +1 -1
  306. package/dist/schemes/Prompt.js +9 -6
  307. package/dist/schemes/Prompt.js.map +1 -1
  308. package/dist/schemes/Skill.d.ts +1 -1
  309. package/dist/schemes/Skill.d.ts.map +1 -1
  310. package/dist/schemes/Skill.js +2 -3
  311. package/dist/schemes/Skill.js.map +1 -1
  312. package/dist/schemes/Worker.d.ts +8 -16
  313. package/dist/schemes/Worker.d.ts.map +1 -1
  314. package/dist/schemes/Worker.js +179 -69
  315. package/dist/schemes/Worker.js.map +1 -1
  316. package/dist/schemes/_entry-chunk.d.ts.map +1 -1
  317. package/dist/schemes/_entry-chunk.js +12 -5
  318. package/dist/schemes/_entry-chunk.js.map +1 -1
  319. package/dist/schemes/_entry-crud.d.ts +10 -9
  320. package/dist/schemes/_entry-crud.d.ts.map +1 -1
  321. package/dist/schemes/_entry-crud.js +59 -13
  322. package/dist/schemes/_entry-crud.js.map +1 -1
  323. package/dist/schemes/_entry-crud.sql +20 -8
  324. package/dist/schemes/_entry-find.d.ts +20 -15
  325. package/dist/schemes/_entry-find.d.ts.map +1 -1
  326. package/dist/schemes/_entry-find.js +339 -174
  327. package/dist/schemes/_entry-find.js.map +1 -1
  328. package/dist/schemes/_entry-find.sql +20 -8
  329. package/dist/schemes/_entry-graph.d.ts +4 -2
  330. package/dist/schemes/_entry-graph.d.ts.map +1 -1
  331. package/dist/schemes/_entry-graph.js +55 -31
  332. package/dist/schemes/_entry-graph.js.map +1 -1
  333. package/dist/schemes/_entry-graph.sql +37 -22
  334. package/dist/schemes/_entry-manifest.d.ts +10 -15
  335. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  336. package/dist/schemes/_entry-manifest.js +50 -268
  337. package/dist/schemes/_entry-manifest.js.map +1 -1
  338. package/dist/schemes/_entry-ops.d.ts +9 -14
  339. package/dist/schemes/_entry-ops.d.ts.map +1 -1
  340. package/dist/schemes/_entry-ops.js +149 -77
  341. package/dist/schemes/_entry-ops.js.map +1 -1
  342. package/dist/schemes/_entry-ops.sql +1 -1
  343. package/dist/schemes/_entry-semantic.d.ts +23 -8
  344. package/dist/schemes/_entry-semantic.d.ts.map +1 -1
  345. package/dist/schemes/_entry-semantic.js +141 -60
  346. package/dist/schemes/_entry-semantic.js.map +1 -1
  347. package/dist/schemes/_entry-semantic.sql +63 -45
  348. package/dist/schemes/_entry-send.d.ts +3 -4
  349. package/dist/schemes/_entry-send.d.ts.map +1 -1
  350. package/dist/schemes/_entry-send.js +48 -23
  351. package/dist/schemes/_entry-send.js.map +1 -1
  352. package/dist/schemes/_path-scope.d.ts +23 -0
  353. package/dist/schemes/_path-scope.d.ts.map +1 -0
  354. package/dist/schemes/_path-scope.js +61 -0
  355. package/dist/schemes/_path-scope.js.map +1 -0
  356. package/dist/schemes/_search-candidate.d.ts +20 -0
  357. package/dist/schemes/_search-candidate.d.ts.map +1 -0
  358. package/dist/schemes/_search-candidate.js +19 -0
  359. package/dist/schemes/_search-candidate.js.map +1 -0
  360. package/dist/schemes/_search-exclusion.d.ts +7 -0
  361. package/dist/schemes/_search-exclusion.d.ts.map +1 -0
  362. package/dist/schemes/_search-exclusion.js +23 -0
  363. package/dist/schemes/_search-exclusion.js.map +1 -0
  364. package/dist/schemes/_search-index.d.ts +6 -0
  365. package/dist/schemes/_search-index.d.ts.map +1 -0
  366. package/dist/schemes/_search-index.js +326 -0
  367. package/dist/schemes/_search-index.js.map +1 -0
  368. package/dist/schemes/cosine.js +1 -1
  369. package/dist/schemes/cosine.js.map +1 -1
  370. package/dist/schemes/exec-abort.js +3 -3
  371. package/dist/schemes/exec-abort.js.map +1 -1
  372. package/dist/schemes/exec-env.js +3 -3
  373. package/dist/schemes/exec-env.js.map +1 -1
  374. package/dist/server/BranchBatches.d.ts +48 -0
  375. package/dist/server/BranchBatches.d.ts.map +1 -0
  376. package/dist/server/BranchBatches.js +591 -0
  377. package/dist/server/BranchBatches.js.map +1 -0
  378. package/dist/server/Daemon.d.ts +36 -66
  379. package/dist/server/Daemon.d.ts.map +1 -1
  380. package/dist/server/Daemon.js +920 -446
  381. package/dist/server/Daemon.js.map +1 -1
  382. package/dist/server/DaemonModule.d.ts +31 -0
  383. package/dist/server/DaemonModule.d.ts.map +1 -0
  384. package/dist/server/DaemonModule.js +2 -0
  385. package/dist/server/DaemonModule.js.map +1 -0
  386. package/dist/server/branch-batch.sql +152 -0
  387. package/dist/server/client-input.d.ts +12 -0
  388. package/dist/server/client-input.d.ts.map +1 -1
  389. package/dist/server/client-input.js +262 -57
  390. package/dist/server/client-input.js.map +1 -1
  391. package/dist/server/dispatch-as-plurnk.d.ts +1 -1
  392. package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
  393. package/dist/server/dispatch-as-plurnk.js +15 -7
  394. package/dist/server/dispatch-as-plurnk.js.map +1 -1
  395. package/dist/server/drain.sql +92 -62
  396. package/dist/server/envelope.d.ts +2 -5
  397. package/dist/server/envelope.d.ts.map +1 -1
  398. package/dist/server/envelope.js +119 -95
  399. package/dist/server/envelope.js.map +1 -1
  400. package/dist/server/envelope.sql +19 -23
  401. package/dist/server/exec-poll-backoff.js +1 -1
  402. package/dist/server/exec-poll-backoff.js.map +1 -1
  403. package/dist/server/lifecycle-recovery.sql +79 -2
  404. package/dist/server/logEntry.d.ts +3 -1
  405. package/dist/server/logEntry.d.ts.map +1 -1
  406. package/dist/server/logEntry.js +4 -2
  407. package/dist/server/logEntry.js.map +1 -1
  408. package/dist/server/logEntry.sql +1 -1
  409. package/dist/server/loop-model.d.ts.map +1 -1
  410. package/dist/server/loop-model.js +22 -9
  411. package/dist/server/loop-model.js.map +1 -1
  412. package/dist/server/loopDocs.d.ts.map +1 -1
  413. package/dist/server/loopDocs.js +5 -4
  414. package/dist/server/loopDocs.js.map +1 -1
  415. package/dist/server/seam-entry-read.sql +15 -10
  416. package/dist/server/seam-log-read.sql +2 -2
  417. package/dist/server/seam-loop.sql +1 -1
  418. package/dist/server/seam-proposal-list.sql +17 -7
  419. package/dist/service.d.ts.map +1 -1
  420. package/dist/service.js +66 -60
  421. package/dist/service.js.map +1 -1
  422. package/migrations/001_schema.sql +897 -0
  423. package/package.json +57 -26
  424. package/dist/core/PluginLoader.d.ts +0 -20
  425. package/dist/core/PluginLoader.d.ts.map +0 -1
  426. package/dist/core/PluginLoader.js +0 -142
  427. package/dist/core/PluginLoader.js.map +0 -1
  428. package/dist/core/TelemetryChannel.d.ts +0 -37
  429. package/dist/core/TelemetryChannel.d.ts.map +0 -1
  430. package/dist/core/TelemetryChannel.js +0 -80
  431. package/dist/core/TelemetryChannel.js.map +0 -1
  432. package/dist/core/path-decode.d.ts +0 -3
  433. package/dist/core/path-decode.d.ts.map +0 -1
  434. package/dist/core/path-decode.js +0 -9
  435. package/dist/core/path-decode.js.map +0 -1
  436. package/dist/core/plugin-attribution.d.ts +0 -5
  437. package/dist/core/plugin-attribution.d.ts.map +0 -1
  438. package/dist/core/plugin-attribution.js +0 -39
  439. package/dist/core/plugin-attribution.js.map +0 -1
  440. package/dist/core/world-state.d.ts +0 -10
  441. package/dist/core/world-state.d.ts.map +0 -1
  442. package/dist/core/world-state.js +0 -35
  443. package/dist/core/world-state.js.map +0 -1
  444. package/dist/core/world-state.sql +0 -35
  445. package/dist/core/zero-pin.d.ts +0 -3
  446. package/dist/core/zero-pin.d.ts.map +0 -1
  447. package/dist/core/zero-pin.js +0 -16
  448. package/dist/core/zero-pin.js.map +0 -1
  449. package/dist/server/auto.d.ts +0 -6
  450. package/dist/server/auto.d.ts.map +0 -1
  451. package/dist/server/auto.js +0 -63
  452. package/dist/server/auto.js.map +0 -1
  453. package/dist/server/clientTurn.d.ts +0 -6
  454. package/dist/server/clientTurn.d.ts.map +0 -1
  455. package/dist/server/clientTurn.js +0 -22
  456. package/dist/server/clientTurn.js.map +0 -1
  457. package/dist/server/clientTurn.sql +0 -10
  458. package/dist/server/noProposals.d.ts +0 -6
  459. package/dist/server/noProposals.d.ts.map +0 -1
  460. package/dist/server/noProposals.js +0 -37
  461. package/dist/server/noProposals.js.map +0 -1
  462. package/dist/server/version-info.d.ts +0 -14
  463. package/dist/server/version-info.d.ts.map +0 -1
  464. package/dist/server/version-info.js +0 -69
  465. package/dist/server/version-info.js.map +0 -1
  466. package/migrations/0000-00-00.01_schema.sql +0 -536
  467. package/migrations/0004_loop-provider.sql +0 -3
  468. package/migrations/0005_subscription-published-channel.sql +0 -3
  469. 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,63 @@ 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
+ CASE
106
+ WHEN COUNT(*) = 0 THEN 0
107
+ WHEN COUNT(usage_cost_usd) = COUNT(*) THEN SUM(usage_cost_usd)
108
+ ELSE NULL
109
+ END AS cost_usd,
110
+ COALESCE((
111
+ SELECT json_group_array(json(cost.value))
112
+ FROM turns charged, json_each(charged.usage_cost) AS cost
113
+ WHERE charged.loop_id = $loop_id
114
+ ), '[]') AS costs,
115
+ (
116
+ SELECT a.usage_prompt
117
+ FROM turn_attempts a
118
+ WHERE a.turn_id = (
119
+ SELECT latest.id
120
+ FROM turns latest
121
+ WHERE latest.loop_id = $loop_id
122
+ ORDER BY latest.sequence DESC
123
+ LIMIT 1
124
+ )
125
+ ORDER BY a.sequence DESC
126
+ LIMIT 1
127
+ ) AS context,
128
+ -- Latest turn's effective packet allowance; NULL when uncapped or unknown.
129
+ -- {§tokenomics-client-gauge}
126
130
  (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.
131
+ -- Latest turn's opaque provider metadata. {§meta-passthrough}
129
132
  (SELECT meta FROM turns WHERE loop_id = $loop_id ORDER BY sequence DESC LIMIT 1) AS meta
130
133
  FROM turns WHERE loop_id = $loop_id;
131
134
 
135
+ -- PREP: engine_loop_attributions
136
+ -- {§attribution} — derive the loop projection from exact response-attempt
137
+ -- evidence plus each turn's latest request (which also covers a call that
138
+ -- failed without response evidence).
139
+ SELECT attribution
140
+ FROM (
141
+ SELECT value AS attribution
142
+ FROM turns t, json_each(t.packet, '$.attributions')
143
+ WHERE t.loop_id = $loop_id
144
+ UNION
145
+ SELECT value AS attribution
146
+ FROM turn_attempts a
147
+ JOIN turns t ON t.id = a.turn_id,
148
+ json_each(a.attributions)
149
+ WHERE t.loop_id = $loop_id
150
+ )
151
+ ORDER BY attribution;
152
+
132
153
  -- PREP: engine_loop_turn_seqs
133
154
  -- Look up (loop_seq, turn_seq) for a given (loop_id, turn_id). Used by
134
155
  -- #writeLog when an op needs to address itself or its output by log
@@ -138,14 +159,14 @@ FROM loops l, turns t
138
159
  WHERE l.id = $loop_id AND t.id = $turn_id;
139
160
 
140
161
  -- 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
162
+ -- Turn-as-container model: insert a turn row at runTurn open with no assembled
163
+ -- model request and status=102 (in-progress). Pre-model writes
164
+ -- (the user prompt; later, system signals/notices) land into
144
165
  -- this row before the provider is called. The turn is then "closed"
145
166
  -- via engine_close_turn with the final packet + status + usage stats
146
167
  -- after dispatch completes.
147
- INSERT INTO turns (loop_id, sequence, status, packet)
148
- VALUES ($loop_id, $sequence, 102, '{}')
168
+ INSERT INTO turns (loop_id, sequence, status)
169
+ VALUES ($loop_id, $sequence, 102)
149
170
  RETURNING id;
150
171
 
151
172
  -- PREP: engine_close_turn
@@ -159,6 +180,7 @@ UPDATE turns SET
159
180
  usage_completion = $usage_completion,
160
181
  usage_reasoning = $usage_reasoning,
161
182
  usage_cached = $usage_cached,
183
+ usage_cost = $usage_cost,
162
184
  usage_cost_usd = $usage_cost_usd,
163
185
  usage_prompt_budget = $usage_prompt_budget,
164
186
  finish_reason = $finish_reason,
@@ -166,81 +188,161 @@ UPDATE turns SET
166
188
  meta = $meta
167
189
  WHERE id = $id;
168
190
 
191
+ -- PREP: engine_record_turn_attempt
192
+ -- One provider attempt carrying response evidence beneath a turn. Rejected or
193
+ -- interrupted attempts remain forensic evidence but never become packet history.
194
+ INSERT INTO turn_attempts (
195
+ turn_id,
196
+ sequence,
197
+ accepted,
198
+ response,
199
+ parse_errors,
200
+ attributions,
201
+ usage_prompt,
202
+ usage_completion,
203
+ usage_reasoning,
204
+ usage_cached,
205
+ usage_cost,
206
+ usage_cost_usd,
207
+ finish_reason,
208
+ model
209
+ )
210
+ VALUES (
211
+ $turn_id,
212
+ $sequence,
213
+ $accepted,
214
+ $response,
215
+ $parse_errors,
216
+ $attributions,
217
+ $usage_prompt,
218
+ $usage_completion,
219
+ $usage_reasoning,
220
+ $usage_cached,
221
+ $usage_cost,
222
+ $usage_cost_usd,
223
+ $finish_reason,
224
+ $model
225
+ );
226
+
169
227
  -- 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.
228
+ -- Every owner-held entry of a workspace — all schemes, all channels — for
229
+ -- internal indexing and aggregate inspection. Addressable catalogs use the
230
+ -- owner-filtered statements above.
231
+ -- The latest subscription carries stream lifecycle into the catalog. `seconds`
232
+ -- is the live age of an open stream; close_status is the exact terminal status
233
+ -- of a closed one. Entries with no subscription remain ordinary static entries.
176
234
  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
235
+ s.id AS subscription_id,
236
+ CASE WHEN s.closed_at IS NULL
237
+ THEN CAST(unixepoch('now') - unixepoch(s.opened_at) AS INTEGER)
238
+ ELSE NULL
239
+ END AS seconds,
240
+ s.close_status
178
241
  FROM entries e
179
242
  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
243
+ LEFT JOIN subscriptions s ON s.id = (
244
+ SELECT latest.id
245
+ FROM subscriptions latest
246
+ WHERE latest.entry_id = e.id
247
+ ORDER BY latest.id DESC
248
+ LIMIT 1
249
+ )
182
250
  WHERE e.workspace_id = $workspace_id
183
251
  -- User Note 5 — mtime-ascending: dormant entries hold the stable prompt-cache prefix; churn clusters at the tail.
184
252
  ORDER BY e.updated_at ASC, e.id ASC, ec.name;
185
253
 
186
254
  -- 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.
255
+ -- Per-scheme entry tally plus one-level catalog-row count (direct entries and
256
+ -- distinct first-segment `dir/**` summaries). The engine uses the latter to
257
+ -- encode a valid first-N file preview range without guessing how many rows the
258
+ -- shallow projection will produce.
190
259
  SELECT e.scheme AS scheme,
191
- COUNT(DISTINCT e.id) AS entries
260
+ COUNT(DISTINCT e.id) AS entries,
261
+ COUNT(DISTINCT CASE
262
+ WHEN instr(ltrim(e.pathname, '/'), '/') = 0
263
+ THEN 'entry:' || ltrim(e.pathname, '/')
264
+ ELSE 'scope:' || substr(ltrim(e.pathname, '/'), 1, instr(ltrim(e.pathname, '/'), '/'))
265
+ END) AS shallow_items
192
266
  FROM entries e
193
267
  JOIN entry_channels ec ON ec.entry_id = e.id
194
268
  WHERE e.workspace_id = $workspace_id
195
269
  GROUP BY e.scheme
196
270
  ORDER BY e.scheme;
197
271
 
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).
272
+ -- PREP: engine_initialize_ambient_cursor
273
+ -- A worker's first packet reads current shared state directly, so pre-existing
274
+ -- occurrences are its baseline rather than historical deltas. The NULL guard
275
+ -- makes this safe on every turn and preserves a fork's inherited progress.
276
+ UPDATE workers
277
+ SET ambient_event_cursor = COALESCE((
278
+ SELECT MAX(ae.id) FROM ambient_events ae WHERE ae.workspace_id = $workspace_id
279
+ ), 0)
280
+ WHERE id = $worker_id
281
+ AND workspace_id = $workspace_id
282
+ AND ambient_event_cursor IS NULL
283
+ RETURNING ambient_event_cursor;
284
+
285
+ -- PREP: engine_pull_ambient_events
286
+ -- One SQLite snapshot captures both ends of the closed observation window.
287
+ -- The LEFT JOIN returns the boundary even when the window contains no event.
288
+ WITH observation AS (
289
+ SELECT w.ambient_event_cursor AS cursor,
290
+ COALESCE(
291
+ (SELECT MAX(ae.id) FROM ambient_events ae WHERE ae.workspace_id = $workspace_id),
292
+ w.ambient_event_cursor,
293
+ 0
294
+ ) AS boundary
295
+ FROM workers w
296
+ WHERE w.id = $worker_id AND w.workspace_id = $workspace_id
297
+ )
298
+ SELECT o.cursor, o.boundary,
299
+ ae.id AS event_id, ae.producer_worker_id, producer.name AS producer_worker_name,
300
+ ae.kind, ae.source,
301
+ ae.op, ae.scheme, ae.hostname, ae.pathname, ae.rx, ae.attrs,
302
+ ae.status_rx, ae.prompt, ae.terminated_by
303
+ FROM observation o
304
+ LEFT JOIN ambient_events ae
305
+ ON ae.workspace_id = $workspace_id
306
+ AND ae.id > o.cursor
307
+ AND ae.id <= o.boundary
308
+ AND ae.producer_worker_id != $worker_id
309
+ LEFT JOIN workers producer ON producer.id = ae.producer_worker_id
310
+ ORDER BY ae.id;
311
+
312
+ -- PREP: engine_insert_ambient_delta
313
+ -- Materialize one occurrence into the observer's self-contained log. The
314
+ -- targeted conflict rule makes crash replay idempotent without swallowing any
315
+ -- unrelated sequence, FK, or shape violation.
229
316
  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
317
+ worker_id, loop_id, turn_id, sequence, origin, source, ambient_event_id,
318
+ op, scheme, hostname, pathname, tx, mimetype_tx,
319
+ rx, mimetype_rx, status_rx, expanded, attrs
232
320
  ) VALUES (
233
- $worker_id, $loop_id, $turn_id, $sequence, 'plurnk', $source,
234
- 'EDIT', $scheme, $pathname, '', 'text/plain', $rx, 'application/json', 200, 0, $attrs
235
- );
321
+ $worker_id, $loop_id, $turn_id, $sequence, 'plurnk', $source, $event_id,
322
+ $op, $scheme, $hostname, $pathname, '', 'text/plain',
323
+ $rx, $mimetype_rx, $status, $expanded, $attrs
324
+ )
325
+ ON CONFLICT(worker_id, ambient_event_id) WHERE ambient_event_id IS NOT NULL DO NOTHING
326
+ RETURNING id;
327
+
328
+ -- PREP: engine_advance_ambient_cursor
329
+ -- Advance only from the snapshot that was actually materialized. A concurrent
330
+ -- pull winning the CAS is safe; a loser replays idempotently on its next turn.
331
+ UPDATE workers
332
+ SET ambient_event_cursor = $boundary
333
+ WHERE id = $worker_id
334
+ AND workspace_id = $workspace_id
335
+ AND ambient_event_cursor IS $cursor
336
+ AND $boundary >= ambient_event_cursor
337
+ RETURNING ambient_event_cursor;
236
338
 
237
339
  -- PREP: engine_worker_stream_channels
238
- -- §exec-stream — every stream channel the worker owns (an EXEC's stdout/stderr live on the
340
+ -- {§exec-stream} — every stream channel the worker owns (an EXEC's stdout/stderr live on the
239
341
  -- runtime-tag entry), with content + state + coordinate, so the per-turn injector can emit the
240
342
  -- channel's unshown byte-delta. Stays listed until its last delta is shown (cursor == content len).
241
343
  SELECT s.id AS subscription_id, e.scheme AS runtime, e.pathname AS coord,
242
344
  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
+ s.close_result AS close_result, s.published_channel AS published_channel
244
346
  FROM subscriptions s
245
347
  JOIN entries e ON e.id = s.entry_id
246
348
  JOIN entry_channels ec ON ec.entry_id = s.entry_id
@@ -249,7 +351,7 @@ WHERE s.worker_id = $worker_id
249
351
  ORDER BY s.id, ec.name;
250
352
 
251
353
  -- PREP: engine_stream_cursor
252
- -- §exec-stream — bytes of this channel already shown to the worker: the streamEnd recorded on its
354
+ -- {§exec-stream} — bytes of this channel already shown to the worker: the streamEnd recorded on its
253
355
  -- latest foisted delta (the caller defaults to 0 when none exists yet).
254
356
  SELECT attrs
255
357
  FROM log_entries
@@ -258,44 +360,16 @@ WHERE worker_id = $worker_id AND origin = 'plurnk' AND op = 'READ'
258
360
  ORDER BY id DESC LIMIT 1;
259
361
 
260
362
  -- 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
363
+ -- {§exec-stream} / {§env-delta} — materialize a channel's unshown byte-delta as a
364
+ -- foisted READ row (the model READs the stream it never typed). origin=plurnk; fragment is
263
365
  -- 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
366
+ -- (the terminal delta auto-OPENs), 0 while it streams (ongoing deltas fold). {§exec-stream}
265
367
  INSERT INTO log_entries (
266
368
  worker_id, loop_id, turn_id, sequence, origin, source,
267
369
  op, scheme, pathname, fragment, tx, mimetype_tx, rx, mimetype_rx, status_rx, attrs, expanded
268
370
  ) VALUES (
269
371
  $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
372
+ 'READ', $scheme, $pathname, $fragment, '', 'text/plain', $rx, 'application/json', $status, $attrs, $expanded
299
373
  );
300
374
 
301
375
  -- PREP: engine_entry_tags
@@ -303,7 +377,7 @@ SELECT tag FROM entry_tags WHERE entry_id = $entry_id ORDER BY tag;
303
377
 
304
378
  -- PREP: engine_child_workers_live
305
379
  -- 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>`
380
+ -- Powers the Active Child Workers orienting section ({§child-orientation}): terse `* <status> worker://<name>`
307
381
  -- pointers so the model SEES what it holds live and reasons for itself (READ/KILL), never told to.
308
382
  -- Empty → section omitted.
309
383
  SELECT r.name, l.status
@@ -314,7 +388,7 @@ ORDER BY r.name;
314
388
 
315
389
  -- PREP: engine_child_streams_open
316
390
  -- 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
391
+ -- Streams orienting section ({§child-orientation}): terse `* active <runtime>:///<coord>` pointers the
318
392
  -- model OPENs/READs/KILLs. Empty → section omitted.
319
393
  SELECT s.scheme, e.pathname
320
394
  FROM subscriptions s
@@ -322,14 +396,14 @@ JOIN entries e ON e.id = s.entry_id
322
396
  WHERE s.worker_id = $worker_id AND s.closed_at IS NULL
323
397
  ORDER BY e.pathname;
324
398
 
325
- -- PREP: engine_render_telemetry_errors
326
- -- SPEC §telemetry: 4xx/5xx log rows are mirrored into the packet's telemetry as
399
+ -- PREP: engine_render_errors
400
+ -- SPEC {§operation-results}: 4xx/5xx log rows are indexed in the packet's errors as
327
401
  -- LogCoordinate pointers, forcing the model to confront failures instead of letting
328
402
  -- them rot in log:///. Window = the current turn AND the immediately-prior one
329
403
  -- (>= current_turn_seq - 1): prior-turn for action failures the model just caused,
330
404
  -- current-turn so a same-turn engine error (the grinder's budget-overflow row, minted
331
405
  -- pre-generate then re-derived) surfaces THIS turn rather than a turn late.
332
- -- §telemetry-uniform-error-channel
406
+ -- {§operation-result-uniform-error-channel}
333
407
  SELECT
334
408
  le.op, le.sequence, le.status_rx, le.rx, le.mimetype_rx,
335
409
  le.scheme, le.pathname,
@@ -339,71 +413,72 @@ JOIN turns t ON t.id = le.turn_id
339
413
  JOIN loops l ON l.id = le.loop_id
340
414
  WHERE le.loop_id = $loop_id
341
415
  AND le.status_rx >= 400
342
- -- §log-row-self-explains: every >=400 row points at ITSELF — the op row carries its failure
416
+ -- {§log-row-self-explains}: every >=400 row points at ITSELF — the op row carries its failure
343
417
  -- message on its meta line (packet-wire), so the pointer leads to a record that states its why.
344
418
  AND t.sequence >= $current_turn_seq - 1
345
419
  ORDER BY t.sequence, le.sequence;
346
420
 
347
- -- PREP: engine_grinder_fold_newest_turn
348
- -- §grinder-layer1-rollback — THE DOCTRINE: the log is the model's memory and the model ALONE
421
+ -- TX: engine_grinder_fold_newest_turn
422
+ -- {§grinder-layer1-rollback} — THE DOCTRINE: the log is the model's memory and the model ALONE
349
423
  -- curates it (FOLD/KILL). The grinder never touches history — it only blocks NEW memories from
350
424
  -- landing when there is no room: one set-op folds the still-open rows of the newest turn
351
425
  -- boundary — the immediately-prior turn's emissions and the current turn's pre-model rows
352
426
  -- (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
427
+ -- Folded, never deleted; THREE exemptions ({§grinder-errors-exempt}): op='error',
428
+ -- the user prompt, and PLAN. The temporary set captures the
429
+ -- selection once so folding and additive `overflow` tagging cannot diverge.
430
+ CREATE TEMP TABLE IF NOT EXISTS engine_grinder_fold_set (id INTEGER PRIMARY KEY);
431
+ DELETE FROM engine_grinder_fold_set;
432
+ INSERT INTO engine_grinder_fold_set (id)
433
+ SELECT id FROM log_entries
360
434
  WHERE loop_id = $loop_id AND expanded = 1 AND op NOT IN ('error', 'PLAN')
361
435
  AND COALESCE(scheme, '') != 'prompt' -- the task frame ({§prompt-self-only}); NULL-safe: a model row's scheme is NULL
362
436
  AND (turn_id = $turn_id
363
437
  OR turn_id = (SELECT MAX(id) FROM turns WHERE loop_id = $loop_id AND id < $turn_id));
364
438
 
439
+ UPDATE log_entries SET expanded = 0
440
+ WHERE id IN (SELECT id FROM engine_grinder_fold_set);
441
+
442
+ INSERT OR IGNORE INTO log_tags (log_entry_id, tag)
443
+ SELECT id, 'overflow' FROM engine_grinder_fold_set;
444
+
445
+ DELETE FROM engine_grinder_fold_set;
446
+
365
447
  -- 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.
448
+ -- Fold one known log row by id. Model mirror rows use this after insertion so
449
+ -- the complete admitted emission remains available without opening by default.
369
450
  UPDATE log_entries SET expanded = 0 WHERE id = $id;
370
451
 
371
452
  -- 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
453
+ -- Render-time log-section assembly ({§body-projection}).
454
+ -- Yields log_entries for the whole worker — the conversation's working
455
+ -- memory carries across loops within a worker, not just the
375
456
  -- current loop. Coordinate is log:///<loop_seq>/<turn_seq>/<sequence>/<op>.
376
457
  -- Status 202 entries in state='proposed' are model-invisible until resolved.
377
458
  -- `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.
459
+ -- (FOLD); the renderer elides the body. {§open-fold}: folded rows stay listed, re-OPENable.
379
460
  SELECT
380
461
  l.sequence AS loop_seq,
381
462
  t.sequence AS turn_seq,
382
463
  le.sequence,
383
- -- le.origin is attribution, never a render filter; the worker's actor — §actor-boundary-origin-not-filter §machine-processes-worker-origin
464
+ -- le.origin is attribution, never a render filter; the worker's actor — {§actor-boundary-origin-not-filter} {§machine-processes-worker-origin}
384
465
  le.origin,
385
466
  le.op, le.suffix, le.signal,
386
467
  le.scheme, le.username, le.password,
387
468
  le.hostname, le.port, le.pathname,
388
- le.params, le.fragment,
469
+ le.query, le.fragment,
389
470
  le.status_rx, le.rx, le.mimetype_rx,
390
471
  le.tx, le.mimetype_tx,
391
472
  le.state, le.outcome, le.expanded, le.source, le.attrs
392
473
  FROM log_entries le
393
474
  JOIN turns t ON t.id = le.turn_id
394
475
  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).
476
+ -- WHERE renders exactly one worker's log — {§actor-boundary-isolation} {§machine-processes-worker-is-its-log}
477
+ -- the AND NOT clauses keep proposed (202) rows hidden until resolved ({§proposal-proposed-hidden}),
478
+ -- and successful log-curation receipts out of the packet. OPEN/FOLD follow
479
+ -- {§fold-open-meta-operations}; only log-target KILL follows
480
+ -- {§kill-log-receipt-suppressed}. Every failed operation remains visible through
481
+ -- {§operation-result-uniform-error-channel}.
407
482
  WHERE le.worker_id = $worker_id
408
483
  AND NOT (le.status_rx = 202 AND le.state = 'proposed')
409
484
  AND NOT (le.op IN ('OPEN', 'FOLD') AND le.status_rx < 400)
@@ -414,19 +489,19 @@ ORDER BY l.sequence, t.sequence, le.sequence;
414
489
  -- Default state='resolved' covers the common path (non-proposing schemes
415
490
  -- return their final status immediately). Status 202 + state='proposed'
416
491
  -- triggers the proposal lifecycle (engine pauses dispatch; client resolves
417
- -- via loop/resolve RPC; entry transitions through engine_resolve_log_entry).
492
+ -- via proposal resolution; entry transitions through engine_resolve_log_entry).
418
493
  INSERT INTO log_entries (
419
494
  worker_id, loop_id, turn_id, sequence, origin, source,
420
495
  op, suffix, signal,
421
496
  scheme, username, password, hostname, port,
422
- pathname, params, fragment, lineMarker,
497
+ pathname, query, fragment, lineMarker,
423
498
  tx, mimetype_tx, rx, mimetype_rx, status_rx, tokens,
424
499
  state, outcome, attrs
425
500
  ) VALUES (
426
501
  $worker_id, $loop_id, $turn_id, $sequence, $origin, $source,
427
502
  $op, $suffix, $signal,
428
503
  $scheme, $username, $password, $hostname, $port,
429
- $pathname, $params, $fragment, $lineMarker,
504
+ $pathname, $query, $fragment, $lineMarker,
430
505
  $tx, $mimetype_tx, $rx, $mimetype_rx, $status_rx, $tokens,
431
506
  $state, $outcome, $attrs
432
507
  )
@@ -434,18 +509,32 @@ RETURNING id;
434
509
 
435
510
  -- PREP: engine_resolve_log_entry
436
511
  -- Transitions a proposed log entry to its terminal state. Used by the
437
- -- proposal lifecycle (loop/resolve RPC, auto resolution, timeout, abort).
512
+ -- proposal lifecycle (client resolution, auto resolution, timeout, abort).
438
513
  -- Updates status_rx + rx + state + outcome atomically.
439
514
  UPDATE log_entries
440
515
  SET state = $state,
441
516
  outcome = $outcome,
442
517
  status_rx = $status_rx,
443
- rx = $rx
518
+ rx = $rx,
519
+ deep_hash = NULL
444
520
  WHERE id = $id
445
521
  AND state = 'proposed';
446
522
 
523
+ -- PREP: engine_log_entry_coordinate
524
+ -- Resolve a durable operation occurrence after a proposal settles so a
525
+ -- Problem Details instance names the same model-facing log URI as every
526
+ -- immediately failed operation.
527
+ SELECT l.sequence AS loop_seq,
528
+ t.sequence AS turn_seq,
529
+ le.sequence AS sequence,
530
+ le.op AS op
531
+ FROM log_entries le
532
+ JOIN turns t ON t.id = le.turn_id
533
+ JOIN loops l ON l.id = le.loop_id
534
+ WHERE le.id = $id;
535
+
447
536
  -- PREP: engine_turn_retrievals
448
- -- §send-premature-terminate — the pending set's retrieval leg: THIS turn's READ/FIND/OPEN rows,
537
+ -- {§send-premature-terminate} — the pending set's retrieval leg: THIS turn's READ/FIND/OPEN rows,
449
538
  -- whose results the model cannot have seen (they fold back next packet). A [200] over them is
450
539
  -- discarding answers it asked for.
451
540
  SELECT id FROM log_entries
@@ -475,36 +564,38 @@ WHERE s.worker_id = $worker_id
475
564
  LIMIT 1;
476
565
 
477
566
  -- 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).
567
+ -- {§send-premature-terminate} — THIS turn's failed op results (the model's own ops, status >= 400), whose
568
+ -- errors the model cannot have seen (they land next packet). A [200] or already-drained [202] over
569
+ -- them concludes blind past a failure — refused 409; [499] abandons regardless (declaring failure
570
+ -- IS weighing it).
571
+ -- Actionless engine errors are excluded: the grinder's overflow row mints pre-packet, so the
572
+ -- recovery turn already saw it ({§grinder-hard-413-recovery}). A model-authored statement that
573
+ -- failed grammar parsing is different: source='grammar' records a bounded operation failure
574
+ -- from the accepted emission, unseen until the next packet, so it gates completion like every
575
+ -- other failed model operation.
485
576
  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.
577
+ WHERE turn_id = $turn_id
578
+ AND origin = 'model'
579
+ AND status_rx >= 400
580
+ AND (op != 'error' OR source = 'grammar');
581
+
582
+ -- PREP: engine_reconcile_turn_status
583
+ -- A SEND's signal is only provisional until dispatch adjudicates live obligations and failures.
584
+ -- The close writes packet+usage before ops dispatch, so reconcile the persisted turn whenever
585
+ -- dispatch changes that disposition (for example refused 200 -> 102 or drained 202 -> 200).
493
586
  UPDATE turns SET status = $status WHERE id = $id;
494
587
 
495
588
 
496
589
 
497
590
  -- PREP: engine_loop_sequence
498
- -- The loop's PER-RUN sequence — the model-facing coordinate (prompt/<run>/<loop-seq>/<turn-seq>,
591
+ -- The loop's per-worker sequence — the model-facing coordinate (prompt/<worker>/<loop-seq>/<turn-seq>,
499
592
  -- matching the log's loop-relative numbering). The raw db id leaked into prompt paths and the
500
593
  -- model's first loop read as prompt/2/1 (the docs loop holds id 1). Owner: minor but annoying.
501
594
  SELECT sequence FROM loops WHERE id = $loop_id;
502
595
 
503
596
  -- 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).
597
+ -- The no-parent root of a worker lineage; a root worker returns itself.
598
+ -- {§worker-primary}
508
599
  WITH RECURSIVE lineage(id, parent_worker_id) AS (
509
600
  SELECT id, parent_worker_id FROM workers WHERE id = $worker_id
510
601
  UNION ALL
@@ -513,14 +604,15 @@ WITH RECURSIVE lineage(id, parent_worker_id) AS (
513
604
  SELECT id FROM lineage WHERE parent_worker_id IS NULL;
514
605
 
515
606
  -- 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)
607
+ -- A child conclusion newer than the parent's observation cursor is complete but
608
+ -- not delivered. This is the same durable boundary the next packet consumes,
609
+ -- not a second timestamp race. {§send-undelivered-child-term}
610
+ SELECT 1 AS pending
611
+ FROM ambient_events ae
612
+ JOIN workers child ON child.id = ae.producer_worker_id
613
+ JOIN workers parent ON parent.id = $worker_id
614
+ WHERE ae.workspace_id = parent.workspace_id
615
+ AND ae.kind = 'loop_termination'
616
+ AND child.parent_worker_id = parent.id
617
+ AND ae.id > COALESCE(parent.ambient_event_cursor, 0)
526
618
  LIMIT 1;