@plurnk/plurnk-service 1.21.0 → 1.22.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 (249) hide show
  1. package/.env.defaults +15 -6
  2. package/INSTALL.md +2 -2
  3. package/README.md +1 -1
  4. package/SPEC.md +329 -228
  5. package/dist/build-info.json +1 -1
  6. package/dist/content/edit-receipt.js +4 -3
  7. package/dist/content/edit-receipt.js.map +1 -1
  8. package/dist/content/index.d.ts +2 -7
  9. package/dist/content/index.d.ts.map +1 -1
  10. package/dist/content/index.js +2 -5
  11. package/dist/content/index.js.map +1 -1
  12. package/dist/content/line-anchors.d.ts.map +1 -1
  13. package/dist/content/line-anchors.js +46 -15
  14. package/dist/content/line-anchors.js.map +1 -1
  15. package/dist/content/line-marker.d.ts +1 -0
  16. package/dist/content/line-marker.d.ts.map +1 -1
  17. package/dist/content/line-marker.js +2 -0
  18. package/dist/content/line-marker.js.map +1 -1
  19. package/dist/content/matcher.d.ts +1 -1
  20. package/dist/content/matcher.d.ts.map +1 -1
  21. package/dist/content/matcher.js +7 -9
  22. package/dist/content/matcher.js.map +1 -1
  23. package/dist/content/pattern-edits.d.ts +6 -0
  24. package/dist/content/pattern-edits.d.ts.map +1 -1
  25. package/dist/content/pattern-edits.js +14 -0
  26. package/dist/content/pattern-edits.js.map +1 -1
  27. package/dist/content/read-projector.d.ts.map +1 -1
  28. package/dist/content/read-projector.js +2 -1
  29. package/dist/content/read-projector.js.map +1 -1
  30. package/dist/content/scope-format.d.ts +2 -2
  31. package/dist/content/scope-format.d.ts.map +1 -1
  32. package/dist/content/scope-format.js.map +1 -1
  33. package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
  34. package/dist/core/AdmittedTurnExecutor.js +5 -2
  35. package/dist/core/AdmittedTurnExecutor.js.map +1 -1
  36. package/dist/core/DataStatementRunner.js +1 -1
  37. package/dist/core/DataStatementRunner.js.map +1 -1
  38. package/dist/core/Dispatcher.d.ts.map +1 -1
  39. package/dist/core/Dispatcher.js +1 -0
  40. package/dist/core/Dispatcher.js.map +1 -1
  41. package/dist/core/Dispatcher.sql +1 -1
  42. package/dist/core/EditMutations.js +4 -4
  43. package/dist/core/EditMutations.js.map +1 -1
  44. package/dist/core/EditSequence.d.ts.map +1 -1
  45. package/dist/core/EditSequence.js +2 -1
  46. package/dist/core/EditSequence.js.map +1 -1
  47. package/dist/core/Engine.d.ts +4 -1
  48. package/dist/core/Engine.d.ts.map +1 -1
  49. package/dist/core/Engine.js +7 -2
  50. package/dist/core/Engine.js.map +1 -1
  51. package/dist/core/ExecutorRegistry.d.ts +1 -0
  52. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  53. package/dist/core/ExecutorRegistry.js +4 -0
  54. package/dist/core/ExecutorRegistry.js.map +1 -1
  55. package/dist/core/FabricatedLog.d.ts +8 -0
  56. package/dist/core/FabricatedLog.d.ts.map +1 -0
  57. package/dist/core/FabricatedLog.js +16 -0
  58. package/dist/core/FabricatedLog.js.map +1 -0
  59. package/dist/core/KnownToxins.d.ts +0 -1
  60. package/dist/core/KnownToxins.d.ts.map +1 -1
  61. package/dist/core/KnownToxins.js +3 -12
  62. package/dist/core/KnownToxins.js.map +1 -1
  63. package/dist/core/LogBody.d.ts.map +1 -1
  64. package/dist/core/LogBody.js +3 -2
  65. package/dist/core/LogBody.js.map +1 -1
  66. package/dist/core/LogVisibility.d.ts +3 -1
  67. package/dist/core/LogVisibility.d.ts.map +1 -1
  68. package/dist/core/LogVisibility.js +30 -16
  69. package/dist/core/LogVisibility.js.map +1 -1
  70. package/dist/core/LoopDriver.d.ts.map +1 -1
  71. package/dist/core/LoopDriver.js +2 -3
  72. package/dist/core/LoopDriver.js.map +1 -1
  73. package/dist/core/LoopOutcome.d.ts +0 -1
  74. package/dist/core/LoopOutcome.d.ts.map +1 -1
  75. package/dist/core/LoopOutcome.js +1 -1
  76. package/dist/core/LoopOutcome.js.map +1 -1
  77. package/dist/core/OutsideEvent.d.ts +10 -0
  78. package/dist/core/OutsideEvent.d.ts.map +1 -0
  79. package/dist/core/OutsideEvent.js +5 -0
  80. package/dist/core/OutsideEvent.js.map +1 -0
  81. package/dist/core/PacketBuilder.js +2 -2
  82. package/dist/core/PacketBuilder.js.map +1 -1
  83. package/dist/core/PatternSelection.d.ts +1 -1
  84. package/dist/core/PatternSelection.d.ts.map +1 -1
  85. package/dist/core/PatternSelection.js +8 -6
  86. package/dist/core/PatternSelection.js.map +1 -1
  87. package/dist/core/ProposalLifecycle.d.ts.map +1 -1
  88. package/dist/core/ProposalLifecycle.js +2 -4
  89. package/dist/core/ProposalLifecycle.js.map +1 -1
  90. package/dist/core/ProviderInstantiate.d.ts +4 -4
  91. package/dist/core/ProviderInstantiate.d.ts.map +1 -1
  92. package/dist/core/ProviderInstantiate.js +24 -25
  93. package/dist/core/ProviderInstantiate.js.map +1 -1
  94. package/dist/core/ProviderRecovery.d.ts +1 -1
  95. package/dist/core/ProviderRecovery.d.ts.map +1 -1
  96. package/dist/core/ProviderRecovery.js +3 -1
  97. package/dist/core/ProviderRecovery.js.map +1 -1
  98. package/dist/core/ResourceSelector.js +1 -1
  99. package/dist/core/ResourceSelector.js.map +1 -1
  100. package/dist/core/StoredPacket.d.ts +1 -1
  101. package/dist/core/StoredPacket.d.ts.map +1 -1
  102. package/dist/core/StoredPacket.js +6 -15
  103. package/dist/core/StoredPacket.js.map +1 -1
  104. package/dist/core/StrikeRail.d.ts +2 -0
  105. package/dist/core/StrikeRail.d.ts.map +1 -1
  106. package/dist/core/StrikeRail.js +7 -1
  107. package/dist/core/StrikeRail.js.map +1 -1
  108. package/dist/core/Turn.d.ts +1 -1
  109. package/dist/core/Turn.d.ts.map +1 -1
  110. package/dist/core/Turn.js.map +1 -1
  111. package/dist/core/TurnDispositionHandler.d.ts.map +1 -1
  112. package/dist/core/TurnDispositionHandler.js +1 -4
  113. package/dist/core/TurnDispositionHandler.js.map +1 -1
  114. package/dist/core/TurnMaterialization.d.ts.map +1 -1
  115. package/dist/core/TurnMaterialization.js +5 -7
  116. package/dist/core/TurnMaterialization.js.map +1 -1
  117. package/dist/core/TurnRunner.d.ts +5 -1
  118. package/dist/core/TurnRunner.d.ts.map +1 -1
  119. package/dist/core/TurnRunner.js +108 -23
  120. package/dist/core/TurnRunner.js.map +1 -1
  121. package/dist/core/WorkerControlHandler.d.ts.map +1 -1
  122. package/dist/core/WorkerControlHandler.js +6 -1
  123. package/dist/core/WorkerControlHandler.js.map +1 -1
  124. package/dist/core/WorkerName.sql +2 -2
  125. package/dist/core/attachments.d.ts +0 -3
  126. package/dist/core/attachments.d.ts.map +1 -1
  127. package/dist/core/attachments.js +3 -3
  128. package/dist/core/attachments.js.map +1 -1
  129. package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
  130. package/dist/core/caps/DbSubscriptionCaps.js +1 -2
  131. package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
  132. package/dist/core/fork.sql +2 -2
  133. package/dist/core/packet-wire.d.ts +1 -2
  134. package/dist/core/packet-wire.d.ts.map +1 -1
  135. package/dist/core/packet-wire.js +51 -54
  136. package/dist/core/packet-wire.js.map +1 -1
  137. package/dist/core/plurnk-uri.d.ts +0 -1
  138. package/dist/core/plurnk-uri.d.ts.map +1 -1
  139. package/dist/core/plurnk-uri.js +1 -1
  140. package/dist/core/plurnk-uri.js.map +1 -1
  141. package/dist/core/worker-ops.sql +1 -1
  142. package/dist/digest/Digest.d.ts.map +1 -1
  143. package/dist/digest/Digest.js +33 -60
  144. package/dist/digest/Digest.js.map +1 -1
  145. package/dist/digest/DigestEvidence.d.ts +9 -0
  146. package/dist/digest/DigestEvidence.d.ts.map +1 -0
  147. package/dist/digest/DigestEvidence.js +52 -0
  148. package/dist/digest/DigestEvidence.js.map +1 -0
  149. package/dist/digest/DigestRender.d.ts +1 -1
  150. package/dist/digest/DigestRender.d.ts.map +1 -1
  151. package/dist/digest/DigestRender.js +115 -66
  152. package/dist/digest/DigestRender.js.map +1 -1
  153. package/dist/digest/DigestRequiem.d.ts.map +1 -1
  154. package/dist/digest/DigestRequiem.js +56 -47
  155. package/dist/digest/DigestRequiem.js.map +1 -1
  156. package/dist/digest/digest-paths.d.ts.map +1 -1
  157. package/dist/digest/digest-paths.js +5 -14
  158. package/dist/digest/digest-paths.js.map +1 -1
  159. package/dist/digest/digest-rows.d.ts +10 -9
  160. package/dist/digest/digest-rows.d.ts.map +1 -1
  161. package/dist/digest/digest.sql +15 -11
  162. package/dist/schemes/EffectPolicy.js +1 -1
  163. package/dist/schemes/EffectPolicy.js.map +1 -1
  164. package/dist/schemes/Exec.d.ts.map +1 -1
  165. package/dist/schemes/Exec.js +26 -6
  166. package/dist/schemes/Exec.js.map +1 -1
  167. package/dist/schemes/ExecScratch.d.ts +10 -0
  168. package/dist/schemes/ExecScratch.d.ts.map +1 -0
  169. package/dist/schemes/ExecScratch.js +43 -0
  170. package/dist/schemes/ExecScratch.js.map +1 -0
  171. package/dist/schemes/File.d.ts.map +1 -1
  172. package/dist/schemes/File.js +39 -5
  173. package/dist/schemes/File.js.map +1 -1
  174. package/dist/schemes/Log.d.ts.map +1 -1
  175. package/dist/schemes/Log.js +5 -4
  176. package/dist/schemes/Log.js.map +1 -1
  177. package/dist/schemes/TurnSource.js +2 -2
  178. package/dist/schemes/TurnSource.js.map +1 -1
  179. package/dist/schemes/Worker.d.ts.map +1 -1
  180. package/dist/schemes/Worker.js +6 -3
  181. package/dist/schemes/Worker.js.map +1 -1
  182. package/dist/schemes/_entry-crud.d.ts.map +1 -1
  183. package/dist/schemes/_entry-crud.js +2 -3
  184. package/dist/schemes/_entry-crud.js.map +1 -1
  185. package/dist/schemes/_entry-find.d.ts.map +1 -1
  186. package/dist/schemes/_entry-find.js +2 -1
  187. package/dist/schemes/_entry-find.js.map +1 -1
  188. package/dist/schemes/_entry-fts.d.ts +1 -0
  189. package/dist/schemes/_entry-fts.d.ts.map +1 -1
  190. package/dist/schemes/_entry-fts.js +34 -2
  191. package/dist/schemes/_entry-fts.js.map +1 -1
  192. package/dist/schemes/_entry-ops.d.ts.map +1 -1
  193. package/dist/schemes/_entry-ops.js +3 -2
  194. package/dist/schemes/_entry-ops.js.map +1 -1
  195. package/dist/schemes/_path-scope.d.ts.map +1 -1
  196. package/dist/schemes/_path-scope.js +2 -3
  197. package/dist/schemes/_path-scope.js.map +1 -1
  198. package/dist/server/Daemon.d.ts +25 -13
  199. package/dist/server/Daemon.d.ts.map +1 -1
  200. package/dist/server/Daemon.js +89 -58
  201. package/dist/server/Daemon.js.map +1 -1
  202. package/dist/server/DrainSupervisor.d.ts +3 -3
  203. package/dist/server/DrainSupervisor.d.ts.map +1 -1
  204. package/dist/server/DrainSupervisor.js +3 -3
  205. package/dist/server/DrainSupervisor.js.map +1 -1
  206. package/dist/server/EnvFunctionality.d.ts +0 -1
  207. package/dist/server/EnvFunctionality.d.ts.map +1 -1
  208. package/dist/server/EnvFunctionality.js +1 -1
  209. package/dist/server/EnvFunctionality.js.map +1 -1
  210. package/dist/server/MembersFunctionality.d.ts +0 -9
  211. package/dist/server/MembersFunctionality.d.ts.map +1 -1
  212. package/dist/server/WorkerModelResolver.d.ts +8 -8
  213. package/dist/server/WorkerModelResolver.d.ts.map +1 -1
  214. package/dist/server/WorkerModelResolver.js +46 -45
  215. package/dist/server/WorkerModelResolver.js.map +1 -1
  216. package/dist/server/client-input.d.ts +1 -0
  217. package/dist/server/client-input.d.ts.map +1 -1
  218. package/dist/server/client-input.js +7 -0
  219. package/dist/server/client-input.js.map +1 -1
  220. package/dist/server/drain.sql +6 -6
  221. package/dist/server/envelope.sql +6 -6
  222. package/dist/server/loopDocs.js +1 -1
  223. package/dist/server/loopDocs.js.map +1 -1
  224. package/dist/server/model-catalog.js +2 -2
  225. package/dist/server/model-catalog.js.map +1 -1
  226. package/dist/server/model-route.d.ts +2 -2
  227. package/dist/server/model-route.d.ts.map +1 -1
  228. package/dist/server/model-route.js +5 -5
  229. package/dist/server/model-route.js.map +1 -1
  230. package/dist/service.d.ts.map +1 -1
  231. package/dist/service.js +41 -6
  232. package/dist/service.js.map +1 -1
  233. package/dist/share/Share.d.ts +15 -0
  234. package/dist/share/Share.d.ts.map +1 -0
  235. package/dist/share/Share.js +106 -0
  236. package/dist/share/Share.js.map +1 -0
  237. package/dist/share/share.sql +6 -0
  238. package/migrations/001_workspaces.sql +2 -2
  239. package/migrations/002_workers.sql +4 -6
  240. package/migrations/003_loops.sql +2 -2
  241. package/migrations/004_inference.sql +2 -2
  242. package/migrations/005_entries.sql +2 -2
  243. package/migrations/006_log.sql +2 -2
  244. package/migrations/007_subscriptions.sql +2 -2
  245. package/migrations/008_interactions.sql +2 -2
  246. package/migrations/009_effort.sql +7 -0
  247. package/migrations/010_outside_text.sql +41 -0
  248. package/migrations/011_settled.sql +133 -0
  249. package/package.json +42 -37
