@plurnk/plurnk-service 1.16.5 → 1.18.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 (661) hide show
  1. package/.env.defaults +140 -246
  2. package/INSTALL.md +84 -138
  3. package/README.md +10 -6
  4. package/SPEC.md +2468 -1694
  5. package/dist/Paths.d.ts +2 -0
  6. package/dist/Paths.d.ts.map +1 -1
  7. package/dist/Paths.js +2 -0
  8. package/dist/Paths.js.map +1 -1
  9. package/dist/build-info.d.ts.map +1 -1
  10. package/dist/build-info.js +7 -1
  11. package/dist/build-info.js.map +1 -1
  12. package/dist/build-info.json +1 -1
  13. package/dist/content/body-preview.d.ts +8 -0
  14. package/dist/content/body-preview.d.ts.map +1 -0
  15. package/dist/content/body-preview.js +39 -0
  16. package/dist/content/body-preview.js.map +1 -0
  17. package/dist/content/byte-view.d.ts +1 -4
  18. package/dist/content/byte-view.d.ts.map +1 -1
  19. package/dist/content/byte-view.js.map +1 -1
  20. package/dist/content/edit-collision.d.ts.map +1 -1
  21. package/dist/content/edit-collision.js +3 -4
  22. package/dist/content/edit-collision.js.map +1 -1
  23. package/dist/content/line-anchors.d.ts +2 -2
  24. package/dist/content/line-anchors.d.ts.map +1 -1
  25. package/dist/content/line-anchors.js +4 -3
  26. package/dist/content/line-anchors.js.map +1 -1
  27. package/dist/content/line-selection.d.ts +9 -0
  28. package/dist/content/line-selection.d.ts.map +1 -0
  29. package/dist/content/line-selection.js +29 -0
  30. package/dist/content/line-selection.js.map +1 -0
  31. package/dist/content/matcher.d.ts +0 -1
  32. package/dist/content/matcher.d.ts.map +1 -1
  33. package/dist/content/matcher.js +2 -3
  34. package/dist/content/matcher.js.map +1 -1
  35. package/dist/content/pattern-edits.d.ts +39 -0
  36. package/dist/content/pattern-edits.d.ts.map +1 -0
  37. package/dist/content/pattern-edits.js +121 -0
  38. package/dist/content/pattern-edits.js.map +1 -0
  39. package/dist/content/read-projector.d.ts +18 -9
  40. package/dist/content/read-projector.d.ts.map +1 -1
  41. package/dist/content/read-projector.js +132 -35
  42. package/dist/content/read-projector.js.map +1 -1
  43. package/dist/content/read-resolve.d.ts +4 -1
  44. package/dist/content/read-resolve.d.ts.map +1 -1
  45. package/dist/content/read-resolve.js +42 -7
  46. package/dist/content/read-resolve.js.map +1 -1
  47. package/dist/core/AdmittedTurnExecutor.d.ts +2 -5
  48. package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
  49. package/dist/core/AdmittedTurnExecutor.js +96 -88
  50. package/dist/core/AdmittedTurnExecutor.js.map +1 -1
  51. package/dist/core/BareBatchRunner.d.ts +6 -1
  52. package/dist/core/BareBatchRunner.d.ts.map +1 -1
  53. package/dist/core/BareBatchRunner.js +20 -5
  54. package/dist/core/BareBatchRunner.js.map +1 -1
  55. package/dist/core/BudgetReadout.d.ts +2 -3
  56. package/dist/core/BudgetReadout.d.ts.map +1 -1
  57. package/dist/core/BudgetReadout.js +23 -32
  58. package/dist/core/BudgetReadout.js.map +1 -1
  59. package/dist/core/CapabilityPolicies.d.ts +3 -8
  60. package/dist/core/CapabilityPolicies.d.ts.map +1 -1
  61. package/dist/core/CapabilityPolicies.js +2 -28
  62. package/dist/core/CapabilityPolicies.js.map +1 -1
  63. package/dist/core/CapabilityResolver.d.ts +10 -10
  64. package/dist/core/CapabilityResolver.d.ts.map +1 -1
  65. package/dist/core/CapabilityResolver.js +122 -93
  66. package/dist/core/CapabilityResolver.js.map +1 -1
  67. package/dist/core/ChannelWrite.d.ts +15 -11
  68. package/dist/core/ChannelWrite.d.ts.map +1 -1
  69. package/dist/core/ChannelWrite.js +12 -13
  70. package/dist/core/ChannelWrite.js.map +1 -1
  71. package/dist/core/ChannelWrite.sql +99 -9
  72. package/dist/core/ClientInteractions.d.ts.map +1 -1
  73. package/dist/core/ClientInteractions.js +7 -0
  74. package/dist/core/ClientInteractions.js.map +1 -1
  75. package/dist/core/CoreSchemeServices.d.ts +13 -10
  76. package/dist/core/CoreSchemeServices.d.ts.map +1 -1
  77. package/dist/core/CoreSchemeServices.js +13 -5
  78. package/dist/core/CoreSchemeServices.js.map +1 -1
  79. package/dist/core/DataStatementRunner.d.ts +2 -2
  80. package/dist/core/DataStatementRunner.d.ts.map +1 -1
  81. package/dist/core/DataStatementRunner.js +208 -161
  82. package/dist/core/DataStatementRunner.js.map +1 -1
  83. package/dist/core/Dispatcher.d.ts +24 -26
  84. package/dist/core/Dispatcher.d.ts.map +1 -1
  85. package/dist/core/Dispatcher.js +381 -232
  86. package/dist/core/Dispatcher.js.map +1 -1
  87. package/dist/core/Dispatcher.sql +66 -0
  88. package/dist/core/DurableStatement.d.ts.map +1 -1
  89. package/dist/core/DurableStatement.js +2 -1
  90. package/dist/core/DurableStatement.js.map +1 -1
  91. package/dist/core/EditMutations.d.ts +14 -18
  92. package/dist/core/EditMutations.d.ts.map +1 -1
  93. package/dist/core/EditMutations.js +211 -280
  94. package/dist/core/EditMutations.js.map +1 -1
  95. package/dist/core/EditMutations.sql +15 -0
  96. package/dist/core/EditSequence.d.ts +13 -0
  97. package/dist/core/EditSequence.d.ts.map +1 -0
  98. package/dist/core/EditSequence.js +73 -0
  99. package/dist/core/EditSequence.js.map +1 -0
  100. package/dist/core/Engine.d.ts +17 -23
  101. package/dist/core/Engine.d.ts.map +1 -1
  102. package/dist/core/Engine.js +74 -164
  103. package/dist/core/Engine.js.map +1 -1
  104. package/dist/core/Engine.sql +0 -724
  105. package/dist/core/EntryAddressBinding.d.ts +7 -17
  106. package/dist/core/EntryAddressBinding.d.ts.map +1 -1
  107. package/dist/core/EntryAddressBinding.js +12 -72
  108. package/dist/core/EntryAddressBinding.js.map +1 -1
  109. package/dist/core/ExecutionOutputs.d.ts +9 -0
  110. package/dist/core/ExecutionOutputs.d.ts.map +1 -0
  111. package/dist/core/ExecutionOutputs.js +36 -0
  112. package/dist/core/ExecutionOutputs.js.map +1 -0
  113. package/dist/core/ExecutionOutputs.sql +21 -0
  114. package/dist/core/ExecutorRegistry.d.ts +11 -5
  115. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  116. package/dist/core/ExecutorRegistry.js +37 -32
  117. package/dist/core/ExecutorRegistry.js.map +1 -1
  118. package/dist/core/HostPaths.d.ts +1 -0
  119. package/dist/core/HostPaths.d.ts.map +1 -1
  120. package/dist/core/HostPaths.js +4 -0
  121. package/dist/core/HostPaths.js.map +1 -1
  122. package/dist/core/InferenceCall.d.ts.map +1 -1
  123. package/dist/core/InferenceCall.js +1 -2
  124. package/dist/core/InferenceCall.js.map +1 -1
  125. package/dist/core/InferenceCall.sql +29 -0
  126. package/dist/core/KillHandler.d.ts +1 -0
  127. package/dist/core/KillHandler.d.ts.map +1 -1
  128. package/dist/core/KillHandler.js +24 -21
  129. package/dist/core/KillHandler.js.map +1 -1
  130. package/dist/core/LogBody.d.ts +8 -1
  131. package/dist/core/LogBody.d.ts.map +1 -1
  132. package/dist/core/LogBody.js +44 -12
  133. package/dist/core/LogBody.js.map +1 -1
  134. package/dist/core/LogEntryProjection.d.ts +1 -0
  135. package/dist/core/LogEntryProjection.d.ts.map +1 -1
  136. package/dist/core/LogEntryProjection.js +12 -10
  137. package/dist/core/LogEntryProjection.js.map +1 -1
  138. package/dist/core/LogVisibility.d.ts +1 -0
  139. package/dist/core/LogVisibility.d.ts.map +1 -1
  140. package/dist/core/LogVisibility.js +3 -0
  141. package/dist/core/LogVisibility.js.map +1 -1
  142. package/dist/core/LogWriter.d.ts +2 -3
  143. package/dist/core/LogWriter.d.ts.map +1 -1
  144. package/dist/core/LogWriter.js +31 -36
  145. package/dist/core/LogWriter.js.map +1 -1
  146. package/dist/core/LogWriter.sql +23 -0
  147. package/dist/core/LoopDriver.d.ts +11 -8
  148. package/dist/core/LoopDriver.d.ts.map +1 -1
  149. package/dist/core/LoopDriver.js +161 -189
  150. package/dist/core/LoopDriver.js.map +1 -1
  151. package/dist/core/LoopDriver.sql +11 -0
  152. package/dist/core/LoopLifecycle.d.ts +32 -2
  153. package/dist/core/LoopLifecycle.d.ts.map +1 -1
  154. package/dist/core/LoopLifecycle.js +88 -4
  155. package/dist/core/LoopLifecycle.js.map +1 -1
  156. package/dist/core/LoopLifecycle.sql +145 -28
  157. package/dist/core/LoopPolicyReader.sql +6 -0
  158. package/dist/core/MembershipMaterialization.d.ts.map +1 -1
  159. package/dist/core/MembershipMaterialization.js +6 -28
  160. package/dist/core/MembershipMaterialization.js.map +1 -1
  161. package/dist/core/ModelCall.d.ts.map +1 -1
  162. package/dist/core/ModelCall.js +2 -6
  163. package/dist/core/ModelCall.js.map +1 -1
  164. package/dist/core/ModelCall.sql +41 -0
  165. package/dist/core/MutationEffects.d.ts +5 -3
  166. package/dist/core/MutationEffects.d.ts.map +1 -1
  167. package/dist/core/MutationEffects.js +10 -28
  168. package/dist/core/MutationEffects.js.map +1 -1
  169. package/dist/core/NativeContent.d.ts +6 -0
  170. package/dist/core/NativeContent.d.ts.map +1 -0
  171. package/dist/core/NativeContent.js +16 -0
  172. package/dist/core/NativeContent.js.map +1 -0
  173. package/dist/core/NativeContent.sql +6 -0
  174. package/dist/core/NoticeChannel.js +1 -1
  175. package/dist/core/NoticeChannel.js.map +1 -1
  176. package/dist/core/OperatorConfig.js +5 -5
  177. package/dist/core/OperatorConfig.js.map +1 -1
  178. package/dist/core/PacketBuilder.d.ts +8 -5
  179. package/dist/core/PacketBuilder.d.ts.map +1 -1
  180. package/dist/core/PacketBuilder.js +117 -81
  181. package/dist/core/PacketBuilder.js.map +1 -1
  182. package/dist/core/PacketBuilder.sql +146 -0
  183. package/dist/core/PatternSelection.d.ts +28 -0
  184. package/dist/core/PatternSelection.d.ts.map +1 -0
  185. package/dist/core/PatternSelection.js +42 -0
  186. package/dist/core/PatternSelection.js.map +1 -0
  187. package/dist/core/ProblemLog.d.ts.map +1 -1
  188. package/dist/core/ProblemLog.js +0 -1
  189. package/dist/core/ProblemLog.js.map +1 -1
  190. package/dist/core/PromptFrames.d.ts +12 -0
  191. package/dist/core/PromptFrames.d.ts.map +1 -0
  192. package/dist/core/PromptFrames.js +28 -0
  193. package/dist/core/PromptFrames.js.map +1 -0
  194. package/dist/core/ProposalLifecycle.d.ts +0 -1
  195. package/dist/core/ProposalLifecycle.d.ts.map +1 -1
  196. package/dist/core/ProposalLifecycle.js +26 -23
  197. package/dist/core/ProposalLifecycle.js.map +1 -1
  198. package/dist/core/ProposalLifecycle.sql +33 -0
  199. package/dist/core/ProviderInstantiate.d.ts +1 -1
  200. package/dist/core/ProviderInstantiate.d.ts.map +1 -1
  201. package/dist/core/ProviderInstantiate.js +7 -14
  202. package/dist/core/ProviderInstantiate.js.map +1 -1
  203. package/dist/core/ReasoningView.d.ts +9 -0
  204. package/dist/core/ReasoningView.d.ts.map +1 -0
  205. package/dist/core/ReasoningView.js +47 -0
  206. package/dist/core/ReasoningView.js.map +1 -0
  207. package/dist/core/ResourceBindings.d.ts +16 -0
  208. package/dist/core/ResourceBindings.d.ts.map +1 -0
  209. package/dist/core/ResourceBindings.js +45 -0
  210. package/dist/core/ResourceBindings.js.map +1 -0
  211. package/dist/core/ResourceMutations.d.ts +5 -8
  212. package/dist/core/ResourceMutations.d.ts.map +1 -1
  213. package/dist/core/ResourceMutations.js +6 -7
  214. package/dist/core/ResourceMutations.js.map +1 -1
  215. package/dist/core/ResourceSelector.d.ts +2 -2
  216. package/dist/core/ResourceSelector.d.ts.map +1 -1
  217. package/dist/core/ResourceSelector.js +122 -62
  218. package/dist/core/ResourceSelector.js.map +1 -1
  219. package/dist/core/ResourceTransfers.d.ts +4 -2
  220. package/dist/core/ResourceTransfers.d.ts.map +1 -1
  221. package/dist/core/ResourceTransfers.js +95 -26
  222. package/dist/core/ResourceTransfers.js.map +1 -1
  223. package/dist/core/RuntimeWorker.d.ts +5 -0
  224. package/dist/core/RuntimeWorker.d.ts.map +1 -0
  225. package/dist/core/RuntimeWorker.js +15 -0
  226. package/dist/core/RuntimeWorker.js.map +1 -0
  227. package/dist/core/RuntimeWorker.sql +11 -0
  228. package/dist/core/SchemeRegistry.d.ts +12 -16
  229. package/dist/core/SchemeRegistry.d.ts.map +1 -1
  230. package/dist/core/SchemeRegistry.js +59 -85
  231. package/dist/core/SchemeRegistry.js.map +1 -1
  232. package/dist/core/StoredPacket.d.ts +6 -1
  233. package/dist/core/StoredPacket.d.ts.map +1 -1
  234. package/dist/core/StoredPacket.js +30 -10
  235. package/dist/core/StoredPacket.js.map +1 -1
  236. package/dist/core/StrikeRail.d.ts +11 -8
  237. package/dist/core/StrikeRail.d.ts.map +1 -1
  238. package/dist/core/StrikeRail.js +63 -114
  239. package/dist/core/StrikeRail.js.map +1 -1
  240. package/dist/core/StrikeRail.sql +12 -0
  241. package/dist/core/TerminalResult.d.ts +1 -1
  242. package/dist/core/TerminalResult.d.ts.map +1 -1
  243. package/dist/core/TerminalResult.js +2 -2
  244. package/dist/core/TerminalResult.js.map +1 -1
  245. package/dist/core/TokenCalibration.d.ts +1 -6
  246. package/dist/core/TokenCalibration.d.ts.map +1 -1
  247. package/dist/core/TokenCalibration.js +13 -9
  248. package/dist/core/TokenCalibration.js.map +1 -1
  249. package/dist/core/TokenCalibration.sql +15 -0
  250. package/dist/core/ToolInputSchema.d.ts +6 -0
  251. package/dist/core/ToolInputSchema.d.ts.map +1 -0
  252. package/dist/core/ToolInputSchema.js +43 -0
  253. package/dist/core/ToolInputSchema.js.map +1 -0
  254. package/dist/core/ToolResources.d.ts.map +1 -1
  255. package/dist/core/ToolResources.js +77 -51
  256. package/dist/core/ToolResources.js.map +1 -1
  257. package/dist/core/Turn.d.ts +5 -2
  258. package/dist/core/Turn.d.ts.map +1 -1
  259. package/dist/core/Turn.js +13 -11
  260. package/dist/core/Turn.js.map +1 -1
  261. package/dist/core/Turn.sql +25 -39
  262. package/dist/core/{SendBroadcastHandler.d.ts → TurnDispositionHandler.d.ts} +24 -18
  263. package/dist/core/TurnDispositionHandler.d.ts.map +1 -0
  264. package/dist/core/TurnDispositionHandler.js +206 -0
  265. package/dist/core/TurnDispositionHandler.js.map +1 -0
  266. package/dist/core/TurnMaterialization.d.ts +2 -3
  267. package/dist/core/TurnMaterialization.d.ts.map +1 -1
  268. package/dist/core/TurnMaterialization.js +47 -24
  269. package/dist/core/TurnMaterialization.js.map +1 -1
  270. package/dist/core/TurnMaterialization.sql +44 -0
  271. package/dist/core/TurnOps.d.ts.map +1 -1
  272. package/dist/core/TurnOps.js +8 -64
  273. package/dist/core/TurnOps.js.map +1 -1
  274. package/dist/core/TurnRunner.d.ts +8 -15
  275. package/dist/core/TurnRunner.d.ts.map +1 -1
  276. package/dist/core/TurnRunner.js +1175 -1317
  277. package/dist/core/TurnRunner.js.map +1 -1
  278. package/dist/core/TurnRunner.sql +74 -0
  279. package/dist/core/TurnSources.sql +39 -0
  280. package/dist/core/WorkerControlAddress.d.ts +1 -0
  281. package/dist/core/WorkerControlAddress.d.ts.map +1 -1
  282. package/dist/core/WorkerControlAddress.js +5 -0
  283. package/dist/core/WorkerControlAddress.js.map +1 -1
  284. package/dist/core/WorkerControlHandler.d.ts +1 -3
  285. package/dist/core/WorkerControlHandler.d.ts.map +1 -1
  286. package/dist/core/WorkerControlHandler.js +64 -48
  287. package/dist/core/WorkerControlHandler.js.map +1 -1
  288. package/dist/core/WorkerName.d.ts +11 -12
  289. package/dist/core/WorkerName.d.ts.map +1 -1
  290. package/dist/core/WorkerName.js +40 -47
  291. package/dist/core/WorkerName.js.map +1 -1
  292. package/dist/core/WorkerName.sql +7 -10
  293. package/dist/core/WorkspaceGate.d.ts +1 -1
  294. package/dist/core/WorkspaceGate.d.ts.map +1 -1
  295. package/dist/core/WorkspaceGate.js +33 -10
  296. package/dist/core/WorkspaceGate.js.map +1 -1
  297. package/dist/core/ambient.sql +236 -0
  298. package/dist/core/attachments.d.ts +2 -1
  299. package/dist/core/attachments.d.ts.map +1 -1
  300. package/dist/core/attachments.js +5 -4
  301. package/dist/core/attachments.js.map +1 -1
  302. package/dist/core/caps/CapsResolve.d.ts +2 -3
  303. package/dist/core/caps/CapsResolve.d.ts.map +1 -1
  304. package/dist/core/caps/CapsResolve.js +5 -5
  305. package/dist/core/caps/CapsResolve.js.map +1 -1
  306. package/dist/core/caps/DbChannelCaps.d.ts +1 -1
  307. package/dist/core/caps/DbChannelCaps.d.ts.map +1 -1
  308. package/dist/core/caps/DbChannelCaps.js +4 -6
  309. package/dist/core/caps/DbChannelCaps.js.map +1 -1
  310. package/dist/core/caps/DbEntryCaps.d.ts +2 -1
  311. package/dist/core/caps/DbEntryCaps.d.ts.map +1 -1
  312. package/dist/core/caps/DbEntryCaps.js +11 -17
  313. package/dist/core/caps/DbEntryCaps.js.map +1 -1
  314. package/dist/core/caps/DbNotifyCaps.d.ts +1 -1
  315. package/dist/core/caps/DbNotifyCaps.d.ts.map +1 -1
  316. package/dist/core/caps/DbNotifyCaps.js +3 -5
  317. package/dist/core/caps/DbNotifyCaps.js.map +1 -1
  318. package/dist/core/caps/DbProjectionCaps.js +1 -1
  319. package/dist/core/caps/DbProjectionCaps.js.map +1 -1
  320. package/dist/core/caps/DbSubscriptionCaps.d.ts +1 -1
  321. package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
  322. package/dist/core/caps/DbSubscriptionCaps.js +5 -7
  323. package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
  324. package/dist/core/caps/SchemeCtxImpl.d.ts +0 -2
  325. package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
  326. package/dist/core/caps/SchemeCtxImpl.js +4 -20
  327. package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
  328. package/dist/core/env-catalog.d.ts +28 -0
  329. package/dist/core/env-catalog.d.ts.map +1 -0
  330. package/dist/core/env-catalog.js +99 -0
  331. package/dist/core/env-catalog.js.map +1 -0
  332. package/dist/core/env-defaults.d.ts.map +1 -1
  333. package/dist/core/env-defaults.js +4 -2
  334. package/dist/core/env-defaults.js.map +1 -1
  335. package/dist/core/file-materialization.d.ts +4 -1
  336. package/dist/core/file-materialization.d.ts.map +1 -1
  337. package/dist/core/file-materialization.js +15 -1
  338. package/dist/core/file-materialization.js.map +1 -1
  339. package/dist/core/fork.d.ts +1 -6
  340. package/dist/core/fork.d.ts.map +1 -1
  341. package/dist/core/fork.js +9 -153
  342. package/dist/core/fork.js.map +1 -1
  343. package/dist/core/fork.sql +162 -185
  344. package/dist/core/git-env.d.ts +1 -0
  345. package/dist/core/git-env.d.ts.map +1 -1
  346. package/dist/core/git-env.js +39 -2
  347. package/dist/core/git-env.js.map +1 -1
  348. package/dist/core/git-membership.d.ts.map +1 -1
  349. package/dist/core/git-membership.js +64 -48
  350. package/dist/core/git-membership.js.map +1 -1
  351. package/dist/core/git-state.d.ts.map +1 -1
  352. package/dist/core/git-state.js +26 -20
  353. package/dist/core/git-state.js.map +1 -1
  354. package/dist/core/glob_match.d.ts +4 -0
  355. package/dist/core/glob_match.d.ts.map +1 -0
  356. package/dist/core/glob_match.js +7 -0
  357. package/dist/core/glob_match.js.map +1 -0
  358. package/dist/core/maintenance.sql +6 -0
  359. package/dist/core/mutation-types.d.ts +7 -28
  360. package/dist/core/mutation-types.d.ts.map +1 -1
  361. package/dist/core/operation-target-groups.d.ts.map +1 -1
  362. package/dist/core/operation-target-groups.js +2 -1
  363. package/dist/core/operation-target-groups.js.map +1 -1
  364. package/dist/core/packet-inject.d.ts.map +1 -1
  365. package/dist/core/packet-inject.js +2 -3
  366. package/dist/core/packet-inject.js.map +1 -1
  367. package/dist/core/packet-wire.d.ts +8 -6
  368. package/dist/core/packet-wire.d.ts.map +1 -1
  369. package/dist/core/packet-wire.js +381 -388
  370. package/dist/core/packet-wire.js.map +1 -1
  371. package/dist/core/plurnk-uri.d.ts +1 -1
  372. package/dist/core/plurnk-uri.d.ts.map +1 -1
  373. package/dist/core/plurnk-uri.js +5 -12
  374. package/dist/core/plurnk-uri.js.map +1 -1
  375. package/dist/core/scheme-types.d.ts +3 -3
  376. package/dist/core/scheme-types.d.ts.map +1 -1
  377. package/dist/core/scheme-types.js.map +1 -1
  378. package/dist/core/sha256.d.ts +4 -0
  379. package/dist/core/sha256.d.ts.map +1 -0
  380. package/dist/core/sha256.js +6 -0
  381. package/dist/core/sha256.js.map +1 -0
  382. package/dist/core/teaching.js +1 -1
  383. package/dist/core/teaching.js.map +1 -1
  384. package/dist/core/turn-scheduler.d.ts.map +1 -1
  385. package/dist/core/turn-scheduler.js +5 -18
  386. package/dist/core/turn-scheduler.js.map +1 -1
  387. package/dist/core/turn-signals.d.ts +0 -6
  388. package/dist/core/turn-signals.d.ts.map +1 -1
  389. package/dist/core/turn-signals.js +1 -7
  390. package/dist/core/turn-signals.js.map +1 -1
  391. package/dist/core/worker-ops.sql +15 -22
  392. package/dist/core/workspace-settings.d.ts.map +1 -1
  393. package/dist/core/workspace-settings.js +18 -2
  394. package/dist/core/workspace-settings.js.map +1 -1
  395. package/dist/core/workspace-settings.sql +6 -0
  396. package/dist/digest/Digest.d.ts.map +1 -1
  397. package/dist/digest/Digest.js +30 -91
  398. package/dist/digest/Digest.js.map +1 -1
  399. package/dist/digest/DigestRender.d.ts +1 -0
  400. package/dist/digest/DigestRender.d.ts.map +1 -1
  401. package/dist/digest/DigestRender.js +58 -62
  402. package/dist/digest/DigestRender.js.map +1 -1
  403. package/dist/digest/digest-rows.d.ts +16 -32
  404. package/dist/digest/digest-rows.d.ts.map +1 -1
  405. package/dist/digest/digest.sql +54 -20
  406. package/dist/schemes/Exec.d.ts +6 -12
  407. package/dist/schemes/Exec.d.ts.map +1 -1
  408. package/dist/schemes/Exec.js +318 -215
  409. package/dist/schemes/Exec.js.map +1 -1
  410. package/dist/schemes/ExecOutputScheme.d.ts +8 -6
  411. package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
  412. package/dist/schemes/ExecOutputScheme.js +33 -61
  413. package/dist/schemes/ExecOutputScheme.js.map +1 -1
  414. package/dist/schemes/ExecScheduler.js +2 -2
  415. package/dist/schemes/ExecScheduler.js.map +1 -1
  416. package/dist/schemes/ExecutionInput.d.ts +12 -0
  417. package/dist/schemes/ExecutionInput.d.ts.map +1 -0
  418. package/dist/schemes/ExecutionInput.js +94 -0
  419. package/dist/schemes/ExecutionInput.js.map +1 -0
  420. package/dist/schemes/File.d.ts +5 -2
  421. package/dist/schemes/File.d.ts.map +1 -1
  422. package/dist/schemes/File.js +62 -91
  423. package/dist/schemes/File.js.map +1 -1
  424. package/dist/schemes/Log.d.ts.map +1 -1
  425. package/dist/schemes/Log.js +84 -79
  426. package/dist/schemes/Log.js.map +1 -1
  427. package/dist/schemes/Log.sql +183 -15
  428. package/dist/schemes/Prompt.d.ts.map +1 -1
  429. package/dist/schemes/Prompt.js +3 -12
  430. package/dist/schemes/Prompt.js.map +1 -1
  431. package/dist/schemes/QuestionTool.d.ts +5 -0
  432. package/dist/schemes/QuestionTool.d.ts.map +1 -1
  433. package/dist/schemes/QuestionTool.js +7 -15
  434. package/dist/schemes/QuestionTool.js.map +1 -1
  435. package/dist/schemes/Skill.d.ts +12 -7
  436. package/dist/schemes/Skill.d.ts.map +1 -1
  437. package/dist/schemes/Skill.js +149 -21
  438. package/dist/schemes/Skill.js.map +1 -1
  439. package/dist/schemes/TurnSource.d.ts +12 -0
  440. package/dist/schemes/TurnSource.d.ts.map +1 -0
  441. package/dist/schemes/TurnSource.js +117 -0
  442. package/dist/schemes/TurnSource.js.map +1 -0
  443. package/dist/schemes/Worker.d.ts +3 -3
  444. package/dist/schemes/Worker.d.ts.map +1 -1
  445. package/dist/schemes/Worker.js +61 -208
  446. package/dist/schemes/Worker.js.map +1 -1
  447. package/dist/schemes/_entry-crud.d.ts +12 -15
  448. package/dist/schemes/_entry-crud.d.ts.map +1 -1
  449. package/dist/schemes/_entry-crud.js +63 -63
  450. package/dist/schemes/_entry-crud.js.map +1 -1
  451. package/dist/schemes/_entry-crud.sql +159 -45
  452. package/dist/schemes/_entry-find.d.ts +1 -3
  453. package/dist/schemes/_entry-find.d.ts.map +1 -1
  454. package/dist/schemes/_entry-find.js +111 -112
  455. package/dist/schemes/_entry-find.js.map +1 -1
  456. package/dist/schemes/_entry-find.sql +22 -14
  457. package/dist/schemes/_entry-fts.d.ts +14 -0
  458. package/dist/schemes/_entry-fts.d.ts.map +1 -0
  459. package/dist/schemes/_entry-fts.js +82 -0
  460. package/dist/schemes/_entry-fts.js.map +1 -0
  461. package/dist/schemes/_entry-fts.sql +31 -0
  462. package/dist/schemes/_entry-graph.d.ts.map +1 -1
  463. package/dist/schemes/_entry-graph.js +6 -14
  464. package/dist/schemes/_entry-graph.js.map +1 -1
  465. package/dist/schemes/_entry-graph.sql +29 -44
  466. package/dist/schemes/_entry-manifest.d.ts +2 -1
  467. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  468. package/dist/schemes/_entry-manifest.js +20 -26
  469. package/dist/schemes/_entry-manifest.js.map +1 -1
  470. package/dist/schemes/_entry-manifest.sql +26 -0
  471. package/dist/schemes/_entry-ops.d.ts +3 -5
  472. package/dist/schemes/_entry-ops.d.ts.map +1 -1
  473. package/dist/schemes/_entry-ops.js +30 -43
  474. package/dist/schemes/_entry-ops.js.map +1 -1
  475. package/dist/schemes/_entry-ops.sql +5 -6
  476. package/dist/schemes/_entry-readable.d.ts +8 -0
  477. package/dist/schemes/_entry-readable.d.ts.map +1 -0
  478. package/dist/schemes/_entry-readable.js +38 -0
  479. package/dist/schemes/_entry-readable.js.map +1 -0
  480. package/dist/schemes/_entry-send.d.ts +1 -1
  481. package/dist/schemes/_entry-send.d.ts.map +1 -1
  482. package/dist/schemes/_entry-send.js +3 -3
  483. package/dist/schemes/_entry-send.js.map +1 -1
  484. package/dist/schemes/_search-index.d.ts +5 -3
  485. package/dist/schemes/_search-index.d.ts.map +1 -1
  486. package/dist/schemes/_search-index.js +169 -160
  487. package/dist/schemes/_search-index.js.map +1 -1
  488. package/dist/schemes/_search-index.sql +47 -0
  489. package/dist/schemes/exec-abort.js +1 -1
  490. package/dist/schemes/exec-abort.js.map +1 -1
  491. package/dist/schemes/exec-env.d.ts +3 -0
  492. package/dist/schemes/exec-env.d.ts.map +1 -1
  493. package/dist/schemes/exec-env.js +66 -15
  494. package/dist/schemes/exec-env.js.map +1 -1
  495. package/dist/schemes/exec-runtime.d.ts +1 -1
  496. package/dist/schemes/exec-runtime.d.ts.map +1 -1
  497. package/dist/schemes/exec-runtime.js +1 -1
  498. package/dist/schemes/exec-runtime.js.map +1 -1
  499. package/dist/server/ClientReads.d.ts +2 -2
  500. package/dist/server/ClientReads.d.ts.map +1 -1
  501. package/dist/server/ClientReads.js +7 -9
  502. package/dist/server/ClientReads.js.map +1 -1
  503. package/dist/server/Daemon.d.ts +15 -21
  504. package/dist/server/Daemon.d.ts.map +1 -1
  505. package/dist/server/Daemon.js +165 -168
  506. package/dist/server/Daemon.js.map +1 -1
  507. package/dist/server/DaemonModule.d.ts +29 -22
  508. package/dist/server/DaemonModule.d.ts.map +1 -1
  509. package/dist/server/DrainSupervisor.d.ts +8 -21
  510. package/dist/server/DrainSupervisor.d.ts.map +1 -1
  511. package/dist/server/DrainSupervisor.js +278 -306
  512. package/dist/server/DrainSupervisor.js.map +1 -1
  513. package/dist/server/EnvFunctionality.d.ts +43 -0
  514. package/dist/server/EnvFunctionality.d.ts.map +1 -0
  515. package/dist/server/EnvFunctionality.js +194 -0
  516. package/dist/server/EnvFunctionality.js.map +1 -0
  517. package/dist/server/Functionality.d.ts +12 -11
  518. package/dist/server/Functionality.d.ts.map +1 -1
  519. package/dist/server/Functionality.js +279 -142
  520. package/dist/server/Functionality.js.map +1 -1
  521. package/dist/server/FunctionalityManager.d.ts +5 -5
  522. package/dist/server/FunctionalityManager.d.ts.map +1 -1
  523. package/dist/server/FunctionalityManager.js +29 -57
  524. package/dist/server/FunctionalityManager.js.map +1 -1
  525. package/dist/server/MembersFunctionality.d.ts +5 -4
  526. package/dist/server/MembersFunctionality.d.ts.map +1 -1
  527. package/dist/server/MembersFunctionality.js +24 -38
  528. package/dist/server/MembersFunctionality.js.map +1 -1
  529. package/dist/server/PlurnkSkill.d.ts +11 -0
  530. package/dist/server/PlurnkSkill.d.ts.map +1 -0
  531. package/dist/server/PlurnkSkill.js +41 -0
  532. package/dist/server/PlurnkSkill.js.map +1 -0
  533. package/dist/server/Retention.d.ts +25 -0
  534. package/dist/server/Retention.d.ts.map +1 -0
  535. package/dist/server/Retention.js +57 -0
  536. package/dist/server/Retention.js.map +1 -0
  537. package/dist/server/Retention.sql +59 -0
  538. package/dist/server/ServiceModules.d.ts +5 -0
  539. package/dist/server/ServiceModules.d.ts.map +1 -0
  540. package/dist/server/ServiceModules.js +10 -0
  541. package/dist/server/ServiceModules.js.map +1 -0
  542. package/dist/server/SkillsFunctionality.d.ts +14 -19
  543. package/dist/server/SkillsFunctionality.d.ts.map +1 -1
  544. package/dist/server/SkillsFunctionality.js +102 -106
  545. package/dist/server/SkillsFunctionality.js.map +1 -1
  546. package/dist/server/WorkerModelResolver.d.ts +4 -0
  547. package/dist/server/WorkerModelResolver.d.ts.map +1 -1
  548. package/dist/server/WorkerModelResolver.js +72 -39
  549. package/dist/server/WorkerModelResolver.js.map +1 -1
  550. package/dist/server/WorkspaceCapabilities.d.ts +21 -0
  551. package/dist/server/WorkspaceCapabilities.d.ts.map +1 -0
  552. package/dist/server/{WorkerCapabilities.js → WorkspaceCapabilities.js} +40 -40
  553. package/dist/server/WorkspaceCapabilities.js.map +1 -0
  554. package/dist/server/WorkspaceResidency.d.ts +38 -0
  555. package/dist/server/WorkspaceResidency.d.ts.map +1 -0
  556. package/dist/server/WorkspaceResidency.js +226 -0
  557. package/dist/server/WorkspaceResidency.js.map +1 -0
  558. package/dist/server/client-input.d.ts +1 -4
  559. package/dist/server/client-input.d.ts.map +1 -1
  560. package/dist/server/client-input.js +5 -46
  561. package/dist/server/client-input.js.map +1 -1
  562. package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
  563. package/dist/server/dispatch-as-plurnk.js +4 -22
  564. package/dist/server/dispatch-as-plurnk.js.map +1 -1
  565. package/dist/server/drain.sql +66 -43
  566. package/dist/server/envelope.d.ts +8 -1
  567. package/dist/server/envelope.d.ts.map +1 -1
  568. package/dist/server/envelope.js +9 -19
  569. package/dist/server/envelope.js.map +1 -1
  570. package/dist/server/envelope.sql +49 -13
  571. package/dist/server/lifecycle-recovery.sql +18 -20
  572. package/dist/server/logEntry.d.ts +1 -1
  573. package/dist/server/logEntry.d.ts.map +1 -1
  574. package/dist/server/logEntry.js +4 -1
  575. package/dist/server/logEntry.js.map +1 -1
  576. package/dist/server/logEntry.sql +25 -1
  577. package/dist/server/loopDocs.d.ts +2 -2
  578. package/dist/server/loopDocs.d.ts.map +1 -1
  579. package/dist/server/loopDocs.js +38 -31
  580. package/dist/server/loopDocs.js.map +1 -1
  581. package/dist/server/loopDocs.sql +1 -3
  582. package/dist/server/model-catalog.d.ts.map +1 -1
  583. package/dist/server/model-catalog.js +2 -1
  584. package/dist/server/model-catalog.js.map +1 -1
  585. package/dist/server/model-route.d.ts +1 -1
  586. package/dist/server/model-route.d.ts.map +1 -1
  587. package/dist/server/model-route.js +4 -2
  588. package/dist/server/model-route.js.map +1 -1
  589. package/dist/server/seam-entry-read.sql +3 -4
  590. package/dist/server/seam-loop.sql +2 -9
  591. package/dist/server/workspace-capabilities.sql +64 -0
  592. package/dist/service.d.ts.map +1 -1
  593. package/dist/service.js +21 -18
  594. package/dist/service.js.map +1 -1
  595. package/docs/env.md +55 -0
  596. package/docs/members.md +83 -0
  597. package/docs/skills.md +50 -0
  598. package/migrations/001_workspaces.sql +53 -0
  599. package/migrations/002_workers.sql +198 -0
  600. package/migrations/003_loops.sql +326 -0
  601. package/migrations/004_inference.sql +401 -0
  602. package/migrations/005_entries.sql +215 -0
  603. package/migrations/006_log.sql +581 -0
  604. package/migrations/007_subscriptions.sql +175 -0
  605. package/migrations/008_interactions.sql +29 -0
  606. package/package.json +44 -41
  607. package/digest-sql/channel-dispositions/dispositions.sql +0 -15
  608. package/digest-sql/channel-state/state.sql +0 -6
  609. package/digest-sql/curation/curation.sql +0 -6
  610. package/digest-sql/derivations/derivations.sql +0 -4
  611. package/digest-sql/embeddings/embeddings.sql +0 -4
  612. package/digest-sql/entry-dispositions/dispositions.sql +0 -15
  613. package/digest-sql/entry-state/state.sql +0 -6
  614. package/digest-sql/token-counts/token-counts.sql +0 -2
  615. package/dist/core/EmbeddingCall.d.ts +0 -23
  616. package/dist/core/EmbeddingCall.d.ts.map +0 -1
  617. package/dist/core/EmbeddingCall.js +0 -149
  618. package/dist/core/EmbeddingCall.js.map +0 -1
  619. package/dist/core/OverflowTurn.d.ts +0 -11
  620. package/dist/core/OverflowTurn.d.ts.map +0 -1
  621. package/dist/core/OverflowTurn.js +0 -80
  622. package/dist/core/OverflowTurn.js.map +0 -1
  623. package/dist/core/Owner.d.ts +0 -8
  624. package/dist/core/Owner.d.ts.map +0 -1
  625. package/dist/core/Owner.js +0 -46
  626. package/dist/core/Owner.js.map +0 -1
  627. package/dist/core/SendBroadcastHandler.d.ts.map +0 -1
  628. package/dist/core/SendBroadcastHandler.js +0 -159
  629. package/dist/core/SendBroadcastHandler.js.map +0 -1
  630. package/dist/core/VectorPump.d.ts +0 -28
  631. package/dist/core/VectorPump.d.ts.map +0 -1
  632. package/dist/core/VectorPump.js +0 -130
  633. package/dist/core/VectorPump.js.map +0 -1
  634. package/dist/core/owner.sql +0 -11
  635. package/dist/core/worker-settings.d.ts +0 -10
  636. package/dist/core/worker-settings.d.ts.map +0 -1
  637. package/dist/core/worker-settings.js +0 -53
  638. package/dist/core/worker-settings.js.map +0 -1
  639. package/dist/schemes/_entry-chunk.d.ts +0 -14
  640. package/dist/schemes/_entry-chunk.d.ts.map +0 -1
  641. package/dist/schemes/_entry-chunk.js +0 -165
  642. package/dist/schemes/_entry-chunk.js.map +0 -1
  643. package/dist/schemes/_entry-semantic.d.ts +0 -63
  644. package/dist/schemes/_entry-semantic.d.ts.map +0 -1
  645. package/dist/schemes/_entry-semantic.js +0 -299
  646. package/dist/schemes/_entry-semantic.js.map +0 -1
  647. package/dist/schemes/_entry-semantic.sql +0 -99
  648. package/dist/schemes/cosine.d.ts +0 -4
  649. package/dist/schemes/cosine.d.ts.map +0 -1
  650. package/dist/schemes/cosine.js +0 -9
  651. package/dist/schemes/cosine.js.map +0 -1
  652. package/dist/server/WorkerCapabilities.d.ts +0 -21
  653. package/dist/server/WorkerCapabilities.d.ts.map +0 -1
  654. package/dist/server/WorkerCapabilities.js.map +0 -1
  655. package/dist/server/WorkerResidency.d.ts +0 -40
  656. package/dist/server/WorkerResidency.d.ts.map +0 -1
  657. package/dist/server/WorkerResidency.js +0 -283
  658. package/dist/server/WorkerResidency.js.map +0 -1
  659. package/dist/server/seam-log-read.sql +0 -21
  660. package/dist/server/worker-capabilities.sql +0 -28
  661. package/migrations/001_schema.sql +0 -2207
