@plurnk/plurnk-service 1.29.0 → 3.0.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 (385) hide show
  1. package/.env.defaults +14 -33
  2. package/INSTALL.md +68 -17
  3. package/README.md +9 -7
  4. package/SPEC.md +503 -741
  5. package/dist/build-info.json +1 -1
  6. package/dist/content/body-preview.d.ts.map +1 -1
  7. package/dist/content/body-preview.js +11 -2
  8. package/dist/content/body-preview.js.map +1 -1
  9. package/dist/content/edit-receipt.d.ts +1 -1
  10. package/dist/content/edit-receipt.d.ts.map +1 -1
  11. package/dist/content/edit-receipt.js +1 -1
  12. package/dist/content/edit-receipt.js.map +1 -1
  13. package/dist/content/line-marker.js +1 -1
  14. package/dist/content/line-marker.js.map +1 -1
  15. package/dist/content/path-mimetype.js +1 -1
  16. package/dist/content/path-mimetype.js.map +1 -1
  17. package/dist/content/read-projector.d.ts.map +1 -1
  18. package/dist/content/read-projector.js +3 -12
  19. package/dist/content/read-projector.js.map +1 -1
  20. package/dist/core/AdministrativeLoop.d.ts +1 -1
  21. package/dist/core/AdministrativeLoop.d.ts.map +1 -1
  22. package/dist/core/AdministrativeLoop.js +2 -6
  23. package/dist/core/AdministrativeLoop.js.map +1 -1
  24. package/dist/core/AdmittedTurnExecutor.d.ts +4 -3
  25. package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
  26. package/dist/core/AdmittedTurnExecutor.js +19 -17
  27. package/dist/core/AdmittedTurnExecutor.js.map +1 -1
  28. package/dist/core/BareBatchRunner.d.ts +2 -2
  29. package/dist/core/BareBatchRunner.d.ts.map +1 -1
  30. package/dist/core/BareBatchRunner.js.map +1 -1
  31. package/dist/core/BudgetReadout.d.ts +1 -0
  32. package/dist/core/BudgetReadout.d.ts.map +1 -1
  33. package/dist/core/BudgetReadout.js +12 -0
  34. package/dist/core/BudgetReadout.js.map +1 -1
  35. package/dist/core/CapabilityPolicies.d.ts +2 -4
  36. package/dist/core/CapabilityPolicies.d.ts.map +1 -1
  37. package/dist/core/CapabilityPolicies.js +3 -23
  38. package/dist/core/CapabilityPolicies.js.map +1 -1
  39. package/dist/core/CapabilityResolver.d.ts +9 -2
  40. package/dist/core/CapabilityResolver.d.ts.map +1 -1
  41. package/dist/core/CapabilityResolver.js +34 -5
  42. package/dist/core/CapabilityResolver.js.map +1 -1
  43. package/dist/core/ChannelWrite.d.ts +0 -2
  44. package/dist/core/ChannelWrite.d.ts.map +1 -1
  45. package/dist/core/ChannelWrite.js.map +1 -1
  46. package/dist/core/ClientInteractions.d.ts +3 -2
  47. package/dist/core/ClientInteractions.d.ts.map +1 -1
  48. package/dist/core/ClientInteractions.js +21 -12
  49. package/dist/core/ClientInteractions.js.map +1 -1
  50. package/dist/core/ClientInteractions.sql +8 -2
  51. package/dist/core/CoreSchemeServices.d.ts +1 -0
  52. package/dist/core/CoreSchemeServices.d.ts.map +1 -1
  53. package/dist/core/CoreSchemeServices.js +1 -0
  54. package/dist/core/CoreSchemeServices.js.map +1 -1
  55. package/dist/core/DataStatementRunner.js +1 -1
  56. package/dist/core/DataStatementRunner.js.map +1 -1
  57. package/dist/core/Dispatcher.d.ts +3 -2
  58. package/dist/core/Dispatcher.d.ts.map +1 -1
  59. package/dist/core/Dispatcher.js +15 -21
  60. package/dist/core/Dispatcher.js.map +1 -1
  61. package/dist/core/Engine.d.ts +2 -2
  62. package/dist/core/Engine.d.ts.map +1 -1
  63. package/dist/core/Engine.js +4 -3
  64. package/dist/core/Engine.js.map +1 -1
  65. package/dist/core/EnvFlags.d.ts.map +1 -1
  66. package/dist/core/EnvFlags.js +4 -3
  67. package/dist/core/EnvFlags.js.map +1 -1
  68. package/dist/core/ExecutorRegistry.d.ts +3 -17
  69. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  70. package/dist/core/ExecutorRegistry.js +6 -6
  71. package/dist/core/ExecutorRegistry.js.map +1 -1
  72. package/dist/core/FabricatedLog.js +1 -1
  73. package/dist/core/FabricatedLog.js.map +1 -1
  74. package/dist/core/HostPaths.d.ts +2 -1
  75. package/dist/core/HostPaths.d.ts.map +1 -1
  76. package/dist/core/HostPaths.js +14 -2
  77. package/dist/core/HostPaths.js.map +1 -1
  78. package/dist/core/KillHandler.js +1 -1
  79. package/dist/core/KillHandler.js.map +1 -1
  80. package/dist/core/LogVisibility.d.ts.map +1 -1
  81. package/dist/core/LogVisibility.js +8 -17
  82. package/dist/core/LogVisibility.js.map +1 -1
  83. package/dist/core/LoopDriver.d.ts.map +1 -1
  84. package/dist/core/LoopDriver.js +4 -6
  85. package/dist/core/LoopDriver.js.map +1 -1
  86. package/dist/core/LoopLifecycle.d.ts.map +1 -1
  87. package/dist/core/LoopLifecycle.js +4 -9
  88. package/dist/core/LoopLifecycle.js.map +1 -1
  89. package/dist/core/LoopLifecycle.sql +6 -6
  90. package/dist/core/OperatorConfig.d.ts +1 -0
  91. package/dist/core/OperatorConfig.d.ts.map +1 -1
  92. package/dist/core/OperatorConfig.js +10 -2
  93. package/dist/core/OperatorConfig.js.map +1 -1
  94. package/dist/core/PacketBuilder.d.ts +5 -7
  95. package/dist/core/PacketBuilder.d.ts.map +1 -1
  96. package/dist/core/PacketBuilder.js +49 -119
  97. package/dist/core/PacketBuilder.js.map +1 -1
  98. package/dist/core/PacketBuilder.sql +15 -0
  99. package/dist/core/ProposalLifecycle.d.ts +1 -1
  100. package/dist/core/ProposalLifecycle.d.ts.map +1 -1
  101. package/dist/core/ProposalLifecycle.js +18 -20
  102. package/dist/core/ProposalLifecycle.js.map +1 -1
  103. package/dist/core/ProposalPolicies.d.ts +6 -0
  104. package/dist/core/ProposalPolicies.d.ts.map +1 -0
  105. package/dist/core/ProposalPolicies.js +28 -0
  106. package/dist/core/ProposalPolicies.js.map +1 -0
  107. package/dist/core/ProviderInstantiate.d.ts.map +1 -1
  108. package/dist/core/ProviderInstantiate.js +3 -4
  109. package/dist/core/ProviderInstantiate.js.map +1 -1
  110. package/dist/core/ResourceSelector.js +2 -2
  111. package/dist/core/ResourceSelector.js.map +1 -1
  112. package/dist/core/ResourceTransfers.js +3 -3
  113. package/dist/core/ResourceTransfers.js.map +1 -1
  114. package/dist/core/RuntimeWorker.sql +1 -2
  115. package/dist/core/SchemeRegistry.d.ts +5 -4
  116. package/dist/core/SchemeRegistry.d.ts.map +1 -1
  117. package/dist/core/SchemeRegistry.js +11 -12
  118. package/dist/core/SchemeRegistry.js.map +1 -1
  119. package/dist/core/ToolInputSchema.d.ts +1 -0
  120. package/dist/core/ToolInputSchema.d.ts.map +1 -1
  121. package/dist/core/ToolInputSchema.js +8 -2
  122. package/dist/core/ToolInputSchema.js.map +1 -1
  123. package/dist/core/ToolResources.d.ts +1 -0
  124. package/dist/core/ToolResources.d.ts.map +1 -1
  125. package/dist/core/ToolResources.js +12 -6
  126. package/dist/core/ToolResources.js.map +1 -1
  127. package/dist/core/Turn.js +1 -1
  128. package/dist/core/Turn.js.map +1 -1
  129. package/dist/core/TurnDispositionHandler.d.ts.map +1 -1
  130. package/dist/core/TurnDispositionHandler.js +1 -7
  131. package/dist/core/TurnDispositionHandler.js.map +1 -1
  132. package/dist/core/TurnMaterialization.js +1 -1
  133. package/dist/core/TurnMaterialization.js.map +1 -1
  134. package/dist/core/TurnOps.d.ts +1 -1
  135. package/dist/core/TurnOps.d.ts.map +1 -1
  136. package/dist/core/TurnOps.js +4 -12
  137. package/dist/core/TurnOps.js.map +1 -1
  138. package/dist/core/TurnRunner.d.ts +1 -2
  139. package/dist/core/TurnRunner.d.ts.map +1 -1
  140. package/dist/core/TurnRunner.js +85 -81
  141. package/dist/core/TurnRunner.js.map +1 -1
  142. package/dist/core/WorkerControlHandler.d.ts.map +1 -1
  143. package/dist/core/WorkerControlHandler.js +1 -8
  144. package/dist/core/WorkerControlHandler.js.map +1 -1
  145. package/dist/core/WorkerName.d.ts +1 -0
  146. package/dist/core/WorkerName.d.ts.map +1 -1
  147. package/dist/core/WorkerName.js +2 -0
  148. package/dist/core/WorkerName.js.map +1 -1
  149. package/dist/core/WorkerName.sql +2 -2
  150. package/dist/core/WorkerOwners.d.ts +13 -0
  151. package/dist/core/WorkerOwners.d.ts.map +1 -0
  152. package/dist/core/WorkerOwners.js +44 -0
  153. package/dist/core/WorkerOwners.js.map +1 -0
  154. package/dist/core/WorkerOwners.sql +55 -0
  155. package/dist/core/caps/DbNotifyCaps.js +2 -2
  156. package/dist/core/caps/DbNotifyCaps.js.map +1 -1
  157. package/dist/core/caps/DbProjectionCaps.js +1 -1
  158. package/dist/core/caps/DbProjectionCaps.js.map +1 -1
  159. package/dist/core/env-catalog.d.ts +3 -0
  160. package/dist/core/env-catalog.d.ts.map +1 -1
  161. package/dist/core/env-catalog.js +44 -9
  162. package/dist/core/env-catalog.js.map +1 -1
  163. package/dist/core/env-defaults.d.ts +2 -1
  164. package/dist/core/env-defaults.d.ts.map +1 -1
  165. package/dist/core/env-defaults.js +17 -9
  166. package/dist/core/env-defaults.js.map +1 -1
  167. package/dist/core/fork.sql +3 -4
  168. package/dist/core/packet-inject.js +0 -2
  169. package/dist/core/packet-inject.js.map +1 -1
  170. package/dist/core/packet-wire.d.ts +2 -11
  171. package/dist/core/packet-wire.d.ts.map +1 -1
  172. package/dist/core/packet-wire.js +31 -111
  173. package/dist/core/packet-wire.js.map +1 -1
  174. package/dist/core/plurnk-uri.d.ts +1 -1
  175. package/dist/core/plurnk-uri.d.ts.map +1 -1
  176. package/dist/core/plurnk-uri.js +4 -4
  177. package/dist/core/plurnk-uri.js.map +1 -1
  178. package/dist/core/scheme-types.d.ts +2 -1
  179. package/dist/core/scheme-types.d.ts.map +1 -1
  180. package/dist/core/types.d.ts +0 -1
  181. package/dist/core/types.d.ts.map +1 -1
  182. package/dist/core/unregistered-scheme.d.ts +1 -3
  183. package/dist/core/unregistered-scheme.d.ts.map +1 -1
  184. package/dist/core/unregistered-scheme.js +3 -11
  185. package/dist/core/unregistered-scheme.js.map +1 -1
  186. package/dist/evidence/EvidenceReader.d.ts +14 -0
  187. package/dist/evidence/EvidenceReader.d.ts.map +1 -0
  188. package/dist/evidence/EvidenceReader.js +137 -0
  189. package/dist/evidence/EvidenceReader.js.map +1 -0
  190. package/dist/{digest → evidence}/digest.sql +1 -2
  191. package/dist/schemes/EffectPolicy.d.ts.map +1 -1
  192. package/dist/schemes/EffectPolicy.js +1 -10
  193. package/dist/schemes/EffectPolicy.js.map +1 -1
  194. package/dist/schemes/Exec.d.ts.map +1 -1
  195. package/dist/schemes/Exec.js +19 -26
  196. package/dist/schemes/Exec.js.map +1 -1
  197. package/dist/schemes/ExecOutputScheme.d.ts +1 -1
  198. package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
  199. package/dist/schemes/File.d.ts.map +1 -1
  200. package/dist/schemes/File.js +11 -17
  201. package/dist/schemes/File.js.map +1 -1
  202. package/dist/schemes/Log.d.ts.map +1 -1
  203. package/dist/schemes/Log.js +14 -11
  204. package/dist/schemes/Log.js.map +1 -1
  205. package/dist/schemes/QuestionTool.d.ts.map +1 -1
  206. package/dist/schemes/QuestionTool.js +1 -3
  207. package/dist/schemes/QuestionTool.js.map +1 -1
  208. package/dist/schemes/{Skill.d.ts → ResourceTreeScheme.d.ts} +5 -6
  209. package/dist/schemes/ResourceTreeScheme.d.ts.map +1 -0
  210. package/dist/schemes/{Skill.js → ResourceTreeScheme.js} +63 -43
  211. package/dist/schemes/ResourceTreeScheme.js.map +1 -0
  212. package/dist/schemes/Worker.d.ts.map +1 -1
  213. package/dist/schemes/Worker.js +7 -9
  214. package/dist/schemes/Worker.js.map +1 -1
  215. package/dist/schemes/_entry-crud.sql +1 -1
  216. package/dist/schemes/_entry-find.js +2 -2
  217. package/dist/schemes/_entry-find.js.map +1 -1
  218. package/dist/schemes/_entry-find.sql +1 -1
  219. package/dist/schemes/_entry-fts.d.ts.map +1 -1
  220. package/dist/schemes/_entry-fts.js +3 -9
  221. package/dist/schemes/_entry-fts.js.map +1 -1
  222. package/dist/schemes/_entry-manifest.js +1 -1
  223. package/dist/schemes/_entry-manifest.js.map +1 -1
  224. package/dist/schemes/_entry-ops.js +1 -1
  225. package/dist/schemes/_entry-ops.js.map +1 -1
  226. package/dist/server/AgentRoots.d.ts +2 -1
  227. package/dist/server/AgentRoots.d.ts.map +1 -1
  228. package/dist/server/AgentRoots.js +13 -10
  229. package/dist/server/AgentRoots.js.map +1 -1
  230. package/dist/server/ConfigurationDiagnostics.d.ts +5 -3
  231. package/dist/server/ConfigurationDiagnostics.d.ts.map +1 -1
  232. package/dist/server/ConfigurationDiagnostics.js +24 -8
  233. package/dist/server/ConfigurationDiagnostics.js.map +1 -1
  234. package/dist/server/Daemon.d.ts +25 -16
  235. package/dist/server/Daemon.d.ts.map +1 -1
  236. package/dist/server/Daemon.js +137 -96
  237. package/dist/server/Daemon.js.map +1 -1
  238. package/dist/server/DrainSupervisor.d.ts +1 -4
  239. package/dist/server/DrainSupervisor.d.ts.map +1 -1
  240. package/dist/server/DrainSupervisor.js +1 -11
  241. package/dist/server/DrainSupervisor.js.map +1 -1
  242. package/dist/server/EnvFunctionality.d.ts +3 -5
  243. package/dist/server/EnvFunctionality.d.ts.map +1 -1
  244. package/dist/server/EnvFunctionality.js +5 -7
  245. package/dist/server/EnvFunctionality.js.map +1 -1
  246. package/dist/server/Functionality.d.ts +3 -2
  247. package/dist/server/Functionality.d.ts.map +1 -1
  248. package/dist/server/Functionality.js +43 -14
  249. package/dist/server/Functionality.js.map +1 -1
  250. package/dist/server/FunctionalityManager.d.ts +3 -4
  251. package/dist/server/FunctionalityManager.d.ts.map +1 -1
  252. package/dist/server/FunctionalityManager.js +17 -9
  253. package/dist/server/FunctionalityManager.js.map +1 -1
  254. package/dist/server/HttpListener.d.ts +2 -0
  255. package/dist/server/HttpListener.d.ts.map +1 -1
  256. package/dist/server/HttpListener.js +23 -9
  257. package/dist/server/HttpListener.js.map +1 -1
  258. package/dist/server/MembersFunctionality.d.ts +2 -5
  259. package/dist/server/MembersFunctionality.d.ts.map +1 -1
  260. package/dist/server/MembersFunctionality.js +5 -3
  261. package/dist/server/MembersFunctionality.js.map +1 -1
  262. package/dist/server/ModuleHost.d.ts +33 -0
  263. package/dist/server/ModuleHost.d.ts.map +1 -0
  264. package/dist/server/ModuleHost.js +2 -0
  265. package/dist/server/ModuleHost.js.map +1 -0
  266. package/dist/server/PlurnkSkill.d.ts.map +1 -1
  267. package/dist/server/PlurnkSkill.js +54 -6
  268. package/dist/server/PlurnkSkill.js.map +1 -1
  269. package/dist/server/ServiceModules.d.ts +0 -2
  270. package/dist/server/ServiceModules.d.ts.map +1 -1
  271. package/dist/server/ServiceModules.js +5 -9
  272. package/dist/server/ServiceModules.js.map +1 -1
  273. package/dist/server/WorkspacePlugins.d.ts +2 -11
  274. package/dist/server/WorkspacePlugins.d.ts.map +1 -1
  275. package/dist/server/WorkspacePlugins.js.map +1 -1
  276. package/dist/server/WorkspaceResidency.d.ts +2 -1
  277. package/dist/server/WorkspaceResidency.d.ts.map +1 -1
  278. package/dist/server/WorkspaceStorage.d.ts.map +1 -1
  279. package/dist/server/WorkspaceStorage.js +7 -4
  280. package/dist/server/WorkspaceStorage.js.map +1 -1
  281. package/dist/server/client-input.d.ts +1 -2
  282. package/dist/server/client-input.d.ts.map +1 -1
  283. package/dist/server/client-input.js +2 -13
  284. package/dist/server/client-input.js.map +1 -1
  285. package/dist/server/dispatch-as-plurnk.js +1 -1
  286. package/dist/server/dispatch-as-plurnk.js.map +1 -1
  287. package/dist/server/drain.sql +6 -6
  288. package/dist/server/envelope.d.ts +2 -1
  289. package/dist/server/envelope.d.ts.map +1 -1
  290. package/dist/server/envelope.js +7 -17
  291. package/dist/server/envelope.js.map +1 -1
  292. package/dist/server/envelope.sql +5 -5
  293. package/dist/server/module-discovery.d.ts +11 -3
  294. package/dist/server/module-discovery.d.ts.map +1 -1
  295. package/dist/server/module-discovery.js +32 -18
  296. package/dist/server/module-discovery.js.map +1 -1
  297. package/dist/server/seam-proposal-list.sql +6 -4
  298. package/dist/service.d.ts.map +1 -1
  299. package/dist/service.js +58 -65
  300. package/dist/service.js.map +1 -1
  301. package/migrations/003_loops.sql +2 -2
  302. package/migrations/006_log.sql +1 -1
  303. package/migrations/016_selection_statements.sql +44 -0
  304. package/migrations/017_skills_module.sql +6 -0
  305. package/migrations/018_worker_owners.sql +102 -0
  306. package/migrations/019_interactive_owners.sql +6 -0
  307. package/migrations/020_log_projection.sql +143 -0
  308. package/package.json +71 -76
  309. package/dist/core/EmissionHead.d.ts +0 -8
  310. package/dist/core/EmissionHead.d.ts.map +0 -1
  311. package/dist/core/EmissionHead.js +0 -29
  312. package/dist/core/EmissionHead.js.map +0 -1
  313. package/dist/core/LegacyHome.d.ts +0 -10
  314. package/dist/core/LegacyHome.d.ts.map +0 -1
  315. package/dist/core/LegacyHome.js +0 -170
  316. package/dist/core/LegacyHome.js.map +0 -1
  317. package/dist/core/LoopPolicies.d.ts +0 -7
  318. package/dist/core/LoopPolicies.d.ts.map +0 -1
  319. package/dist/core/LoopPolicies.js +0 -42
  320. package/dist/core/LoopPolicies.js.map +0 -1
  321. package/dist/core/LoopPolicyReader.d.ts +0 -7
  322. package/dist/core/LoopPolicyReader.d.ts.map +0 -1
  323. package/dist/core/LoopPolicyReader.js +0 -33
  324. package/dist/core/LoopPolicyReader.js.map +0 -1
  325. package/dist/core/LoopPolicyReader.sql +0 -6
  326. package/dist/core/operation-target-groups.d.ts +0 -3
  327. package/dist/core/operation-target-groups.d.ts.map +0 -1
  328. package/dist/core/operation-target-groups.js +0 -77
  329. package/dist/core/operation-target-groups.js.map +0 -1
  330. package/dist/digest/Digest.d.ts +0 -10
  331. package/dist/digest/Digest.d.ts.map +0 -1
  332. package/dist/digest/Digest.js +0 -252
  333. package/dist/digest/Digest.js.map +0 -1
  334. package/dist/digest/DigestEvidence.d.ts +0 -11
  335. package/dist/digest/DigestEvidence.d.ts.map +0 -1
  336. package/dist/digest/DigestEvidence.js +0 -66
  337. package/dist/digest/DigestEvidence.js.map +0 -1
  338. package/dist/digest/DigestRender.d.ts +0 -18
  339. package/dist/digest/DigestRender.d.ts.map +0 -1
  340. package/dist/digest/DigestRender.js +0 -1044
  341. package/dist/digest/DigestRender.js.map +0 -1
  342. package/dist/digest/DigestRequiem.d.ts +0 -13
  343. package/dist/digest/DigestRequiem.d.ts.map +0 -1
  344. package/dist/digest/DigestRequiem.js +0 -337
  345. package/dist/digest/DigestRequiem.js.map +0 -1
  346. package/dist/digest/digest-db.d.ts +0 -3
  347. package/dist/digest/digest-db.d.ts.map +0 -1
  348. package/dist/digest/digest-db.js +0 -68
  349. package/dist/digest/digest-db.js.map +0 -1
  350. package/dist/digest/digest-paths.d.ts +0 -6
  351. package/dist/digest/digest-paths.d.ts.map +0 -1
  352. package/dist/digest/digest-paths.js +0 -14
  353. package/dist/digest/digest-paths.js.map +0 -1
  354. package/dist/digest/digest-rows.d.ts +0 -346
  355. package/dist/digest/digest-rows.d.ts.map +0 -1
  356. package/dist/digest/digest-rows.js +0 -2
  357. package/dist/digest/digest-rows.js.map +0 -1
  358. package/dist/index.d.ts +0 -15
  359. package/dist/index.d.ts.map +0 -1
  360. package/dist/index.js +0 -23
  361. package/dist/index.js.map +0 -1
  362. package/dist/schemes/Skill.d.ts.map +0 -1
  363. package/dist/schemes/Skill.js.map +0 -1
  364. package/dist/server/DaemonModule.d.ts +0 -101
  365. package/dist/server/DaemonModule.d.ts.map +0 -1
  366. package/dist/server/DaemonModule.js +0 -2
  367. package/dist/server/DaemonModule.js.map +0 -1
  368. package/dist/server/SkillSource.d.ts +0 -37
  369. package/dist/server/SkillSource.d.ts.map +0 -1
  370. package/dist/server/SkillSource.js +0 -267
  371. package/dist/server/SkillSource.js.map +0 -1
  372. package/dist/server/SkillsFunctionality.d.ts +0 -45
  373. package/dist/server/SkillsFunctionality.d.ts.map +0 -1
  374. package/dist/server/SkillsFunctionality.js +0 -405
  375. package/dist/server/SkillsFunctionality.js.map +0 -1
  376. package/dist/server/skills-problems.d.ts +0 -8
  377. package/dist/server/skills-problems.d.ts.map +0 -1
  378. package/dist/server/skills-problems.js +0 -18
  379. package/dist/server/skills-problems.js.map +0 -1
  380. package/dist/share/Share.d.ts +0 -15
  381. package/dist/share/Share.d.ts.map +0 -1
  382. package/dist/share/Share.js +0 -106
  383. package/dist/share/Share.js.map +0 -1
  384. package/dist/share/share.sql +0 -6
  385. package/docs/skills.md +0 -73
