@plurnk/plurnk-service 1.17.0 → 1.19.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 (501) hide show
  1. package/.env.defaults +95 -14
  2. package/README.md +5 -3
  3. package/SPEC.md +1756 -1442
  4. package/dist/Paths.js +3 -3
  5. package/dist/build-info.json +1 -1
  6. package/dist/content/body-preview.d.ts +1 -0
  7. package/dist/content/body-preview.d.ts.map +1 -1
  8. package/dist/content/body-preview.js +8 -10
  9. package/dist/content/body-preview.js.map +1 -1
  10. package/dist/content/edit-receipt.d.ts.map +1 -1
  11. package/dist/content/edit-receipt.js +30 -29
  12. package/dist/content/edit-receipt.js.map +1 -1
  13. package/dist/content/line-anchors.d.ts.map +1 -1
  14. package/dist/content/line-anchors.js +17 -5
  15. package/dist/content/line-anchors.js.map +1 -1
  16. package/dist/content/read-projector.d.ts +2 -2
  17. package/dist/content/read-projector.d.ts.map +1 -1
  18. package/dist/content/read-projector.js +81 -39
  19. package/dist/content/read-projector.js.map +1 -1
  20. package/dist/content/read-resolve.d.ts +1 -0
  21. package/dist/content/read-resolve.d.ts.map +1 -1
  22. package/dist/content/read-resolve.js +13 -10
  23. package/dist/content/read-resolve.js.map +1 -1
  24. package/dist/content/scope-format.d.ts +9 -0
  25. package/dist/content/scope-format.d.ts.map +1 -0
  26. package/dist/content/scope-format.js +28 -0
  27. package/dist/content/scope-format.js.map +1 -0
  28. package/dist/core/AdministrativeLoop.d.ts +8 -0
  29. package/dist/core/AdministrativeLoop.d.ts.map +1 -0
  30. package/dist/core/AdministrativeLoop.js +16 -0
  31. package/dist/core/AdministrativeLoop.js.map +1 -0
  32. package/dist/core/AdmittedTurnExecutor.d.ts +2 -2
  33. package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
  34. package/dist/core/AdmittedTurnExecutor.js +26 -26
  35. package/dist/core/AdmittedTurnExecutor.js.map +1 -1
  36. package/dist/core/BareBatchRunner.d.ts +1 -2
  37. package/dist/core/BareBatchRunner.d.ts.map +1 -1
  38. package/dist/core/BareBatchRunner.js +7 -12
  39. package/dist/core/BareBatchRunner.js.map +1 -1
  40. package/dist/core/BudgetReadout.d.ts.map +1 -1
  41. package/dist/core/BudgetReadout.js +3 -4
  42. package/dist/core/BudgetReadout.js.map +1 -1
  43. package/dist/core/CapabilityPolicies.d.ts +4 -2
  44. package/dist/core/CapabilityPolicies.d.ts.map +1 -1
  45. package/dist/core/CapabilityPolicies.js +23 -2
  46. package/dist/core/CapabilityPolicies.js.map +1 -1
  47. package/dist/core/CapabilityResolver.d.ts +2 -2
  48. package/dist/core/CapabilityResolver.d.ts.map +1 -1
  49. package/dist/core/CapabilityResolver.js +46 -36
  50. package/dist/core/CapabilityResolver.js.map +1 -1
  51. package/dist/core/ChannelWrite.d.ts +4 -6
  52. package/dist/core/ChannelWrite.d.ts.map +1 -1
  53. package/dist/core/ChannelWrite.js +8 -8
  54. package/dist/core/ChannelWrite.js.map +1 -1
  55. package/dist/core/ChannelWrite.sql +17 -11
  56. package/dist/core/ClientInteractions.d.ts +11 -1
  57. package/dist/core/ClientInteractions.d.ts.map +1 -1
  58. package/dist/core/ClientInteractions.js +26 -2
  59. package/dist/core/ClientInteractions.js.map +1 -1
  60. package/dist/core/CoreSchemeServices.d.ts.map +1 -1
  61. package/dist/core/CoreSchemeServices.js +1 -0
  62. package/dist/core/CoreSchemeServices.js.map +1 -1
  63. package/dist/core/DataStatementRunner.d.ts.map +1 -1
  64. package/dist/core/DataStatementRunner.js +198 -148
  65. package/dist/core/DataStatementRunner.js.map +1 -1
  66. package/dist/core/Dispatcher.d.ts +18 -5
  67. package/dist/core/Dispatcher.d.ts.map +1 -1
  68. package/dist/core/Dispatcher.js +135 -114
  69. package/dist/core/Dispatcher.js.map +1 -1
  70. package/dist/core/Dispatcher.sql +11 -26
  71. package/dist/core/DurableStatement.d.ts +4 -1
  72. package/dist/core/DurableStatement.d.ts.map +1 -1
  73. package/dist/core/DurableStatement.js +4 -4
  74. package/dist/core/DurableStatement.js.map +1 -1
  75. package/dist/core/EditMutations.d.ts.map +1 -1
  76. package/dist/core/EditMutations.js +5 -2
  77. package/dist/core/EditMutations.js.map +1 -1
  78. package/dist/core/Engine.d.ts +11 -9
  79. package/dist/core/Engine.d.ts.map +1 -1
  80. package/dist/core/Engine.js +27 -65
  81. package/dist/core/Engine.js.map +1 -1
  82. package/dist/core/Engine.sql +2 -22
  83. package/dist/core/EnvFlags.d.ts.map +1 -1
  84. package/dist/core/EnvFlags.js +4 -2
  85. package/dist/core/EnvFlags.js.map +1 -1
  86. package/dist/core/ExecutionOutputs.sql +8 -0
  87. package/dist/core/ExecutorRegistry.d.ts +4 -0
  88. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  89. package/dist/core/ExecutorRegistry.js +3 -1
  90. package/dist/core/ExecutorRegistry.js.map +1 -1
  91. package/dist/core/KillHandler.d.ts.map +1 -1
  92. package/dist/core/KillHandler.js +7 -12
  93. package/dist/core/KillHandler.js.map +1 -1
  94. package/dist/core/Knob.d.ts +9 -0
  95. package/dist/core/Knob.d.ts.map +1 -0
  96. package/dist/core/Knob.js +50 -0
  97. package/dist/core/Knob.js.map +1 -0
  98. package/dist/core/LogBody.d.ts.map +1 -1
  99. package/dist/core/LogBody.js +8 -36
  100. package/dist/core/LogBody.js.map +1 -1
  101. package/dist/core/LogEntryProjection.d.ts.map +1 -1
  102. package/dist/core/LogEntryProjection.js +8 -10
  103. package/dist/core/LogEntryProjection.js.map +1 -1
  104. package/dist/core/LogVisibility.d.ts.map +1 -1
  105. package/dist/core/LogVisibility.js +2 -1
  106. package/dist/core/LogVisibility.js.map +1 -1
  107. package/dist/core/LogWriter.d.ts.map +1 -1
  108. package/dist/core/LogWriter.js +11 -9
  109. package/dist/core/LogWriter.js.map +1 -1
  110. package/dist/core/LoopDriver.d.ts +1 -1
  111. package/dist/core/LoopDriver.d.ts.map +1 -1
  112. package/dist/core/LoopDriver.js +24 -32
  113. package/dist/core/LoopDriver.js.map +1 -1
  114. package/dist/core/LoopLifecycle.d.ts +4 -17
  115. package/dist/core/LoopLifecycle.d.ts.map +1 -1
  116. package/dist/core/LoopLifecycle.js +20 -22
  117. package/dist/core/LoopLifecycle.js.map +1 -1
  118. package/dist/core/LoopLifecycle.sql +36 -49
  119. package/dist/core/LoopOutcome.d.ts +10 -0
  120. package/dist/core/LoopOutcome.d.ts.map +1 -0
  121. package/dist/core/LoopOutcome.js +28 -0
  122. package/dist/core/LoopOutcome.js.map +1 -0
  123. package/dist/core/LoopPolicies.d.ts +7 -0
  124. package/dist/core/LoopPolicies.d.ts.map +1 -0
  125. package/dist/core/LoopPolicies.js +37 -0
  126. package/dist/core/LoopPolicies.js.map +1 -0
  127. package/dist/core/MessageResources.d.ts +15 -0
  128. package/dist/core/MessageResources.d.ts.map +1 -0
  129. package/dist/core/MessageResources.js +46 -0
  130. package/dist/core/MessageResources.js.map +1 -0
  131. package/dist/core/MessageResources.sql +36 -0
  132. package/dist/core/ModelCall.d.ts.map +1 -1
  133. package/dist/core/ModelCall.js +2 -6
  134. package/dist/core/ModelCall.js.map +1 -1
  135. package/dist/core/ModelCall.sql +7 -36
  136. package/dist/core/OperatorConfig.d.ts +2 -1
  137. package/dist/core/OperatorConfig.d.ts.map +1 -1
  138. package/dist/core/OperatorConfig.js +14 -6
  139. package/dist/core/OperatorConfig.js.map +1 -1
  140. package/dist/core/PacketBuilder.d.ts.map +1 -1
  141. package/dist/core/PacketBuilder.js +20 -35
  142. package/dist/core/PacketBuilder.js.map +1 -1
  143. package/dist/core/PacketBuilder.sql +24 -6
  144. package/dist/core/PatternSelection.d.ts +1 -1
  145. package/dist/core/PatternSelection.d.ts.map +1 -1
  146. package/dist/core/ProposalLifecycle.d.ts +3 -1
  147. package/dist/core/ProposalLifecycle.d.ts.map +1 -1
  148. package/dist/core/ProposalLifecycle.js +93 -28
  149. package/dist/core/ProposalLifecycle.js.map +1 -1
  150. package/dist/core/ProviderInstantiate.d.ts +1 -0
  151. package/dist/core/ProviderInstantiate.d.ts.map +1 -1
  152. package/dist/core/ProviderInstantiate.js +12 -7
  153. package/dist/core/ProviderInstantiate.js.map +1 -1
  154. package/dist/core/ReasoningView.d.ts +1 -2
  155. package/dist/core/ReasoningView.d.ts.map +1 -1
  156. package/dist/core/ReasoningView.js +9 -20
  157. package/dist/core/ReasoningView.js.map +1 -1
  158. package/dist/core/ResourceBindings.d.ts.map +1 -1
  159. package/dist/core/ResourceBindings.js +5 -4
  160. package/dist/core/ResourceBindings.js.map +1 -1
  161. package/dist/core/ResourceMutations.d.ts +4 -4
  162. package/dist/core/ResourceMutations.d.ts.map +1 -1
  163. package/dist/core/ResourceMutations.js +2 -3
  164. package/dist/core/ResourceMutations.js.map +1 -1
  165. package/dist/core/ResourceSelector.d.ts +10 -3
  166. package/dist/core/ResourceSelector.d.ts.map +1 -1
  167. package/dist/core/ResourceSelector.js +52 -13
  168. package/dist/core/ResourceSelector.js.map +1 -1
  169. package/dist/core/ResourceTransfers.d.ts.map +1 -1
  170. package/dist/core/ResourceTransfers.js +4 -2
  171. package/dist/core/ResourceTransfers.js.map +1 -1
  172. package/dist/core/RuntimeWorker.d.ts.map +1 -1
  173. package/dist/core/RuntimeWorker.js +6 -1
  174. package/dist/core/RuntimeWorker.js.map +1 -1
  175. package/dist/core/RuntimeWorker.sql +7 -1
  176. package/dist/core/SchemeRegistry.d.ts +2 -0
  177. package/dist/core/SchemeRegistry.d.ts.map +1 -1
  178. package/dist/core/SchemeRegistry.js +12 -6
  179. package/dist/core/SchemeRegistry.js.map +1 -1
  180. package/dist/core/StoredPacket.d.ts +3 -1
  181. package/dist/core/StoredPacket.d.ts.map +1 -1
  182. package/dist/core/StoredPacket.js +7 -3
  183. package/dist/core/StoredPacket.js.map +1 -1
  184. package/dist/core/StrikeRail.d.ts +2 -2
  185. package/dist/core/StrikeRail.d.ts.map +1 -1
  186. package/dist/core/StrikeRail.js +15 -7
  187. package/dist/core/StrikeRail.js.map +1 -1
  188. package/dist/core/TerminalResult.d.ts +2 -2
  189. package/dist/core/TerminalResult.d.ts.map +1 -1
  190. package/dist/core/TerminalResult.js +15 -8
  191. package/dist/core/TerminalResult.js.map +1 -1
  192. package/dist/core/ToolInputSchema.d.ts.map +1 -1
  193. package/dist/core/ToolInputSchema.js +24 -8
  194. package/dist/core/ToolInputSchema.js.map +1 -1
  195. package/dist/core/ToolResources.d.ts +1 -0
  196. package/dist/core/ToolResources.d.ts.map +1 -1
  197. package/dist/core/ToolResources.js +50 -26
  198. package/dist/core/ToolResources.js.map +1 -1
  199. package/dist/core/Turn.d.ts +3 -1
  200. package/dist/core/Turn.d.ts.map +1 -1
  201. package/dist/core/Turn.js +4 -1
  202. package/dist/core/Turn.js.map +1 -1
  203. package/dist/core/Turn.sql +14 -2
  204. package/dist/core/TurnDispositionHandler.d.ts +13 -23
  205. package/dist/core/TurnDispositionHandler.d.ts.map +1 -1
  206. package/dist/core/TurnDispositionHandler.js +30 -180
  207. package/dist/core/TurnDispositionHandler.js.map +1 -1
  208. package/dist/core/TurnMaterialization.d.ts +9 -7
  209. package/dist/core/TurnMaterialization.d.ts.map +1 -1
  210. package/dist/core/TurnMaterialization.js +66 -46
  211. package/dist/core/TurnMaterialization.js.map +1 -1
  212. package/dist/core/TurnMaterialization.sql +23 -6
  213. package/dist/core/TurnOps.d.ts.map +1 -1
  214. package/dist/core/TurnOps.js +2 -2
  215. package/dist/core/TurnOps.js.map +1 -1
  216. package/dist/core/TurnRunner.d.ts +2 -8
  217. package/dist/core/TurnRunner.d.ts.map +1 -1
  218. package/dist/core/TurnRunner.js +1116 -1123
  219. package/dist/core/TurnRunner.js.map +1 -1
  220. package/dist/core/TurnRunner.sql +1 -24
  221. package/dist/core/TurnSources.sql +42 -11
  222. package/dist/core/WorkerControlHandler.d.ts.map +1 -1
  223. package/dist/core/WorkerControlHandler.js +23 -0
  224. package/dist/core/WorkerControlHandler.js.map +1 -1
  225. package/dist/core/WorkerName.d.ts +3 -6
  226. package/dist/core/WorkerName.d.ts.map +1 -1
  227. package/dist/core/WorkerName.js +10 -26
  228. package/dist/core/WorkerName.js.map +1 -1
  229. package/dist/core/WorkspaceGate.js +4 -4
  230. package/dist/core/WorkspaceGate.js.map +1 -1
  231. package/dist/core/ambient.sql +45 -19
  232. package/dist/core/attachments.d.ts +3 -1
  233. package/dist/core/attachments.d.ts.map +1 -1
  234. package/dist/core/attachments.js +4 -0
  235. package/dist/core/attachments.js.map +1 -1
  236. package/dist/core/caps/CoreInteractionCaps.d.ts +1 -1
  237. package/dist/core/caps/CoreInteractionCaps.d.ts.map +1 -1
  238. package/dist/core/caps/CoreInteractionCaps.js +4 -2
  239. package/dist/core/caps/CoreInteractionCaps.js.map +1 -1
  240. package/dist/core/caps/DbChannelCaps.js +6 -6
  241. package/dist/core/caps/DbChannelCaps.js.map +1 -1
  242. package/dist/core/caps/DbEntryCaps.js +1 -1
  243. package/dist/core/caps/DbEntryCaps.js.map +1 -1
  244. package/dist/core/caps/DbMessageCaps.d.ts +10 -0
  245. package/dist/core/caps/DbMessageCaps.d.ts.map +1 -0
  246. package/dist/core/caps/DbMessageCaps.js +39 -0
  247. package/dist/core/caps/DbMessageCaps.js.map +1 -0
  248. package/dist/core/caps/DbProjectionCaps.d.ts +2 -2
  249. package/dist/core/caps/DbProjectionCaps.d.ts.map +1 -1
  250. package/dist/core/caps/DbProjectionCaps.js +10 -4
  251. package/dist/core/caps/DbProjectionCaps.js.map +1 -1
  252. package/dist/core/caps/SchemeCtxImpl.d.ts +3 -1
  253. package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
  254. package/dist/core/caps/SchemeCtxImpl.js +11 -0
  255. package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
  256. package/dist/core/env-catalog.d.ts +28 -0
  257. package/dist/core/env-catalog.d.ts.map +1 -0
  258. package/dist/core/env-catalog.js +99 -0
  259. package/dist/core/env-catalog.js.map +1 -0
  260. package/dist/core/file-materialization.js +1 -1
  261. package/dist/core/file-materialization.js.map +1 -1
  262. package/dist/core/fork.sql +7 -6
  263. package/dist/core/git-state.d.ts +3 -2
  264. package/dist/core/git-state.d.ts.map +1 -1
  265. package/dist/core/git-state.js +38 -21
  266. package/dist/core/git-state.js.map +1 -1
  267. package/dist/core/operation-target-groups.d.ts.map +1 -1
  268. package/dist/core/operation-target-groups.js +2 -1
  269. package/dist/core/operation-target-groups.js.map +1 -1
  270. package/dist/core/packet-inject.js +1 -1
  271. package/dist/core/packet-wire.d.ts +11 -0
  272. package/dist/core/packet-wire.d.ts.map +1 -1
  273. package/dist/core/packet-wire.js +382 -333
  274. package/dist/core/packet-wire.js.map +1 -1
  275. package/dist/core/plurnk-uri.d.ts +4 -5
  276. package/dist/core/plurnk-uri.d.ts.map +1 -1
  277. package/dist/core/plurnk-uri.js +10 -31
  278. package/dist/core/plurnk-uri.js.map +1 -1
  279. package/dist/core/scheme-types.d.ts +3 -1
  280. package/dist/core/scheme-types.d.ts.map +1 -1
  281. package/dist/core/scheme-types.js +1 -1
  282. package/dist/core/scheme-types.js.map +1 -1
  283. package/dist/core/teaching.d.ts.map +1 -1
  284. package/dist/core/teaching.js +2 -1
  285. package/dist/core/teaching.js.map +1 -1
  286. package/dist/core/types.d.ts +1 -2
  287. package/dist/core/types.d.ts.map +1 -1
  288. package/dist/core/types.js +1 -1
  289. package/dist/core/types.js.map +1 -1
  290. package/dist/core/worker-ops.sql +3 -8
  291. package/dist/digest/Digest.d.ts.map +1 -1
  292. package/dist/digest/Digest.js +37 -30
  293. package/dist/digest/Digest.js.map +1 -1
  294. package/dist/digest/DigestRender.d.ts +2 -0
  295. package/dist/digest/DigestRender.d.ts.map +1 -1
  296. package/dist/digest/DigestRender.js +97 -9
  297. package/dist/digest/DigestRender.js.map +1 -1
  298. package/dist/digest/DigestRequiem.d.ts.map +1 -1
  299. package/dist/digest/DigestRequiem.js +13 -15
  300. package/dist/digest/DigestRequiem.js.map +1 -1
  301. package/dist/digest/digest-db.d.ts +3 -0
  302. package/dist/digest/digest-db.d.ts.map +1 -0
  303. package/dist/digest/digest-db.js +68 -0
  304. package/dist/digest/digest-db.js.map +1 -0
  305. package/dist/digest/digest-paths.d.ts +6 -0
  306. package/dist/digest/digest-paths.d.ts.map +1 -0
  307. package/dist/digest/digest-paths.js +23 -0
  308. package/dist/digest/digest-paths.js.map +1 -0
  309. package/dist/digest/digest-rows.d.ts +21 -0
  310. package/dist/digest/digest-rows.d.ts.map +1 -1
  311. package/dist/digest/digest.sql +24 -5
  312. package/dist/index.d.ts +0 -1
  313. package/dist/index.d.ts.map +1 -1
  314. package/dist/index.js +0 -1
  315. package/dist/index.js.map +1 -1
  316. package/dist/observe/genai.d.ts +2 -2
  317. package/dist/observe/genai.d.ts.map +1 -1
  318. package/dist/observe/genai.js +15 -5
  319. package/dist/observe/genai.js.map +1 -1
  320. package/dist/schemes/EffectPolicy.d.ts +0 -2
  321. package/dist/schemes/EffectPolicy.d.ts.map +1 -1
  322. package/dist/schemes/EffectPolicy.js +25 -36
  323. package/dist/schemes/EffectPolicy.js.map +1 -1
  324. package/dist/schemes/Exec.d.ts +4 -5
  325. package/dist/schemes/Exec.d.ts.map +1 -1
  326. package/dist/schemes/Exec.js +129 -82
  327. package/dist/schemes/Exec.js.map +1 -1
  328. package/dist/schemes/ExecOutputScheme.d.ts +6 -5
  329. package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
  330. package/dist/schemes/ExecOutputScheme.js +49 -16
  331. package/dist/schemes/ExecOutputScheme.js.map +1 -1
  332. package/dist/schemes/ExecScheduler.js +2 -2
  333. package/dist/schemes/ExecScheduler.js.map +1 -1
  334. package/dist/schemes/File.d.ts.map +1 -1
  335. package/dist/schemes/File.js +30 -21
  336. package/dist/schemes/File.js.map +1 -1
  337. package/dist/schemes/Log.d.ts +4 -4
  338. package/dist/schemes/Log.d.ts.map +1 -1
  339. package/dist/schemes/Log.js +30 -10
  340. package/dist/schemes/Log.js.map +1 -1
  341. package/dist/schemes/QuestionTool.d.ts.map +1 -1
  342. package/dist/schemes/QuestionTool.js +15 -2
  343. package/dist/schemes/QuestionTool.js.map +1 -1
  344. package/dist/schemes/TurnSource.d.ts +3 -2
  345. package/dist/schemes/TurnSource.d.ts.map +1 -1
  346. package/dist/schemes/TurnSource.js +87 -41
  347. package/dist/schemes/TurnSource.js.map +1 -1
  348. package/dist/schemes/Worker.d.ts.map +1 -1
  349. package/dist/schemes/Worker.js +22 -56
  350. package/dist/schemes/Worker.js.map +1 -1
  351. package/dist/schemes/_entry-crud.js +6 -6
  352. package/dist/schemes/_entry-crud.js.map +1 -1
  353. package/dist/schemes/_entry-crud.sql +37 -17
  354. package/dist/schemes/_entry-find.d.ts.map +1 -1
  355. package/dist/schemes/_entry-find.js +6 -5
  356. package/dist/schemes/_entry-find.js.map +1 -1
  357. package/dist/schemes/_entry-fts.d.ts.map +1 -1
  358. package/dist/schemes/_entry-fts.js +6 -3
  359. package/dist/schemes/_entry-fts.js.map +1 -1
  360. package/dist/schemes/_entry-fts.sql +25 -6
  361. package/dist/schemes/_entry-manifest.d.ts +1 -1
  362. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  363. package/dist/schemes/_entry-manifest.js +10 -17
  364. package/dist/schemes/_entry-manifest.js.map +1 -1
  365. package/dist/schemes/_entry-manifest.sql +1 -1
  366. package/dist/schemes/_entry-ops.js +4 -4
  367. package/dist/schemes/_entry-ops.js.map +1 -1
  368. package/dist/schemes/_entry-ops.sql +2 -2
  369. package/dist/schemes/_entry-readable.d.ts.map +1 -1
  370. package/dist/schemes/_entry-readable.js +5 -4
  371. package/dist/schemes/_entry-readable.js.map +1 -1
  372. package/dist/schemes/_entry-send.js +2 -2
  373. package/dist/schemes/_entry-send.js.map +1 -1
  374. package/dist/schemes/_search-exclusion.d.ts +1 -0
  375. package/dist/schemes/_search-exclusion.d.ts.map +1 -1
  376. package/dist/schemes/_search-exclusion.js +12 -0
  377. package/dist/schemes/_search-exclusion.js.map +1 -1
  378. package/dist/schemes/_search-index.d.ts +5 -1
  379. package/dist/schemes/_search-index.d.ts.map +1 -1
  380. package/dist/schemes/_search-index.js +99 -59
  381. package/dist/schemes/_search-index.js.map +1 -1
  382. package/dist/schemes/_search-index.sql +17 -0
  383. package/dist/schemes/exec-abort.d.ts.map +1 -1
  384. package/dist/schemes/exec-abort.js +5 -4
  385. package/dist/schemes/exec-abort.js.map +1 -1
  386. package/dist/schemes/exec-env.d.ts +3 -0
  387. package/dist/schemes/exec-env.d.ts.map +1 -1
  388. package/dist/schemes/exec-env.js +66 -15
  389. package/dist/schemes/exec-env.js.map +1 -1
  390. package/dist/schemes/exec-lifetime.d.ts +11 -0
  391. package/dist/schemes/exec-lifetime.d.ts.map +1 -0
  392. package/dist/schemes/exec-lifetime.js +29 -0
  393. package/dist/schemes/exec-lifetime.js.map +1 -0
  394. package/dist/schemes/exec-runtime.d.ts +1 -1
  395. package/dist/schemes/exec-runtime.d.ts.map +1 -1
  396. package/dist/schemes/exec-runtime.js +1 -1
  397. package/dist/schemes/exec-runtime.js.map +1 -1
  398. package/dist/server/ClientReads.d.ts.map +1 -1
  399. package/dist/server/ClientReads.js +5 -2
  400. package/dist/server/ClientReads.js.map +1 -1
  401. package/dist/server/Daemon.d.ts +31 -7
  402. package/dist/server/Daemon.d.ts.map +1 -1
  403. package/dist/server/Daemon.js +137 -60
  404. package/dist/server/Daemon.js.map +1 -1
  405. package/dist/server/DaemonModule.d.ts +25 -6
  406. package/dist/server/DaemonModule.d.ts.map +1 -1
  407. package/dist/server/DrainSupervisor.d.ts +13 -11
  408. package/dist/server/DrainSupervisor.d.ts.map +1 -1
  409. package/dist/server/DrainSupervisor.js +87 -98
  410. package/dist/server/DrainSupervisor.js.map +1 -1
  411. package/dist/server/EnvFunctionality.d.ts +52 -0
  412. package/dist/server/EnvFunctionality.d.ts.map +1 -0
  413. package/dist/server/EnvFunctionality.js +199 -0
  414. package/dist/server/EnvFunctionality.js.map +1 -0
  415. package/dist/server/Functionality.d.ts +4 -2
  416. package/dist/server/Functionality.d.ts.map +1 -1
  417. package/dist/server/Functionality.js +250 -106
  418. package/dist/server/Functionality.js.map +1 -1
  419. package/dist/server/FunctionalityManager.d.ts +5 -1
  420. package/dist/server/FunctionalityManager.d.ts.map +1 -1
  421. package/dist/server/FunctionalityManager.js +24 -8
  422. package/dist/server/FunctionalityManager.js.map +1 -1
  423. package/dist/server/HttpListener.d.ts +16 -0
  424. package/dist/server/HttpListener.d.ts.map +1 -0
  425. package/dist/server/HttpListener.js +81 -0
  426. package/dist/server/HttpListener.js.map +1 -0
  427. package/dist/server/MembersFunctionality.d.ts.map +1 -1
  428. package/dist/server/MembersFunctionality.js +12 -17
  429. package/dist/server/MembersFunctionality.js.map +1 -1
  430. package/dist/server/PlurnkSkill.d.ts.map +1 -1
  431. package/dist/server/PlurnkSkill.js +1 -0
  432. package/dist/server/PlurnkSkill.js.map +1 -1
  433. package/dist/server/Retention.d.ts +14 -0
  434. package/dist/server/Retention.d.ts.map +1 -1
  435. package/dist/server/Retention.js +52 -4
  436. package/dist/server/Retention.js.map +1 -1
  437. package/dist/server/Retention.sql +55 -1
  438. package/dist/server/ServiceModules.d.ts.map +1 -1
  439. package/dist/server/ServiceModules.js +2 -0
  440. package/dist/server/ServiceModules.js.map +1 -1
  441. package/dist/server/SkillsFunctionality.d.ts +2 -0
  442. package/dist/server/SkillsFunctionality.d.ts.map +1 -1
  443. package/dist/server/SkillsFunctionality.js +27 -17
  444. package/dist/server/SkillsFunctionality.js.map +1 -1
  445. package/dist/server/WorkspaceCapabilities.d.ts.map +1 -1
  446. package/dist/server/WorkspaceCapabilities.js +1 -0
  447. package/dist/server/WorkspaceCapabilities.js.map +1 -1
  448. package/dist/server/WorkspaceResidency.d.ts +2 -0
  449. package/dist/server/WorkspaceResidency.d.ts.map +1 -1
  450. package/dist/server/WorkspaceResidency.js +27 -0
  451. package/dist/server/WorkspaceResidency.js.map +1 -1
  452. package/dist/server/WorkspaceStorage.d.ts +8 -0
  453. package/dist/server/WorkspaceStorage.d.ts.map +1 -0
  454. package/dist/server/WorkspaceStorage.js +26 -0
  455. package/dist/server/WorkspaceStorage.js.map +1 -0
  456. package/dist/server/client-input.d.ts +4 -3
  457. package/dist/server/client-input.d.ts.map +1 -1
  458. package/dist/server/client-input.js +25 -27
  459. package/dist/server/client-input.js.map +1 -1
  460. package/dist/server/dispatch-as-plurnk.js +2 -2
  461. package/dist/server/dispatch-as-plurnk.js.map +1 -1
  462. package/dist/server/drain.sql +69 -132
  463. package/dist/server/envelope.d.ts +2 -3
  464. package/dist/server/envelope.d.ts.map +1 -1
  465. package/dist/server/envelope.js +7 -21
  466. package/dist/server/envelope.js.map +1 -1
  467. package/dist/server/envelope.sql +10 -6
  468. package/dist/server/exec-poll-backoff.js +3 -3
  469. package/dist/server/exec-poll-backoff.js.map +1 -1
  470. package/dist/server/lifecycle-recovery.sql +12 -38
  471. package/dist/server/logEntry.sql +2 -2
  472. package/dist/server/loopDocs.js +3 -3
  473. package/dist/server/loopDocs.sql +4 -2
  474. package/dist/server/model-catalog.d.ts.map +1 -1
  475. package/dist/server/model-catalog.js +2 -2
  476. package/dist/server/model-catalog.js.map +1 -1
  477. package/dist/server/seam-loop.sql +0 -1
  478. package/dist/server/workspace-capabilities.sql +45 -0
  479. package/dist/server/workspace-storage.sql +8 -0
  480. package/dist/service.d.ts.map +1 -1
  481. package/dist/service.js +37 -11
  482. package/dist/service.js.map +1 -1
  483. package/docs/copy-move.md +31 -0
  484. package/docs/env.md +67 -0
  485. package/docs/members.md +4 -4
  486. package/docs/skills.md +2 -2
  487. package/migrations/002_workers.sql +41 -17
  488. package/migrations/003_loops.sql +82 -28
  489. package/migrations/004_inference.sql +53 -12
  490. package/migrations/005_entries.sql +135 -14
  491. package/migrations/006_log.sql +79 -24
  492. package/migrations/007_subscriptions.sql +10 -15
  493. package/package.json +45 -36
  494. package/dist/core/PromptFrames.d.ts +0 -12
  495. package/dist/core/PromptFrames.d.ts.map +0 -1
  496. package/dist/core/PromptFrames.js +0 -28
  497. package/dist/core/PromptFrames.js.map +0 -1
  498. package/dist/schemes/Prompt.d.ts +0 -8
  499. package/dist/schemes/Prompt.d.ts.map +0 -1
  500. package/dist/schemes/Prompt.js +0 -25
  501. package/dist/schemes/Prompt.js.map +0 -1