@@ -1,17 +1,22 @@
1
1
  var _a;
2
- // {§functionality-coordinator} — the one owner of the Worker Functionality
2
+ // {§functionality-coordinator} — the one owner of the workspace Functionality
3
3
  // lifecycle above the family adapters (Agent Skills, MCP, outbound A2A). It owns
4
- // durable per-Worker state, lifecycle ordering, serialization, atomic
5
- // publication, and both projections: worker-scoped client actions and a
6
- // per-Worker generated executor family whose host verbs propose. An explicit
4
+ // durable workspace state, lifecycle ordering, serialization, atomic
5
+ // publication, and both projections: workspace-scoped client actions and a
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 { isDeepStrictEqual } from "node:util";
10
+ import { DocFile } from "@plurnk/plurnk-execs";
9
11
  import FunctionalityManager, { FUNCTIONALITY_VERBS, functionalityRuntimeDecl, } from "./FunctionalityManager.js";
10
12
  import Results, { OperationFailureError } from "../core/results.js";
11
13
  import { generatedPathname } from "../core/plurnk-uri.js";
12
14
  const STATE_VERSION = 1;
13
15
  const FAMILY = /^[a-z][a-z0-9]*$/u;
14
16
  const ALIAS = /^[a-z][a-z0-9-]*$/u;