@@ -1,8 +1,9 @@
1
1
  // Top-level daemon orchestrator. Owns the DB connection, engine, registries,
2
- // the transport-free plugin-module seam ({§rpc}).
2
+ // the transport-free module seam ({§rpc}).
3
3
  import { readFile } from "node:fs/promises";
4
4
  import { resolve, dirname } from "node:path";
5
- import Share from "../share/Share.js";
5
+ import { Share } from "@plurnk/plurnk-digest";
6
+ import EvidenceReader from "@plurnk/plurnk-service/evidence";
6
7
  import Paths from "../Paths.js";
7
8
  import Engine from "../core/Engine.js";
8
9
  import ExecutorRegistry from "../core/ExecutorRegistry.js";
@@ -16,20 +17,18 @@ import EffectPolicy from "../schemes/EffectPolicy.js";
16
17
  import QuestionTool, { questionRuntimeDecl } from "../schemes/QuestionTool.js";
17
18
  import DrainSupervisor from "./DrainSupervisor.js";
18
19
  import Retention, { retentionPolicy } from "./Retention.js";
19
- import PacketBuilder from "../core/PacketBuilder.js";
20
20
  import TurnDispositionHandler from "../core/TurnDispositionHandler.js";
21
21
  import { Validator } from "@plurnk/plurnk-contracts";
