@plurnk/plurnk-service 1.10.1 → 1.12.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 (314) hide show
  1. package/.env.defaults +41 -17
  2. package/INSTALL.md +4 -4
  3. package/README.md +2 -2
  4. package/SPEC.md +573 -273
  5. package/digest-sql/curation/curation.sql +1 -0
  6. package/dist/Paths.d.ts +3 -3
  7. package/dist/Paths.d.ts.map +1 -1
  8. package/dist/Paths.js +9 -9
  9. package/dist/Paths.js.map +1 -1
  10. package/dist/build-info.json +1 -1
  11. package/dist/content/edit-collision.d.ts +1 -1
  12. package/dist/content/edit-collision.d.ts.map +1 -1
  13. package/dist/content/edit-collision.js +5 -4
  14. package/dist/content/edit-collision.js.map +1 -1
  15. package/dist/content/edit-receipt.d.ts +6 -5
  16. package/dist/content/edit-receipt.d.ts.map +1 -1
  17. package/dist/content/edit-receipt.js +28 -8
  18. package/dist/content/edit-receipt.js.map +1 -1
  19. package/dist/content/index.d.ts +2 -2
  20. package/dist/content/index.d.ts.map +1 -1
  21. package/dist/content/index.js +1 -1
  22. package/dist/content/index.js.map +1 -1
  23. package/dist/content/line-anchors.d.ts +2 -0
  24. package/dist/content/line-anchors.d.ts.map +1 -1
  25. package/dist/content/line-anchors.js +15 -6
  26. package/dist/content/line-anchors.js.map +1 -1
  27. package/dist/content/line-marker.d.ts +0 -1
  28. package/dist/content/line-marker.d.ts.map +1 -1
  29. package/dist/content/line-marker.js.map +1 -1
  30. package/dist/content/matcher.d.ts.map +1 -1
  31. package/dist/content/matcher.js +3 -2
  32. package/dist/content/matcher.js.map +1 -1
  33. package/dist/content/read-projector.js +3 -3
  34. package/dist/content/read-projector.js.map +1 -1
  35. package/dist/core/BudgetReadout.d.ts +6 -1
  36. package/dist/core/BudgetReadout.d.ts.map +1 -1
  37. package/dist/core/BudgetReadout.js +38 -2
  38. package/dist/core/BudgetReadout.js.map +1 -1
  39. package/dist/core/CapabilityPolicies.d.ts +15 -0
  40. package/dist/core/CapabilityPolicies.d.ts.map +1 -0
  41. package/dist/core/CapabilityPolicies.js +60 -0
  42. package/dist/core/CapabilityPolicies.js.map +1 -0
  43. package/dist/core/CapabilityResolver.d.ts +24 -0
  44. package/dist/core/CapabilityResolver.d.ts.map +1 -0
  45. package/dist/core/CapabilityResolver.js +180 -0
  46. package/dist/core/CapabilityResolver.js.map +1 -0
  47. package/dist/core/ChannelWrite.d.ts +4 -3
  48. package/dist/core/ChannelWrite.d.ts.map +1 -1
  49. package/dist/core/CoreSchemeServices.d.ts +2 -2
  50. package/dist/core/CoreSchemeServices.d.ts.map +1 -1
  51. package/dist/core/CoreSchemeServices.js +2 -2
  52. package/dist/core/CoreSchemeServices.js.map +1 -1
  53. package/dist/core/Dispatcher.d.ts +5 -2
  54. package/dist/core/Dispatcher.d.ts.map +1 -1
  55. package/dist/core/Dispatcher.js +157 -165
  56. package/dist/core/Dispatcher.js.map +1 -1
  57. package/dist/core/DurableStatement.d.ts.map +1 -1
  58. package/dist/core/DurableStatement.js +19 -15
  59. package/dist/core/DurableStatement.js.map +1 -1
  60. package/dist/core/EmbeddingCall.d.ts +23 -0
  61. package/dist/core/EmbeddingCall.d.ts.map +1 -0
  62. package/dist/core/EmbeddingCall.js +149 -0
  63. package/dist/core/EmbeddingCall.js.map +1 -0
  64. package/dist/core/Engine.d.ts +6 -4
  65. package/dist/core/Engine.d.ts.map +1 -1
  66. package/dist/core/Engine.js +20 -9
  67. package/dist/core/Engine.js.map +1 -1
  68. package/dist/core/Engine.sql +119 -56
  69. package/dist/core/ExecutorRegistry.d.ts +3 -3
  70. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  71. package/dist/core/ExecutorRegistry.js +10 -6
  72. package/dist/core/ExecutorRegistry.js.map +1 -1
  73. package/dist/core/GitBranch.d.ts +4 -1
  74. package/dist/core/GitBranch.d.ts.map +1 -1
  75. package/dist/core/GitBranch.js +12 -2
  76. package/dist/core/GitBranch.js.map +1 -1
  77. package/dist/core/InferenceCall.d.ts +18 -0
  78. package/dist/core/InferenceCall.d.ts.map +1 -0
  79. package/dist/core/InferenceCall.js +86 -0
  80. package/dist/core/InferenceCall.js.map +1 -0
  81. package/dist/core/LogEntryProjection.d.ts +1 -0
  82. package/dist/core/LogEntryProjection.d.ts.map +1 -1
  83. package/dist/core/LogEntryProjection.js +12 -4
  84. package/dist/core/LogEntryProjection.js.map +1 -1
  85. package/dist/core/LoopPolicyReader.d.ts +7 -0
  86. package/dist/core/LoopPolicyReader.d.ts.map +1 -0
  87. package/dist/core/LoopPolicyReader.js +33 -0
  88. package/dist/core/LoopPolicyReader.js.map +1 -0
  89. package/dist/core/ModelCall.d.ts +4 -12
  90. package/dist/core/ModelCall.d.ts.map +1 -1
  91. package/dist/core/ModelCall.js +10 -74
  92. package/dist/core/ModelCall.js.map +1 -1
  93. package/dist/core/NoticeChannel.d.ts +2 -2
  94. package/dist/core/NoticeChannel.d.ts.map +1 -1
  95. package/dist/core/NoticeChannel.js +18 -9
  96. package/dist/core/NoticeChannel.js.map +1 -1
  97. package/dist/core/OperatorConfig.d.ts.map +1 -1
  98. package/dist/core/OperatorConfig.js +4 -0
  99. package/dist/core/OperatorConfig.js.map +1 -1
  100. package/dist/core/OverflowTurn.d.ts.map +1 -1
  101. package/dist/core/OverflowTurn.js +4 -3
  102. package/dist/core/OverflowTurn.js.map +1 -1
  103. package/dist/core/Owner.js +5 -5
  104. package/dist/core/Owner.js.map +1 -1
  105. package/dist/core/PacketBuilder.d.ts +2 -2
  106. package/dist/core/PacketBuilder.d.ts.map +1 -1
  107. package/dist/core/PacketBuilder.js +55 -35
  108. package/dist/core/PacketBuilder.js.map +1 -1
  109. package/dist/core/ProblemLog.d.ts.map +1 -1
  110. package/dist/core/ProblemLog.js +1 -0
  111. package/dist/core/ProblemLog.js.map +1 -1
  112. package/dist/core/ProposalLifecycle.d.ts.map +1 -1
  113. package/dist/core/ProposalLifecycle.js +16 -13
  114. package/dist/core/ProposalLifecycle.js.map +1 -1
  115. package/dist/core/ReasoningEvent.d.ts +1 -0
  116. package/dist/core/ReasoningEvent.d.ts.map +1 -1
  117. package/dist/core/ResourceMutations.d.ts +6 -4
  118. package/dist/core/ResourceMutations.d.ts.map +1 -1
  119. package/dist/core/ResourceMutations.js +209 -63
  120. package/dist/core/ResourceMutations.js.map +1 -1
  121. package/dist/core/SchemeRegistry.d.ts +6 -3
  122. package/dist/core/SchemeRegistry.d.ts.map +1 -1
  123. package/dist/core/SchemeRegistry.js +14 -17
  124. package/dist/core/SchemeRegistry.js.map +1 -1
  125. package/dist/core/ServiceTeardown.d.ts +1 -1
  126. package/dist/core/ServiceTeardown.d.ts.map +1 -1
  127. package/dist/core/ServiceTeardown.js +4 -8
  128. package/dist/core/ServiceTeardown.js.map +1 -1
  129. package/dist/core/StrikeRail.d.ts +1 -0
  130. package/dist/core/StrikeRail.d.ts.map +1 -1
  131. package/dist/core/StrikeRail.js +12 -3
  132. package/dist/core/StrikeRail.js.map +1 -1
  133. package/dist/core/ToolResources.d.ts +2 -2
  134. package/dist/core/ToolResources.d.ts.map +1 -1
  135. package/dist/core/ToolResources.js +18 -8
  136. package/dist/core/ToolResources.js.map +1 -1
  137. package/dist/core/Turn.sql +6 -3
  138. package/dist/core/TurnOps.d.ts.map +1 -1
  139. package/dist/core/TurnOps.js +22 -8
  140. package/dist/core/TurnOps.js.map +1 -1
  141. package/dist/core/TurnRunner.d.ts +7 -4
  142. package/dist/core/TurnRunner.d.ts.map +1 -1
  143. package/dist/core/TurnRunner.js +345 -83
  144. package/dist/core/TurnRunner.js.map +1 -1
  145. package/dist/core/WorkerControlAddress.d.ts.map +1 -1
  146. package/dist/core/WorkerControlAddress.js +1 -2
  147. package/dist/core/WorkerControlAddress.js.map +1 -1
  148. package/dist/core/WorkerName.d.ts +2 -0
  149. package/dist/core/WorkerName.d.ts.map +1 -1
  150. package/dist/core/WorkerName.js +3 -2
  151. package/dist/core/WorkerName.js.map +1 -1
  152. package/dist/core/WorkerName.sql +2 -1
  153. package/dist/core/caps/DbProjectionCaps.d.ts +2 -1
  154. package/dist/core/caps/DbProjectionCaps.d.ts.map +1 -1
  155. package/dist/core/caps/DbProjectionCaps.js +12 -1
  156. package/dist/core/caps/DbProjectionCaps.js.map +1 -1
  157. package/dist/core/file-materialization.d.ts +22 -0
  158. package/dist/core/file-materialization.d.ts.map +1 -0
  159. package/dist/core/file-materialization.js +77 -0
  160. package/dist/core/file-materialization.js.map +1 -0
  161. package/dist/core/fork.d.ts +2 -1
  162. package/dist/core/fork.d.ts.map +1 -1
  163. package/dist/core/fork.js +13 -4
  164. package/dist/core/fork.js.map +1 -1
  165. package/dist/core/fork.sql +27 -11
  166. package/dist/core/git-membership.d.ts +25 -14
  167. package/dist/core/git-membership.d.ts.map +1 -1
  168. package/dist/core/git-membership.js +260 -164
  169. package/dist/core/git-membership.js.map +1 -1
  170. package/dist/core/git-state.d.ts +2 -0
  171. package/dist/core/git-state.d.ts.map +1 -1
  172. package/dist/core/git-state.js +27 -1
  173. package/dist/core/git-state.js.map +1 -1
  174. package/dist/core/operation-target-groups.d.ts.map +1 -1
  175. package/dist/core/operation-target-groups.js +8 -7
  176. package/dist/core/operation-target-groups.js.map +1 -1
  177. package/dist/core/owner.sql +7 -10
  178. package/dist/core/packet-wire.d.ts +11 -0
  179. package/dist/core/packet-wire.d.ts.map +1 -1
  180. package/dist/core/packet-wire.js +98 -34
  181. package/dist/core/packet-wire.js.map +1 -1
  182. package/dist/core/scheme-types.d.ts +2 -2
  183. package/dist/core/scheme-types.d.ts.map +1 -1
  184. package/dist/core/scheme-types.js +1 -1
  185. package/dist/core/scheme-types.js.map +1 -1
  186. package/dist/core/types.d.ts +3 -2
  187. package/dist/core/types.d.ts.map +1 -1
  188. package/dist/core/types.js +1 -1
  189. package/dist/core/types.js.map +1 -1
  190. package/dist/core/worker-settings.d.ts +4 -3
  191. package/dist/core/worker-settings.d.ts.map +1 -1
  192. package/dist/core/worker-settings.js +40 -19
  193. package/dist/core/worker-settings.js.map +1 -1
  194. package/dist/core/workspace-settings.d.ts +3 -1
  195. package/dist/core/workspace-settings.d.ts.map +1 -1
  196. package/dist/core/workspace-settings.js +6 -2
  197. package/dist/core/workspace-settings.js.map +1 -1
  198. package/dist/digest/Digest.d.ts.map +1 -1
  199. package/dist/digest/Digest.js +151 -42
  200. package/dist/digest/Digest.js.map +1 -1
  201. package/dist/digest/digest.sql +48 -20
  202. package/dist/index.js +1 -1
  203. package/dist/index.js.map +1 -1
  204. package/dist/schemes/Exec.d.ts +4 -5
  205. package/dist/schemes/Exec.d.ts.map +1 -1
  206. package/dist/schemes/Exec.js +111 -94
  207. package/dist/schemes/Exec.js.map +1 -1
  208. package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
  209. package/dist/schemes/ExecOutputScheme.js +24 -6
  210. package/dist/schemes/ExecOutputScheme.js.map +1 -1
  211. package/dist/schemes/ExecScheduler.d.ts +15 -0
  212. package/dist/schemes/ExecScheduler.d.ts.map +1 -0
  213. package/dist/schemes/ExecScheduler.js +95 -0
  214. package/dist/schemes/ExecScheduler.js.map +1 -0
  215. package/dist/schemes/File.d.ts.map +1 -1
  216. package/dist/schemes/File.js +26 -19
  217. package/dist/schemes/File.js.map +1 -1
  218. package/dist/schemes/Log.d.ts +6 -4
  219. package/dist/schemes/Log.d.ts.map +1 -1
  220. package/dist/schemes/Log.js +132 -39
  221. package/dist/schemes/Log.js.map +1 -1
  222. package/dist/schemes/Log.sql +23 -18
  223. package/dist/schemes/QuestionTool.d.ts +17 -4
  224. package/dist/schemes/QuestionTool.d.ts.map +1 -1
  225. package/dist/schemes/QuestionTool.js +2 -4
  226. package/dist/schemes/QuestionTool.js.map +1 -1
  227. package/dist/schemes/Worker.d.ts.map +1 -1
  228. package/dist/schemes/Worker.js +20 -20
  229. package/dist/schemes/Worker.js.map +1 -1
  230. package/dist/schemes/_entry-chunk.d.ts.map +1 -1
  231. package/dist/schemes/_entry-chunk.js +6 -2
  232. package/dist/schemes/_entry-chunk.js.map +1 -1
  233. package/dist/schemes/_entry-crud.sql +18 -17
  234. package/dist/schemes/_entry-find.d.ts.map +1 -1
  235. package/dist/schemes/_entry-find.js +9 -14
  236. package/dist/schemes/_entry-find.js.map +1 -1
  237. package/dist/schemes/_entry-graph.js +12 -12
  238. package/dist/schemes/_entry-graph.js.map +1 -1
  239. package/dist/schemes/_entry-graph.sql +5 -5
  240. package/dist/schemes/_entry-ops.d.ts.map +1 -1
  241. package/dist/schemes/_entry-ops.js +15 -5
  242. package/dist/schemes/_entry-ops.js.map +1 -1
  243. package/dist/schemes/_entry-semantic.d.ts +5 -3
  244. package/dist/schemes/_entry-semantic.d.ts.map +1 -1
  245. package/dist/schemes/_entry-semantic.js +21 -9
  246. package/dist/schemes/_entry-semantic.js.map +1 -1
  247. package/dist/schemes/_path-scope.d.ts.map +1 -1
  248. package/dist/schemes/_path-scope.js +6 -1
  249. package/dist/schemes/_path-scope.js.map +1 -1
  250. package/dist/schemes/_search-index.d.ts.map +1 -1
  251. package/dist/schemes/_search-index.js +14 -2
  252. package/dist/schemes/_search-index.js.map +1 -1
  253. package/dist/server/BranchBatches.d.ts +3 -3
  254. package/dist/server/BranchBatches.d.ts.map +1 -1
  255. package/dist/server/BranchBatches.js +9 -2
  256. package/dist/server/BranchBatches.js.map +1 -1
  257. package/dist/server/Daemon.d.ts +12 -41
  258. package/dist/server/Daemon.d.ts.map +1 -1
  259. package/dist/server/Daemon.js +60 -93
  260. package/dist/server/Daemon.js.map +1 -1
  261. package/dist/server/DaemonModule.d.ts +10 -1
  262. package/dist/server/DaemonModule.d.ts.map +1 -1
  263. package/dist/server/DrainSupervisor.d.ts +6 -5
  264. package/dist/server/DrainSupervisor.d.ts.map +1 -1
  265. package/dist/server/DrainSupervisor.js +14 -11
  266. package/dist/server/DrainSupervisor.js.map +1 -1
  267. package/dist/server/Functionality.d.ts +2 -2
  268. package/dist/server/Functionality.d.ts.map +1 -1
  269. package/dist/server/Functionality.js +8 -5
  270. package/dist/server/Functionality.js.map +1 -1
  271. package/dist/server/FunctionalityManager.d.ts +13 -1
  272. package/dist/server/FunctionalityManager.d.ts.map +1 -1
  273. package/dist/server/FunctionalityManager.js +82 -17
  274. package/dist/server/FunctionalityManager.js.map +1 -1
  275. package/dist/server/MembersFunctionality.d.ts +56 -0
  276. package/dist/server/MembersFunctionality.d.ts.map +1 -0
  277. package/dist/server/MembersFunctionality.js +350 -0
  278. package/dist/server/MembersFunctionality.js.map +1 -0
  279. package/dist/server/SkillsFunctionality.d.ts +12 -1
  280. package/dist/server/SkillsFunctionality.d.ts.map +1 -1
  281. package/dist/server/SkillsFunctionality.js +6 -1
  282. package/dist/server/SkillsFunctionality.js.map +1 -1
  283. package/dist/server/client-input.d.ts +5 -8
  284. package/dist/server/client-input.d.ts.map +1 -1
  285. package/dist/server/client-input.js +49 -108
  286. package/dist/server/client-input.js.map +1 -1
  287. package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
  288. package/dist/server/dispatch-as-plurnk.js +3 -0
  289. package/dist/server/dispatch-as-plurnk.js.map +1 -1
  290. package/dist/server/drain.sql +4 -4
  291. package/dist/server/envelope.d.ts +1 -1
  292. package/dist/server/envelope.d.ts.map +1 -1
  293. package/dist/server/envelope.js +11 -10
  294. package/dist/server/envelope.js.map +1 -1
  295. package/dist/server/envelope.sql +1 -1
  296. package/dist/server/lifecycle-recovery.sql +14 -20
  297. package/dist/server/loopDocs.d.ts.map +1 -1
  298. package/dist/server/loopDocs.js +12 -5
  299. package/dist/server/loopDocs.js.map +1 -1
  300. package/dist/server/seam-proposal-list.sql +2 -2
  301. package/dist/server/worker-capabilities.sql +9 -0
  302. package/dist/service.d.ts.map +1 -1
  303. package/dist/service.js +18 -23
  304. package/dist/service.js.map +1 -1
  305. package/migrations/001_schema.sql +477 -131
  306. package/package.json +31 -33
  307. package/dist/core/LoopFlagsReader.d.ts +0 -7
  308. package/dist/core/LoopFlagsReader.d.ts.map +0 -1
  309. package/dist/core/LoopFlagsReader.js +0 -33
  310. package/dist/core/LoopFlagsReader.js.map +0 -1
  311. package/dist/core/resolveForLoop.d.ts +0 -5
  312. package/dist/core/resolveForLoop.d.ts.map +0 -1
  313. package/dist/core/resolveForLoop.js +0 -12
  314. package/dist/core/resolveForLoop.js.map +0 -1