17
+ // A family may declare its own alias grammar ({§functionality-adapter}); the coordinator enforces it
18
+ // wherever an alias enters: admission, the service projection, and persisted state.
19
+ const aliasPattern = (adapter) => adapter.aliasPattern ?? ALIAS;
15
20
  const EMPTY_STATE = Object.freeze({ version: STATE_VERSION, definitions: Object.freeze({}) });
16
21
  const SCHEMA = (name) => ({ $ref: `https://schemas.plurnk.xyz/v0/${name}.json` });
17
22
  const ALIAS_INPUT = Object.freeze({
@@ -34,7 +39,7 @@ class Functionality {
34
39
  this.#host = host;
35
40
  }
36
41
  // {§functionality-adapter} — registration publishes the family's client
37
- // actions and its Worker capability provider at once.
42
+ // actions and its workspace capability provider at once.
38
43
  register(adapter) {
39
44
  const { family, namespaceOwner } = adapter;
40
45
  if (!FAMILY.test(family))
@@ -63,17 +68,28 @@ class Functionality {
63
68
  disable: ALIAS_INPUT,
64
69
  remove: ALIAS_INPUT,
65
70
  });
71
+ // {§functionality-model-projection} — the taught `add` example must satisfy the schema it teaches.
72
+ if (adapter.example !== undefined) {
73
+ const example = Validator.validateJsonSchemaInstance(schemas.add, adapter.example);
74
+ if (!example.valid) {
75
+ throw new Error(`Functionality family '${family}' teaches an add example that violates its own definition schema: ${JSON.stringify(example.errors)}`);
76
+ }
77
+ }
66
78
  this.#adapters.set(family, adapter);
67
79
  this.#owners.add(namespaceOwner);
68
80
  this.#schemas.set(family, schemas);
69
- this.#host.registerWorkerCapabilityProvider(namespaceOwner, {
81
+ this.#host.registerWorkspaceCapabilityProvider(namespaceOwner, {
70
82
  activate: (context) => this.#activate(adapter, context),
71
83
  deactivate: (identity) => this.#deactivate(adapter, identity),
72
84
  });