22
22
  import LogEntry from "./logEntry.js";
23
+ import HttpListener from "./HttpListener.js";
23
24
  import Envelope, { projectWorkerRow } from "./envelope.js";
24
25
  import ClientInput from "./client-input.js";
25
26
  import Turn from "../core/Turn.js";
26
- import { expandTargetGroup } from "../core/operation-target-groups.js";
27
- import SkillsFunctionality from "./SkillsFunctionality.js";
28
27
  import WorkspacePlugins from "./WorkspacePlugins.js";
29
- import { agentRootScopes, configurationDirectories } from "./AgentRoots.js";
28
+ import { agentRootScopes, workspacePaths } from "./AgentRoots.js";
30
29
  import ExecEnv from "../schemes/exec-env.js";
31
30
  import PlurnkSkill from "./PlurnkSkill.js";
32
- import Skill from "../schemes/Skill.js";
31
+ import ResourceTreeScheme from "../schemes/ResourceTreeScheme.js";
33
32
  import MembersFunctionality, { modelScope, serviceMembers } from "./MembersFunctionality.js";
34
33
  import FileCreationPolicy from "../core/file-creation-policy.js";
35
34
  import EnvFunctionality, { ENV_OWNER } from "./EnvFunctionality.js";
@@ -39,8 +38,9 @@ import Fork from "../core/fork.js";
39
38
  import WorkerControlAddress from "../core/WorkerControlAddress.js";