@@ -6,6 +6,7 @@ var _a;
6
6
  // generated executor family whose host verbs propose. An explicit
7
7
  // client mutation and an accepted model proposal converge on `invoke`.
8
8
  import { Validator } from "@plurnk/plurnk-contracts";
9
+ import discoverySchema from "@plurnk/plurnk-contracts/schema/FunctionalityDiscoverQuery.json" with { type: "json" };
9
10
  import { isDeepStrictEqual } from "node:util";
10
11
  import { DocFile } from "@plurnk/plurnk-execs";
11
12
  import FunctionalityManager, { FUNCTIONALITY_VERBS, functionalityRuntimeDecl, } from "./FunctionalityManager.js";
@@ -14,6 +15,10 @@ import { generatedPathname } from "../core/plurnk-uri.js";
14
15
  const STATE_VERSION = 1;
15
16
  const FAMILY = /^[a-z][a-z0-9]*$/u;
16
17
  const ALIAS = /^[a-z][a-z0-9-]*$/u;
18
+ // A family may declare its own alias grammar ({§functionality-adapter}); the coordinator enforces it
19
+ // wherever an alias enters: admission, the service projection, and persisted state.
20
+ const aliasPattern = (adapter) => adapter.aliasPattern ?? ALIAS;
21
+ const scopesOf = (adapter) => adapter.scopes ?? ["workspace"];
17
22
  const EMPTY_STATE = Object.freeze({ version: STATE_VERSION, definitions: Object.freeze({}) });