85
+ // {§functionality-scope} — a worker-scoped family projects `worker.<family>.<verb>`, whose
86
+ // context names the Worker the verb acts for; every other family projects
87
+ // `workspace.<family>.<verb>`. One implementation sits beneath both.
88
+ const scope = adapter.scope ?? "workspace";
73
89
  for (const verb of FUNCTIONALITY_VERBS) {
74
90
  this.#host.registerModuleAction({
75
- name: `worker.${family}.${verb}`,
76
- scope: "worker",
91
+ name: `${scope}.${family}.${verb}`,
92
+ scope,
77
93
  inputSchema: schemas[verb],
78
94
  outputSchema: SCHEMA(verb === "list"
79
95
  ? "FunctionalityListResult"
@@ -81,10 +97,12 @@ class Functionality {
81
97
  ? "FunctionalityDiscoverResult"
82
98
  : "FunctionalityMutationResult"),
83
99
  handler: async (params, context) => {
84
- if (context.scope !== "worker")
85
- throw new Error(`worker.${family}.${verb} requires a worker-scoped context.`);
86
- const { workspaceId, workerId } = context;
87
- return (await this.invoke(family, verb, params, { workspaceId, workerId }, "action")).body;
100
+ if (context.scope === "worldless" || context.scope !== scope)
101
+ throw new Error(`${scope}.${family}.${verb} requires a ${scope}-scoped context.`);
102
+ const identity = context.scope === "worker"
103
+ ? { workspaceId: context.workspaceId, workerId: context.workerId }
104
+ : { workspaceId: context.workspaceId };
105
+ return (await this.invoke(family, verb, params, identity, "action")).body;
88
106
  },
89
107
  });