40
39
  import LoopLifecycle from "../core/LoopLifecycle.js";
41
40
  import { ConfigurationError, Knob } from "@plurnk/plurnk-meta";
42
- import LoopPolicies from "../core/LoopPolicies.js";
43
- import LoopPolicyReader from "../core/LoopPolicyReader.js";
41
+ import ProposalPolicies from "../core/ProposalPolicies.js";
42
+ import WorkerOwners from "../core/WorkerOwners.js";
43
+ import RuntimeWorker from "../core/RuntimeWorker.js";
44
44
  import { contentWeight } from "../core/content-weight.js";
45
45
  import MessageResources from "../core/MessageResources.js";
46
46
  import { parseAliasesFromEnv, resolveActiveRoute } from "@plurnk/plurnk-providers";
@@ -69,15 +69,13 @@ export default class Daemon {
69
69
  static validateConfiguration() {
70
70
  FileCreationPolicy.serviceScope();
71
71
  EffectPolicy.validateConfiguration();
72
- LoopPolicies.validateConfiguration();
72
+ ProposalPolicies.read();
73
73
  TurnDispositionHandler.configuredWaitSeconds();
74
74
  retentionPolicy();
75
- PacketBuilder.validateConfiguration();
76
75
  Exec.validateConfiguration();
77
76
  ExecutorRegistry.validateConfiguration();
78
77
  }
79
78
  static validateWorkspaceConfiguration() {
80
- SkillsFunctionality.validateConfiguration();
81
79
  agentRootScopes();
82
80
  serviceMembers();
83
81
  modelScope();
@@ -100,13 +98,15 @@ export default class Daemon {
100
98
  #discoveryCwd;
101
99
  #started = false; // {§module-lifecycle}: one discovery/module boot; no listener
102
100
  #modules = [];
101
+ // {§module-http-mounts} — each claimed prefix's owner, and the claims mounted at start.
102
+ #mountClaims = new Map();
103
+ #mounted = new Set();
103
104
  #moduleLifetimes = [];
104
105
  #moduleActions = new Map();
105
106
  #residency;
106
107
  #functionality;
107
108
  // {§retention-policy} — the operator's retention, run on a cadence and at shutdown.
108
109
  #retention = null;
109
- #skills;
110
110
  #plugins;
111
111
  #members;
112
112
  // {§methods-event-subscribe} — the broadcast's in-process event source. A transport
@@ -127,9 +127,9 @@ export default class Daemon {
127
127
  this.#lifecycle = new LoopLifecycle(db);
128
128
  this.#schemes = schemes ?? new SchemeRegistry();
129
129
  this.#provider = provider ?? null;
130
- // Plugin discovery resolves from the SERVICE's node_modules (its exec/scheme/mimetype
130
+ // Extension discovery resolves from the SERVICE's node_modules (its exec/scheme/mimetype
131
131
  // deps), NOT process.cwd() — else a globally-installed daemon started from a project dir
132
- // finds no plugins. The bin passes the package-relative path; cwd default holds for
132
+ // finds no extensions. The bin passes the package-relative path; cwd default holds for
133
133
  // in-repo tests. discover() takes a cwd and joins node_modules, so derive the parent.
134
134
  this.#nodeModulesPath = nodeModulesPath ?? resolve(process.cwd(), "node_modules");
135
135
  this.#discoveryCwd = dirname(this.#nodeModulesPath);
@@ -174,20 +174,7 @@ export default class Daemon {
174
174
  retainWorkspace: (workspaceId) => this.#residency.retain(workspaceId),
175
175
  preparationChanged: (workspaceId, preparation) => this.#broadcast({ workspaceId }, "workspace/preparation", { workspaceId, preparation })
176
176
  });
177
- // {§skills-functionality} — Core's own family: standard Agent Skills.
178
177
  this.#plugins = new WorkspacePlugins({ db, hostPaths, nodeModules: this.#nodeModulesPath });
179
- this.#skills = new SkillsFunctionality({
180
- db,
181
- plugins: this.#plugins,
182
- storage: this.#storage,
183
- hostPaths,
184
- provided: async () => {
185
- const tree = await PlurnkSkill.load(this.#nodeModulesPath);
186
- return new Map([[tree.document.name, tree]]);
187
- },
188
- });
189
- this.#skills.attach(this.#functionality.register(this.#skills));
190
- this.#schemes.register("skill", new Skill((workspaceId) => this.#skills.trees(workspaceId)));
191
178
  // {§members-functionality} — Core's own family: file membership on the same surface.
192
179
  this.#members = new MembersFunctionality({ db, engine: () => this.#engine });
193
180
  this.#functionality.register(this.#members);
@@ -210,7 +197,7 @@ export default class Daemon {
210
197
  // daemon owns provider + the law-file system prompt; the worker scheme
211
198
  // handler carries neither. Fire-and-forget: the returned drain runs
212
199
  // independently (the sister is its own worker). {§machine-processes}
213
- injectWorker: async ({ workspaceId, workerId, sourceLoopId, prompt, freshLoopPolicy, spawn, environment, attachments }) => {
200
+ injectWorker: async ({ workspaceId, workerId, sourceLoopId, prompt, spawn, environment, attachments }) => {
214
201
  await this.#assertModelWorker(workspaceId, workerId);
215
202
  const sender = await this.#db.drain_message_source.get({ loop_id: sourceLoopId });
216
203
  if (sender === undefined || sender.workspace_id !== workspaceId) {
@@ -267,8 +254,7 @@ export default class Daemon {
267
254
  providerSpec,
268
255
  effort,
269
256
  childProviderSpec,
270
- systemPrompt,
271
- ...(freshLoopPolicy === undefined ? {} : { freshLoopPolicy })
257
+ systemPrompt
272
258
  });
273
259
  return { action, loopId };
274
260
  },
@@ -292,8 +278,7 @@ export default class Daemon {
292
278
  db,
293
279
  lifecycle: this.#lifecycle,
294
280
  injectPrompt: (loopId, prompt, openPaths, source, evidence, messageAddress) => this.#engine.injectIntoLoop(loopId, prompt, openPaths, source, evidence, messageAddress),
295
- assertInjectionCompatibility: async ({ workerId, loopId, providerSpec, providerSpecExplicit, effort, childProviderSpec, turnCeiling, policy }) => {
296
- await this.#assertFoldPosture(workerId, policy, loopId);
281
+ assertInjectionCompatibility: async ({ workerId, loopId, providerSpec, providerSpecExplicit, effort, childProviderSpec, turnCeiling }) => {
297
282
  // An omitted selector keeps the loop's durable provider; only an
298
283
  // explicit selection is checked against it (a deliberate switch).
299
284
  if (providerSpecExplicit !== false) {
@@ -371,6 +356,18 @@ export default class Daemon {
371
356
  this.#eventSubscribers.add(handler);
372
357
  return () => { this.#eventSubscribers.delete(handler); };
373
358
  }
359
+ async registerWorkerOwner(workspaceId, owner) {
360
+ const id = ClientInput.assertId("registerWorkerOwner", "workspaceId", workspaceId);
361
+ await WorkerOwners.register(this.#db, id, owner);
362
+ }
363
+ async claimWorkerOwner(args) {
364
+ const workspaceId = ClientInput.assertId("claimWorkerOwner", "workspaceId", args.workspaceId);
365
+ const workerId = ClientInput.assertId("claimWorkerOwner", "workerId", args.workerId);
366
+ const worker = await this.readWorker({ workspaceId, identity: { id: workerId } });
367
+ if (worker === null)
368
+ throw daemonFailure("worker:owner", "worker-not-found", 404, `Worker ${workerId} does not belong to workspace ${workspaceId}.`, { workspaceId, workerId });
369
+ return WorkerOwners.claim(this.#db, workspaceId, workerId, args.owner);
370
+ }
374
371
  // {§methods-proposal-resolve} — proposal HITL. A transport module reads the stopped-world
375
372
  // proposals for a workspace (rendering each as a TOOL_CALL) and feeds back the human's decision. The
376
373
  // gate, validation, and applyResolution stay core (Engine.resolveProposal); the seam is the read +
@@ -379,23 +376,29 @@ export default class Daemon {
379
376
  const checkedWorkspaceId = ClientInput.assertId("pendingProposals", "workspaceId", workspaceId);
380
377
  return this.#engine.pendingProposals(checkedWorkspaceId);
381
378
  }
382
- resolveProposal(logEntryId, resolution) {
379
+ async resolveProposal(logEntryId, resolution, owner) {
383
380
  const checkedLogEntryId = ClientInput.assertId("resolveProposal", "logEntryId", logEntryId);
384
381
  const checkedResolution = ClientInput.assertProposalResolution("resolveProposal", resolution);
382
+ const workspaceId = ClientInput.assertId("resolveProposal", "workspaceId", owner.workspaceId);
383
+ const pending = await this.#db.worker_owner_for_proposal.get({ log_entry_id: checkedLogEntryId });
384
+ if (pending !== undefined && (pending.workspaceId !== workspaceId || pending.owner !== owner.address)) {
385
+ throw daemonFailure("proposal:resolution", "owner-mismatch", 403, "Only the worker's owner may resolve this proposal.", { logEntryId: checkedLogEntryId });
386
+ }
385
387
  this.#engine.resolveProposal(checkedLogEntryId, checkedResolution);
386
388
  }
387
389
  async pendingClientInteractions(workspaceId) {
388
390
  const checkedWorkspaceId = ClientInput.assertId("pendingClientInteractions", "workspaceId", workspaceId);
389
391
  return this.#engine.pendingClientInteractions(checkedWorkspaceId);
390
392
  }
391
- async resolveClientInteraction(interactionId, resolution, message) {
393
+ async resolveClientInteraction(interactionId, resolution, respondent, message) {
392
394
  const checkedInteractionId = ClientInput.assertId("resolveClientInteraction", "interactionId", interactionId);
393
395
  const checkedResolution = ClientInput.assertClientInteractionResolution("resolveClientInteraction", resolution);
394
396
  if (message !== undefined) {
395
397
  ClientInput.assertPrompt("resolveClientInteraction", message.body);
396
398
  ClientInput.assertOptionalSource("resolveClientInteraction", message.source);
397
399
  }
398
- await this.#engine.resolveClientInteraction(checkedInteractionId, checkedResolution, message);
400
+ ClientInput.assertId("resolveClientInteraction", "workspaceId", respondent.workspaceId);
401
+ await this.#engine.resolveClientInteraction(checkedInteractionId, checkedResolution, respondent, message);
399
402
  }
400
403
  async #prepareMessage(workspaceId, workerId, body, attachments = [], envelope) {
401
404
  const published = await MessageResources.publish(body, attachments, {
@@ -427,9 +430,6 @@ export default class Daemon {
427
430
  const openPaths = ClientInput.assertOpenPaths("runLoop", args.openPaths);
428
431
  const selector = ClientInput.assertOptionalSelector("runLoop", "selector", args.selector);
429
432
  const childSelector = ClientInput.assertOptionalChildSelector("runLoop", args.childSelector);
430
- const policy = args.policy === undefined
431
- ? undefined
432
- : ClientInput.normalizeLoopPolicy("runLoop", args.policy);
433
433
  // {§worker-model-selection} — the worker owns the model. An explicit selector
434
434
  // persists onto the worker; an omitted selector resolves the worker's durable model
435
435
  // (seeded once from the daemon default). The loop then snapshots the resolved route.
@@ -464,7 +464,6 @@ export default class Daemon {
464
464
  evidence: delivered.evidence,
465
465
  ...(messageAddress === undefined ? {} : { messageAddress }),
466
466
  ...(source === undefined ? {} : { source }),
467
- ...(policy !== undefined ? { policy } : {}),
468
467
  ...(openPaths !== undefined ? { openPaths } : {}),
469
468
  turnCeiling,
470
469
  providerSpec: selection,
@@ -572,6 +571,13 @@ export default class Daemon {
572
571
  const checked = ClientInput.assertId("worker.ensure-model", "workspaceId", workspaceId);
573
572
  return await Envelope.ensureModelWorker(this.#db, checked);
574
573
  }
574
+ async ensureRuntimeWorker(workspaceId) {
575
+ const checked = ClientInput.assertId("worker.ensure-runtime", "workspaceId", workspaceId);
576
+ if (await this.#db.envelope_get_workspace.get({ id: checked }) === undefined) {
577
+ throw daemonFailure("worker:owner", "workspace-not-found", 404, `Workspace ${checked} does not exist.`);
578
+ }
579
+ return RuntimeWorker.ensure(this.#db, checked);
580
+ }
575
581
  async readWorkspaceCapabilities(args) {
576
582
  const workspaceId = ClientInput.assertId("workspace.capabilities.get", "workspaceId", args.workspaceId);
577
583
  return this.#engine.capabilityProjection(workspaceId);
@@ -769,14 +775,7 @@ export default class Daemon {
769
775
  try {
770
776
  const clientLoopId = await Envelope.ensureClientLoop(this.#db, workerId);
771
777
  try {
772
- // {§safe-uri-target-groups} — a client-authored group runs member by member on the one seam
773
- // result: the first failure, otherwise the last outcome.
774
- let result;
775
- for (const member of expandTargetGroup(statement)) {
776
- const outcome = await this.#dispatchClientStatement({ workspaceId, workerId, loopId: clientLoopId, statement: member });
777
- if (result === undefined || result.status < 400)
778
- result = outcome;
779
- }
778
+ const result = await this.#dispatchClientStatement({ workspaceId, workerId, loopId: clientLoopId, statement });
780
779
  await Envelope.closeClientLoop(this.#db, clientLoopId, { status: 200 });
781
780
  return result;
782
781
  }
@@ -813,8 +812,7 @@ export default class Daemon {
813
812
  const clientLoopId = await Envelope.ensureClientLoop(this.#db, workerId);
814
813
  try {
815
814
  const results = [];
816
- // {§safe-uri-target-groups} — a client-authored group is one result per member.
817
- for (const statement of statements.flatMap(expandTargetGroup)) {
815
+ for (const statement of statements) {
818
816
  results.push(await this.#dispatchClientStatement({ workspaceId, workerId, loopId: clientLoopId, statement }));
819
817
  }
820
818
  await Envelope.closeClientLoop(this.#db, clientLoopId, { status: 200 });
@@ -874,7 +872,7 @@ export default class Daemon {
874
872
  // full scheme resolver and return its content, writing NO log row — the client's out-of-band
875
873
  // inspection primitive (the module rewrites LOOK→READ and parses at its edge, exactly like
876
874
  // dispatchClientAction). Its closed observation segment supplies the numeric loop coordinate
877
- // required by plugin context and relative log:/// addresses without impersonating an active
875
+ // required by extension context and relative log:/// addresses without impersonating an active
878
876
  // client lifecycle. It creates no turn or log row. Engine.look enforces READ-only.
879
877
  // {§op-look} — the segment is the acting worker's; the READ resolves as the perspective worker.
880
878
  async look(args) {
@@ -1034,7 +1032,7 @@ export default class Daemon {
1034
1032
  const checkedFolder = ClientInput.assertShareFolder("workspace.share", folder);
1035
1033
  if (this.#dbPath === undefined)
1036
1034
  throw new Error("share: this daemon was started without its database path");
1037
- return await Share.write({ dbPath: this.#dbPath, folder: checkedFolder, workspaceId: checkedWorkspaceId });
1035
+ return await Share.write({ openEvidence: EvidenceReader.open, dbPath: this.#dbPath, folder: checkedFolder, workspaceId: checkedWorkspaceId });
1038
1036
  }
1039
1037
  listPrompts(workspaceId, limit, workerId) {
1040
1038
  const checkedWorkspaceId = ClientInput.assertId("workspace.prompts", "workspaceId", workspaceId);
@@ -1082,7 +1080,7 @@ export default class Daemon {
1082
1080
  throw new Error("ClientInput.assertOptionalName accepted a required name as undefined");
1083
1081
  return { id: checkedWorkspaceId, name: await Envelope.updateWorkspaceName(this.#db, checkedWorkspaceId, checkedName) };
1084
1082
  }
1085
- // {§methods-conversation-worker}: a fresh conversation is a model-origin root worker with an empty private log.
1083
+ // {§methods-conversation-worker}: a fresh conversation is a model-origin worker with an empty private log.
1086
1084
  // AG-UI threads map to these workers while the workspace world remains shared ({§machine-processes}).
1087
1085
  async createConversationWorker(args) {
1088
1086
  const workspaceId = ClientInput.assertId("worker.create", "workspaceId", args.workspaceId);
@@ -1091,13 +1089,24 @@ export default class Daemon {
1091
1089
  if (workspace === undefined) {
1092
1090
  throw daemonFailure("daemon:workspace", "workspace-not-found", 404, `Workspace ${workspaceId} does not exist.`, { workspaceId });
1093
1091
  }
1092
+ const parentWorkerId = args.parentWorkerId === undefined ? undefined : ClientInput.assertId("worker.create", "parentWorkerId", args.parentWorkerId);
1093
+ if (parentWorkerId !== undefined) {
1094
+ if (args.owner !== undefined)
1095
+ throw daemonFailure("worker:owner", "child-owner-inherited", 400, "A child inherits its parent's owner.", { workspaceId, parentWorkerId });
1096
+ const parent = await this.readWorker({ workspaceId, identity: { id: parentWorkerId } });
1097
+ if (parent === null)
1098
+ throw daemonFailure("worker:owner", "worker-not-found", 404, `Parent worker ${parentWorkerId} does not belong to workspace ${workspaceId}.`, { workspaceId, parentWorkerId });
1099
+ }
1100
+ else if (args.owner !== undefined) {
1101
+ await WorkerOwners.registered(this.#db, workspaceId, args.owner);
1102
+ }
1094
1103
  if (name !== undefined) {
1095
1104
  const taken = await this.#db.envelope_get_worker_by_name.get({ workspace_id: workspaceId, name });
1096
1105
  if (taken !== undefined) {
1097
1106
  throw daemonFailure("daemon:worker", "name-conflict", 409, `Worker name '${name}' is already in use in workspace ${workspaceId} by a ${taken.origin} worker.`, { workspaceId, name, actualOrigin: taken.origin, recovery: "Choose another worker name.", retryable: false });
1098
1107
  }
1099
1108
  }
1100
- const worker = await Envelope.createModelWorker(this.#db, workspaceId, name);
1109
+ const worker = await Envelope.createModelWorker(this.#db, workspaceId, name, parentWorkerId, args.owner);
1101
1110
  return { workerId: worker.id, workerName: worker.name };
1102
1111
  }
1103
1112
  // {§worker-scheme-fork} — branch a worker's log while sharing the workspace world.
@@ -1142,6 +1151,9 @@ export default class Daemon {
1142
1151
  await this.#schemes.ready();
1143
1152
  await this.#residency.rematerializeActive();
1144
1153
  }
1154
+ registerResourceTreeScheme(name, source) {
1155
+ return this.registerScheme(name, new ResourceTreeScheme(name, source));
1156
+ }
1145
1157
  #normalizeRuntime({ namespaceOwner, decl, executor, availability, scheme }) {
1146
1158
  if (typeof namespaceOwner !== "string" || namespaceOwner.trim().length === 0) {
1147
1159
  throw new Error("runtime registration namespaceOwner must be a non-empty string");
@@ -1169,7 +1181,11 @@ export default class Daemon {
1169
1181
  registerHttpRoute(prefix, handler) {
1170
1182
  if (this.#http === null)
1171
1183
  throw new Error(`registerHttpRoute: this daemon has no HTTP listener to mount '${prefix}' on`);
1184
+ // {§module-http-mounts} — a module mounts exactly what it claimed.
1185
+ if (!this.#mountClaims.has(prefix))
1186
+ throw new Error(`registerHttpRoute: no module declared '${prefix}' among its mounts`);
1172
1187
  this.#http.registerHttpRoute(prefix, handler);
1188
+ this.#mounted.add(prefix);
1173
1189
  }
1174
1190
  httpAddress() {
1175
1191
  if (this.#http === null)
@@ -1271,14 +1287,18 @@ export default class Daemon {
1271
1287
  workspaceStateDirectory(workspaceId, namespaceOwner) {
1272
1288
  return this.#storage.directory(workspaceId, namespaceOwner);
1273
1289
  }
1274
- async workspaceConfigurationDirectories(workspaceId) {
1290
+ async workspacePaths(workspaceId) {
1275
1291
  const workspace = await this.#db.envelope_get_workspace.get({ id: workspaceId });
1276
- return configurationDirectories(this.#hostPaths, workspace?.project_root ?? null);
1292
+ return workspacePaths(this.#hostPaths, workspace?.project_root ?? null);
1277
1293
  }
1278
1294
  // {§agent-plugins-hosting}
1279
1295
  readWorkspacePlugins(workspaceId) {
1280
1296
  return this.#plugins.read(workspaceId);
1281
1297
  }
1298
+ async readProvidedSkills() {
1299
+ const tree = await PlurnkSkill.load(this.#nodeModulesPath);
1300
+ return new Map([[tree.document.name, tree]]);
1301
+ }
1282
1302
  // {§mcp-launch-environment}
1283
1303
  operatorEnvironment() {
1284
1304
  return ExecEnv.withoutOwnSecrets();
@@ -1301,19 +1321,19 @@ export default class Daemon {
1301
1321
  get provider() { return this.#provider; }
1302
1322
  get schemes() { return this.#schemes; }
1303
1323
  get mimetypes() { return this.#mimetypes; }
1304
- registerModule(module) {
1324
+ // {§module-discovery} — `owner` is the module's package name; diagnostics name it.
1325
+ registerModule(module, owner) {
1305
1326
  if (this.#started)
1306
1327
  throw new Error("registerModule: modules must be registered before daemon start");
1307
- this.#modules.push(module);
1328
+ this.#modules.push({ module, owner });
1308
1329
  }
1309
1330
  async start() {
1310
1331
  if (this.#started)
1311
1332
  throw new Error("daemon already started");
1312
1333
  await this.#configuration.capture("file-creation", () => FileCreationPolicy.serviceScope());
1313
1334
  await this.#configuration.capture("effect-policy", () => EffectPolicy.validateConfiguration());
1314
- await this.#configuration.capture("loop-policy", () => LoopPolicies.validateConfiguration());
1335
+ await this.#configuration.capture("proposal-policy", () => ProposalPolicies.read());
1315
1336
  await this.#configuration.capture("wait", () => TurnDispositionHandler.configuredWaitSeconds());
1316
- await this.#configuration.capture("packet", () => PacketBuilder.validateConfiguration());
1317
1337
  await this.#configuration.capture("execution", () => Exec.validateConfiguration());
1318
1338
  this.#retention = await this.#configuration.capture("retention", () => new Retention(this.#db, retentionPolicy()));
1319
1339
  this.#started = true;
@@ -1330,7 +1350,7 @@ export default class Daemon {
1330
1350
  // packages; pre-warm it so first index render doesn't pay the cost.
1331
1351
  await this.#mimetypes.ready();
1332
1352
  for (const name of await this.#mimetypes.skippedPackages()) {
1333
- console.warn(`mimetype discovery: '${name}' is discovered but untrusted (PLURNK_PLUGINS_TRUSTED_ONLY); not registered`);
1353
+ console.warn(`mimetype discovery: '${name}' is discovered but untrusted (PLURNK_EXTENSIONS_TRUSTED_ONLY); not registered`);
1334
1354
  }
1335
1355
  // Discover + probe the installed executor siblings, then hand the
1336
1356
  // registry to the engine for exec dispatch ({§exec-registry-resolves}).
@@ -1360,23 +1380,42 @@ export default class Daemon {
1360
1380
  this.#schemes.registerRuntimeSchemes(executors);
1361
1381
  // Discover external @plurnk/plurnk-schemes-* siblings + register them
1362
1382
  // (agnostic, by plurnk.kind:"scheme"). They light up http://, etc. with
1363
- // no further engine change — #run wraps their context in SchemeCtxImpl ({§plugin-discovery}).
1383
+ // no further engine change — #run wraps their context in SchemeCtxImpl ({§extension-discovery}).
1364
1384
  await this.#schemes.discoverExternal(this.#discoveryCwd);
1365
1385
  // {§module-discovery} — third-party daemon-module composition: trusted
1366
1386
  // packages declaring `plurnk.kind: "module"` register beside the
1367
1387
  // service's explicit composition before any module setup runs.
1368
- const discoveredModules = await discoverDaemonModules({ cwd: this.#discoveryCwd, hostPaths: this.#hostPaths });
1369
- for (const cause of discoveredModules.configurationErrors)
1370
- this.#configuration.record("native-plugins", cause);
1388
+ const discoveredModules = await discoverDaemonModules({
1389
+ cwd: this.#discoveryCwd, hostPaths: this.#hostPaths, registered: new Set(this.#modules.map(({ owner }) => owner)),
1390
+ });
1391
+ for (const { owner, cause } of discoveredModules.configurationErrors)
1392
+ this.#configuration.record(owner, cause);
1371
1393
  this.#configuration.pluginReports(discoveredModules.reports);
1372
1394
  for (const packageName of discoveredModules.skipped) {
1373
- console.warn(`module discovery: '${packageName}' is discovered but untrusted (PLURNK_PLUGINS_TRUSTED_ONLY); not registered`);
1395
+ console.warn(`module discovery: '${packageName}' is discovered but untrusted (PLURNK_EXTENSIONS_TRUSTED_ONLY); not registered`);
1396
+ }
1397
+ for (const { module, owner } of discoveredModules.modules) {
1398
+ this.#modules.push({ module, owner });
1399
+ }
1400
+ // {§module-http-mounts} — a daemon without a listener has nothing to serve a mount on: it
1401
+ // leaves out every module that declares one, and says so.
1402
+ if (this.#http === null) {
1403
+ this.#modules = this.#modules.filter(({ module, owner }) => {
1404
+ const mounts = module.mounts ?? [];
1405
+ if (mounts.length === 0)
1406
+ return true;
1407
+ this.#configuration.leftOut(`module:${owner}`, `module '${owner}' mounts ${mounts.map((prefix) => `'${prefix}'`).join(", ")} and this daemon has no HTTP listener: left out`);
1408
+ return false;
1409
+ });
1374
1410
  }
1375
- for (const module of discoveredModules.modules) {
1376
- this.#modules.push(module);
1411
+ // {§module-contained-configuration} — what a module contained is its own configuration diagnostic.
1412
+ for (const { module, owner } of this.#modules) {
1413
+ for (const { key, message } of module.contained ?? [])
1414
+ this.#configuration.record(`module:${owner}`, new ConfigurationError(key, message));
1377
1415
  }
1416
+ this.#claimMounts();
1378
1417
  const setupSeam = this;
1379
- for (const module of this.#modules) {
1418
+ for (const { module } of this.#modules) {
1380
1419
  if (module.stop !== undefined || module.close !== undefined)
1381
1420
  this.#moduleLifetimes.push(module);
1382
1421
  await module.setup?.(setupSeam);
@@ -1387,12 +1426,39 @@ export default class Daemon {
1387
1426
  // {§module-lifecycle} — the daemon opened its one transport before admission ({§http-host});
1388
1427
  // modules mount their routes on it here, only after capability publication and durable
1389
1428
  // lifecycle recovery are complete. None opens a listener of its own.
1390
- for (const module of this.#modules) {
1429
+ for (const { module } of this.#modules) {
1391
1430
  const started = await module.start?.(this);
1392
1431
  if (started !== undefined && !this.#moduleLifetimes.includes(started)) {
1393
1432
  this.#moduleLifetimes.push(started);
1394
1433
  }
1395
1434
  }
1435
+ this.#admitMounts();
1436
+ }
1437
+ // {§module-http-mounts} — every prefix is claimed before any module sets up: one owner per
1438
+ // prefix, including the optional root mount.
1439
+ #claimMounts() {
1440
+ for (const { module, owner } of this.#modules) {
1441
+ for (const prefix of module.mounts ?? []) {
1442
+ if (!HttpListener.isPrefix(prefix)) {
1443
+ throw new Error(`module '${owner}' declares HTTP mount '${prefix}', which is not an absolute pathname prefix`);
1444
+ }
1445
+ const holder = this.#mountClaims.get(prefix);
1446
+ if (holder !== undefined)
1447
+ throw new Error(`HTTP mount '${prefix}' is claimed by both '${holder}' and '${owner}'`);
1448
+ this.#mountClaims.set(prefix, owner);
1449
+ }
1450
+ }
1451
+ }
1452
+ // {§module-http-mounts} — the listener is admitted once every module has started and every
1453
+ // claim is mounted, so readiness never depends on registration order.
1454
+ #admitMounts() {
1455
+ if (this.#http === null)
1456
+ return;
1457
+ for (const [prefix, owner] of this.#mountClaims) {
1458
+ if (!this.#mounted.has(prefix))
1459
+ throw new Error(`module '${owner}' claimed HTTP mount '${prefix}' but did not mount it at start`);
1460
+ }
1461
+ this.#http.admit();
1396
1462
  }
1397
1463
  async #recoverLifecycle() {
1398
1464
  await this.#db.recovery_fail_active_loops.run({});
@@ -1554,30 +1620,6 @@ export default class Daemon {
1554
1620
  notifyNotice(workspaceId, payload) {
1555
1621
  this.#broadcast({ workspaceId }, "notice/event", payload);
1556
1622
  }
1557
- // {§methods-loop-run-fold-consistency} — a folded prompt cannot reconfigure its loop.
1558
- async #assertFoldPosture(workerId, policy, loopId) {
1559
- if (policy === undefined || Object.keys(policy).length === 0)
1560
- return;
1561
- const effective = await LoopPolicyReader.read(this.#db, loopId);
1562
- const requested = Object.entries(policy);
1563
- const conflicts = requested
1564
- .filter(([key, value]) => {
1565
- if (value === undefined)
1566
- return false;
1567
- return effective[key] !== value;
1568
- })
1569
- .map(([key, value]) => `${key}: ${JSON.stringify(effective[key])} -> ${JSON.stringify(value)}`);
1570
- if (conflicts.length > 0) {
1571
- throw daemonFailure("daemon:loop", "loop-policy-conflict", 409, "The requested loop policy differs from the active loop policy.", {
1572
- workerId,
1573
- loopId,
1574
- conflicts,
1575
- stage: "loop-injection",
1576
- recovery: "Cancel the active loop before changing policy, or omit policy to keep its current posture.",
1577
- retryable: false
1578
- });
1579
- }
1580
- }
1581
1623
  inject(args) {
1582
1624
  return this.#drains.inject(args);
1583
1625
  }
@@ -1592,7 +1634,6 @@ export default class Daemon {
1592
1634
  worker_id: workerId,
1593
1635
  prompt: first.body,
1594
1636
  prompt_source: first.source,
1595
- policy: first.policy,
1596
1637
  model_route_id: first.model_route_id,
1597
1638
  spawn_model_route_id: first.spawn_model_route_id,
1598
1639
  effort: first.effort,
@@ -1649,7 +1690,7 @@ export default class Daemon {
1649
1690
  // {§methods-event-subscribe}: publish to the in-process source; transport modules subscribe
1650
1691
  // here (plurnk-agui renders to AG-UI+). Each subscriber owns its own fan-out; core just emits.
1651
1692
  // Scope-stamping onto the notification envelope ({§notifications-envelope-carries-workspaceid})
1652
- // is each subscriber's edge concern now — the seam hands (workspaceId, method, params) raw.
1693
+ // is each subscriber's edge concern; the seam hands (workspaceId, method, params) raw.
1653
1694
  this.#emitTo(target.workspaceId, method, params);
1654
1695
  });
1655
1696
  }