18
23
  const SCHEMA = (name) => ({ $ref: `https://schemas.plurnk.xyz/v0/${name}.json` });
19
24
  const ALIAS_INPUT = Object.freeze({
@@ -49,21 +54,37 @@ class Functionality {
49
54
  throw new Error(`Functionality namespace owner '${namespaceOwner}' is already registered.`);
50
55
  if (!isRecord(adapter.definitionSchema))
51
56
  throw new Error(`Functionality family '${family}' requires a definition schema.`);
57
+ const scopes = scopesOf(adapter);
58
+ if (scopes.length === 0 || new Set(scopes).size !== scopes.length || scopes.some((scope) => scope !== "workspace" && scope !== "worker")) {
59
+ throw new Error(`Functionality family '${family}' declares invalid scopes.`);
60
+ }
61
+ const scopeProperties = scopes.length > 1
62
+ ? { scope: { enum: [...scopes], description: `Definition scope; model calls default to ${scopes[0]}.` } }
63
+ : {};
64
+ const scopedInput = (schema) => {
65
+ if (scopes.length === 1)
66
+ return schema;
67
+ const { $id: _id, ...source } = schema;
68
+ if (!isRecord(source.properties))
69
+ throw new Error(`Functionality ${family} input has no property map.`);
70
+ return { ...source, properties: { ...source.properties, ...scopeProperties } };
71
+ };
52
72
  const schemas = Object.freeze({
53
- list: EMPTY_INPUT,
54
- discover: SCHEMA("FunctionalityDiscoverQuery"),
73
+ list: scopedInput(EMPTY_INPUT),
74
+ discover: scopes.length === 1 ? SCHEMA("FunctionalityDiscoverQuery") : scopedInput(discoverySchema),
55
75
  add: Object.freeze({
56
76
  type: "object",
57
77
  additionalProperties: false,
58
78
  required: ["definition"],
59
79
  properties: {
80
+ ...scopeProperties,
60
81
  alias: { type: "string", minLength: 1 },
61
82
  definition: adapter.definitionSchema,
62
83
  },
63
84
  }),
64
- enable: ALIAS_INPUT,
65
- disable: ALIAS_INPUT,
66
- remove: ALIAS_INPUT,
85
+ enable: scopedInput(ALIAS_INPUT),
86
+ disable: scopedInput(ALIAS_INPUT),
87
+ remove: scopedInput(ALIAS_INPUT),
67
88
  });
68
89
  // {§functionality-model-projection} — the taught `add` example must satisfy the schema it teaches.
69
90
  if (adapter.example !== undefined) {
@@ -79,23 +100,28 @@ class Functionality {
79
100
  activate: (context) => this.#activate(adapter, context),
80
101
  deactivate: (identity) => this.#deactivate(adapter, identity),
81
102
  });
82
- for (const verb of FUNCTIONALITY_VERBS) {
83
- this.#host.registerModuleAction({
84
- name: `workspace.${family}.${verb}`,
85
- scope: "workspace",
86
- inputSchema: schemas[verb],
87
- outputSchema: SCHEMA(verb === "list"
88
- ? "FunctionalityListResult"
89
- : verb === "discover"
90
- ? "FunctionalityDiscoverResult"
91
- : "FunctionalityMutationResult"),
92
- handler: async (params, context) => {
93
- if (context.scope !== "workspace")
94
- throw new Error(`workspace.${family}.${verb} requires a workspace-scoped context.`);
95
- const { workspaceId } = context;
96
- return (await this.invoke(family, verb, params, { workspaceId }, "action")).body;
97
- },
98
- });
103
+ // {§functionality-scope} The action context binds one of the family's supported scopes.
104
+ for (const scope of scopes) {
105
+ for (const verb of FUNCTIONALITY_VERBS) {
106
+ this.#host.registerModuleAction({
107
+ name: `${scope}.${family}.${verb}`,
108
+ scope,
109
+ inputSchema: schemas[verb],
110
+ outputSchema: SCHEMA(verb === "list"
111
+ ? "FunctionalityListResult"
112
+ : verb === "discover"
113
+ ? "FunctionalityDiscoverResult"
114
+ : "FunctionalityMutationResult"),
115
+ handler: async (params, context) => {
116
+ if (context.scope === "worldless" || context.scope !== scope)
117
+ throw new Error(`${scope}.${family}.${verb} requires a ${scope}-scoped context.`);
118
+ const identity = context.scope === "worker"
119
+ ? { workspaceId: context.workspaceId, workerId: context.workerId, scope }
120
+ : { workspaceId: context.workspaceId, scope };
121
+ return (await this.invoke(family, verb, params, identity, "action")).body;
122
+ },
123
+ });
124
+ }
99
125
  }