@@ -17,7 +17,7 @@ SELECT * FROM workspaces ORDER BY id;
17
17
  SELECT * FROM workers ORDER BY id;
18
18
 
19
19
  -- PREP: digest_loops
20
- SELECT id, worker_id, sequence, status, prompt, flags, terminated_by, terminal_result
20
+ SELECT id, worker_id, sequence, status, prompt, policy, terminated_by, terminal_result
21
21
  FROM loops ORDER BY worker_id, sequence;
22
22
 
23
23
  -- PREP: digest_turns
@@ -26,30 +26,48 @@ SELECT id, loop_id, sequence, producer, kind, status, completed_at, packet,
26
26
  FROM turns ORDER BY loop_id, sequence;
27
27
 
28
28
  -- PREP: digest_turn_attempts
29
- SELECT a.id, mc.id AS model_call_id, mc.turn_id, mc.sequence, mc.kind,
30
- mc.state, a.accepted, mc.response, mc.failure,
31
- a.parse_errors, mc.attributions,
32
- mc.finish_reason, mc.model, mc.timestamp, mc.completed_at
29
+ SELECT a.id, mc.id AS model_call_id, ic.turn_id, ic.sequence, ic.kind,
30
+ ic.state, a.accepted, mc.response, mc.failure,
31
+ a.parse_errors, ic.attributions,
32
+ mc.finish_reason, COALESCE(mc.response_model, ic.request_model) AS model,
33
+ ic.request_model, mc.response_model, ic.timestamp, ic.completed_at
33
34
  FROM turn_attempts a