90
108
  }
@@ -93,20 +111,20 @@ class Functionality {
93
111
  refresh: (identity, options) => this.refresh(family, identity, options),
94
112
  };
95
113
  }
96
- // Republish a family's unchanged state for one Worker — a live catalog
114
+ // Republish a family's unchanged state for one workspace — a live catalog
97
115
  // change, not a lifecycle mutation. Serialized like every publication.
98
116
  // `gate: "none"` publishes inside the caller's own held turn (turn admission
99
117
  // refreshing a family before packet assembly) instead of contending for
100
118
  // workspace exclusivity it could never win.
101
119
  async refresh(family, identity, options = {}) {
102
120
  const adapter = this.#adapter(family);
103
- await this.#serialize(identity.workerId, family, async () => {
104
- const current = this.#families.get(this.#key(identity.workerId, family));
121
+ await this.#serialize(this.#key(identity.workspaceId, family), async () => {
122
+ const current = this.#families.get(this.#key(identity.workspaceId, family));
105
123
  if (current === undefined)
106
124
  return;
107
125
  await this.#publish(adapter, identity, current.state, {
108
126
  failure: "publish-unavailable",
109
- retain: () => this.#host.retainWorker(identity.workerId),
127
+ retain: () => this.#host.retainWorkspace(identity.workspaceId),
110
128
  gate: options.gate ?? "wait",
111
129
  });
112
130
  });