100
126
  return {
101
127
  invoke: (verb, params, identity) => this.invoke(family, verb, params, identity, "action"),
@@ -109,7 +135,7 @@ class Functionality {
109
135
  // workspace exclusivity it could never win.
110
136
  async refresh(family, identity, options = {}) {
111
137
  const adapter = this.#adapter(family);
112
- await this.#serialize(identity.workspaceId, family, async () => {
138
+ await this.#serialize(this.#key(identity.workspaceId, family), async () => {
113
139
  const current = this.#families.get(this.#key(identity.workspaceId, family));
114
140
  if (current === undefined)
115
141
  return;
@@ -158,7 +184,7 @@ class Functionality {
158
184
  return out;
159
185
  }
160
186
  // The one lifecycle entry for both projections ({§functionality-model-mutation}).
161
- async invoke(family, verb, params, identity, caller) {
187
+ async invoke(family, verb, params, identity, caller, options = {}) {
162
188
  const adapter = this.#adapter(family);
163
189
  const schema = this.#schemas.get(family)[verb];
164
190
  const validation = Validator.validateJsonSchemaInstance(schema, params);
@@ -170,11 +196,38 @@ class Functionality {
170
196
  });
171
197
  }
172
198
  const input = params;
173
- switch (verb) {
174
- case "list": return { status: 200, body: await this.#list(adapter, identity) };
175
- case "discover": return { status: 200, body: await this.#discover(adapter, input, identity) };
176
- default: return this.#host.mutateWorkspace(identity.workspaceId, adapter.namespaceOwner, caller, () => this.#serialize(identity.workspaceId, family, () => this.#mutate(adapter, verb, input, identity, caller)));
199
+ const scope = (input.scope ?? identity.scope ?? scopesOf(adapter)[0]);
200
+ if (!scopesOf(adapter).includes(scope) || (identity.scope !== undefined && identity.scope !== scope)) {
201
+ throw failure(family, "scope-mismatch", 400, `The ${family} operation's scope does not match its bound context.`, { retryable: false });
202
+ }
203
+ identity = { ...identity, scope };
204
+ if (verb === "discover") {
205
+ const { scope: _scope, ...query } = input;
206
+ return { status: 200, body: await this.#discover(adapter, query, identity, options) };
177
207
  }
208
+ // {§functionality-scope} — a worker-scoped family's list and mutations act for the invoking
209
+ // Worker. The state is that Worker's and nothing resident changes, so they serialize on the
210
+ // Worker's own lane and take no workspace exclusivity: a Worker shapes its environment while
211
+ // its siblings run.
212
+ if (scope === "worker") {
213
+ const workerId = _a.#workerOf(adapter, identity);
214
+ return this.#serialize(`${this.#key(identity.workspaceId, family)}:${workerId}`, () => this.#invokeForWorker(adapter, verb, input, identity, workerId, caller, options));
215
+ }
216
+ if (verb === "list")
217
+ return { status: 200, body: await this.#list(adapter, identity) };
218
+ return this.#host.mutateWorkspace(identity.workspaceId, adapter.namespaceOwner, caller, () => this.#serialize(this.#key(identity.workspaceId, family), () => this.#mutate(adapter, verb, input, identity, caller, options)));
219
+ }
220
+ // A worker-scoped verb that names no Worker is a defect at the projection, never a client
221
+ // failure: both projections name the Worker ({§functionality-model-projection}).
222
+ static #workerOf(adapter, identity) {
223
+ if (identity.workerId === undefined)
224
+ throw new Error(`${adapter.family} is worker-scoped; the invocation names no Worker.`);
225
+ return identity.workerId;
226
+ }
227
+ // The origin a definition carries when this family owns it locally. Service definitions
228
+ // always come from the adapter's own `available()`; everything else is the family's own.
229
+ static #localOrigin(identity) {
230
+ return identity.scope ?? "workspace";
178
231
  }
179
232
  #adapter(family) {
180
233
  const adapter = this.#adapters.get(family);
@@ -185,8 +238,7 @@ class Functionality {
185
238
  #key(workspaceId, family) {
186
239
  return `${workspaceId}:${family}`;
187
240
  }
188
- #serialize(workspaceId, family, work) {
189
- const key = this.#key(workspaceId, family);
241
+ #serialize(key, work) {
190
242
  const previous = this.#queues.get(key) ?? Promise.resolve();
191
243
  const next = previous.catch(() => undefined).then(work);
192
244
  this.#queues.set(key, next);
@@ -194,13 +246,13 @@ class Functionality {
194
246
  }
195
247
  async #activate(adapter, context) {
196
248
  const identity = { workspaceId: context.workspaceId };
197
- await this.#serialize(identity.workspaceId, adapter.family, async () => {
249
+ await this.#serialize(this.#key(identity.workspaceId, adapter.family), async () => {
198
250
  const state = await this.#loadState(adapter, identity.workspaceId);
199
251
  await this.#publish(adapter, identity, state, { failure: "publish-unavailable", retain: context.retain, gate: "none" });
200
252
  });
201
253
  }
202
254
  async #deactivate(adapter, identity) {
203
- await this.#serialize(identity.workspaceId, adapter.family, async () => {
255
+ await this.#serialize(this.#key(identity.workspaceId, adapter.family), async () => {
204
256
  const key = this.#key(identity.workspaceId, adapter.family);
205
257
  const family = this.#families.get(key);
206
258
  this.#families.delete(key);
@@ -210,30 +262,42 @@ class Functionality {
210
262
  });
211
263
  }