34
35
  JOIN model_calls mc ON mc.id = a.model_call_id
35
- ORDER BY mc.turn_id, mc.sequence;
36
+ JOIN inference_calls ic ON ic.id = mc.id
37
+ ORDER BY ic.turn_id, ic.sequence;
38
+
39
+ -- PREP: digest_inference_calls
40
+ SELECT id, workspace_id, turn_id, sequence, kind, state, attributions,
41
+ request_model, timestamp, completed_at
42
+ FROM inference_calls
43
+ ORDER BY workspace_id, timestamp, id;
36
44
 
37
45
  -- PREP: digest_model_calls
38
- SELECT mc.id, mc.turn_id, mc.sequence, mc.kind, mc.state,
39
- mc.response, mc.failure, mc.attributions,
40
- mc.finish_reason, mc.model, mc.timestamp, mc.completed_at,
46
+ SELECT mc.id, ic.workspace_id, ic.turn_id, ic.sequence, ic.kind, ic.state,
47
+ mc.response, mc.failure, mc.capacity, ic.attributions,
48
+ mc.finish_reason, COALESCE(mc.response_model, ic.request_model) AS model,
49
+ ic.request_model, mc.response_model, ic.timestamp, ic.completed_at,
41
50
  a.id AS turn_attempt_id, a.accepted, a.parse_errors,
