@osolmaz/pi-workflows 0.16.2 → 0.16.3

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 (315) hide show
  1. package/README.md +41 -41
  2. package/dist/builtins/monitor.workflow.d.ts +1 -1
  3. package/dist/builtins/monitor.workflow.js +8 -8
  4. package/dist/builtins/pi-agent-group.js +3 -3
  5. package/dist/builtins/pi-agent-group.js.map +1 -1
  6. package/dist/channels/adapter-entry.js +14 -14
  7. package/dist/channels/adapter-entry.js.map +1 -1
  8. package/dist/client/client.d.ts +6 -6
  9. package/dist/client/client.js +27 -27
  10. package/dist/client/client.js.map +1 -1
  11. package/dist/client/protocol.d.ts +4 -1
  12. package/dist/client/protocol.js +17 -11
  13. package/dist/client/protocol.js.map +1 -1
  14. package/dist/client/resolver.d.ts +4 -4
  15. package/dist/client/view.d.ts +1 -1
  16. package/dist/extension/index.d.ts +1 -1
  17. package/dist/extension/index.js +32 -32
  18. package/dist/extension/index.js.map +1 -1
  19. package/dist/extension/recorder.d.ts +1 -1
  20. package/dist/extension/recorder.js +1 -1
  21. package/dist/extension/recorder.js.map +1 -1
  22. package/dist/extension/remote-recorder-store.d.ts +1 -1
  23. package/dist/extension/remote-recorder-store.js +2 -2
  24. package/dist/extension/remote-recorder-store.js.map +1 -1
  25. package/dist/extension/{controller-command.d.ts → resource-manager-command.d.ts} +6 -6
  26. package/dist/extension/{controller-command.js → resource-manager-command.js} +7 -7
  27. package/dist/extension/resource-manager-command.js.map +1 -0
  28. package/dist/extension/session-delivery.d.ts +1 -1
  29. package/dist/extension/session-delivery.js +2 -2
  30. package/dist/extension/session-delivery.js.map +1 -1
  31. package/dist/extension/session-view.d.ts +1 -1
  32. package/dist/extension/session-view.js +1 -1
  33. package/dist/extension/session-view.js.map +1 -1
  34. package/dist/extension/workflow-message-coordinator.d.ts +1 -1
  35. package/dist/extension/workflow-message-coordinator.js +6 -6
  36. package/dist/extension/workflow-message-coordinator.js.map +1 -1
  37. package/dist/resource-managers/conditions.d.ts +6 -0
  38. package/dist/{controllers → resource-managers}/conditions.js +3 -3
  39. package/dist/resource-managers/conditions.js.map +1 -0
  40. package/dist/resource-managers/definition.d.ts +6 -0
  41. package/dist/resource-managers/definition.js +45 -0
  42. package/dist/resource-managers/definition.js.map +1 -0
  43. package/dist/resource-managers/effects.d.ts +15 -0
  44. package/dist/{controllers → resource-managers}/effects.js +2 -2
  45. package/dist/resource-managers/effects.js.map +1 -0
  46. package/dist/resource-managers/errors.d.ts +12 -0
  47. package/dist/resource-managers/errors.js +25 -0
  48. package/dist/resource-managers/errors.js.map +1 -0
  49. package/dist/resource-managers/index.d.ts +12 -0
  50. package/dist/resource-managers/index.js +12 -0
  51. package/dist/resource-managers/index.js.map +1 -0
  52. package/dist/resource-managers/json.js.map +1 -0
  53. package/dist/resource-managers/loader.d.ts +23 -0
  54. package/dist/resource-managers/loader.js +75 -0
  55. package/dist/resource-managers/loader.js.map +1 -0
  56. package/dist/resource-managers/results.d.ts +5 -0
  57. package/dist/resource-managers/results.js.map +1 -0
  58. package/dist/resource-managers/runtime.d.ts +59 -0
  59. package/dist/{controllers/manager.js → resource-managers/runtime.js} +57 -57
  60. package/dist/resource-managers/runtime.js.map +1 -0
  61. package/dist/{controllers → resource-managers}/sqlite.d.ts +44 -44
  62. package/dist/{controllers → resource-managers}/sqlite.js +139 -130
  63. package/dist/resource-managers/sqlite.js.map +1 -0
  64. package/dist/{controllers → resource-managers}/store.d.ts +33 -33
  65. package/dist/{controllers → resource-managers}/store.js.map +1 -1
  66. package/dist/{controllers → resource-managers}/types.d.ts +41 -41
  67. package/dist/{controllers → resource-managers}/types.js.map +1 -1
  68. package/dist/resource-managers/workflows.d.ts +34 -0
  69. package/dist/{controllers → resource-managers}/workflows.js +15 -15
  70. package/dist/resource-managers/workflows.js.map +1 -0
  71. package/dist/server/channel-effects.js.map +1 -0
  72. package/dist/{host → server}/channel-supervisor.d.ts +6 -6
  73. package/dist/{host → server}/channel-supervisor.js +3 -3
  74. package/dist/server/channel-supervisor.js.map +1 -0
  75. package/dist/{host/child-worker-supervisor.d.ts → server/child-runner-supervisor.d.ts} +15 -13
  76. package/dist/{host/child-worker-supervisor.js → server/child-runner-supervisor.js} +6 -5
  77. package/dist/server/child-runner-supervisor.js.map +1 -0
  78. package/dist/{host → server}/processes.d.ts +3 -3
  79. package/dist/{host → server}/processes.js +3 -3
  80. package/dist/server/processes.js.map +1 -0
  81. package/dist/{host → server}/resolver-entry.d.ts +6 -6
  82. package/dist/{host → server}/resolver-entry.js +14 -14
  83. package/dist/server/resolver-entry.js.map +1 -0
  84. package/dist/server/resource-runner-entry.d.ts +2 -0
  85. package/dist/{host/controller-worker-entry.js → server/resource-runner-entry.js} +33 -33
  86. package/dist/server/resource-runner-entry.js.map +1 -0
  87. package/dist/server/resource-runner-protocol.d.ts +36 -0
  88. package/dist/server/resource-runner-protocol.js +49 -0
  89. package/dist/server/resource-runner-protocol.js.map +1 -0
  90. package/dist/server/resource-runner-supervisor.d.ts +21 -0
  91. package/dist/{host/worker-supervisor.js → server/resource-runner-supervisor.js} +17 -17
  92. package/dist/server/resource-runner-supervisor.js.map +1 -0
  93. package/dist/{host → server}/rpc-bridge.d.ts +3 -3
  94. package/dist/{host → server}/rpc-bridge.js +3 -3
  95. package/dist/server/rpc-bridge.js.map +1 -0
  96. package/dist/{host → server}/rpc-executor.d.ts +1 -1
  97. package/dist/{host → server}/rpc-executor.js +3 -3
  98. package/dist/server/rpc-executor.js.map +1 -0
  99. package/dist/{host/host-entry.js → server/server-entry.js} +6 -6
  100. package/dist/server/server-entry.js.map +1 -0
  101. package/dist/{host/runner.d.ts → server/server.d.ts} +39 -38
  102. package/dist/{host/runner.js → server/server.js} +408 -374
  103. package/dist/server/server.js.map +1 -0
  104. package/dist/{host → server}/state.d.ts +25 -25
  105. package/dist/{host → server}/state.js +49 -49
  106. package/dist/server/state.js.map +1 -0
  107. package/dist/{host → server}/view.d.ts +7 -7
  108. package/dist/{host → server}/view.js +13 -13
  109. package/dist/server/view.js.map +1 -0
  110. package/dist/server/workflow-runner-content.d.ts +6 -0
  111. package/dist/server/workflow-runner-content.js +96 -0
  112. package/dist/server/workflow-runner-content.js.map +1 -0
  113. package/dist/{host/worker-entry.d.ts → server/workflow-runner-entry.d.ts} +3 -3
  114. package/dist/{host/worker-entry.js → server/workflow-runner-entry.js} +68 -35
  115. package/dist/server/workflow-runner-entry.js.map +1 -0
  116. package/dist/server/workflow-runner-protocol.d.ts +69 -0
  117. package/dist/server/workflow-runner-protocol.js +176 -0
  118. package/dist/server/workflow-runner-protocol.js.map +1 -0
  119. package/dist/{host/worker-store.d.ts → server/workflow-runner-store.d.ts} +11 -11
  120. package/dist/{host/worker-store.js → server/workflow-runner-store.js} +8 -8
  121. package/dist/server/workflow-runner-store.js.map +1 -0
  122. package/dist/server/workflow-runner-supervisor.d.ts +22 -0
  123. package/dist/server/workflow-runner-supervisor.js +56 -0
  124. package/dist/server/workflow-runner-supervisor.js.map +1 -0
  125. package/dist/state/prune.d.ts +1 -1
  126. package/dist/state/prune.js +17 -10
  127. package/dist/state/prune.js.map +1 -1
  128. package/dist/state/schema.js +2 -2
  129. package/dist/state/workflow-messages.d.ts +1 -1
  130. package/dist/state/workflow-messages.js +1 -1
  131. package/dist/state/workflow-messages.js.map +1 -1
  132. package/dist/viewer/backup.js +1 -1
  133. package/dist/viewer/backup.js.map +1 -1
  134. package/dist/viewer/cli.d.ts +2 -2
  135. package/dist/viewer/cli.js +46 -32
  136. package/dist/viewer/cli.js.map +1 -1
  137. package/dist/viewer/tui.d.ts +1 -1
  138. package/dist/viewer/tui.js +1 -1
  139. package/dist/viewer/tui.js.map +1 -1
  140. package/dist/workflows/command-batch.js +2 -2
  141. package/dist/workflows/engine.js +14 -15
  142. package/dist/workflows/engine.js.map +1 -1
  143. package/dist/workflows/store.d.ts +12 -11
  144. package/dist/workflows/store.js +24 -18
  145. package/dist/workflows/store.js.map +1 -1
  146. package/dist/workflows/types.d.ts +2 -2
  147. package/docs/2026-08-20-durable-workflow-launch-plan.md +12 -12
  148. package/docs/2026-08-25-workflow-follow-ups.md +7 -7
  149. package/docs/2026-08-25-workflow-settings.md +3 -3
  150. package/docs/2026-08-30-out-of-process-workflow-host-plan.md +3 -3
  151. package/docs/2026-09-01-restore-session-delivery-controls-plan.md +5 -5
  152. package/docs/2026-09-01-unified-workflow-client-plan.md +6 -6
  153. package/docs/2026-09-02-installed-live-e2e-plan.md +3 -3
  154. package/docs/2026-09-02-unify-workflow-messages-plan.md +8 -8
  155. package/docs/2026-09-04-workflow-run-state-plan.md +6 -6
  156. package/docs/DEFERRED_TURNS.md +7 -7
  157. package/docs/DESIGN_PHILOSOPHY.md +1 -1
  158. package/docs/HUMAN_DECISIONS.md +11 -11
  159. package/docs/HUMAN_DECISION_PRESENTATIONS.md +4 -4
  160. package/docs/MONITOR.md +1 -1
  161. package/docs/RESOURCE_MANAGERS.md +221 -0
  162. package/docs/SQLITE_STATE.md +35 -33
  163. package/docs/WORKFLOW_COMPOSITION.md +1 -1
  164. package/docs/{WORKFLOW_HOST.md → WORKFLOW_SERVER.md} +125 -119
  165. package/docs/WORKFLOW_STEP_MESSAGES.md +18 -18
  166. package/docs/WORKFLOW_UPDATES.md +16 -16
  167. package/docs/development.md +15 -14
  168. package/docs/live-replay-protocol.md +20 -20
  169. package/docs/plans/2026-08-04-controller-runtime-plan.md +25 -25
  170. package/docs/plans/2026-08-05-always-on-workflows-plan.md +8 -8
  171. package/docs/plans/2026-08-10-agent-managed-monitor-workflows-plan.md +2 -2
  172. package/docs/plans/2026-08-13-session-addressed-workflow-notifications-plan.md +1 -1
  173. package/docs/plans/2026-08-16-workflow-updates-plan.md +5 -5
  174. package/docs/plans/2026-08-19-human-decision-gates-plan.md +1 -1
  175. package/docs/plans/2026-08-20-bounded-command-batches-plan.md +1 -1
  176. package/docs/plans/2026-08-21-deferred-turn-intents-plan.md +3 -3
  177. package/docs/plans/2026-08-21-sanity-check-plan.md +2 -2
  178. package/docs/plans/2026-08-23-assistant-agent-completion-plan.md +5 -5
  179. package/docs/plans/2026-08-23-sqlite-state-plan.md +25 -25
  180. package/docs/plans/2026-08-25-live-workflow-settings-plan.md +4 -4
  181. package/docs/plans/2026-08-27-workflow-terminal-restart-plan.md +3 -3
  182. package/docs/plans/2026-09-04-workflow-runner-resume-state-plan.md +318 -0
  183. package/docs/plans/piw-viewer-experience-implementation-plan.md +1 -1
  184. package/docs/tui-viewer.md +9 -9
  185. package/docs/workflows.md +72 -66
  186. package/examples/{controllers/pull-request.controller.ts → resource-managers/pull-request.resource-manager.ts} +12 -12
  187. package/herdr-plugin.toml +1 -1
  188. package/package.json +5 -5
  189. package/protocol/client.v1.schema.json +7 -7
  190. package/protocol/fixtures/client-v1.json +1 -1
  191. package/src/builtins/monitor.workflow.ts +9 -9
  192. package/src/builtins/pi-agent-group.ts +3 -3
  193. package/src/channels/adapter-entry.ts +14 -14
  194. package/src/client/client.ts +33 -32
  195. package/src/client/protocol.ts +16 -11
  196. package/src/client/resolver.ts +4 -4
  197. package/src/client/view.ts +1 -1
  198. package/src/extension/index.ts +44 -34
  199. package/src/extension/recorder.ts +1 -1
  200. package/src/extension/remote-recorder-store.ts +2 -2
  201. package/src/extension/resource-manager-command.ts +45 -0
  202. package/src/extension/session-delivery.ts +2 -2
  203. package/src/extension/session-view.ts +1 -1
  204. package/src/extension/workflow-message-coordinator.ts +6 -6
  205. package/src/{controllers → resource-managers}/conditions.ts +23 -23
  206. package/src/resource-managers/definition.ts +71 -0
  207. package/src/{controllers → resource-managers}/effects.ts +9 -9
  208. package/src/resource-managers/errors.ts +27 -0
  209. package/src/resource-managers/index.ts +88 -0
  210. package/src/resource-managers/loader.ts +111 -0
  211. package/src/{controllers → resource-managers}/results.ts +4 -4
  212. package/src/{controllers/manager.ts → resource-managers/runtime.ts} +95 -92
  213. package/src/{controllers → resource-managers}/sqlite.ts +198 -186
  214. package/src/{controllers → resource-managers}/store.ts +46 -38
  215. package/src/{controllers → resource-managers}/types.ts +50 -41
  216. package/src/{controllers → resource-managers}/workflows.ts +43 -41
  217. package/src/{host → server}/channel-supervisor.ts +8 -8
  218. package/src/{host/child-worker-supervisor.ts → server/child-runner-supervisor.ts} +22 -18
  219. package/src/{host → server}/processes.ts +3 -3
  220. package/src/{host → server}/resolver-entry.ts +28 -25
  221. package/src/{host/controller-worker-entry.ts → server/resource-runner-entry.ts} +67 -65
  222. package/src/server/resource-runner-protocol.ts +103 -0
  223. package/src/server/resource-runner-supervisor.ts +76 -0
  224. package/src/{host → server}/rpc-bridge.ts +3 -3
  225. package/src/{host → server}/rpc-executor.ts +4 -4
  226. package/src/{host/host-entry.ts → server/server-entry.ts} +5 -5
  227. package/src/{host/runner.ts → server/server.ts} +526 -461
  228. package/src/{host → server}/state.ts +78 -67
  229. package/src/{host → server}/view.ts +15 -15
  230. package/src/server/workflow-runner-content.ts +119 -0
  231. package/src/{host/worker-entry.ts → server/workflow-runner-entry.ts} +98 -57
  232. package/src/server/workflow-runner-protocol.ts +241 -0
  233. package/src/{host/worker-store.ts → server/workflow-runner-store.ts} +18 -20
  234. package/src/server/workflow-runner-supervisor.ts +79 -0
  235. package/src/state/prune.ts +27 -9
  236. package/src/state/schema.ts +2 -2
  237. package/src/state/workflow-messages.ts +1 -1
  238. package/src/viewer/backup.ts +1 -1
  239. package/src/viewer/cli.ts +50 -36
  240. package/src/viewer/tui.ts +1 -1
  241. package/src/workflows/command-batch.ts +2 -2
  242. package/src/workflows/engine.ts +14 -15
  243. package/src/workflows/store.ts +31 -28
  244. package/src/workflows/types.ts +2 -2
  245. package/dist/controllers/conditions.d.ts +0 -6
  246. package/dist/controllers/conditions.js.map +0 -1
  247. package/dist/controllers/definition.d.ts +0 -6
  248. package/dist/controllers/definition.js +0 -45
  249. package/dist/controllers/definition.js.map +0 -1
  250. package/dist/controllers/effects.d.ts +0 -15
  251. package/dist/controllers/effects.js.map +0 -1
  252. package/dist/controllers/errors.d.ts +0 -12
  253. package/dist/controllers/errors.js +0 -25
  254. package/dist/controllers/errors.js.map +0 -1
  255. package/dist/controllers/index.d.ts +0 -12
  256. package/dist/controllers/index.js +0 -12
  257. package/dist/controllers/index.js.map +0 -1
  258. package/dist/controllers/json.js.map +0 -1
  259. package/dist/controllers/loader.d.ts +0 -23
  260. package/dist/controllers/loader.js +0 -74
  261. package/dist/controllers/loader.js.map +0 -1
  262. package/dist/controllers/manager.d.ts +0 -59
  263. package/dist/controllers/manager.js.map +0 -1
  264. package/dist/controllers/results.d.ts +0 -5
  265. package/dist/controllers/results.js.map +0 -1
  266. package/dist/controllers/sqlite.js.map +0 -1
  267. package/dist/controllers/workflows.d.ts +0 -34
  268. package/dist/controllers/workflows.js.map +0 -1
  269. package/dist/extension/controller-command.js.map +0 -1
  270. package/dist/host/channel-effects.js.map +0 -1
  271. package/dist/host/channel-supervisor.js.map +0 -1
  272. package/dist/host/child-worker-supervisor.js.map +0 -1
  273. package/dist/host/controller-worker-entry.d.ts +0 -2
  274. package/dist/host/controller-worker-entry.js.map +0 -1
  275. package/dist/host/controller-worker-protocol.d.ts +0 -36
  276. package/dist/host/controller-worker-protocol.js +0 -49
  277. package/dist/host/controller-worker-protocol.js.map +0 -1
  278. package/dist/host/controller-worker-supervisor.d.ts +0 -21
  279. package/dist/host/controller-worker-supervisor.js +0 -54
  280. package/dist/host/controller-worker-supervisor.js.map +0 -1
  281. package/dist/host/host-entry.js.map +0 -1
  282. package/dist/host/processes.js.map +0 -1
  283. package/dist/host/resolver-entry.js.map +0 -1
  284. package/dist/host/rpc-bridge.js.map +0 -1
  285. package/dist/host/rpc-executor.js.map +0 -1
  286. package/dist/host/runner.js.map +0 -1
  287. package/dist/host/state.js.map +0 -1
  288. package/dist/host/view.js.map +0 -1
  289. package/dist/host/worker-entry.js.map +0 -1
  290. package/dist/host/worker-protocol.d.ts +0 -46
  291. package/dist/host/worker-protocol.js +0 -122
  292. package/dist/host/worker-protocol.js.map +0 -1
  293. package/dist/host/worker-store.js.map +0 -1
  294. package/dist/host/worker-supervisor.d.ts +0 -22
  295. package/dist/host/worker-supervisor.js.map +0 -1
  296. package/docs/CONTROLLERS.md +0 -217
  297. package/src/controllers/definition.ts +0 -65
  298. package/src/controllers/errors.ts +0 -27
  299. package/src/controllers/index.ts +0 -88
  300. package/src/controllers/loader.ts +0 -104
  301. package/src/extension/controller-command.ts +0 -45
  302. package/src/host/controller-worker-protocol.ts +0 -104
  303. package/src/host/controller-worker-supervisor.ts +0 -79
  304. package/src/host/worker-protocol.ts +0 -176
  305. package/src/host/worker-supervisor.ts +0 -74
  306. /package/dist/{controllers → resource-managers}/json.d.ts +0 -0
  307. /package/dist/{controllers → resource-managers}/json.js +0 -0
  308. /package/dist/{controllers → resource-managers}/results.js +0 -0
  309. /package/dist/{controllers → resource-managers}/store.js +0 -0
  310. /package/dist/{controllers → resource-managers}/types.js +0 -0
  311. /package/dist/{host → server}/channel-effects.d.ts +0 -0
  312. /package/dist/{host → server}/channel-effects.js +0 -0
  313. /package/dist/{host/host-entry.d.ts → server/server-entry.d.ts} +0 -0
  314. /package/src/{controllers → resource-managers}/json.ts +0 -0
  315. /package/src/{host → server}/channel-effects.ts +0 -0