212
264
  async #loadState(adapter, workspaceId) {
213
- const raw = await this.#host.readWorkspaceModuleState(workspaceId, adapter.namespaceOwner);
265
+ return _a.#parseState(adapter, await this.#host.readWorkspaceModuleState(workspaceId, adapter.namespaceOwner), `workspace ${workspaceId}`, "workspace");
266
+ }
267
+ async #loadWorkerState(adapter, workerId) {
268
+ return _a.#parseState(adapter, await this.#host.readWorkerModuleState(workerId, adapter.namespaceOwner), `worker ${workerId}`, "worker");
269
+ }
270
+ static #parseState(adapter, raw, where, scope) {
214
271
  if (raw === null)
215
272
  return EMPTY_STATE;
216
273
  if (!isRecord(raw) || raw.version !== STATE_VERSION || !isRecord(raw.definitions)) {
217
- throw new Error(`Functionality state for ${adapter.family} in workspace ${workspaceId} is not a version ${STATE_VERSION} record.`);
274
+ throw new Error(`Functionality state for ${adapter.family} in ${where} is not a version ${STATE_VERSION} record.`);
218
275
  }
219
276
  const definitions = {};
220
277
  for (const [alias, value] of Object.entries(raw.definitions)) {
221
- if (!ALIAS.test(alias) || !isRecord(value))
278
+ if (!aliasPattern(adapter).test(alias) || !isRecord(value))
222
279
  throw new Error(`Functionality state for ${adapter.family} has an invalid alias '${alias}'.`);
223
- const { origin, enabled, definition } = value;
224
- if ((origin !== "service" && origin !== "workspace") || typeof enabled !== "boolean") {
280
+ const { origin, enabled, definition, inherited } = value;
281
+ if ((origin !== "service" && origin !== "workspace" && origin !== "worker") || typeof enabled !== "boolean") {
225
282
  throw new Error(`Functionality state for ${adapter.family} alias '${alias}' is malformed.`);
226
283
  }
227
- if (origin === "workspace") {
284
+ if (origin !== "service" && origin !== scope && !(scope === "worker" && origin === "workspace" && scopesOf(adapter).includes("workspace"))) {
285
+ throw new Error(`Functionality state for ${adapter.family} alias '${alias}' has an invalid origin for ${scope} scope.`);
286
+ }
287
+ if (inherited !== undefined && (typeof inherited !== "string" || inherited.length === 0 || scope !== "worker")) {
288
+ throw new Error(`Functionality state for ${adapter.family} alias '${alias}' carries an invalid inheritance.`);
289
+ }
290
+ const provenance = inherited === undefined ? {} : { inherited };
291
+ if (origin === scope) {
228
292
  const result = Validator.validateJsonSchemaInstance(adapter.definitionSchema, definition);
229
293
  if (!result.valid)
230
294
  throw new Error(`Functionality state for ${adapter.family} alias '${alias}' holds an invalid definition.`);
231
- definitions[alias] = { origin, enabled, definition: definition };
295
+ definitions[alias] = { origin, enabled, definition: definition, ...provenance };
232
296
  }
233
297
  else {
234
298
  if (definition !== undefined)
235
- throw new Error(`Functionality state for ${adapter.family} alias '${alias}' persists a service definition.`);
236
- definitions[alias] = { origin, enabled };
299
+ throw new Error(`Functionality state for ${adapter.family} alias '${alias}' persists a lower-layer definition.`);
300
+ definitions[alias] = { origin, enabled, ...provenance };
237
301
  }
238
302
  }
239
303
  return { version: STATE_VERSION, definitions };
@@ -243,33 +307,41 @@ class Functionality {
243
307
  }
244
308
  async #effective(adapter, identity, state) {
245
309
  const effective = new Map();
246
- for (const service of await adapter.available(identity)) {
247
- if (!ALIAS.test(service.alias))
248
- throw new Error(`${adapter.family} service alias '${service.alias}' must match ${ALIAS}.`);
310
+ const local = _a.#localOrigin(identity);
311
+ const inheritsWorkspace = identity.scope === "worker" && scopesOf(adapter).includes("workspace");
312
+ const lower = inheritsWorkspace
313
+ ? [...(await this.#effective(adapter, { workspaceId: identity.workspaceId, scope: "workspace" }, await this.#loadState(adapter, identity.workspaceId))).values()]
314
+ : (await adapter.available(identity)).map((entry) => ({ ...entry, origin: "service" }));
315
+ for (const service of lower) {
316
+ if (!aliasPattern(adapter).test(service.alias))
317
+ throw new Error(`${adapter.family} service alias '${service.alias}' must match ${aliasPattern(adapter)}.`);
249
318
  const record = state.definitions[service.alias];
250
- const enabled = record?.origin === "service" ? record.enabled : service.enabled;
251
- effective.set(service.alias, { alias: service.alias, origin: "service", definition: service.definition, enabled });
319
+ const overlay = record !== undefined && record.origin !== local ? record : undefined;
320
+ const enabled = overlay === undefined ? service.enabled : overlay.enabled && (!inheritsWorkspace || service.enabled);
321
+ const inherited = overlay?.inherited === undefined ? {} : { inherited: overlay.inherited };
322
+ effective.set(service.alias, { alias: service.alias, origin: service.origin, definition: service.definition, enabled, ...inherited });
252
323
  }
253
324
  for (const [alias, record] of Object.entries(state.definitions)) {
254
- if (record.origin !== "workspace")
325
+ if (record.origin !== local)
255
326
  continue;
256
- effective.set(alias, { alias, origin: "workspace", definition: record.definition, enabled: record.enabled });
327
+ const inherited = record.inherited === undefined ? {} : { inherited: record.inherited };
328
+ effective.set(alias, { alias, origin: local, definition: record.definition, enabled: record.enabled, ...inherited });
257
329
  }
258
330
  return new Map([...effective].toSorted(([left], [right]) => left.localeCompare(right)));
259
331
  }
260
332
  #projection(definition, outcome) {
261
- if (!definition.enabled) {
262
- return { alias: definition.alias, origin: definition.origin, state: "disabled", definition: definition.definition };
263
- }
333
+ const base = {
334
+ alias: definition.alias, origin: definition.origin, definition: definition.definition,
335
+ ...(definition.inherited === undefined ? {} : { inherited: definition.inherited }),
336
+ };
337
+ if (!definition.enabled)
338
+ return { ...base, state: "disabled" };
264
339
  if (outcome === undefined)
265
340
  throw new Error(`enabled ${definition.alias} has no preparation outcome`);
266
341
  switch (outcome.state) {
267
- case "active": return {
268
- alias: definition.alias, origin: definition.origin, state: "active", definition: definition.definition,
269
- ...(outcome.detail === undefined ? {} : { detail: outcome.detail }),
270
- };
271
- case "unavailable": return { alias: definition.alias, origin: definition.origin, state: "unavailable", definition: definition.definition, problem: outcome.problem };
272
- case "authorization-required": return { alias: definition.alias, origin: definition.origin, state: "authorization-required", definition: definition.definition, authorization: outcome.authorization };
342
+ case "active": return { ...base, state: "active", ...(outcome.detail === undefined ? {} : { detail: outcome.detail }) };
343
+ case "unavailable": return { ...base, state: "unavailable", problem: outcome.problem };
344
+ case "authorization-required": return { ...base, state: "authorization-required", authorization: outcome.authorization };
273
345
  }
274
346
  }
275
347
  async #list(adapter, identity) {
@@ -283,34 +355,33 @@ class Functionality {
283
355
  definitions: [...effective.values()].map((definition) => this.#projection(definition, outcomes.get(definition.alias))),
284
356
  });
285
357
  }
286
- async #discover(adapter, query, identity) {
287
- const candidates = await adapter.discover(query, identity);
358
+ async #discover(adapter, query, identity, options) {
359
+ const candidates = await adapter.discover(query, identity, options);
288
360
  return Validator.assertFunctionalityDiscoverResult({ family: adapter.family, candidates: [...candidates] });
289
361
  }
290
- async #mutate(adapter, verb, input, identity, caller) {
291
- const key = this.#key(identity.workspaceId, adapter.family);
292
- const family = this.#families.get(key);
293
- if (family === undefined)
294
- throw failure(adapter.family, "workspace-not-resident", 409, `Workspace ${identity.workspaceId} has no resident ${adapter.family} Functionality.`, { recovery: "Retry through a workspace operation, then retry.", retryable: false });
295
- const effective = await this.#effective(adapter, identity, family.state);
296
- const definitions = { ...family.state.definitions };
362
+ // The verb semantics, one implementation for every family ({§functionality-scope}): the next
363
+ // state, the alias it concerns, and how the mutation reports. Only publication differs by scope.
364
+ async #transition(adapter, verb, input, identity, caller, state, effective, options) {
365
+ const local = _a.#localOrigin(identity);
366
+ const here = local === "worker" ? "this worker" : "this workspace";
367
+ const definitions = { ...state.definitions };
297
368
  let alias;
298
369
  let status = 200;
299
370
  let removed = false;
300
371
  switch (verb) {
301
372
  case "add": {
302
- const admitted = await adapter.admit(input, identity, caller);
373
+ const admitted = await adapter.admit(input, identity, caller, options);
303
374
  alias = admitted.alias;
304
- if (!ALIAS.test(alias))
305
- throw failure(adapter.family, "alias-invalid", 400, `Alias '${alias}' must match ${ALIAS}.`, { alias, retryable: false });
306
- // A workspace definition may shadow a service definition of the same
375
+ if (!aliasPattern(adapter).test(alias))
376
+ throw failure(adapter.family, "alias-invalid", 400, `Alias '${alias}' must match ${aliasPattern(adapter)}.`, { alias, retryable: false });
377
+ // A local definition may shadow a service definition of the same
307
378
  // alias; removing it reveals the service baseline again, disabled.
308
379
  const current = effective.get(alias);
309
- if (current?.origin === "workspace" && !isDeepStrictEqual(current.definition, admitted.definition)) {
310
- throw failure(adapter.family, "alias-exists", 409, `'${alias}' already has a different workspace definition.`, { alias, recovery: "Use the existing definition, or remove it before adding its replacement.", retryable: false });
380
+ if (current?.origin === local && !isDeepStrictEqual(current.definition, admitted.definition)) {
381
+ throw failure(adapter.family, "alias-exists", 409, `'${alias}' already has a different ${local} definition.`, { alias, recovery: "Use the existing definition, or remove it before adding its replacement.", retryable: false });
311
382
  }
312
- definitions[alias] = { origin: "workspace", definition: admitted.definition, enabled: true };
313
- status = current?.origin === "workspace" ? 200 : 201;
383
+ definitions[alias] = { origin: local, definition: admitted.definition, enabled: true };
384
+ status = current?.origin === local ? 200 : 201;
314
385
  break;
315
386
  }
316
387
  case "enable":
@@ -318,42 +389,36 @@ class Functionality {
318
389
  alias = input.alias;
319
390
  const current = effective.get(alias);
320
391
  if (current === undefined)
321
- throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to this workspace.`, { alias, retryable: false });
322
- definitions[alias] = current.origin === "workspace"
323
- ? { origin: "workspace", definition: current.definition, enabled: verb === "enable" }
324
- : { origin: "service", enabled: verb === "enable" };
392
+ throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to ${here}.`, { alias, retryable: false });
393
+ definitions[alias] = current.origin === local
394
+ ? { origin: local, definition: current.definition, enabled: verb === "enable" }
395
+ : { origin: current.origin, enabled: verb === "enable" };
325
396
  break;
326
397
  }
327
398
  case "remove": {
328
399
  alias = input.alias;
329
400
  const current = effective.get(alias);
330
401
  if (current === undefined)
331
- throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to this workspace.`, { alias, retryable: false });
402
+ throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to ${here}.`, { alias, retryable: false });
332
403
  if (current.origin === "service")
333
404
  throw failure(adapter.family, "alias-service-owned", 409, `'${alias}' is a service definition and cannot be removed here.`, { alias, recovery: `Disable it, or change the service configuration that contributes it.`, retryable: false });
405
+ if (current.origin !== local)
406
+ throw failure(adapter.family, "alias-workspace-owned", 409, `'${alias}' is a workspace definition; remove it in workspace scope or disable it here.`, { alias, retryable: false });
334
407
  await adapter.forget?.({ alias, definition: current.definition }, identity);
335
408
  delete definitions[alias];
336
- const revealed = (await adapter.available(identity)).some((service) => service.alias === alias);
409
+ const revealed = (await this.#effective(adapter, identity, EMPTY_STATE)).get(alias);
337
410
  if (revealed)
338
- definitions[alias] = { origin: "service", enabled: false };
411
+ definitions[alias] = { origin: revealed.origin, enabled: false };
339
412
  removed = true;
340
413
  break;
341
414
  }
342
415
  default: throw new Error(`unreachable verb ${verb}`);
343
416
  }
344
- const nextState = { version: STATE_VERSION, definitions };
345
- // Re-enabling an alias that is not active retries its preparation; an
346
- // already-active alias keeps its live attachment.
347
- const retry = verb === "enable" && family.prepared?.outcomes.get(alias)?.state !== "active";
348
- const publication = await this.#publish(adapter, identity, nextState, {
349
- failure: caller === "action" ? "reject" : "publish-unavailable",
350
- retain: () => this.#host.retainWorkspace(identity.workspaceId),
351
- gate: "none",
352
- forceAlias: retry ? alias : null,
353
- });
354
- const effectiveAfter = await this.#effective(adapter, identity, nextState);
417
+ return { definitions, alias, status, removed };
418
+ }
419
+ #mutationResult(adapter, { alias, status, removed }, effectiveAfter, outcomes) {
355
420
  const definition = effectiveAfter.get(alias);