@@ -114,20 +132,33 @@ class Functionality {
114
132
  families() {
115
133
  return [...this.#adapters.keys()].toSorted();
116
134
  }
117
- // Await every queued publication (boundary publications included). Shutdown
118
- // and tests settle before inspecting or closing durable state.
119
- async settle(workerId) {
135
+ // Join outstanding invocations before inspecting or closing durable state.
136
+ // Rejections have already been delivered to their action or execution stream.
137
+ async settle(workspaceId) {
120
138
  const pending = [...this.#queues]
121
- .filter(([key]) => workerId === undefined || key.startsWith(`${workerId}:`))
139
+ .filter(([key]) => workspaceId === undefined || key.startsWith(`${workspaceId}:`))
122
140
  .map(([, queue]) => queue.catch(() => undefined));
123
141
  await Promise.all(pending);
124
142
  }
125
143
  // {§functionality-documents} — the family-generated documents of every
126
- // published family for one Worker, addressed under its generated subtree.
127
- documents(workerId) {
144
+ // published family for one workspace, projected under each reader's generated subtree.
145
+ // {§functionality-document-body} — read once per family from the adapter's package, the same
146
+ // `docs/<tag>.md` rule runtimes use. A family that ships no file has a header-only document.
147
+ #documentBodies = new Map();
148
+ #documentBody(adapter) {
149
+ let body = this.#documentBodies.get(adapter.family);
150
+ if (body === undefined) {
151
+ body = adapter.docsDir === undefined
152
+ ? Promise.resolve("")
153
+ : DocFile.read(adapter.docsDir, adapter.family).then((text) => text ?? "");
154
+ this.#documentBodies.set(adapter.family, body);
155
+ }
156
+ return body;
157
+ }
158
+ documents(workspaceId) {
128
159
  const out = [];
129
160
  for (const [key, family] of this.#families) {
130
- if (!key.startsWith(`${workerId}:`) || family.prepared === null)
161
+ if (!key.startsWith(`${workspaceId}:`) || family.prepared === null)
131
162
  continue;
132
163
  for (const document of family.prepared.documents) {
133
164
  out.push({ pathname: generatedPathname(document.pathname), content: document.content });
@@ -148,11 +179,31 @@ class Functionality {
148
179
  });
149
180
  }
150
181
  const input = params;
151
- switch (verb) {
152
- case "list": return { status: 200, body: await this.#list(adapter, identity) };
153
- case "discover": return { status: 200, body: await this.#discover(adapter, input, identity) };
154
- default: return this.#serialize(identity.workerId, family, () => this.#mutate(adapter, verb, input, identity, caller));
182
+ if (verb === "discover")
183
+ return { status: 200, body: await this.#discover(adapter, input, identity) };
184
+ // {§functionality-scope} — a worker-scoped family's list and mutations act for the invoking
185
+ // Worker. The state is that Worker's and nothing resident changes, so they serialize on the
186
+ // Worker's own lane and take no workspace exclusivity: a Worker shapes its environment while
187
+ // its siblings run.
188
+ if (adapter.scope === "worker") {
189
+ const workerId = _a.#workerOf(adapter, identity);
190
+ return this.#serialize(`${this.#key(identity.workspaceId, family)}:${workerId}`, () => this.#invokeForWorker(adapter, verb, input, identity, workerId, caller));
155
191
  }
192
+ if (verb === "list")
193
+ return { status: 200, body: await this.#list(adapter, identity) };
194
+ return this.#host.mutateWorkspace(identity.workspaceId, adapter.namespaceOwner, caller, () => this.#serialize(this.#key(identity.workspaceId, family), () => this.#mutate(adapter, verb, input, identity, caller)));
195
+ }
196
+ // A worker-scoped verb that names no Worker is a defect at the projection, never a client
197
+ // failure: both projections name the Worker ({§functionality-model-projection}).
198
+ static #workerOf(adapter, identity) {
199
+ if (identity.workerId === undefined)
200
+ throw new Error(`${adapter.family} is worker-scoped; the invocation names no Worker.`);
201
+ return identity.workerId;
202
+ }
203
+ // The origin a definition carries when this family owns it locally. Service definitions
204
+ // always come from the adapter's own `available()`; everything else is the family's own.
205
+ static #localOrigin(adapter) {
206
+ return adapter.scope === "worker" ? "worker" : "workspace";
156
207
  }
157
208
  #adapter(family) {
158
209
  const adapter = this.#adapters.get(family);
@@ -160,26 +211,25 @@ class Functionality {
160
211
  throw failure(family, "family-unknown", 404, `No Functionality family '${family}' is registered.`, { retryable: false });
161
212
  return adapter;
162
213
  }
163
- #key(workerId, family) {
164
- return `${workerId}:${family}`;
214
+ #key(workspaceId, family) {
215
+ return `${workspaceId}:${family}`;
165
216
  }
166
- #serialize(workerId, family, work) {
167
- const key = this.#key(workerId, family);
217
+ #serialize(key, work) {
168
218
  const previous = this.#queues.get(key) ?? Promise.resolve();
169
219
  const next = previous.catch(() => undefined).then(work);
170
220
  this.#queues.set(key, next);
171
221
  return next;
172
222
  }
173
223
  async #activate(adapter, context) {
174
- const identity = { workspaceId: context.workspaceId, workerId: context.workerId };
175
- await this.#serialize(identity.workerId, adapter.family, async () => {
176
- const state = await this.#loadState(adapter, identity.workerId);
224
+ const identity = { workspaceId: context.workspaceId };
225
+ await this.#serialize(this.#key(identity.workspaceId, adapter.family), async () => {
226
+ const state = await this.#loadState(adapter, identity.workspaceId);
177
227
  await this.#publish(adapter, identity, state, { failure: "publish-unavailable", retain: context.retain, gate: "none" });
178
228
  });
179
229
  }
180
230
  async #deactivate(adapter, identity) {
181
- await this.#serialize(identity.workerId, adapter.family, async () => {
182
- const key = this.#key(identity.workerId, adapter.family);
231
+ await this.#serialize(this.#key(identity.workspaceId, adapter.family), async () => {
232
+ const key = this.#key(identity.workspaceId, adapter.family);
183
233
  const family = this.#families.get(key);
184
234
  this.#families.delete(key);
185
235
  if (family?.prepared !== null && family?.prepared !== undefined) {
@@ -187,31 +237,40 @@ class Functionality {
187
237
  }
188
238
  });
189
239
  }
190
- async #loadState(adapter, workerId) {
191
- const raw = await this.#host.readWorkerModuleState(workerId, adapter.namespaceOwner);
240
+ async #loadState(adapter, workspaceId) {
241
+ return _a.#parseState(adapter, await this.#host.readWorkspaceModuleState(workspaceId, adapter.namespaceOwner), `workspace ${workspaceId}`);
242
+ }
243
+ async #loadWorkerState(adapter, workerId) {
244
+ return _a.#parseState(adapter, await this.#host.readWorkerModuleState(workerId, adapter.namespaceOwner), `worker ${workerId}`);
245
+ }
246
+ static #parseState(adapter, raw, where) {
192
247
  if (raw === null)
193
248
  return EMPTY_STATE;
194
249
  if (!isRecord(raw) || raw.version !== STATE_VERSION || !isRecord(raw.definitions)) {
195
- throw new Error(`Functionality state for ${adapter.family} on worker ${workerId} is not a version ${STATE_VERSION} record.`);
250
+ throw new Error(`Functionality state for ${adapter.family} in ${where} is not a version ${STATE_VERSION} record.`);
196
251
  }
197
252
  const definitions = {};