42
51
  le.id AS log_entry_id
43
52
  FROM model_calls mc
53
+ JOIN inference_calls ic ON ic.id = mc.id
44
54
  LEFT JOIN turn_attempts a ON a.model_call_id = mc.id
45
55
  LEFT JOIN log_entries le ON le.model_call_id = mc.id
46
- ORDER BY mc.turn_id, mc.sequence;
56
+ ORDER BY ic.workspace_id, ic.timestamp, ic.id;
57
+
58
+ -- PREP: digest_embedding_calls
59
+ SELECT ec.id, ic.workspace_id, ic.turn_id, ic.sequence, ic.kind, ic.state,
60
+ ic.request_model AS model, ec.input_count, ec.output_count,
61
+ ec.metadata, ec.failure, ic.timestamp, ic.completed_at
62
+ FROM embedding_calls ec
63
+ JOIN inference_calls ic ON ic.id = ec.id
64
+ ORDER BY ic.workspace_id, ic.timestamp, ic.id;
47
65
 
48
66
  -- PREP: digest_provider_requests
49
67
  -- Cardinal physical-request ledger with ownership coordinates for derived
50
68
  -- workspace/worker/loop/turn projections.
51
- SELECT pr.id, pr.model_call_id, a.id AS turn_attempt_id, mc.kind,
52
- mc.turn_id, t.loop_id, l.worker_id, w.workspace_id,
69
+ SELECT pr.id, pr.inference_call_id, a.id AS turn_attempt_id, ic.kind,
70
+ ic.turn_id, t.loop_id, l.worker_id, ic.workspace_id,
53
71
  pr.sequence, pr.provider, pr.model, pr.state, pr.outcome, pr.status,
54
72
  pr.usage_input, pr.usage_output, pr.usage_total,
55
73
  pr.usage_input_no_cache, pr.usage_input_cache_read, pr.usage_input_cache_write,
@@ -57,20 +75,30 @@ SELECT pr.id, pr.model_call_id, a.id AS turn_attempt_id, mc.kind,
57
75
  pr.cost_kind, pr.cost_amount, pr.cost_currency, pr.cost_usd_equivalent,
58
76
  pr.cost_source, pr.cost_reason, pr.started_at, pr.completed_at
59
77
  FROM provider_requests pr
60
- JOIN model_calls mc ON mc.id = pr.model_call_id
61
- LEFT JOIN turn_attempts a ON a.model_call_id = mc.id
62
- JOIN turns t ON t.id = mc.turn_id
63
- JOIN loops l ON l.id = t.loop_id
64
- JOIN workers w ON w.id = l.worker_id
65
- ORDER BY w.id, l.sequence, t.sequence, mc.sequence, pr.sequence;
78
+ JOIN inference_calls ic ON ic.id = pr.inference_call_id
79
+ LEFT JOIN turn_attempts a ON a.model_call_id = ic.id
80
+ LEFT JOIN turns t ON t.id = ic.turn_id
81
+ LEFT JOIN loops l ON l.id = t.loop_id
82
+ LEFT JOIN workers w ON w.id = l.worker_id
83
+ ORDER BY ic.workspace_id, ic.timestamp, ic.id, pr.sequence;
66
84
 
67
85
  -- PREP: digest_log_entries
68
86
  SELECT id, worker_id, loop_id, turn_id, sequence, at, origin, source, model_call_id,
69
87
  op, delimiter, signal,
70
88
  scheme, hostname, port, pathname, query, fragment,
71
89
  rx, status_rx, mimetype_rx,