356
- const projection = definition === undefined ? undefined : this.#projection(definition, publication.outcomes.get(alias));
421
+ const projection = definition === undefined ? undefined : this.#projection(definition, outcomes.get(alias));
357
422
  const body = Validator.assertFunctionalityMutationResult({
358
423
  status: projection?.state === "authorization-required" ? 202 : status,
359
424
  family: adapter.family,
@@ -363,6 +428,89 @@ class Functionality {
363
428
  });
364
429
  return { status: body.status, body };
365
430
  }
431
+ async #mutate(adapter, verb, input, identity, caller, options) {
432
+ const key = this.#key(identity.workspaceId, adapter.family);
433
+ const family = this.#families.get(key);
434
+ if (family === undefined)
435
+ throw failure(adapter.family, "workspace-not-resident", 409, `Workspace ${identity.workspaceId} has no resident ${adapter.family} Functionality.`, { recovery: "Retry through a workspace operation, then retry.", retryable: false });
436
+ const effective = await this.#effective(adapter, identity, family.state);
437
+ const transition = await this.#transition(adapter, verb, input, identity, caller, family.state, effective, options);
438
+ const nextState = { version: STATE_VERSION, definitions: transition.definitions };
439
+ // Re-enabling an alias that is not active retries its preparation; an
440
+ // already-active alias keeps its live attachment.
441
+ const retry = verb === "enable" && family.prepared?.outcomes.get(transition.alias)?.state !== "active";
442
+ const publication = await this.#publish(adapter, identity, nextState, {
443
+ failure: caller === "action" ? "reject" : "publish-unavailable",
444
+ retain: () => this.#host.retainWorkspace(identity.workspaceId),
445
+ gate: "none",
446
+ forceAlias: retry ? transition.alias : null,
447
+ });
448
+ const effectiveAfter = await this.#effective(adapter, identity, nextState);
449
+ return this.#mutationResult(adapter, transition, effectiveAfter, publication.outcomes);
450
+ }
451
+ // {§functionality-scope} — the Worker's own lane. State is read at each verb rather than held: the
452
+ // spawn reads the same row, and a Worker's row is written at its creation, so nothing in memory
453
+ // could be more current than the table.
454
+ async #invokeForWorker(adapter, verb, input, identity, workerId, caller, options) {
455
+ if (!this.#families.has(this.#key(identity.workspaceId, adapter.family)))
456
+ throw failure(adapter.family, "workspace-not-resident", 409, `Workspace ${identity.workspaceId} has no resident ${adapter.family} Functionality.`, { recovery: "Retry through a workspace operation, then retry.", retryable: false });
457
+ const state = await this.#loadWorkerState(adapter, workerId);
458
+ const effective = await this.#effective(adapter, identity, state);
459
+ if (verb === "list") {
460
+ const prepared = await this.#prepareForWorker(adapter, identity, effective, "publish-unavailable");
461
+ await prepared.commit();
462
+ return { status: 200, body: Validator.assertFunctionalityListResult({
463
+ family: adapter.family,
464
+ definitions: [...effective.values()].map((definition) => this.#projection(definition, prepared.outcomes.get(definition.alias))),
465
+ }) };
466
+ }
467
+ const transition = await this.#transition(adapter, verb, input, identity, caller, state, effective, options);
468
+ const nextState = { version: STATE_VERSION, definitions: transition.definitions };
469
+ const effectiveAfter = await this.#effective(adapter, identity, nextState);
470
+ const prepared = await this.#prepareForWorker(adapter, identity, effectiveAfter, caller === "action" ? "reject" : "publish-unavailable");
471
+ try {
472
+ await this.#host.replaceWorkerModuleState(workerId, adapter.namespaceOwner, _a.#persisted(nextState));
473
+ }
474
+ catch (cause) {
475
+ return _a.#abort(prepared, cause);
476
+ }
477
+ await prepared.commit();
478
+ return this.#mutationResult(adapter, transition, effectiveAfter, prepared.outcomes);
479
+ }
480
+ // A worker-scoped family's preparation yields outcomes only. It holds no residency — no runtimes,
481
+ // documents or snapshot ({§module-workspace-residency}) — because its definitions are read at the
482
+ // spawn that uses them rather than leased and cooled; the coordinator enforces that here.
483
+ async #prepareForWorker(adapter, identity, effective, failureMode) {
484
+ const enabled = _a.#enabled(effective);
485
+ const prepared = await adapter.prepare({
486
+ workspaceId: identity.workspaceId, enabled, previous: null, failure: failureMode,
487
+ retain: () => this.#host.retainWorkspace(identity.workspaceId),
488
+ });
489
+ try {
490
+ _a.#checkOutcomes(adapter, enabled, prepared);
491
+ if ((prepared.runtimes?.length ?? 0) > 0 || prepared.documents.length > 0 || prepared.snapshot !== null) {
492
+ throw new Error(`${adapter.family} is worker-scoped and holds no residency, yet its preparation published runtimes, documents or a snapshot.`);
493
+ }
494
+ }
495
+ catch (cause) {
496
+ return _a.#abort(prepared, cause);
497
+ }
498
+ return prepared;
499
+ }
500
+ static #enabled(effective) {
501
+ const enabled = new Map();
502
+ for (const definition of effective.values()) {
503
+ if (definition.enabled)
504
+ enabled.set(definition.alias, definition.definition);
505
+ }
506
+ return enabled;
507
+ }
508
+ static #checkOutcomes(adapter, enabled, prepared) {
509
+ for (const alias of enabled.keys()) {
510
+ if (!prepared.outcomes.has(alias))
511
+ throw new Error(`${adapter.family} preparation reported no outcome for enabled alias '${alias}'.`);
512
+ }
513
+ }
366
514
  // {§functionality-publication} — prepare, publish runtimes and state in one