198
253
  for (const [alias, value] of Object.entries(raw.definitions)) {
199
- if (!ALIAS.test(alias) || !isRecord(value))
254
+ if (!aliasPattern(adapter).test(alias) || !isRecord(value))
200
255
  throw new Error(`Functionality state for ${adapter.family} has an invalid alias '${alias}'.`);
201
- const { origin, enabled, definition } = value;
202
- if ((origin !== "service" && origin !== "worker") || typeof enabled !== "boolean") {
256
+ const { origin, enabled, definition, inherited } = value;
257
+ if ((origin !== "service" && origin !== "workspace" && origin !== "worker") || typeof enabled !== "boolean") {
203
258
  throw new Error(`Functionality state for ${adapter.family} alias '${alias}' is malformed.`);
204
259
  }
205
- if (origin === "worker") {
260
+ if (inherited !== undefined && (typeof inherited !== "string" || inherited.length === 0 || adapter.scope !== "worker")) {
261
+ throw new Error(`Functionality state for ${adapter.family} alias '${alias}' carries an invalid inheritance.`);
262
+ }
263
+ const provenance = inherited === undefined ? {} : { inherited };
264
+ if (origin === _a.#localOrigin(adapter)) {
206
265
  const result = Validator.validateJsonSchemaInstance(adapter.definitionSchema, definition);
207
266
  if (!result.valid)
208
267
  throw new Error(`Functionality state for ${adapter.family} alias '${alias}' holds an invalid definition.`);
209
- definitions[alias] = { origin, enabled, definition: definition };
268
+ definitions[alias] = { origin, enabled, definition: definition, ...provenance };
210
269
  }
211
270
  else {
212
271
  if (definition !== undefined)
213
272
  throw new Error(`Functionality state for ${adapter.family} alias '${alias}' persists a service definition.`);
214
- definitions[alias] = { origin, enabled };
273
+ definitions[alias] = { origin, enabled, ...provenance };
215
274
  }
216
275
  }
217
276
  return { version: STATE_VERSION, definitions };
@@ -222,38 +281,41 @@ class Functionality {
222
281
  async #effective(adapter, identity, state) {
223
282
  const effective = new Map();
224
283
  for (const service of await adapter.available(identity)) {
225
- if (!ALIAS.test(service.alias))
226
- throw new Error(`${adapter.family} service alias '${service.alias}' must match ${ALIAS}.`);
284
+ if (!aliasPattern(adapter).test(service.alias))
285
+ throw new Error(`${adapter.family} service alias '${service.alias}' must match ${aliasPattern(adapter)}.`);
227
286
  const record = state.definitions[service.alias];
228
287
  const enabled = record?.origin === "service" ? record.enabled : service.enabled;
229
- effective.set(service.alias, { alias: service.alias, origin: "service", definition: service.definition, enabled });
288
+ const inherited = record?.origin === "service" && record.inherited !== undefined ? { inherited: record.inherited } : {};
289
+ effective.set(service.alias, { alias: service.alias, origin: "service", definition: service.definition, enabled, ...inherited });
230
290
  }
231
291
  for (const [alias, record] of Object.entries(state.definitions)) {
232
- if (record.origin !== "worker")
292
+ const local = _a.#localOrigin(adapter);
293
+ if (record.origin !== local)
233
294
  continue;
234
- effective.set(alias, { alias, origin: "worker", definition: record.definition, enabled: record.enabled });
295
+ const inherited = record.inherited === undefined ? {} : { inherited: record.inherited };
296
+ effective.set(alias, { alias, origin: local, definition: record.definition, enabled: record.enabled, ...inherited });
235
297
  }
236
298
  return new Map([...effective].toSorted(([left], [right]) => left.localeCompare(right)));
237
299
  }
238
300
  #projection(definition, outcome) {
239
- if (!definition.enabled) {
240
- return { alias: definition.alias, origin: definition.origin, state: "disabled", definition: definition.definition };
241
- }
301
+ const base = {
302
+ alias: definition.alias, origin: definition.origin, definition: definition.definition,
303
+ ...(definition.inherited === undefined ? {} : { inherited: definition.inherited }),
304
+ };
305
+ if (!definition.enabled)
306
+ return { ...base, state: "disabled" };
242
307
  if (outcome === undefined)
243
308
  throw new Error(`enabled ${definition.alias} has no preparation outcome`);
244
309
  switch (outcome.state) {
245
- case "active": return {
246
- alias: definition.alias, origin: definition.origin, state: "active", definition: definition.definition,
247
- ...(outcome.detail === undefined ? {} : { detail: outcome.detail }),
248
- };
249
- case "unavailable": return { alias: definition.alias, origin: definition.origin, state: "unavailable", definition: definition.definition, problem: outcome.problem };
250
- case "authorization-required": return { alias: definition.alias, origin: definition.origin, state: "authorization-required", definition: definition.definition, authorization: outcome.authorization };
310
+ case "active": return { ...base, state: "active", ...(outcome.detail === undefined ? {} : { detail: outcome.detail }) };
311
+ case "unavailable": return { ...base, state: "unavailable", problem: outcome.problem };
312
+ case "authorization-required": return { ...base, state: "authorization-required", authorization: outcome.authorization };
251
313
  }
252
314
  }
253
315
  async #list(adapter, identity) {
254
- const family = this.#families.get(this.#key(identity.workerId, adapter.family));
316
+ const family = this.#families.get(this.#key(identity.workspaceId, adapter.family));
255
317
  if (family === undefined)
256
- throw failure(adapter.family, "worker-not-resident", 409, `Worker ${identity.workerId} has no resident ${adapter.family} Functionality.`, { recovery: "Activate the Worker through an ordinary operation, then retry.", retryable: false });
318
+ 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 });
257
319
  const effective = await this.#effective(adapter, identity, family.state);
258
320
  const outcomes = family.prepared?.outcomes ?? new Map();
259
321
  return Validator.assertFunctionalityListResult({
@@ -265,13 +327,12 @@ class Functionality {
265
327
  const candidates = await adapter.discover(query, identity);
266
328
  return Validator.assertFunctionalityDiscoverResult({ family: adapter.family, candidates: [...candidates] });
267
329
  }
268
- async #mutate(adapter, verb, input, identity, caller) {
269
- const key = this.#key(identity.workerId, adapter.family);
270
- const family = this.#families.get(key);
271
- if (family === undefined)
272
- throw failure(adapter.family, "worker-not-resident", 409, `Worker ${identity.workerId} has no resident ${adapter.family} Functionality.`, { recovery: "Activate the Worker through an ordinary operation, then retry.", retryable: false });
273
- const effective = await this.#effective(adapter, identity, family.state);
274
- const definitions = { ...family.state.definitions };
330
+ // The verb semantics, one implementation for every family ({§functionality-scope}): the next
331
+ // state, the alias it concerns, and how the mutation reports. Only publication differs by scope.
332
+ async #transition(adapter, verb, input, identity, caller, state, effective) {
333
+ const local = _a.#localOrigin(adapter);
334
+ const here = adapter.scope === "worker" ? "this worker" : "this workspace";
335
+ const definitions = { ...state.definitions };
275
336
  let alias;
276
337
  let status = 200;
277
338
  let removed = false;
@@ -279,14 +340,16 @@ class Functionality {
279
340
  case "add": {
280
341
  const admitted = await adapter.admit(input, identity, caller);
281
342
  alias = admitted.alias;
282
- if (!ALIAS.test(alias))
283
- throw failure(adapter.family, "alias-invalid", 400, `Alias '${alias}' must match ${ALIAS}.`, { alias, retryable: false });
284
- // A worker definition may shadow a service definition of the same
343
+ if (!aliasPattern(adapter).test(alias))
344
+ throw failure(adapter.family, "alias-invalid", 400, `Alias '${alias}' must match ${aliasPattern(adapter)}.`, { alias, retryable: false });
345
+ // A local definition may shadow a service definition of the same
285
346
  // alias; removing it reveals the service baseline again, disabled.
286
- if (effective.get(alias)?.origin === "worker")
287
- throw failure(adapter.family, "alias-exists", 409, `'${alias}' is already this Worker's own definition.`, { alias, recovery: "Enable, disable, or remove the existing definition, or add under another alias.", retryable: false });
288
- definitions[alias] = { origin: "worker", definition: admitted.definition, enabled: true };
289
- status = 201;
347
+ const current = effective.get(alias);
348
+ if (current?.origin === local && !isDeepStrictEqual(current.definition, admitted.definition)) {
349
+ 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 });
350
+ }
351
+ definitions[alias] = { origin: local, definition: admitted.definition, enabled: true };
352
+ status = current?.origin === local ? 200 : 201;
290
353
  break;
291
354
  }
292
355
  case "enable":
@@ -294,9 +357,9 @@ class Functionality {
294
357
  alias = input.alias;
295
358
  const current = effective.get(alias);
296
359
  if (current === undefined)
297
- throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to this Worker.`, { alias, retryable: false });
298
- definitions[alias] = current.origin === "worker"
299
- ? { origin: "worker", definition: current.definition, enabled: verb === "enable" }
360
+ throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to ${here}.`, { alias, retryable: false });
361
+ definitions[alias] = current.origin === local
362
+ ? { origin: local, definition: current.definition, enabled: verb === "enable" }
300
363
  : { origin: "service", enabled: verb === "enable" };
301
364
  break;
302
365
  }