@@ -6,8 +6,8 @@ import { canonicalJson } from "../state/json.js";
6
6
  import { resourceIdFor, tokenHash } from "../state/mutation.js";
7
7
  import { initializeViewerRun, recordViewerDeltas } from "../state/viewer.js";
8
8
  import { WorkflowMessageStore } from "../state/workflow-messages.js";
9
- import { EffectRequestConflictError, ResourceConflictError, ResourceNotFoundError, WorkflowRequestConflictError, } from "./errors.js";
10
- export class SqliteControllerStore {
9
+ import { EffectRequestConflictError, ManagedResourceConflictError, ManagedResourceNotFoundError, WorkflowRequestConflictError, } from "./errors.js";
10
+ export class SqliteResourceManagerStore {
11
11
  filePath;
12
12
  state;
13
13
  workflowMessages;
@@ -43,27 +43,30 @@ export class SqliteControllerStore {
43
43
  }
44
44
  putResource(options) {
45
45
  this.assertWritable();
46
- validateName(options.controller, "controller");
46
+ validateName(options.resourceManager, "resource manager");
47
47
  validateKey(options.key, "resource key");
48
48
  const now = epoch(validTimestamp(options.now));
49
49
  const specHash = this.state.putJson(options.spec, now);
50
50
  const initialStatus = {
51
51
  observedGeneration: 0,
52
52
  conditions: [],
53
- controllerStatus: options.initialStatus,
53
+ resourceManagerStatus: options.initialStatus,
54
54
  };
55
55
  const statusHash = this.state.putJson(initialStatus, now);
56
56
  return this.state.transaction(() => {
57
- const existing = this.controllerRow({ controller: options.controller, key: options.key });
57
+ const existing = this.resourceManagerRow({
58
+ resourceManager: options.resourceManager,
59
+ key: options.key,
60
+ });
58
61
  if (existing === undefined) {
59
62
  const uid = randomUUID();
60
- const controllerResourceId = `controller-resource-${randomUUID()}`;
61
- const resourceId = resourceIdFor("controller", `${this.requireProjectId()}:${options.controller}:${options.key}`);
63
+ const managedResourceId = `controller-resource-${randomUUID()}`;
64
+ const resourceId = resourceIdFor("controller", `${this.requireProjectId()}:${options.resourceManager}:${options.key}`);
62
65
  this.state.connection
63
66
  .prepare(`INSERT INTO resources(
64
67
  resource_id, resource_type, aggregate_key, revision, created_at, updated_at
65
68
  ) VALUES (?, 'controller', ?, 1, ?, ?)`)
66
- .run(resourceId, controllerResourceId, now, now);
69
+ .run(resourceId, managedResourceId, now, now);
67
70
  this.state.connection
68
71
  .prepare("INSERT INTO leases(resource_id, generation) VALUES (?, 0)")
69
72
  .run(resourceId);
@@ -72,8 +75,8 @@ export class SqliteControllerStore {
72
75
  controller_resource_id, resource_id, project_id, controller_name,
73
76
  resource_key, uid, generation, spec_hash, status_hash, created_at, updated_at
74
77
  ) VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?)`)
75
- .run(controllerResourceId, resourceId, this.requireProjectId(), options.controller, options.key, uid, specHash, statusHash, now, now);
76
- this.enqueueControllerRow(controllerResourceId, now, now);
78
+ .run(managedResourceId, resourceId, this.requireProjectId(), options.resourceManager, options.key, uid, specHash, statusHash, now, now);
79
+ this.enqueueResourceManagerRow(managedResourceId, now, now);
77
80
  this.insertEvent(resourceId, 1, "resource.created", "control", null, { generation: 1 }, now);
78
81
  }
79
82
  else if (!existing.specHash.equals(specHash)) {
@@ -82,26 +85,26 @@ export class SqliteControllerStore {
82
85
  .prepare(`UPDATE controller_resources
83
86
  SET spec_hash = ?, generation = generation + 1, updated_at = ?
84
87
  WHERE controller_resource_id = ?`)
85
- .run(specHash, now, existing.controllerResourceId);
88
+ .run(specHash, now, existing.managedResourceId);
86
89
  this.bumpResource(existing.resourceId, existing.resourceVersion, now);
87
- this.enqueueControllerRow(existing.controllerResourceId, now, now);
90
+ this.enqueueResourceManagerRow(existing.managedResourceId, now, now);
88
91
  this.insertEvent(existing.resourceId, revision, "resource.spec_updated", "control", null, { generation: existing.generation + 1 }, now);
89
92
  }
90
93
  return this.requireResource({
91
- controller: options.controller,
94
+ resourceManager: options.resourceManager,
92
95
  key: options.key,
93
96
  });
94
97
  });
95
98
  }
96
99
  getResource(ref) {
97
- const row = this.controllerRow(ref);
100
+ const row = this.resourceManagerRow(ref);
98
101
  return row === undefined
99
102
  ? undefined
100
- : this.mapControllerResource(row);
103
+ : this.mapManagedResource(row);
101
104
  }
102
105
  getResourceByUid(uid) {
103
- const row = this.state.connection.prepare(controllerSelect("WHERE c.uid = ?")).get(uid);
104
- return isControllerRow(row) ? this.mapControllerResource(row) : undefined;
106
+ const row = this.state.connection.prepare(resourceManagerSelect("WHERE c.uid = ?")).get(uid);
107
+ return isResourceManagerRow(row) ? this.mapManagedResource(row) : undefined;
105
108
  }
106
109
  listResources(options = {}) {
107
110
  const clauses = ["1 = 1"];
@@ -110,31 +113,31 @@ export class SqliteControllerStore {
110
113
  clauses.push("c.project_id = ?");
111
114
  params.push(this.projectId);
112
115
  }
113
- if (options.controller !== undefined) {
116
+ if (options.resourceManager !== undefined) {
114
117
  clauses.push("c.controller_name = ?");
115
- params.push(options.controller);
118
+ params.push(options.resourceManager);
116
119
  }
117
120
  const rows = this.state.connection
118
- .prepare(controllerSelect(`WHERE ${clauses.join(" AND ")} ORDER BY c.controller_name, c.resource_key`))
121
+ .prepare(resourceManagerSelect(`WHERE ${clauses.join(" AND ")} ORDER BY c.controller_name, c.resource_key`))
119
122
  .all(...params);
120
123
  return rows
121
- .filter(isControllerRow)
122
- .map((row) => this.mapControllerResource(row));
124
+ .filter(isResourceManagerRow)
125
+ .map((row) => this.mapManagedResource(row));
123
126
  }
124
127
  updateStatus(options) {
125
128
  const now = epoch(validTimestamp(options.now));
126
129
  return this.state.transaction(() => {
127
- const row = this.requireControllerRow(options.ref);
128
- this.assertControllerClaim(row, options.claim, now);
130
+ const row = this.requireResourceManagerRow(options.ref);
131
+ this.assertResourceManagerClaim(row, options.claim, now);
129
132
  if (row.resourceVersion !== options.expectedResourceVersion) {
130
- throw new ResourceConflictError(options.ref.controller, options.ref.key);
133
+ throw new ManagedResourceConflictError(options.ref.resourceManager, options.ref.key);
131
134
  }
132
135
  const statusHash = this.state.putJson(options.status, now);
133
136
  this.state.connection
134
137
  .prepare("UPDATE controller_resources SET status_hash = ?, updated_at = ? WHERE controller_resource_id = ?")
135
- .run(statusHash, now, row.controllerResourceId);
138
+ .run(statusHash, now, row.managedResourceId);
136
139
  if (options.finalizers !== undefined)
137
- this.replaceFinalizers(row.controllerResourceId, options.finalizers);
140
+ this.replaceFinalizers(row.managedResourceId, options.finalizers);
138
141
  this.bumpResource(row.resourceId, row.resourceVersion, now);
139
142
  this.insertEvent(row.resourceId, row.resourceVersion + 1, "resource.status_updated", "controller", options.claim.ownerId, {}, now, options.claim.generation);
140
143
  options.claim.resourceVersion = row.resourceVersion + 1;
@@ -144,13 +147,13 @@ export class SqliteControllerStore {
144
147
  requestDeletion(ref, nowValue) {
145
148
  const now = epoch(validTimestamp(nowValue));
146
149
  return this.state.transaction(() => {
147
- const row = this.requireControllerRow(ref);
150
+ const row = this.requireResourceManagerRow(ref);
148
151
  if (row.deletionRequestedAt === null) {
149
152
  this.state.connection
150
153
  .prepare("UPDATE controller_resources SET deletion_requested_at = ?, updated_at = ? WHERE controller_resource_id = ?")
151
- .run(now, now, row.controllerResourceId);
154
+ .run(now, now, row.managedResourceId);
152
155
  this.bumpResource(row.resourceId, row.resourceVersion, now);
153
- this.enqueueControllerRow(row.controllerResourceId, now, now);
156
+ this.enqueueResourceManagerRow(row.managedResourceId, now, now);
154
157
  this.insertEvent(row.resourceId, row.resourceVersion + 1, "resource.deletion_requested", "control", null, {}, now);
155
158
  }
156
159
  return this.requireResource(ref);
@@ -159,14 +162,14 @@ export class SqliteControllerStore {
159
162
  updateFinalizers(options) {
160
163
  const now = epoch(validTimestamp(options.now));
161
164
  return this.state.transaction(() => {
162
- const row = this.requireControllerRow(options.ref);
165
+ const row = this.requireResourceManagerRow(options.ref);
163
166
  if (row.resourceVersion !== options.expectedResourceVersion) {
164
- throw new ResourceConflictError(options.ref.controller, options.ref.key);
167
+ throw new ManagedResourceConflictError(options.ref.resourceManager, options.ref.key);
165
168
  }
166
- this.replaceFinalizers(row.controllerResourceId, options.finalizers);
169
+ this.replaceFinalizers(row.managedResourceId, options.finalizers);
167
170
  this.state.connection
168
171
  .prepare("UPDATE controller_resources SET updated_at = ? WHERE controller_resource_id = ?")
169
- .run(now, row.controllerResourceId);
172
+ .run(now, row.managedResourceId);
170
173
  this.bumpResource(row.resourceId, row.resourceVersion, now);
171
174
  this.insertEvent(row.resourceId, row.resourceVersion + 1, "resource.finalizers_updated", "control", null, {}, now);
172
175
  return this.requireResource(options.ref);
@@ -174,37 +177,37 @@ export class SqliteControllerStore {
174
177
  }
175
178
  deleteResource(ref, expectedResourceVersion, claim) {
176
179
  return this.state.transaction(() => {
177
- const row = this.requireControllerRow(ref);
178
- this.assertControllerClaim(row, claim, Date.now());
180
+ const row = this.requireResourceManagerRow(ref);
181
+ this.assertResourceManagerClaim(row, claim, Date.now());
179
182
  if (row.resourceVersion !== expectedResourceVersion) {
180
- throw new ResourceConflictError(ref.controller, ref.key);
183
+ throw new ManagedResourceConflictError(ref.resourceManager, ref.key);
181
184
  }
182
- if (row.deletionRequestedAt === null || this.finalizers(row.controllerResourceId).length > 0)
185
+ if (row.deletionRequestedAt === null || this.finalizers(row.managedResourceId).length > 0)
183
186
  return false;
184
187
  this.state.connection
185
188
  .prepare("DELETE FROM controller_resources WHERE controller_resource_id = ?")
186
- .run(row.controllerResourceId);
189
+ .run(row.managedResourceId);
187
190
  return true;
188
191
  });
189
192
  }
190
193
  enqueue(ref, availableAt) {
191
- const row = this.requireControllerRow(ref);
194
+ const row = this.requireResourceManagerRow(ref);
192
195
  const now = Date.now();
193
- this.enqueueControllerRow(row.controllerResourceId, epoch(validTimestamp(availableAt)), now);
196
+ this.enqueueResourceManagerRow(row.managedResourceId, epoch(validTimestamp(availableAt)), now);
194
197
  }
195
198
  claimNext(options) {
196
- if (options.controllers.length === 0)
199
+ if (options.resourceManagers.length === 0)
197
200
  return undefined;
198
201
  const now = epoch(validTimestamp(options.now));
199
- const placeholders = options.controllers.map(() => "?").join(", ");
202
+ const placeholders = options.resourceManagers.map(() => "?").join(", ");
200
203
  const exclusions = options.exclude ?? [];
201
204
  const exclusionSql = exclusions
202
205
  .map(() => "AND NOT (c.controller_name = ? AND c.resource_key = ?)")
203
206
  .join("\n ");
204
- const exclusionParams = exclusions.flatMap((ref) => [ref.controller, ref.key]);
207
+ const exclusionParams = exclusions.flatMap((ref) => [ref.resourceManager, ref.key]);
205
208
  return this.state.transaction(() => {
206
209
  const row = this.state.connection
207
- .prepare(`${controllerSelect(`
210
+ .prepare(`${resourceManagerSelect(`
208
211
  JOIN controller_queue q ON q.controller_resource_id = c.controller_resource_id
209
212
  JOIN leases l ON l.resource_id = c.resource_id
210
213
  WHERE c.project_id = ?
@@ -214,8 +217,8 @@ export class SqliteControllerStore {
214
217
  AND (l.owner_id IS NULL OR l.expires_at <= ?)
215
218
  ORDER BY q.available_at, c.controller_name, c.resource_key
216
219
  LIMIT 1`)}`)
217
- .get(this.requireProjectId(), ...options.controllers, ...exclusionParams, now, now);
218
- if (!isControllerRow(row))
220
+ .get(this.requireProjectId(), ...options.resourceManagers, ...exclusionParams, now, now);
221
+ if (!isResourceManagerRow(row))
219
222
  return undefined;
220
223
  const lease = this.requireLease(row.resourceId);
221
224
  const token = randomBytes(32).toString("base64url");
@@ -234,14 +237,14 @@ export class SqliteControllerStore {
234
237
  this.bumpResource(row.resourceId, row.resourceVersion, now);
235
238
  this.insertEvent(row.resourceId, row.resourceVersion + 1, "lease.claimed", "controller", options.ownerId, { expiresAt }, now, generation);
236
239
  return {
237
- controller: row.controllerName,
240
+ resourceManager: row.resourceManagerName,
238
241
  key: row.resourceKey,
239
242
  ownerId: options.ownerId,
240
243
  token,
241
244
  generation,
242
- queueVersion: this.queueVersion(row.controllerResourceId),
245
+ queueVersion: this.queueVersion(row.managedResourceId),
243
246
  resourceVersion: row.resourceVersion + 1,
244
- consecutiveErrors: this.queueErrors(row.controllerResourceId),
247
+ consecutiveErrors: this.queueErrors(row.managedResourceId),
245
248
  expiresAt: new Date(expiresAt).toISOString(),
246
249
  };
247
250
  });
@@ -249,7 +252,7 @@ export class SqliteControllerStore {
249
252
  renewClaim(claim, leaseMs, nowValue) {
250
253
  const now = epoch(validTimestamp(nowValue));
251
254
  const expiresAt = now + leaseMs;
252
- const row = this.controllerRow({ controller: claim.controller, key: claim.key });
255
+ const row = this.resourceManagerRow({ resourceManager: claim.resourceManager, key: claim.key });
253
256
  if (row === undefined)
254
257
  return false;
255
258
  const result = this.state.connection
@@ -262,14 +265,14 @@ export class SqliteControllerStore {
262
265
  return result.changes === 1;
263
266
  }
264
267
  settleClaim(claim, nowValue) {
265
- return this.settleControllerClaim(claim, undefined, nowValue);
268
+ return this.settleResourceManagerClaim(claim, undefined, nowValue);
266
269
  }
267
270
  requeueClaim(claim, options, nowValue) {
268
- return this.settleControllerClaim(claim, options, nowValue);
271
+ return this.settleResourceManagerClaim(claim, options, nowValue);
269
272
  }
270
273
  listQueue() {
271
274
  const rows = this.state.connection
272
- .prepare(`SELECT c.controller_name AS controller, c.resource_key AS resourceKey,
275
+ .prepare(`SELECT c.controller_name AS resourceManager, c.resource_key AS resourceKey,
273
276
  q.available_at AS availableAt, q.consecutive_errors AS consecutiveErrors,
274
277
  l.expires_at AS claimExpiresAt
275
278
  FROM controller_queue q
@@ -278,7 +281,7 @@ export class SqliteControllerStore {
278
281
  WHERE c.project_id = ? ORDER BY q.available_at, c.controller_name, c.resource_key`)
279
282
  .all(this.requireProjectId());
280
283
  return rows.filter(isQueueListRow).map((row) => ({
281
- controller: row.controller,
284
+ resourceManager: row.resourceManager,
282
285
  key: row.resourceKey,
283
286
  availableAt: new Date(row.availableAt).toISOString(),
284
287
  consecutiveErrors: row.consecutiveErrors,
@@ -290,8 +293,8 @@ export class SqliteControllerStore {
290
293
  reserveEffect(options) {
291
294
  const now = epoch(validTimestamp(options.now));
292
295
  return this.state.transaction(() => {
293
- const source = this.requireControllerRowByUid(options.resourceUid);
294
- this.assertControllerClaim(source, options.claim, now);
296
+ const source = this.requireResourceManagerRowByUid(options.resourceUid);
297
+ this.assertResourceManagerClaim(source, options.claim, now);
295
298
  const effectId = effectIdFor(source.resourceId, options.key);
296
299
  const existing = this.effectRow(options.resourceUid, options.key);
297
300
  if (existing !== undefined) {
@@ -338,8 +341,8 @@ export class SqliteControllerStore {
338
341
  updateEffect(options) {
339
342
  const now = epoch(validTimestamp(options.now));
340
343
  return this.state.transaction(() => {
341
- const source = this.requireControllerRowByUid(options.resourceUid);
342
- this.assertControllerClaim(source, options.claim, now);
344
+ const source = this.requireResourceManagerRowByUid(options.resourceUid);
345
+ this.assertResourceManagerClaim(source, options.claim, now);
343
346
  const row = this.requireEffectRow(options.resourceUid, options.key);
344
347
  const effectResourceId = resourceIdFor("effect", row.effectId);
345
348
  const revision = this.resourceRevision(effectResourceId);
@@ -363,8 +366,8 @@ export class SqliteControllerStore {
363
366
  reserveWorkflow(options) {
364
367
  const now = Date.now();
365
368
  return this.state.transaction(() => {
366
- const source = this.requireControllerRowByUid(options.resourceUid);
367
- this.assertControllerClaim(source, options.claim, now);
369
+ const source = this.requireResourceManagerRowByUid(options.resourceUid);
370
+ this.assertResourceManagerClaim(source, options.claim, now);
368
371
  const existing = this.workflowRow(options.resourceUid, options.requestKey);
369
372
  if (existing !== undefined) {
370
373
  if (existing.workflowName !== options.workflow ||
@@ -379,7 +382,7 @@ export class SqliteControllerStore {
379
382
  request_id, controller_resource_id, request_key, workflow_name,
380
383
  input_fingerprint, status, attempt_count, created_at, updated_at
381
384
  ) VALUES (?, ?, ?, ?, ?, 'pending', 0, ?, ?)`)
382
- .run(requestId, source.controllerResourceId, options.requestKey, options.workflow, Buffer.from(options.inputFingerprint, "hex"), now, now);
385
+ .run(requestId, source.managedResourceId, options.requestKey, options.workflow, Buffer.from(options.inputFingerprint, "hex"), now, now);
383
386
  return { record: this.mapWorkflow(this.requireWorkflowRow(requestId)), created: true };
384
387
  });
385
388
  }
@@ -395,8 +398,8 @@ export class SqliteControllerStore {
395
398
  const now = Date.now();
396
399
  return this.state.transaction(() => {
397
400
  const row = this.requireWorkflowRow(requestId);
398
- const source = this.requireControllerRowByUid(row.resourceUid);
399
- this.assertControllerClaim(source, claim, now);
401
+ const source = this.requireResourceManagerRowByUid(row.resourceUid);
402
+ this.assertResourceManagerClaim(source, claim, now);
400
403
  const errorHash = update.error === undefined || update.error === null
401
404
  ? null
402
405
  : this.state.putText(update.error, now);
@@ -422,7 +425,7 @@ export class SqliteControllerStore {
422
425
  if (update.runId !== undefined && row.runId !== null && update.runId !== row.runId) {
423
426
  throw new Error("Scheduler completion run ID does not match the reserved child run");
424
427
  }
425
- const source = this.requireControllerRowByUid(row.resourceUid);
428
+ const source = this.requireResourceManagerRowByUid(row.resourceUid);
426
429
  const now = Date.now();
427
430
  return this.state.transaction(() => {
428
431
  const errorHash = update.error === undefined || update.error === null
@@ -453,9 +456,12 @@ export class SqliteControllerStore {
453
456
  recordEvent(options) {
454
457
  const now = epoch(validTimestamp(options.now));
455
458
  return this.state.transaction(() => {
456
- const row = this.requireControllerRow({ controller: options.controller, key: options.key });
459
+ const row = this.requireResourceManagerRow({
460
+ resourceManager: options.resourceManager,
461
+ key: options.key,
462
+ });
457
463
  if (options.claim !== undefined)
458
- this.assertControllerClaim(row, options.claim, now);
464
+ this.assertResourceManagerClaim(row, options.claim, now);
459
465
  const revision = this.resourceRevision(row.resourceId) + 1;
460
466
  this.bumpResource(row.resourceId, revision - 1, now);
461
467
  const eventId = this.insertEvent(row.resourceId, revision, options.type, options.claim === undefined ? "control" : "controller", options.claim?.ownerId ?? null, options.payload ?? {}, now, options.claim?.generation);
@@ -466,11 +472,11 @@ export class SqliteControllerStore {
466
472
  .get(eventId);
467
473
  /* istanbul ignore if -- exact schema and internal query shape */
468
474
  if (!isSequenceRow(event))
469
- throw new Error("Controller event was not recorded");
475
+ throw new Error("ResourceManager event was not recorded");
470
476
  return {
471
477
  seq: event.seq,
472
478
  recordedAt: new Date(now).toISOString(),
473
- controller: options.controller,
479
+ resourceManager: options.resourceManager,
474
480
  key: options.key,
475
481
  type: options.type,
476
482
  payload: options.payload ?? {},
@@ -484,9 +490,9 @@ export class SqliteControllerStore {
484
490
  clauses.push("c.project_id = ?");
485
491
  params.push(this.projectId);
486
492
  }
487
- if (options.controller !== undefined) {
493
+ if (options.resourceManager !== undefined) {
488
494
  clauses.push("c.controller_name = ?");
489
- params.push(options.controller);
495
+ params.push(options.resourceManager);
490
496
  }
491
497
  if (options.key !== undefined) {
492
498
  clauses.push("c.resource_key = ?");
@@ -495,7 +501,7 @@ export class SqliteControllerStore {
495
501
  params.push(options.limit ?? 100);
496
502
  const rows = this.state.connection
497
503
  .prepare(`SELECT e.event_seq AS seq, e.recorded_at AS recordedAt,
498
- c.controller_name AS controller, c.resource_key AS resourceKey,
504
+ c.controller_name AS resourceManager, c.resource_key AS resourceKey,
499
505
  e.event_type AS eventType, e.payload_hash AS payloadHash
500
506
  FROM events e
501
507
  JOIN resources r ON r.resource_id = e.resource_id
@@ -503,10 +509,10 @@ export class SqliteControllerStore {
503
509
  WHERE ${clauses.join(" AND ")}
504
510
  ORDER BY e.event_seq DESC LIMIT ?`)
505
511
  .all(...params);
506
- return rows.filter(isControllerEventRow).map((row) => ({
512
+ return rows.filter(isResourceManagerEventRow).map((row) => ({
507
513
  seq: row.seq,
508
514
  recordedAt: new Date(row.recordedAt).toISOString(),
509
- controller: row.controller,
515
+ resourceManager: row.resourceManager,
510
516
  key: row.resourceKey,
511
517
  type: row.eventType,
512
518
  payload: row.payloadHash === null ? {} : this.state.readJson(row.payloadHash),
@@ -750,14 +756,14 @@ export class SqliteControllerStore {
750
756
  const now = epoch(validTimestamp(options.now));
751
757
  return this.claimRun(options.runId, options.runnerId, options.claimToken, options.leaseMs, now);
752
758
  }
753
- /** Schedule a worker that validates one pending interactive submission. */
759
+ /** Schedule a runner that validates one pending interactive submission. */
754
760
  claimWorkflowRunForInteractionValidation(options) {
755
761
  const now = epoch(validTimestamp(options.now));
756
762
  return this.claimRun(options.runId, options.runnerId, options.claimToken, options.leaseMs, now, {
757
763
  allowPendingInteraction: true,
758
764
  });
759
765
  }
760
- /** Take a short host claim without scheduling a parked interactive run. */
766
+ /** Take a short server claim without scheduling a parked interactive run. */
761
767
  claimWorkflowRunForControl(options) {
762
768
  const now = epoch(validTimestamp(options.now));
763
769
  return this.claimRun(options.runId, options.runnerId, options.claimToken, options.leaseMs, now, { allowPendingInteraction: true, preserveQueueStatus: true });
@@ -836,7 +842,7 @@ export class SqliteControllerStore {
836
842
  "(q.affinity_runner_id IS NULL OR q.affinity_runner_id = ? OR q.status IN ('parked', 'starting', 'running'))",
837
843
  "NOT (q.status = 'parked' AND (r.status = 'waiting' OR r.paused = 1))",
838
844
  "NOT EXISTS (SELECT 1 FROM interactive_requests i WHERE i.run_id = r.run_id AND i.status = 'pending')",
839
- "(q.error_code IS NULL OR q.error_code NOT IN ('workflowSourceChanged', 'workerNoProgress'))",
845
+ "(q.error_code IS NULL OR q.error_code NOT IN ('workflowSourceChanged', 'runnerNoProgress'))",
840
846
  ];
841
847
  const params = [now, now, options.runnerId, options.runnerId];
842
848
  if (this.projectId !== null) {
@@ -910,7 +916,7 @@ export class SqliteControllerStore {
910
916
  parkWorkflowRun(options) {
911
917
  return this.releaseRunClaim(options.runId, options.claimToken, "parked", options.now);
912
918
  }
913
- parkWorkflowRunForWorkerNoProgress(options) {
919
+ parkWorkflowRunForRunnerNoProgress(options) {
914
920
  const now = epoch(validTimestamp(options.now));
915
921
  return this.state.transaction(() => {
916
922
  if (!this.verifyWorkflowRunClaim({
@@ -930,12 +936,12 @@ export class SqliteControllerStore {
930
936
  .run(detail, now, options.runId);
931
937
  const queue = this.state.connection
932
938
  .prepare(`UPDATE run_queue
933
- SET status = 'parked', error_code = 'workerNoProgress', error_hash = ?,
939
+ SET status = 'parked', error_code = 'runnerNoProgress', error_hash = ?,
934
940
  available_at = ?, updated_at = ?, finished_at = NULL
935
941
  WHERE run_id = ? AND status IN ('queued', 'starting', 'running', 'parked')`)
936
942
  .run(errorHash, now, now, options.runId);
937
943
  if (run.changes !== 1 || queue.changes !== 1) {
938
- throw new Error(`Workflow run ${options.runId} changed during worker recovery`);
944
+ throw new Error(`Workflow run ${options.runId} changed during runner recovery`);
939
945
  }
940
946
  const released = this.state.connection
941
947
  .prepare(`UPDATE leases
@@ -945,11 +951,11 @@ export class SqliteControllerStore {
945
951
  .run(row.resourceId, tokenHash(options.claimToken), lease.generation, now);
946
952
  /* istanbul ignore if -- the exact live claim is stable in this transaction */
947
953
  if (released.changes !== 1) {
948
- throw new Error(`Workflow run ${options.runId} claim changed during worker recovery`);
954
+ throw new Error(`Workflow run ${options.runId} claim changed during runner recovery`);
949
955
  }
950
956
  const revision = this.resourceRevision(row.resourceId);
951
957
  this.bumpResource(row.resourceId, revision, now);
952
- this.insertEvent(row.resourceId, revision + 1, "run.worker_no_progress", lease.ownerType ?? "system", lease.ownerId, { status: "parked", code: "workerNoProgress" }, now, lease.generation || undefined);
958
+ this.insertEvent(row.resourceId, revision + 1, "run.worker_no_progress", lease.ownerType ?? "system", lease.ownerId, { status: "parked", code: "runnerNoProgress" }, now, lease.generation || undefined);
953
959
  recordViewerDeltas(this.state, options.runId, [{ targetType: "summary" }, { targetType: "replay" }], now);
954
960
  return true;
955
961
  });
@@ -1309,73 +1315,73 @@ export class SqliteControllerStore {
1309
1315
  }
1310
1316
  requireProjectId() {
1311
1317
  if (this.projectId === null)
1312
- throw new Error("Controller project is not registered in the state database");
1318
+ throw new Error("ResourceManager project is not registered in the state database");
1313
1319
  return this.projectId;
1314
1320
  }
1315
- controllerRow(ref) {
1321
+ resourceManagerRow(ref) {
1316
1322
  if (this.projectId === null)
1317
1323
  return undefined;
1318
1324
  const row = this.state.connection
1319
- .prepare(controllerSelect("WHERE c.project_id = ? AND c.controller_name = ? AND c.resource_key = ?"))
1320
- .get(this.projectId, ref.controller, ref.key);
1321
- return isControllerRow(row) ? row : undefined;
1325
+ .prepare(resourceManagerSelect("WHERE c.project_id = ? AND c.controller_name = ? AND c.resource_key = ?"))
1326
+ .get(this.projectId, ref.resourceManager, ref.key);
1327
+ return isResourceManagerRow(row) ? row : undefined;
1322
1328
  }
1323
- requireControllerRow(ref) {
1324
- const row = this.controllerRow(ref);
1329
+ requireResourceManagerRow(ref) {
1330
+ const row = this.resourceManagerRow(ref);
1325
1331
  if (row === undefined)
1326
- throw new ResourceNotFoundError(ref.controller, ref.key);
1332
+ throw new ManagedResourceNotFoundError(ref.resourceManager, ref.key);
1327
1333
  return row;
1328
1334
  }
1329
- requireControllerRowByUid(uid) {
1330
- const row = this.state.connection.prepare(controllerSelect("WHERE c.uid = ?")).get(uid);
1335
+ requireResourceManagerRowByUid(uid) {
1336
+ const row = this.state.connection.prepare(resourceManagerSelect("WHERE c.uid = ?")).get(uid);
1331
1337
  /* istanbul ignore if -- impossible after exact schema and transaction checks */
1332
- if (!isControllerRow(row))
1333
- throw new Error(`Controller resource not found: ${uid}`);
1338
+ if (!isResourceManagerRow(row))
1339
+ throw new Error(`Managed resource not found: ${uid}`);
1334
1340
  return row;
1335
1341
  }
1336
1342
  requireResource(ref) {
1337
1343
  const resource = this.getResource(ref);
1338
1344
  if (resource === undefined)
1339
- throw new ResourceNotFoundError(ref.controller, ref.key);
1345
+ throw new ManagedResourceNotFoundError(ref.resourceManager, ref.key);
1340
1346
  return resource;
1341
1347
  }
1342
1348
  /* istanbul ignore next -- pure projection covered by integration tests */
1343
- mapControllerResource(row) {
1349
+ mapManagedResource(row) {
1344
1350
  const spec = this.state.readJson(row.specHash);
1345
1351
  const status = this.state.readJson(row.statusHash);
1346
1352
  return {
1347
1353
  metadata: {
1348
1354
  uid: row.uid,
1349
- controller: row.controllerName,
1355
+ resourceManager: row.resourceManagerName,
1350
1356
  key: row.resourceKey,
1351
1357
  resourceVersion: row.resourceVersion,
1352
1358
  generation: row.generation,
1353
1359
  ...(row.deletionRequestedAt === null
1354
1360
  ? {}
1355
1361
  : { deletionTimestamp: new Date(row.deletionRequestedAt).toISOString() }),
1356
- finalizers: this.finalizers(row.controllerResourceId),
1362
+ finalizers: this.finalizers(row.managedResourceId),
1357
1363
  },
1358
1364
  spec,
1359
1365
  status,
1360
1366
  };
1361
1367
  }
1362
- finalizers(controllerResourceId) {
1368
+ finalizers(managedResourceId) {
1363
1369
  const rows = this.state.connection
1364
1370
  .prepare("SELECT finalizer FROM controller_finalizers WHERE controller_resource_id = ? ORDER BY position")
1365
- .all(controllerResourceId);
1371
+ .all(managedResourceId);
1366
1372
  return rows.flatMap((row) => (isFinalizerRow(row) ? [row.finalizer] : []));
1367
1373
  }
1368
- replaceFinalizers(controllerResourceId, finalizers) {
1374
+ replaceFinalizers(managedResourceId, finalizers) {
1369
1375
  const unique = [...new Set(finalizers)];
1370
1376
  if (unique.length !== finalizers.length)
1371
- throw new Error("Controller finalizers must be unique");
1377
+ throw new Error("ResourceManager finalizers must be unique");
1372
1378
  this.state.connection
1373
1379
  .prepare("DELETE FROM controller_finalizers WHERE controller_resource_id = ?")
1374
- .run(controllerResourceId);
1380
+ .run(managedResourceId);
1375
1381
  const insert = this.state.connection.prepare("INSERT INTO controller_finalizers(controller_resource_id, finalizer, position) VALUES (?, ?, ?)");
1376
- unique.forEach((finalizer, index) => insert.run(controllerResourceId, finalizer, index));
1382
+ unique.forEach((finalizer, index) => insert.run(managedResourceId, finalizer, index));
1377
1383
  }
1378
- enqueueControllerRow(controllerResourceId, availableAt, now) {
1384
+ enqueueResourceManagerRow(managedResourceId, availableAt, now) {
1379
1385
  this.state.connection
1380
1386
  .prepare(`INSERT INTO controller_queue(
1381
1387
  controller_resource_id, available_at, queue_version,
@@ -1385,42 +1391,45 @@ export class SqliteControllerStore {
1385
1391
  available_at = MIN(controller_queue.available_at, excluded.available_at),
1386
1392
  queue_version = controller_queue.queue_version + 1,
1387
1393
  updated_at = excluded.updated_at`)
1388
- .run(controllerResourceId, availableAt, now, now);
1394
+ .run(managedResourceId, availableAt, now, now);
1389
1395
  }
1390
- queueErrors(controllerResourceId) {
1396
+ queueErrors(managedResourceId) {
1391
1397
  const row = this.state.connection
1392
1398
  .prepare("SELECT consecutive_errors AS consecutiveErrors FROM controller_queue WHERE controller_resource_id = ?")
1393
- .get(controllerResourceId);
1399
+ .get(managedResourceId);
1394
1400
  return isErrorCountRow(row) ? row.consecutiveErrors : 0;
1395
1401
  }
1396
- queueVersion(controllerResourceId) {
1402
+ queueVersion(managedResourceId) {
1397
1403
  const row = this.state.connection
1398
1404
  .prepare("SELECT queue_version AS queueVersion FROM controller_queue WHERE controller_resource_id = ?")
1399
- .get(controllerResourceId);
1405
+ .get(managedResourceId);
1400
1406
  /* istanbul ignore if -- exact schema and internal query shape */
1401
1407
  /* istanbul ignore if -- impossible after exact schema and transaction checks */
1402
1408
  if (!isQueueVersionRow(row))
1403
- throw new Error("Controller queue item is missing");
1409
+ throw new Error("ResourceManager queue item is missing");
1404
1410
  return row.queueVersion;
1405
1411
  }
1406
- settleControllerClaim(claim, requeue, nowValue) {
1412
+ settleResourceManagerClaim(claim, requeue, nowValue) {
1407
1413
  const now = epoch(validTimestamp(nowValue));
1408
1414
  return this.state.transaction(() => {
1409
- const row = this.controllerRow({ controller: claim.controller, key: claim.key });
1415
+ const row = this.resourceManagerRow({
1416
+ resourceManager: claim.resourceManager,
1417
+ key: claim.key,
1418
+ });
1410
1419
  if (row === undefined)
1411
1420
  return false;
1412
1421
  try {
1413
- this.assertControllerClaim(row, claim, now, false);
1422
+ this.assertResourceManagerClaim(row, claim, now, false);
1414
1423
  }
1415
1424
  catch {
1416
1425
  return false;
1417
1426
  }
1418
- const currentQueueVersion = this.queueVersion(row.controllerResourceId);
1427
+ const currentQueueVersion = this.queueVersion(row.managedResourceId);
1419
1428
  if (requeue === undefined) {
1420
1429
  if (currentQueueVersion === claim.queueVersion) {
1421
1430
  this.state.connection
1422
1431
  .prepare("DELETE FROM controller_queue WHERE controller_resource_id = ?")
1423
- .run(row.controllerResourceId);
1432
+ .run(row.managedResourceId);
1424
1433
  }
1425
1434
  }
1426
1435
  else {
@@ -1430,15 +1439,15 @@ export class SqliteControllerStore {
1430
1439
  SET available_at = ?, queue_version = queue_version + 1,
1431
1440
  consecutive_errors = consecutive_errors + 1,
1432
1441
  last_error_hash = ?, updated_at = ? WHERE controller_resource_id = ?`)
1433
- .run(epoch(requeue.availableAt), errorHash, now, row.controllerResourceId);
1442
+ .run(epoch(requeue.availableAt), errorHash, now, row.managedResourceId);
1434
1443
  }
1435
1444
  this.releaseLease(row.resourceId, claim, now);
1436
1445
  return true;
1437
1446
  });
1438
1447
  }
1439
- assertControllerClaim(row, claim, now, requireUnexpired = true) {
1440
- if (row.controllerName !== claim.controller || row.resourceKey !== claim.key)
1441
- throw new Error("Controller claim targets another resource");
1448
+ assertResourceManagerClaim(row, claim, now, requireUnexpired = true) {
1449
+ if (row.resourceManagerName !== claim.resourceManager || row.resourceKey !== claim.key)
1450
+ throw new Error("ResourceManager claim targets another resource");
1442
1451
  const lease = this.requireLease(row.resourceId);
1443
1452
  if (lease.ownerType !== "controller" ||
1444
1453
  lease.ownerId !== claim.ownerId ||
@@ -1446,7 +1455,7 @@ export class SqliteControllerStore {
1446
1455
  lease.tokenHash === null ||
1447
1456
  !lease.tokenHash.equals(tokenHash(claim.token)) ||
1448
1457
  (requireUnexpired && (lease.expiresAt === null || lease.expiresAt <= now))) {
1449
- throw new Error("Controller claim is stale");
1458
+ throw new Error("ResourceManager claim is stale");
1450
1459
  }
1451
1460
  }
1452
1461
  requireLease(resourceId) {
@@ -1462,7 +1471,7 @@ export class SqliteControllerStore {
1462
1471
  return row;
1463
1472
  }
1464
1473
  releaseLease(resourceId, claim, now) {
1465
- const row = this.controllerRow({ controller: claim.controller, key: claim.key });
1474
+ const row = this.resourceManagerRow({ resourceManager: claim.resourceManager, key: claim.key });
1466
1475
  if (row === undefined)
1467
1476
  return;
1468
1477
  const revision = this.resourceRevision(resourceId);
@@ -1537,7 +1546,7 @@ export class SqliteControllerStore {
1537
1546
  resourceUid: row.resourceUid,
1538
1547
  generation: row.generation,
1539
1548
  kind: row.kind,
1540
- state: controllerEffectState(row.state),
1549
+ state: resourceManagerEffectState(row.state),
1541
1550
  requestFingerprint: row.requestFingerprint,
1542
1551
  startedAt: new Date(row.startedAt).toISOString(),
1543
1552
  ...(row.completedAt === null ? {} : { completedAt: new Date(row.completedAt).toISOString() }),
@@ -1893,13 +1902,13 @@ export class SqliteControllerStore {
1893
1902
  }
1894
1903
  assertWritable() {
1895
1904
  if (this.state.mode === "read-only")
1896
- throw new Error("Controller store is read-only");
1905
+ throw new Error("ResourceManager store is read-only");
1897
1906
  }
1898
1907
  }
1899
- function controllerSelect(clause) {
1900
- return `SELECT c.controller_resource_id AS controllerResourceId,
1908
+ function resourceManagerSelect(clause) {
1909
+ return `SELECT c.controller_resource_id AS managedResourceId,
1901
1910
  c.resource_id AS resourceId, r.revision AS resourceVersion,
1902
- c.controller_name AS controllerName, c.resource_key AS resourceKey,
1911
+ c.controller_name AS resourceManagerName, c.resource_key AS resourceKey,
1903
1912
  c.uid, c.generation, c.spec_hash AS specHash, c.status_hash AS statusHash,
1904
1913
  c.deletion_requested_at AS deletionRequestedAt
1905
1914
  FROM controller_resources c JOIN resources r ON r.resource_id = c.resource_id ${clause}`;
@@ -1965,7 +1974,7 @@ function workflowRunViewSelect(clause) {
1965
1974
  function isRecord(value) {
1966
1975
  return typeof value === "object" && value !== null && !Array.isArray(value);
1967
1976
  }
1968
- function isControllerRow(value) {
1977
+ function isResourceManagerRow(value) {
1969
1978
  return isRecord(value);
1970
1979
  }
1971
1980
  function isLeaseRow(value) {
@@ -2060,7 +2069,7 @@ function isWorkflowRow(value) {
2060
2069
  function isQueueListRow(value) {
2061
2070
  return isRecord(value);
2062
2071
  }
2063
- function isControllerEventRow(value) {
2072
+ function isResourceManagerEventRow(value) {
2064
2073
  return isRecord(value);
2065
2074
  }
2066
2075
  function isRunEventRow(value) {
@@ -2204,7 +2213,7 @@ function rowToSource(row) {
2204
2213
  function effectStatus(value) {
2205
2214
  return value === "indeterminate" ? "ambiguous" : value;
2206
2215
  }
2207
- function controllerEffectState(value) {
2216
+ function resourceManagerEffectState(value) {
2208
2217
  return value === "ambiguous" ? "indeterminate" : value;
2209
2218
  }
2210
2219
  function validTimestamp(value) {