367
515
  // host replacement, then commit; on any failure abort and keep the previous
368
516
  // snapshot authoritative. An execution stream stays pending until its
@@ -370,12 +518,10 @@ class Functionality {
370
518
  async #publish(adapter, identity, nextState, options) {
371
519
  const key = this.#key(identity.workspaceId, adapter.family);
372
520
  const previous = this.#families.get(key)?.prepared ?? null;
373
- const effective = await this.#effective(adapter, identity, nextState);
374
- const enabled = new Map();
375
- for (const definition of effective.values()) {
376
- if (definition.enabled)
377
- enabled.set(definition.alias, definition.definition);
378
- }
521
+ // A worker-scoped family's workspace publication carries only its manager: what is enabled
522
+ // is decided per Worker, at each verb and each spawn ({§functionality-scope}).
523
+ const effective = !scopesOf(adapter).includes("workspace") ? new Map() : await this.#effective(adapter, { ...identity, scope: "workspace" }, nextState);
524
+ const enabled = _a.#enabled(effective);
379
525
  const prepared = await adapter.prepare({
380
526
  workspaceId: identity.workspaceId,
381
527
  enabled,
@@ -386,11 +532,8 @@ class Functionality {
386
532
  });
387
533
  let runtimes;
388
534
  try {
389
- for (const alias of enabled.keys()) {
390
- if (!prepared.outcomes.has(alias))
391
- throw new Error(`${adapter.family} preparation reported no outcome for enabled alias '${alias}'.`);
392
- }
393
- for (const runtime of prepared.runtimes) {
535
+ _a.#checkOutcomes(adapter, enabled, prepared);
536
+ for (const runtime of prepared.runtimes ?? []) {
394
537
  if (runtime.namespaceOwner !== adapter.namespaceOwner) {
395
538
  throw new Error(`${adapter.family} prepared a runtime owned by '${runtime.namespaceOwner}' instead of '${adapter.namespaceOwner}'.`);
396
539
  }
@@ -400,11 +543,12 @@ class Functionality {
400
543
  decl: functionalityRuntimeDecl(adapter.family, adapter.summary, await this.#documentBody(adapter)),
401
544
  executor: new FunctionalityManager({
402
545
  family: adapter.family, workspaceId: identity.workspaceId, coordinator: this,
403
- inputSchemas: this.#schemas.get(adapter.family), example: adapter.example, discovery: adapter.discovery,
546
+ traits: adapter.traits, inputSchemas: this.#schemas.get(adapter.family), example: adapter.example, discovery: adapter.discovery,
404
547
  }),
405
548
  availability: { available: true, detail: "workspace Functionality manager" },
549
+ ...(adapter.scheme === undefined ? {} : { scheme: adapter.scheme }),
406
550
  };
407
- runtimes = [manager, ...prepared.runtimes];
551
+ runtimes = [manager, ...(prepared.runtimes ?? [])];
408
552
  }
409
553
  catch (cause) {
410
554
  return _a.#abort(prepared, cause);