@@ -304,7 +367,7 @@ class Functionality {
304
367
  alias = input.alias;
305
368
  const current = effective.get(alias);
306
369
  if (current === undefined)
307
- throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to this Worker.`, { alias, retryable: false });
370
+ throw failure(adapter.family, "alias-unknown", 404, `'${alias}' is not available to ${here}.`, { alias, retryable: false });
308
371
  if (current.origin === "service")
309
372
  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 });
310
373
  await adapter.forget?.({ alias, definition: current.definition }, identity);
@@ -317,19 +380,11 @@ class Functionality {
317
380
  }
318
381
  default: throw new Error(`unreachable verb ${verb}`);
319
382
  }
320
- const nextState = { version: STATE_VERSION, definitions };
321
- // Re-enabling an alias that is not active retries its preparation; an
322
- // already-active alias keeps its live attachment.
323
- const retry = verb === "enable" && family.prepared?.outcomes.get(alias)?.state !== "active";
324
- const publication = await this.#publish(adapter, identity, nextState, {
325
- failure: caller === "action" ? "reject" : "publish-unavailable",
326
- retain: () => this.#host.retainWorker(identity.workerId),
327
- gate: caller === "operation" ? "wait" : "try",
328
- forceAlias: retry ? alias : null,
329
- });
330
- const effectiveAfter = await this.#effective(adapter, identity, nextState);
383
+ return { definitions, alias, status, removed };
384
+ }
385
+ #mutationResult(adapter, { alias, status, removed }, effectiveAfter, outcomes) {
331
386
  const definition = effectiveAfter.get(alias);
332
- const projection = definition === undefined ? undefined : this.#projection(definition, publication.outcomes.get(alias));
387
+ const projection = definition === undefined ? undefined : this.#projection(definition, outcomes.get(alias));
333
388
  const body = Validator.assertFunctionalityMutationResult({
334
389
  status: projection?.state === "authorization-required" ? 202 : status,
335
390
  family: adapter.family,
@@ -339,86 +394,168 @@ class Functionality {
339
394
  });
340
395
  return { status: body.status, body };
341
396
  }
342
- // {§functionality-publication} — prepare, publish runtimes and state in one
343
- // host replacement, then commit; on any failure abort and keep the previous
344
- // snapshot authoritative. A model caller's publication waits for its own
345
- // turn boundary in the same serialized lane, so the next packet sees it.
346
- async #publish(adapter, identity, nextState, options) {
347
- const key = this.#key(identity.workerId, adapter.family);
348
- const previous = this.#families.get(key)?.prepared ?? null;
349
- const effective = await this.#effective(adapter, identity, nextState);
397
+ async #mutate(adapter, verb, input, identity, caller) {
398
+ const key = this.#key(identity.workspaceId, adapter.family);
399
+ const family = this.#families.get(key);
400
+ if (family === undefined)
401
+ 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 });
402
+ const effective = await this.#effective(adapter, identity, family.state);
403
+ const transition = await this.#transition(adapter, verb, input, identity, caller, family.state, effective);
404
+ const nextState = { version: STATE_VERSION, definitions: transition.definitions };
405
+ // Re-enabling an alias that is not active retries its preparation; an
406
+ // already-active alias keeps its live attachment.
407
+ const retry = verb === "enable" && family.prepared?.outcomes.get(transition.alias)?.state !== "active";
408
+ const publication = await this.#publish(adapter, identity, nextState, {
409
+ failure: caller === "action" ? "reject" : "publish-unavailable",
410
+ retain: () => this.#host.retainWorkspace(identity.workspaceId),
411
+ gate: "none",
412
+ forceAlias: retry ? transition.alias : null,
413
+ });
414
+ const effectiveAfter = await this.#effective(adapter, identity, nextState);
415
+ return this.#mutationResult(adapter, transition, effectiveAfter, publication.outcomes);
416
+ }
417
+ // {§functionality-scope} — the Worker's own lane. State is read at each verb rather than held: the
418
+ // spawn reads the same row, and a Worker's row is written at its creation, so nothing in memory
419
+ // could be more current than the table.
420
+ async #invokeForWorker(adapter, verb, input, identity, workerId, caller) {
421
+ if (!this.#families.has(this.#key(identity.workspaceId, adapter.family)))
422
+ 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 });
423
+ const state = await this.#loadWorkerState(adapter, workerId);
424
+ const effective = await this.#effective(adapter, identity, state);
425
+ if (verb === "list") {
426
+ const prepared = await this.#prepareForWorker(adapter, identity, effective, "publish-unavailable");
427
+ await prepared.commit();
428
+ return { status: 200, body: Validator.assertFunctionalityListResult({
429
+ family: adapter.family,
430
+ definitions: [...effective.values()].map((definition) => this.#projection(definition, prepared.outcomes.get(definition.alias))),
431
+ }) };
432
+ }
433
+ const transition = await this.#transition(adapter, verb, input, identity, caller, state, effective);
434
+ const nextState = { version: STATE_VERSION, definitions: transition.definitions };
435
+ const effectiveAfter = await this.#effective(adapter, identity, nextState);
436
+ const prepared = await this.#prepareForWorker(adapter, identity, effectiveAfter, caller === "action" ? "reject" : "publish-unavailable");
437
+ try {
438
+ await this.#host.replaceWorkerModuleState(workerId, adapter.namespaceOwner, _a.#persisted(nextState));
439
+ }
440
+ catch (cause) {
441
+ return _a.#abort(prepared, cause);
442
+ }
443
+ await prepared.commit();
444
+ return this.#mutationResult(adapter, transition, effectiveAfter, prepared.outcomes);
445
+ }
446
+ // A worker-scoped family's preparation yields outcomes only. It holds no residency — no runtimes,
447
+ // documents or snapshot ({§module-workspace-residency}) — because its definitions are read at the
448
+ // spawn that uses them rather than leased and cooled; the coordinator enforces that here.
449
+ async #prepareForWorker(adapter, identity, effective, failureMode) {
450
+ const enabled = _a.#enabled(effective);
451
+ const prepared = await adapter.prepare({
452
+ workspaceId: identity.workspaceId, enabled, previous: null, failure: failureMode,
453
+ retain: () => this.#host.retainWorkspace(identity.workspaceId),
454
+ });
455
+ try {
456
+ _a.#checkOutcomes(adapter, enabled, prepared);
457
+ if ((prepared.runtimes?.length ?? 0) > 0 || prepared.documents.length > 0 || prepared.snapshot !== null) {
458
+ throw new Error(`${adapter.family} is worker-scoped and holds no residency, yet its preparation published runtimes, documents or a snapshot.`);
459
+ }
460
+ }
461
+ catch (cause) {
462
+ return _a.#abort(prepared, cause);
463
+ }
464
+ return prepared;
465
+ }
466
+ static #enabled(effective) {
350
467
  const enabled = new Map();
351
468
  for (const definition of effective.values()) {
352
469
  if (definition.enabled)
353
470
  enabled.set(definition.alias, definition.definition);
354
471
  }
472
+ return enabled;
473
+ }
474
+ static #checkOutcomes(adapter, enabled, prepared) {
475
+ for (const alias of enabled.keys()) {
476
+ if (!prepared.outcomes.has(alias))
477
+ throw new Error(`${adapter.family} preparation reported no outcome for enabled alias '${alias}'.`);
478
+ }
479
+ }
480
+ // {§functionality-publication} — prepare, publish runtimes and state in one
481
+ // host replacement, then commit; on any failure abort and keep the previous
482
+ // snapshot authoritative. An execution stream stays pending until its
483
+ // workspace publication completes; it never acknowledges a future commit.
484
+ async #publish(adapter, identity, nextState, options) {
485
+ const key = this.#key(identity.workspaceId, adapter.family);
486
+ const previous = this.#families.get(key)?.prepared ?? null;
487
+ // A worker-scoped family's workspace publication carries only its manager: what is enabled
488
+ // is decided per Worker, at each verb and each spawn ({§functionality-scope}).
489
+ const effective = adapter.scope === "worker" ? new Map() : await this.#effective(adapter, identity, nextState);
490
+ const enabled = _a.#enabled(effective);
355
491
  const prepared = await adapter.prepare({
356
492
  workspaceId: identity.workspaceId,
357
- workerId: identity.workerId,
358
493
  enabled,
359
494
  previous: previous?.snapshot ?? null,
360
495
  failure: options.failure,
361
496
  retain: options.retain,
362
497
  ...(options.forceAlias ? { force: options.forceAlias } : {}),
363
498
  });
364
- for (const alias of enabled.keys()) {
365
- if (!prepared.outcomes.has(alias))
366
- throw new Error(`${adapter.family} preparation reported no outcome for enabled alias '${alias}'.`);
367
- }
368
- const manager = {
369
- namespaceOwner: adapter.namespaceOwner,
370
- decl: functionalityRuntimeDecl(adapter.family, adapter.summary),
371
- executor: new FunctionalityManager({
372
- family: adapter.family, workspaceId: identity.workspaceId, workerId: identity.workerId, coordinator: this,
373
- definitionSchema: adapter.definitionSchema, example: adapter.example, discovery: adapter.discovery,
374
- }),
375
- availability: { available: true, detail: "Worker Functionality manager" },
376
- };
377
- const runtimes = [manager, ...prepared.runtimes];
378
- for (const runtime of prepared.runtimes) {
379
- if (runtime.namespaceOwner !== adapter.namespaceOwner) {
380
- await prepared.abort();
381
- throw new Error(`${adapter.family} prepared a runtime owned by '${runtime.namespaceOwner}' instead of '${adapter.namespaceOwner}'.`);
499
+ let runtimes;
500
+ try {
501
+ _a.#checkOutcomes(adapter, enabled, prepared);
502
+ for (const runtime of prepared.runtimes ?? []) {
503
+ if (runtime.namespaceOwner !== adapter.namespaceOwner) {
504
+ throw new Error(`${adapter.family} prepared a runtime owned by '${runtime.namespaceOwner}' instead of '${adapter.namespaceOwner}'.`);
505
+ }
382
506
  }
507
+ const manager = {
508
+ namespaceOwner: adapter.namespaceOwner,
509
+ decl: functionalityRuntimeDecl(adapter.family, adapter.summary, await this.#documentBody(adapter)),
510
+ executor: new FunctionalityManager({
511
+ family: adapter.family, workspaceId: identity.workspaceId, coordinator: this,
512
+ inputSchemas: this.#schemas.get(adapter.family), example: adapter.example, discovery: adapter.discovery,
513
+ }),
514
+ availability: { available: true, detail: "workspace Functionality manager" },
515
+ };
516
+ runtimes = [manager, ...(prepared.runtimes ?? [])];
517
+ }
518
+ catch (cause) {
519
+ return _a.#abort(prepared, cause);
383
520
  }
384
521
  const commit = async () => {
385
- // The host reconciles the Worker's documents inside the replacement,
386
- // so the snapshot it reads must already be the next one; a failed
387
- // replacement restores the previous snapshot before aborting.
388
522
  const before = this.#families.get(key);
389
- this.#families.set(key, { state: nextState, prepared });
390
523
  try {
391
- await this.#host.replaceWorkerCapabilities({
524
+ await this.#host.replaceWorkspaceCapabilities({
392
525
  workspaceId: identity.workspaceId,
393
- workerId: identity.workerId,
394
526
  namespaceOwner: adapter.namespaceOwner,
395
527
  state: _a.#persisted(nextState),
396
528
  runtimes,
397
- }, { gate: options.gate });
529
+ }, {
530
+ gate: options.gate,
531
+ publish: () => {
532
+ this.#families.set(key, { state: nextState, prepared });
533
+ return () => {
534
+ if (before === undefined)
535
+ this.#families.delete(key);
536
+ else
537
+ this.#families.set(key, before);
538
+ };
539
+ },
540
+ });
398
541
  }
399
542
  catch (cause) {
400
- if (before === undefined)
401
- this.#families.delete(key);
402
- else
403
- this.#families.set(key, before);
404
- await prepared.abort();
405
- throw cause;
543
+ return _a.#abort(prepared, cause);
406
544
  }
407
545
  await prepared.commit();
408
546
  };
409
- if (options.gate !== "wait") {
410
- await commit();
411
- return { outcomes: prepared.outcomes };
412
- }
413
- // Inside the caller's own turn the workspace is held by that turn:
414
- // publication queues behind it in this family's lane and settles
415
- // before the next packet. The caller learns the preparation outcome now.
416
- const pending = (this.#queues.get(key) ?? Promise.resolve()).catch(() => undefined).then(commit);
417
- this.#queues.set(key, pending.catch((cause) => {
418
- console.error(`[plurnk] ${adapter.family} publication for worker ${identity.workerId} failed at its turn boundary:`, cause);
419
- }));
547
+ await commit();
420
548
  return { outcomes: prepared.outcomes };
421
549
  }
550
+ static async #abort(prepared, cause) {
551
+ try {
552
+ await prepared.abort();
553
+ }
554
+ catch (abortCause) {
555
+ throw new AggregateError([cause, abortCause], "Functionality publication and candidate cleanup failed");
556
+ }
557
+ throw cause;
558
+ }
422
559
  }
423
560
  _a = Functionality;
424
561
  export default Functionality;