@@ -2,6 +2,7 @@
2
2
  // the transport-free plugin-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
6
  import Paths from "../Paths.js";
6
7
  import Engine from "../core/Engine.js";
7
8
  import ExecutorRegistry from "../core/ExecutorRegistry.js";
@@ -56,6 +57,7 @@ const clientActionFailure = (error) => {
56
57
  };
57
58
  export default class Daemon {
58
59
  #db;
60
+ #dbPath;
59
61
  #engine;
60
62
  #workspaceGate;
61
63
  #lifecycle;
@@ -86,8 +88,9 @@ export default class Daemon {
86
88
  #workerModels;
87
89
  #reads;
88
90
  #storage;
89
- constructor({ db, schemes, mimetypes, provider, nodeModulesPath, hostPaths = new HostPaths(), skills, http = null }) {
91
+ constructor({ db, schemes, mimetypes, provider, nodeModulesPath, hostPaths = new HostPaths(), skills, http = null, dbPath }) {
90
92
  this.#db = db;
93
+ this.#dbPath = dbPath;
91
94
  this.#http = http;
92
95
  this.#storage = new WorkspaceStorage(db, hostPaths);
93
96
  this.#lifecycle = new LoopLifecycle(db);
@@ -165,6 +168,7 @@ export default class Daemon {
165
168
  streamEventNotify: (workspaceId, event) => this.notifyStreamEvent(workspaceId, event),
166
169
  operationSettledNotify: (workspaceId, logEntryId) => this.#drains.operationSettled(workspaceId, logEntryId),
167
170
  reasoningEventNotify: (workspaceId, event) => this.notifyReasoningEvent(workspaceId, event),
171
+ outsideEventNotify: (workspaceId, event) => this.notifyOutsideEvent(workspaceId, event),
168
172
  wakeWorkerNotify: (payload) => this.#drains.notifyWakeWorker(payload),
169
173
  // worker:// loop-start primitive — spawn/fork/irc deliver through
170
174
  // Daemon.inject (active sister → fold; idle → enqueue + drain). The
@@ -181,7 +185,7 @@ export default class Daemon {
181
185
  const systemPrompt = await readFile(Paths.instructionsSystem, "utf8");
182
186
  let providerSpec;
183
187
  let childProviderSpec;
184
- let reasoningPolicy;
188
+ let effort;
185
189
  if (spawn !== true) {
186
190
  // {§worker-model-selection} — the voice door addresses an
187
191
  // existing worker. Its own durable generation policy is the
@@ -192,23 +196,23 @@ export default class Daemon {
192
196
  throw new Error(`injectWorker: worker ${workerId} has no resolvable model route`);
193
197
  }
194
198
  providerSpec = targetPolicy.providerSpec;
195
- reasoningPolicy = targetPolicy.reasoningPolicy;
199
+ effort = targetPolicy.effort;
196
200
  childProviderSpec = await this.#workerModels.resolveWorkerSpawnModel(workerId, undefined);
197
201
  }
198
202
  else {
199
203
  const parentPolicy = await this.#providerPolicyForLoop(sourceLoopId);
200
204
  providerSpec = parentPolicy.childProviderSpec ?? parentPolicy.providerSpec;
201
- reasoningPolicy = parentPolicy.reasoningPolicy;
205
+ effort = parentPolicy.effort;
202
206
  // {§worker-model-selection} — lineage inheritance by value:
203
207
  // the child begins with the spawning loop's effective spawn
204
208
  // model and no separate override of its own.
205
209
  childProviderSpec = null;
206
- // {§worker-reasoning-source} — inherited by value, chosen by nobody on this worker.
210
+ // {§worker-effort-source} — inherited by value, chosen by nobody on this worker.
207
211
  await this.#workerModels.persistGenerationPolicy(workerId, {
208
212
  model_route_id: await routeForSpec(this.#db, providerSpec),
209
213
  spawn_model_route_id: null,
210
- reasoning_policy: reasoningPolicy,
211
- reasoning_source: "default"
214
+ effort: effort,
215
+ effort_source: "default"
212
216
  });
213
217
  // {§env-option} — the heading's environment lands as the child's own entries through the
214
218
  // family's add, after the copy it inherited at creation ({§functionality-scope}); names
@@ -226,7 +230,7 @@ export default class Daemon {
226
230
  sourceLoopId,
227
231
  ...(source === undefined ? {} : { source }),
228
232
  providerSpec,
229
- reasoningPolicy,
233
+ effort,
230
234
  childProviderSpec,
231
235
  systemPrompt,
232
236
  ...(freshLoopPolicy === undefined ? {} : { freshLoopPolicy })
@@ -253,14 +257,14 @@ export default class Daemon {
253
257
  db,
254
258
  lifecycle: this.#lifecycle,
255
259
  injectPrompt: (loopId, prompt, openPaths, source, evidence, messageAddress) => this.#engine.injectIntoLoop(loopId, prompt, openPaths, source, evidence, messageAddress),
256
- assertInjectionCompatibility: async ({ workerId, loopId, providerSpec, providerSpecExplicit, reasoningPolicy, childProviderSpec, turnCeiling, policy }) => {
260
+ assertInjectionCompatibility: async ({ workerId, loopId, providerSpec, providerSpecExplicit, effort, childProviderSpec, turnCeiling, policy }) => {
257
261
  await this.#assertFoldPosture(workerId, policy, loopId);
258
262
  // An omitted selector keeps the loop's durable provider; only an
259
263
  // explicit selection is checked against it (a deliberate switch).
260
264
  if (providerSpecExplicit !== false) {
261
265
  await this.#assertLoopProvider(loopId, providerSpec);
262
266
  }
263
- await this.#assertLoopReasoningPolicy(loopId, reasoningPolicy);
267
+ await this.#assertLoopEffort(loopId, effort);
264
268
  if (childProviderSpec !== undefined) {
265
269
  await this.#assertLoopChildProvider(loopId, childProviderSpec);
266
270
  }
@@ -403,7 +407,7 @@ export default class Daemon {
403
407
  retryable: false
404
408
  }));
405
409
  }
406
- const { providerSpec: selection, reasoningPolicy } = generationPolicy;
410
+ const { providerSpec: selection, effort } = generationPolicy;
407
411
  // {§methods-loop-run-child-provider} — the worker's persistent spawn override.
408
412
  const childSelection = await this.#workerModels.resolveWorkerSpawnModel(workerId, childSelector);
409
413
  const systemPrompt = await readFile(Paths.instructionsSystem, "utf8");
@@ -429,7 +433,7 @@ export default class Daemon {
429
433
  turnCeiling,
430
434
  providerSpec: selection,
431
435
  providerSpecExplicit: selectorExplicit,
432
- reasoningPolicy,
436
+ effort,
433
437
  childProviderSpec: childSelection,
434
438
  systemPrompt
435
439
  });
@@ -446,13 +450,13 @@ export default class Daemon {
446
450
  if (providerSpec === null) {
447
451
  throw new Error(`loop ${loopId}: persisted provider selection is missing — refusing boot-default substitution`);
448
452
  }
449
- if (row.reasoning_policy === null) {
450
- throw new Error(`loop ${loopId}: persisted reasoning policy is missing`);
453
+ if (row.effort === null) {
454
+ throw new Error(`loop ${loopId}: persisted effort is missing`);
451
455
  }
452
456
  return {
453
457
  providerSpec,
454
458
  childProviderSpec: await specForRoute(this.#db, row.spawn_model_route_id),
455
- reasoningPolicy: row.reasoning_policy
459
+ effort: row.effort
456
460
  };
457
461
  }
458
462
  async #providerSpecForLoop(loopId) {
@@ -460,10 +464,10 @@ export default class Daemon {
460
464
  }
461
465
  async #providersForLoop(loopId) {
462
466
  const policy = await this.#providerPolicyForLoop(loopId);
463
- const provider = await this.#workerModels.providerForPolicy(policy.providerSpec, policy.reasoningPolicy);
467
+ const provider = await this.#workerModels.providerForPolicy(policy.providerSpec, policy.effort);
464
468
  const childProvider = policy.childProviderSpec === null
465
469
  ? provider
466
- : await this.#workerModels.providerForPolicy(policy.childProviderSpec, policy.reasoningPolicy);
470
+ : await this.#workerModels.providerForPolicy(policy.childProviderSpec, policy.effort);
467
471
  return { provider, childProvider };
468
472
  }
469
473
  async #assertLoopProvider(loopId, requested) {
@@ -481,15 +485,15 @@ export default class Daemon {
481
485
  });
482
486
  }
483
487
  }
484
- async #assertLoopReasoningPolicy(loopId, requested) {
485
- const selected = (await this.#providerPolicyForLoop(loopId)).reasoningPolicy;
488
+ async #assertLoopEffort(loopId, requested) {
489
+ const selected = (await this.#providerPolicyForLoop(loopId)).effort;
486
490
  if (selected !== requested) {
487
- throw daemonFailure("daemon:provider", "loop-reasoning-policy-conflict", 409, `Loop ${loopId} uses reasoning policy '${selected}', not '${requested}'.`, {
491
+ throw daemonFailure("daemon:provider", "loop-effort-conflict", 409, `Loop ${loopId} uses effort '${selected}', not '${requested}'.`, {
488
492
  loopId,
489
- selectedReasoningPolicy: selected,
490
- requestedReasoningPolicy: requested,
493
+ selectedEffort: selected,
494
+ requestedEffort: requested,
491
495
  stage: "loop-injection",
492
- recovery: "Cancel or conclude the loop before selecting another reasoning policy.",
496
+ recovery: "Cancel or conclude the loop before selecting another effort.",
493
497
  retryable: false
494
498
  });
495
499
  }
@@ -564,8 +568,8 @@ export default class Daemon {
564
568
  const modelSpec = await specForRoute(this.#db, row.model_route_id);
565
569
  const spawnModelSpec = await specForRoute(this.#db, row.spawn_model_route_id);
566
570
  return {
567
- model: modelSpec === null ? null : projectModelRoute(modelSpec, row.reasoning_policy, row.reasoning_source),
568
- spawnModel: spawnModelSpec === null ? null : projectModelRoute(spawnModelSpec, row.reasoning_policy, row.reasoning_source)
571
+ model: modelSpec === null ? null : projectModelRoute(modelSpec, row.effort, row.effort_source),
572
+ spawnModel: spawnModelSpec === null ? null : projectModelRoute(spawnModelSpec, row.effort, row.effort_source)
569
573
  };
570
574
  }
571
575
  // {§worker-model-selection} — persist an explicit model selection onto the worker
@@ -575,70 +579,83 @@ export default class Daemon {
575
579
  const workerId = ClientInput.assertId("worker.model.set", "workerId", args.workerId);
576
580
  await this.#assertModelWorker(workspaceId, workerId);
577
581
  const selector = ClientInput.assertSelector("worker.model.set", "selector", args.selector);
578
- const policy = await this.#workerModels.resolveWorkerModel(workerId, selector);
582
+ let chosen;
583
+ if (args.effort !== undefined) {
584
+ try {
585
+ chosen = Validator.assertEffort(args.effort);
586
+ }
587
+ catch (cause) {
588
+ throw daemonFailure("daemon:input", "effort-invalid", 400, cause instanceof Error ? cause.message : "The effort is invalid.", { field: "effort", retryable: false });
589
+ }
590
+ }
591
+ const policy = await this.#workerModels.resolveWorkerModel(workerId, selector, chosen);
579
592
  if (policy === null) {
580
593
  throw new OperationFailureError(Results.failure("daemon:provider", "not-configured", 501, "No provider is configured for this worker.", {}, { stage: "provider-selection", recovery: "Select a configured model provider.", retryable: false }));
581
594
  }
582
- return projectModelRoute(policy.providerSpec, policy.reasoningPolicy, policy.reasoningSource);
595
+ return projectModelRoute(policy.providerSpec, policy.effort, policy.effortSource);
583
596
  }
584
- // {§worker-reasoning-policy} — the worker's reasoning policy is durable and
597
+ // {§worker-effort} — the worker's effort is durable and
585
598
  // provider-relative. A model-less worker remains explicitly uninitialized.
586
- async readWorkerReasoning(args) {
587
- const workspaceId = ClientInput.assertId("worker.reasoning.get", "workspaceId", args.workspaceId);
588
- const workerId = ClientInput.assertId("worker.reasoning.get", "workerId", args.workerId);
599
+ async readWorkerEffort(args) {
600
+ const workspaceId = ClientInput.assertId("worker.effort.get", "workspaceId", args.workspaceId);
601
+ const workerId = ClientInput.assertId("worker.effort.get", "workerId", args.workerId);
589
602
  await this.#assertModelWorker(workspaceId, workerId);
590
603
  await this.#workerModels.resolveWorkerModel(workerId, undefined);
591
604
  const row = await this.#db.worker_generation_policy_read.get({ id: workerId });
592
605
  if (row === undefined)
593
606
  throw new Error(`worker ${workerId}: generation policy row missing`);
594
607
  if (row.model_route_id === null) {
595
- if (row.reasoning_policy !== null) {
596
- throw new Error(`worker ${workerId}: reasoning policy exists without a model route`);
608
+ if (row.effort !== null) {
609
+ throw new Error(`worker ${workerId}: effort exists without a model route`);
597
610
  }
598
- return { policy: null, source: "default", supportedPolicies: [] };
611
+ return { effort: null, source: "default", supportedEfforts: [] };
599
612
  }
600
- if (row.reasoning_policy === null) {
601
- throw new Error(`worker ${workerId}: durable model has no reasoning policy`);
613
+ if (row.effort === null) {
614
+ throw new Error(`worker ${workerId}: durable model has no effort`);
602
615
  }
603
616
  return {
604
- policy: row.reasoning_policy,
605
- source: row.reasoning_source,
606
- supportedPolicies: await this.#workerModels.supportedPolicies(row)
617
+ effort: row.effort,
618
+ source: row.effort_source,
619
+ supportedEfforts: await this.#workerModels.supportedEfforts(row)
607
620
  };
608
621
  }
609
- // {§worker-reasoning-policy} — mutate between loops, validate against both
622
+ // {§worker-effort} — mutate between loops, validate against both
610
623
  // the worker model and its optional spawn model, then persist atomically.
611
- async setWorkerReasoning(args) {
612
- const workspaceId = ClientInput.assertId("worker.reasoning.set", "workspaceId", args.workspaceId);
613
- const workerId = ClientInput.assertId("worker.reasoning.set", "workerId", args.workerId);
614
- let policy;
624
+ async setWorkerEffort(args) {
625
+ const workspaceId = ClientInput.assertId("worker.effort.set", "workspaceId", args.workspaceId);
626
+ const workerId = ClientInput.assertId("worker.effort.set", "workerId", args.workerId);
627
+ let effort;
615
628
  try {
616
- policy = Validator.assertReasoningPolicy(args.policy);
629
+ effort = Validator.assertEffort(args.effort);
617
630
  }
618
631
  catch (cause) {
619
- throw daemonFailure("daemon:input", "reasoning-policy-invalid", 400, cause instanceof Error ? cause.message : "The reasoning policy is invalid.", { field: "policy", retryable: false });
632
+ throw daemonFailure("daemon:input", "effort-invalid", 400, cause instanceof Error ? cause.message : "The effort is invalid.", { field: "effort", retryable: false });
620
633
  }
621
634
  await this.#assertModelWorker(workspaceId, workerId);
622
- await this.#workerModels.resolveWorkerModel(workerId, undefined);
635
+ // A model-less worker takes the default first; an existing pair is replaced, not re-validated, so an
636
+ // effort its model no longer supports can be corrected ({§worker-effort}).
637
+ const current = await this.#db.worker_generation_policy_read.get({ id: workerId });
638
+ if (current?.model_route_id === null)
639
+ await this.#workerModels.resolveWorkerModel(workerId, undefined);
623
640
  const row = await this.#db.worker_generation_policy_read.get({ id: workerId });
624
641
  if (row === undefined)
625
642
  throw new Error(`worker ${workerId}: generation policy row missing`);
626
643
  const spec = await specForRoute(this.#db, row.model_route_id);
627
644
  if (spec === null) {
628
- throw daemonFailure("daemon:provider", "worker-model-unset", 409, `Worker ${workerId} has no model against which to validate a reasoning policy.`, {
645
+ throw daemonFailure("daemon:provider", "worker-model-unset", 409, `Worker ${workerId} has no model against which to validate an effort.`, {
629
646
  workerId,
630
647
  stage: "provider-selection",
631
- recovery: "Select a model before selecting its reasoning policy.",
648
+ recovery: "Select a model before selecting its effort.",
632
649
  retryable: false
633
650
  });
634
651
  }
635
- const supportedPolicies = await this.#workerModels.persistGenerationPolicy(workerId, {
652
+ const supportedEfforts = await this.#workerModels.persistGenerationPolicy(workerId, {
636
653
  model_route_id: row.model_route_id,
637
654
  spawn_model_route_id: row.spawn_model_route_id,
638
- reasoning_policy: policy,
639
- reasoning_source: "explicit"
655
+ effort,
656
+ effort_source: "explicit"
640
657
  });
641
- return { policy, source: "explicit", supportedPolicies };
658
+ return { effort, source: "explicit", supportedEfforts };
642
659
  }
643
660
  // {§worker-model-selection} — persist the worker's spawn override; a null
644
661
  // selector means inherit (clears the override).
@@ -651,7 +668,7 @@ export default class Daemon {
651
668
  if (spec === null)
652
669
  return null;
653
670
  const row = await this.#db.worker_generation_policy_read.get({ id: workerId });
654
- return projectModelRoute(spec, row?.reasoning_policy ?? null, row?.reasoning_source ?? "default");
671
+ return projectModelRoute(spec, row?.effort ?? null, row?.effort_source ?? "default");
655
672
  }
656
673
  async #assertWorkerOwned(workspaceId, workerId) {
657
674
  const owner = await this.#db.envelope_get_worker_by_id.get({ id: workerId });
@@ -736,6 +753,9 @@ export default class Daemon {
736
753
  executorTags(workspaceId) {
737
754
  return this.#engine.executorTags(workspaceId);
738
755
  }
756
+ executorJsonBodyTags(workspaceId) {
757
+ return this.#engine.executorJsonBodyTags(workspaceId);
758
+ }
739
759
  async dispatchClientAction(args) {
740
760
  const workspaceId = ClientInput.assertId("operation.dispatch-batch", "workspaceId", args.workspaceId);
741
761
  const workerId = ClientInput.assertId("operation.dispatch-batch", "workerId", args.workerId);
@@ -941,12 +961,19 @@ export default class Daemon {
941
961
  promptSource: row.promptSource,
942
962
  terminatedAt: row.terminatedAt,
943
963
  packetCount: row.packetCount,
944
- terminalResult: row.terminalResult === null
945
- ? null
946
- : Validator.assertOperationResult(JSON.parse(row.terminalResult))
964
+ // {§validation-topology}: a stored result is chapter 3's (`loops_terminal_result_contract`); it is parsed, not re-asserted.
965
+ terminalResult: row.terminalResult === null ? null : JSON.parse(row.terminalResult)
947
966
  }));
948
967
  }
949
968
  // {§methods-workspace-prompts}: root-conversation loop seeds, newest-first.
969
+ // {§share} — one workspace's share. The daemon names its own database; the caller names an absolute folder.
970
+ async shareWorkspace({ workspaceId, folder }) {
971
+ const checkedWorkspaceId = ClientInput.assertId("workspace.share", "workspaceId", workspaceId);
972
+ const checkedFolder = ClientInput.assertShareFolder("workspace.share", folder);
973
+ if (this.#dbPath === undefined)
974
+ throw new Error("share: this daemon was started without its database path");
975
+ return await Share.write({ dbPath: this.#dbPath, folder: checkedFolder, workspaceId: checkedWorkspaceId });
976
+ }
950
977
  listPrompts(workspaceId, limit) {
951
978
  const checkedWorkspaceId = ClientInput.assertId("workspace.prompts", "workspaceId", workspaceId);
952
979
  const checkedLimit = ClientInput.assertLimit("workspace.prompts", limit);
@@ -1435,6 +1462,10 @@ export default class Daemon {
1435
1462
  notifyReasoningEvent(workspaceId, event) {
1436
1463
  this.#broadcast({ workspaceId }, "reasoning/event", event);
1437
1464
  }
1465
+ /** Emit one admitted emission's text outside every operation ({§notifications-outside-event}). */
1466
+ notifyOutsideEvent(workspaceId, event) {
1467
+ this.#broadcast({ workspaceId }, "outside/event", event);
1468
+ }
1438
1469
  /**
1439
1470
  * Emit a transient notice scoped to the workspace containing the loop.
1440
1471
  */
@@ -1482,7 +1513,7 @@ export default class Daemon {
1482
1513
  policy: first.policy,
1483
1514
  model_route_id: first.model_route_id,
1484
1515
  spawn_model_route_id: first.spawn_model_route_id,
1485
- reasoning_policy: first.reasoning_policy,
1516
+ effort: first.effort,
1486
1517
  max_turns: first.max_turns,
1487
1518
  orphan_source_loop_id: endedLoopId
1488
1519
  });