72
- state, outcome, attrs
73
- FROM log_entries ORDER BY loop_id, turn_id, sequence;
90
+ state, outcome, attrs, initial_folded,
91
+ projection.active AS projection_active,
92
+ projection.folded AS projection_folded,
93
+ COALESCE((
94
+ SELECT json_group_array(ordered.tag)
95
+ FROM (
96
+ SELECT tag FROM log_tags WHERE log_entry_id = le.id ORDER BY tag
97
+ ) ordered
98
+ ), '[]') AS tags
99
+ FROM log_entries le
100
+ JOIN log_entry_projections projection ON projection.log_entry_id = le.id
101
+ ORDER BY loop_id, turn_id, sequence;
74
102
 
75
103
  -- PREP: digest_worker_rollups
76
104
  -- Structural per-worker aggregates. Accounting is derived through the shared
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ export { default as Exec } from "./schemes/Exec.js";
14
14
  export { default as File } from "./schemes/File.js";
15
15
  export { Mock } from "@plurnk/plurnk-providers";
16
16
  // Package-relative paths to non-code artifacts (migrations, the upstream
17
- // grammar's plurnk.md, default requirements). Resolution lives in the
17
+ // grammar's plurnk.md, default Recap). Resolution lives in the
18
18
  // Paths class so this entry stays a pure re-export barrel.
19
19
  export { default as Paths } from "./Paths.js";
20
20
  // CLI-flag derivation from .env.defaults (PLURNK_X → --x, the comment above
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8EAA8E;AAC9E,mEAAmE;AAEnE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACrE,4EAA4E;AAC5E,+CAA+C;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAShD,yEAAyE;AACzE,sEAAsE;AACtE,2DAA2D;AAC3D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAE9C,4EAA4E;AAC5E,8EAA8E;AAC9E,sEAAsE;AACtE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8EAA8E;AAC9E,mEAAmE;AAEnE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACrE,4EAA4E;AAC5E,+CAA+C;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAShD,yEAAyE;AACzE,+DAA+D;AAC/D,2DAA2D;AAC3D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAE9C,4EAA4E;AAC5E,8EAA8E;AAC9E,sEAAsE;AACtE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,oBAAoB,CAAC"}
@@ -6,7 +6,7 @@ import type { FindResult } from "./_entry-find.ts";
6
6
  import { CoreSchemeAdapterBase } from "../core/CoreSchemeServices.ts";
7
7
  import type { CoreSchemeCallContext } from "../core/CoreSchemeServices.ts";
8
8
  import { type SchemeResultBase } from "../core/results.ts";
9
- import { type EntryAddress } from "@plurnk/plurnk-schemes";
9
+ import { type EntryAddress, type ProposalApplyRequest } from "@plurnk/plurnk-schemes";
10
10
  type ExecResult = SchemeResultBase & {
11
11
  body?: string;
12
12
  attrs?: object;
@@ -22,6 +22,7 @@ export type WebFetch = (url: string, opts?: {
22
22
  }) => Promise<WebFetchResult | null>;
23
23
  export default class Exec extends CoreSchemeAdapterBase {
24
24
  #private;
25
+ static sourceRecovery(source: string, upstream: unknown): string;
25
26
  static manifest: SchemeManifest;
26
27
  constructor(fetchWeb?: WebFetch);
27
28
  idle(): Promise<void>;
@@ -31,12 +32,10 @@ export default class Exec extends CoreSchemeAdapterBase {
31
32
  hasActiveHoldSpawns(workerId: number, holdSet: ReadonlySet<string>): boolean;
32
33
  kill(pathname: string, signal: number | null, ctx: CoreSchemeCallContext, scheme?: string): Promise<SchemeResultBase>;
33
34
  exec(statement: ExecStatement, ctx: CoreSchemeCallContext): Promise<ExecResult>;
34
- applyResolution(args: {
35
- attrs: object;
36
- body?: string;
37
- }, ctx: CoreSchemeCallContext): Promise<SchemeResultBase & {
35
+ applyResolution(args: ProposalApplyRequest, ctx: CoreSchemeCallContext): Promise<SchemeResultBase & {
38
36
  outcome?: string;
39
37
  body?: string;
38
+ result?: object;
40
39
  }>;
41
40
  resolveEntryAddress(target: ParsedPath, ctx: CoreSchemeCallContext): Promise<EntryAddress | SchemeResultBase | null>;
42
41
  find(statement: FindStatement, ctx: CoreSchemeCallContext): Promise<FindResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"Exec.d.ts","sourceRoot":"","sources":["../../src/schemes/Exec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Exec.d.ts","sourceRoot":"","sources":["../../src/schemes/Exec.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,5 @@
1
1
  import { parsePath, PathSyntax, TagSignal } from "@plurnk/plurnk-contracts";
2
- import { Policy } from "@plurnk/plurnk-execs";
3
2
  import { WebFetcher, WebMaterializationError, } from "@plurnk/plurnk-schemes-http";
4
- import WorkspaceSettings from "../core/workspace-settings.js";
5
3
  import EffectPolicy from "./EffectPolicy.js";
6
4
  import EntryCrud from "./_entry-crud.js";
7
5
  import Owner from "../core/Owner.js";
@@ -16,7 +14,7 @@ import { isAbsolute, join, resolve } from "node:path";
16
14
  import { CoreSchemeAdapterBase } from "../core/CoreSchemeServices.js";
17
15
  import ErrorDetail from "../core/ErrorDetail.js";
18
16
  import Results, { OperationFailureError } from "../core/results.js";
19
- import { InvalidOperationResultError, NetworkAddress } from "@plurnk/plurnk-schemes";
17
+ import { InvalidOperationResultError, NetworkAddress, } from "@plurnk/plurnk-schemes";
20
18
  import DbProjectionCaps from "../core/caps/DbProjectionCaps.js";
21
19
  import WorkerControlAddress from "../core/WorkerControlAddress.js";
22
20
  import Turn from "../core/Turn.js";
@@ -24,6 +22,7 @@ import LoopLifecycle from "../core/LoopLifecycle.js";
24
22
  import LogEntryProjection from "../core/LogEntryProjection.js";
25
23
  import LogBody from "../core/LogBody.js";
26
24
  import { setTimeout as delay } from "node:timers/promises";
25
+ import ExecScheduler from "./ExecScheduler.js";
27
26
  // Executors are discovered + probed at boot into ExecutorRegistry and reach
28
27
  // the scheme through ctx.executors ({§exec-registry-resolves}). Each runtime tag
29
28
  // resolves to its sibling executor; the scheme itself stays runtime-agnostic.
@@ -70,8 +69,8 @@ const coordinateFromPathname = (pathname) => {
70
69
  // rides the owner_id column, never the pathname). Empty authority = the CALLING worker — your own
71
70
  // streams need no qualifier, so a fan-out sibling's identical coordinate can never be yours
72
71
  // ({§stream-owner-scoped}).
73
- // A named authority = that worker's streams, ancestry-gated (reader must be the owner or an
74
- // ancestor); an unknown name or unpermitted reader resolves null → the face 404s, no existence leak.
72
+ // A named authority = that worker's streams, any worker of the workspace (#394); an unknown
73
+ // name resolves null → the face 404s.
75
74
  export const resolveStreamStatement = async (statement, ctx) => {
76
75
  const t = statement.target;
77
76
  const hostname = t !== null && t.kind === "url" ? t.hostname : null;
@@ -83,6 +82,12 @@ export const resolveStreamStatement = async (statement, ctx) => {
83
82
  return { statement: { ...statement, target: { ...t, hostname: null } }, ownerId };
84
83
  };
85
84
  export default class Exec extends CoreSchemeAdapterBase {
85
+ // The slot contract, stated when a resource source cannot be read: the resource IS the
86
+ // program and the body its stdin; a command belongs beneath a targetless heading.
87
+ static sourceRecovery(source, upstream) {
88
+ const contract = `\`## EXEC0 (${source})\` runs that resource as the program (its content is the program; the body is its stdin). To run a command in the workspace, write it beneath a targetless \`## EXEC0\`.`;
89
+ return typeof upstream === "string" && upstream.length > 0 ? `${contract} ${upstream}` : contract;
90
+ }
86
91
  static manifest = {
87
92
  name: "exec",
88
93
  authority: "owner",
@@ -94,16 +99,15 @@ export default class Exec extends CoreSchemeAdapterBase {
94
99
  writableBy: ["model", "client"],
95
100
  volatile: true,
96
101
  modelVisible: true,
97
- documentation: "Runs a registered executable tool — `## EXEC0 [executor] (target) <timeout,poll>\nbody` — using its `worker://~/_plurnk/tools/` invocation contract. Output streams into the worker's `<executor>:///<loop>/<turn>/<seq>` entry on that tool's own channels. A host-effecting invocation proposes for review before it runs; a read-only or pure one runs ungated. Either way you never fetch the output: the engine surfaces each turn's new stream bytes automatically — folded while it runs, opened when it finishes.",
98
- flags: {
99
- excludedInAsk: true,
100
- },
102
+ documentation: "Runs a registered executable tool — `## EXEC0 [executor] (target) <timeout minutes,poll minutes>\nbody` — using its `worker://~/_plurnk/tools/` invocation contract. Output streams into the worker's `<executor>:///<loop>/<turn>/<seq>` entry on that tool's own channels. A host-effecting invocation proposes for review before it runs; a read-only or pure one runs ungated. Either way you never fetch the output: the engine surfaces each turn's new stream bytes automatically — folded while it runs, opened when it finishes.",
101
103
  };
102
104
  // The web-fetch the entry sink calls on content:null ({§exec-entry-sink}).
103
105
  // Default = schemes-http's checked WebFetcher; injectable for tests.
104
106
  #fetchWeb;
107
+ #scheduler;
105
108
  constructor(fetchWeb) {
106
109
  super();
110
+ this.#scheduler = new ExecScheduler();
107
111
  if (fetchWeb === undefined) {
108
112
  const webFetcher = new WebFetcher();
109
113
  this.#fetchWeb = (url, opts) => webFetcher.fetch(url, opts);
@@ -213,38 +217,13 @@ export default class Exec extends CoreSchemeAdapterBase {
213
217
  const runtime = requested === "" ? "sh" : requested; // empty signal = default shell
214
218
  if (core.executors === undefined)
215
219
  throw new Error("exec dispatched without an executor registry");
216
- const workspaceExecs = (await WorkspaceSettings.read(core.db, core.workspaceId)).execs;
217
220
  // {§exec-registry-resolves} — a non-empty tag selects exactly one registered executable
218
221
  // tool. Unknown tags are not reinterpreted as shell command words: that would make the
219
222
  // executed command differ from the authored body. Bare EXEC remains the default-shell form.
220
223
  const resolved = core.executors.entry(runtime, core.functionalityWorkerId);
221
224
  if (resolved === undefined) {
222
- const available = core.executors.availableRuntimes(core.functionalityWorkerId)
223
- .filter((tag) => workspaceExecs === null || Policy.isEnabled(tag, workspaceExecs));
224
225
  return Results.failure("scheme:exec", "runtime-not-registered", 501, `Executable tool '${runtime}' is not registered for this worker.`, {}, {
225
226
  requestedRuntime: runtime,
226
- availableRuntimes: available,
227
- ...(available.length > 0
228
- ? {
229
- recovery: available.includes("sh")
230
- ? `Use bare EXEC for a shell command or select a registered executable tool: ${available.join(", ")}.`
231
- : `Select a registered executable tool: ${available.join(", ")}.`,
232
- }
233
- : {}),
234
- retryable: false,
235
- });
236
- }
237
- // {§operator-config-workspace-execs} — the workspace layer only narrows
238
- // the registered set. Bare EXEC resolves to sh before the same gate.
239
- if (workspaceExecs !== null && !Policy.isEnabled(runtime, workspaceExecs)) {
240
- const available = core.executors.availableRuntimes(core.functionalityWorkerId)
241
- .filter((tag) => Policy.isEnabled(tag, workspaceExecs));
242
- return Results.failure("scheme:exec", "runtime-disabled", 501, `Executable tool '${runtime}' is disabled by workspace policy.`, {}, {
243
- requestedRuntime: runtime,
244
- availableRuntimes: available,
245
- recovery: available.length > 0
246
- ? `Use an enabled executable tool: ${available.join(", ")}.`
247
- : "Continue without executing a tool in this workspace.",
248
227
  retryable: false,
249
228
  });
250
229
  }
@@ -264,10 +243,10 @@ export default class Exec extends CoreSchemeAdapterBase {
264
243
  ? `Executable tool family '${runtime}' requires one registered tool target.`
265
244
  : `Executable tool family '${runtime}' has no registered target '${exactTarget}'.`, {}, {
266
245
  runtime,
267
- availableTargets,
268
- recovery: availableTargets.length > 0
269
- ? `Select one registered target: ${availableTargets.join(", ")}.`
270
- : `Continue without executing '${runtime}'; it has no enabled targets.`,
246
+ availableTargetCount: availableTargets.length,
247
+ ...(availableTargets.length === 0 ? {} : {
248
+ recovery: `Select a target documented under worker://~/_plurnk/tools/${runtime}/.`,
249
+ }),
271
250
  retryable: false,
272
251
  });
273
252
  }
@@ -336,7 +315,17 @@ export default class Exec extends CoreSchemeAdapterBase {
336
315
  console.error(`EXEC target classification failed for '${inspected}':`, cause);
337
316
  return Results.failure("scheme:exec", "target-classification-failed", 500, `EXEC target '${target}' could not be inspected: ${ErrorDetail.preview(cause)}`, {}, { target, stage: "target-classification" });
338
317
  }
339
- return refuse("target-not-found", `Looked for a directory or script named \`${target}\` under ${runRoot} and found neither.`, "A target is a cwd, a script, or a tool name — never a command. A command belongs in the body: `## EXEC0 (.)` with the command as the body.", { target, root: runRoot });
318
+ // The target is not a script here, but it may be a registered tool of another
319
+ // runtime — say so first; that is what exists (#388).
320
+ const executors = core.executors;
321
+ const ownerRuntimes = executors === undefined
322
+ ? []
323
+ : executors.availableRuntimes(core.functionalityWorkerId)
324
+ .filter((tag) => executors.toolRegistry(tag, core.functionalityWorkerId)?.tools.some((tool) => tool.target === target) === true);
325
+ const recovery = ownerRuntimes.length === 0
326
+ ? "Use an existing directory or script as the target, or place a shell command beneath targetless `## EXEC0`."
327
+ : `Run the registered tool with \`## EXEC0 [${ownerRuntimes[0]}] (${target})\`.`;
328
+ return refuse("target-not-found", "The EXEC target does not resolve as a directory, script, or registered tool for this runtime.", recovery, { target, ...(ownerRuntimes.length === 0 ? {} : { toolRuntimes: ownerRuntimes }) });
340
329
  }
341
330
  }
342
331
  if (!hasBody && target === null && resourceSource === null) {
@@ -352,14 +341,14 @@ export default class Exec extends CoreSchemeAdapterBase {
352
341
  // <turn_seq>/<sequence> (executor-domain + coordinate, e.g. sh/1/1/2).
353
342
  // `pathname` is stamped into attrs at log-write time; applyResolution
354
343
  // reads it back here.
355
- // EXEC repurposes the `<L>` slot as `<timeout, poll>` (seconds): mark[0] caps the spawn's
344
+ // EXEC repurposes the `<L>` slot as `<timeout, poll>` (MINUTES, held in seconds): mark[0] caps the spawn's
356
345
  // lifetime, mark[1] sets the hibernation poll-wake cadence ({§exec-poll}). N>0 → deadline (504);
357
346
  // -1 / absent → unbounded (loop-life bounded); 0 → turn-scoped (reaped at the next pre-turn,
358
347
  // never surviving into the subsequent turn).
359
348
  const marks = statement.lineMarker?.marks;
360
- const timeoutSec = typeof marks?.[0] === "number" && marks[0] > 0 ? Math.floor(marks[0]) : undefined;
349
+ const timeoutSec = typeof marks?.[0] === "number" && marks[0] > 0 ? Math.floor(marks[0]) * 60 : undefined;
361
350
  const turnScoped = typeof marks?.[0] === "number" && marks[0] === 0;
362
- const pollSec = typeof marks?.[1] === "number" && marks[1] >= 0 ? Math.floor(marks[1]) : undefined;
351
+ const pollSec = typeof marks?.[1] === "number" && marks[1] >= 0 ? Math.floor(marks[1]) * 60 : undefined;
363
352
  const attrs = {
364
353
  runtime, cwd, body, target, pathname: "", effect,
365
354
  ...(resourceSource !== null ? { resourceSource } : {}),
@@ -400,18 +389,20 @@ export default class Exec extends CoreSchemeAdapterBase {
400
389
  annotation: null,
401
390
  signal: null,
402
391
  target: sourceTarget,
392
+ metadata: args.metadata === null ? null : [...args.metadata],
403
393
  lineMarker: { marks: [1, -1] },
404
394
  body: null,
405
395
  position: { line: 0, column: 0 },
406
396
  }, core);
407
397
  if (read.status >= 400) {
408
- // A missing scheme source is usually a tool call written as an address
409
- // (`## EXEC0 (pm:///…)`): name the form that works.
410
- const problem = read.problem;
411
- const recovered = read.status === 404 && problem !== undefined && !("recovery" in problem)
412
- ? { ...problem, recovery: `\`${sourceTarget.scheme}:///…\` is an entry address, not a tool. A tool call names its runtime in brackets and the tool name in parens — \`## EXEC0 [${sourceTarget.scheme}] (<tool>)\`; a shell command belongs in the body of a bare \`## EXEC0 (.)\`.` }
413
- : problem;
414
- return Results.assert({ ...read, ...(recovered === undefined ? {} : { problem: recovered }), outcome: "scheme_source_read_failed" });
398
+ // {§exec-target-routing} — the failure stays the owning READ's (#163); the EXEC
399
+ // contract rides its recovery, because a stream address in the target slot is
400
+ // almost always a command that belonged beneath a targetless heading (#425 F4).
401
+ const problem = read.problem === undefined ? undefined : {
402
+ ...read.problem,
403
+ recovery: Exec.sourceRecovery(attrs.resourceSource, read.problem.recovery),
404
+ };
405
+ return Results.assert({ ...read, outcome: "scheme_source_read_failed", ...(problem === undefined ? {} : { problem }) });
415
406
  }
416
407
  const content = read.content;
417
408
  if (typeof content !== "string") {
@@ -489,11 +480,19 @@ export default class Exec extends CoreSchemeAdapterBase {
489
480
  this.liveSubscriptions().register(subscriptionId, {
490
481
  cancel: () => controller.abort(ExecAbort.teardownReason()),
491
482
  });
492
- const tail = this.#runExecutor({
493
- executor: resolved.executor,
494
- runtime, body, cwd, target, ctx: core, pathname,
495
- entryId, subscriptionId, signal: controller.signal, controller, tempPath,
496
- timeoutSec: typeof attrs.timeoutSec === "number" ? attrs.timeoutSec : null,
483
+ const admission = this.#scheduler.admit(core.workspaceId, controller.signal);
484
+ const tail = admission.ready.then(async (release) => {
485
+ try {
486
+ return await this.#runExecutor({
487
+ executor: resolved.executor,
488
+ runtime, body, cwd, target, ctx: core, pathname,
489
+ entryId, subscriptionId, signal: controller.signal, controller, tempPath,
490
+ timeoutSec: typeof attrs.timeoutSec === "number" ? attrs.timeoutSec : null,
491
+ });
492
+ }
493
+ finally {
494
+ release();
495
+ }
497
496
  });
498
497
  // Every exec backgrounds + streams ({§exec-stream}): no same-turn receipt — the output
499
498
  // surfaces as the environment-observation injector's delta on the next turn (folded while
@@ -501,7 +500,16 @@ export default class Exec extends CoreSchemeAdapterBase {
501
500
  // from the preserved effect fact; they resolve a turn later, uniformly
502
501
  // with host streams.
503
502
  this.#activeSpawns.set(subscriptionId, tail);
504
- return { status: 200, outcome: "started" };
503
+ return admission.queued
504
+ ? {
505
+ status: 202,
506
+ outcome: "queued",
507
+ result: {
508
+ executionsAhead: admission.executionsAhead,
509
+ concurrency: admission.concurrency,
510
+ },
511
+ }
512
+ : { status: 200, outcome: "started" };
505
513
  }
506
514
  // Bridge the executor's sink-style contract (write/setState/emit)
507
515
  // onto plurnk-service's storage primitives (appendToChannel,
@@ -695,6 +703,7 @@ export default class Exec extends CoreSchemeAdapterBase {
695
703
  // Durable provenance for clients/forensics. This is machine
696
704
  // ambience, not a human/model action waterfall item.
697
705
  attrs,
706
+ initial_folded: "[]",
698
707
  });
699
708
  if (logRow === undefined)
700
709
  throw new Error("entry(): log insert returned no row");
@@ -708,57 +717,65 @@ export default class Exec extends CoreSchemeAdapterBase {
708
717
  };
709
718
  const executionFailures = [];
710
719
  try {
711
- try {
712
- const reported = await executor.run({
713
- runtime, body, cwd, target, signal,
714
- entry: entrySink,
715
- interact: (request) => {
716
- if (ctx.requestInteraction === undefined) {
717
- throw new Error("EXEC client interaction capability is unavailable.");
718
- }
719
- return ctx.requestInteraction(request);
720
- },
721
- env: ExecEnv.scoped(), // SPEC {§exec} {§exec-env-scoped} — never plurnk's own secrets
722
- write: (channel, chunk, mimetype) => enqueue(() => ChannelWrite.appendToChannel(db, {
723
- entryId, channel, chunk, mimetype, notify: ctx.streamEventNotify, coordinate,
724
- })),
725
- setState: (channel, state) => enqueue(() => ChannelWrite.setChannelState(db, {
726
- entryId, channel, state, notify: ctx.streamEventNotify, coordinate,
727
- })),
728
- emit: (event) => ctx.pushNotice?.(event),
720
+ if (signal.aborted) {
721
+ result = Results.failure("scheme:exec", "execution-cancelled", 499, `Execution of '${runtime}' was cancelled by the service.`, {}, {
722
+ runtime,
723
+ stage: "execution",
724
+ retryable: false,
729
725
  });
730
- // Drain the queue so the subscription doesn't close before
731
- // final chunk events / state transitions have committed.
732
- await queue;
726
+ }
727
+ else
733
728
  try {
734
- result = Results.assert(reported);
729
+ const reported = await executor.run({
730
+ runtime, body, cwd, target, signal,
731
+ entry: entrySink,
732
+ interact: (request) => {
733
+ if (ctx.requestInteraction === undefined) {
734
+ throw new Error("EXEC client interaction capability is unavailable.");
735
+ }
736
+ return ctx.requestInteraction(request);
737
+ },
738
+ env: ExecEnv.scoped(), // SPEC {§exec} {§exec-env-scoped} — never plurnk's own secrets
739
+ write: (channel, chunk, mimetype) => enqueue(() => ChannelWrite.appendToChannel(db, {
740
+ entryId, channel, chunk, mimetype, notify: ctx.streamEventNotify, coordinate,
741
+ })),
742
+ setState: (channel, state) => enqueue(() => ChannelWrite.setChannelState(db, {
743
+ entryId, channel, state, notify: ctx.streamEventNotify, coordinate,
744
+ })),
745
+ emit: (event) => ctx.pushNotice?.(event),
746
+ });
747
+ // Drain the queue so the subscription doesn't close before
748
+ // final chunk events / state transitions have committed.
749
+ await queue;
750
+ try {
751
+ result = Results.assert(reported);
752
+ }
753
+ catch (cause) {
754
+ console.error(`Executor '${runtime}' returned an invalid operation result:`, cause);
755
+ result = Results.failure("scheme:exec", "executor-invalid-result", 500, `The '${runtime}' executor returned an invalid operation result.`, {}, {
756
+ runtime,
757
+ stage: "result-validation",
758
+ retryable: false,
759
+ });
760
+ }
735
761
  }
736
762
  catch (cause) {
737
- console.error(`Executor '${runtime}' returned an invalid operation result:`, cause);
738
- result = Results.failure("scheme:exec", "executor-invalid-result", 500, `The '${runtime}' executor returned an invalid operation result.`, {}, {
763
+ // A rejecting driver must still CONCLUDE its stream — uncaught, the subscription sat
764
+ // open forever and the floating spawn promise was an unhandled rejection.
765
+ console.error(`Executor '${runtime}' threw outside its operation result contract:`, cause);
766
+ result = Results.failure("scheme:exec", "executor-threw", 500, `The '${runtime}' executor failed outside its operation result contract.`, {}, {
739
767
  runtime,
740
- stage: "result-validation",
768
+ stage: "execution",
741
769
  retryable: false,
742
770
  });
743
771
  }
744
- }
745
- catch (cause) {
746
- // A rejecting driver must still CONCLUDE its stream — uncaught, the subscription sat
747
- // open forever and the floating spawn promise was an unhandled rejection.
748
- console.error(`Executor '${runtime}' threw outside its operation result contract:`, cause);
749
- result = Results.failure("scheme:exec", "executor-threw", 500, `The '${runtime}' executor failed outside its operation result contract.`, {}, {
750
- runtime,
751
- stage: "execution",
752
- retryable: false,
753
- });
754
- }
755
772
  const exitCode = typeof result.exitCode === "number" ? result.exitCode : null;
756
773
  // A timeout aborts the spawn → the executor reports 499; replace the
757
774
  // complete result so status and Problem remain one valid truth.
758
775
  if (timedOut) {
759
- result = Results.failure("scheme:exec", "execution-timeout", 504, `Execution of '${runtime}' exceeded its ${timeoutSec}-second deadline.`, exitCode === null ? {} : { exitCode }, {
776
+ result = Results.failure("scheme:exec", "execution-timeout", 504, `Execution of '${runtime}' exceeded its ${(timeoutSec ?? 0) / 60}-minute deadline.`, exitCode === null ? {} : { exitCode }, {
760
777
  runtime,
761
- timeoutSeconds: timeoutSec,
778
+ timeoutMinutes: (timeoutSec ?? 0) / 60,
762
779
  stage: "execution",
763
780
  retryable: false,
764
781
  });
@@ -773,7 +790,7 @@ export default class Exec extends CoreSchemeAdapterBase {
773
790
  });
774
791
  }
775
792
  exitLabel = timedOut
776
- ? `timed out after ${timeoutSec}s`
793
+ ? `timed out after ${(timeoutSec ?? 0) / 60}m`
777
794
  : result.status === 499
778
795
  ? "aborted"
779
796
  : exitCode !== null