cloving 1.3.0 → 1.5.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 (484) hide show
  1. package/README.md +329 -215
  2. package/dist/src/agent-harness-shell.d.ts +2 -1
  3. package/dist/src/agent-harness-shell.js +8 -5
  4. package/dist/src/authority/command-wait-checks.d.ts +8 -0
  5. package/dist/src/authority/command-wait-checks.js +88 -0
  6. package/dist/src/authority/command-wait-results.d.ts +15 -0
  7. package/dist/src/authority/command-wait-results.js +73 -0
  8. package/dist/src/authority/command-wait-view.d.ts +21 -0
  9. package/dist/src/authority/command-wait-view.js +34 -0
  10. package/dist/src/authority/command-waits.d.ts +39 -0
  11. package/dist/src/authority/command-waits.js +97 -0
  12. package/dist/src/authority/commands.js +22 -1
  13. package/dist/src/authority/dispatch-decision.d.ts +8 -0
  14. package/dist/src/authority/dispatch-decision.js +26 -1
  15. package/dist/src/authority/effect-requests.js +6 -3
  16. package/dist/src/authority/effect-results.js +4 -2
  17. package/dist/src/authority/history-state.d.ts +2 -0
  18. package/dist/src/authority/history-state.js +13 -1
  19. package/dist/src/authority/instants.d.ts +1 -0
  20. package/dist/src/authority/instants.js +21 -0
  21. package/dist/src/authority/reduction-state.d.ts +2 -0
  22. package/dist/src/authority/reduction-state.js +5 -0
  23. package/dist/src/authority/reduction.js +24 -0
  24. package/dist/src/authority/status-input.d.ts +2 -0
  25. package/dist/src/authority/status.d.ts +2 -0
  26. package/dist/src/authority/status.js +1 -0
  27. package/dist/src/authority/stop-sequence.d.ts +1 -0
  28. package/dist/src/authority/stop-sequence.js +2 -1
  29. package/dist/src/authority/transitions.d.ts +6 -4
  30. package/dist/src/authority/transitions.js +7 -0
  31. package/dist/src/broker/actor/authority-health.d.ts +9 -0
  32. package/dist/src/broker/actor/authority-health.js +24 -0
  33. package/dist/src/broker/actor/authority-queries.d.ts +2 -1
  34. package/dist/src/broker/actor/authority-queries.js +14 -5
  35. package/dist/src/broker/actor/authority-receipts.js +1 -1
  36. package/dist/src/broker/actor/authority-runtime.d.ts +4 -2
  37. package/dist/src/broker/actor/authority-runtime.js +29 -20
  38. package/dist/src/broker/actor/authority-session.d.ts +6 -19
  39. package/dist/src/broker/actor/authority-session.js +66 -88
  40. package/dist/src/broker/actor/authority-settings.d.ts +2 -1
  41. package/dist/src/broker/actor/authority-settings.js +6 -3
  42. package/dist/src/broker/actor/authority-upgrades.d.ts +23 -2
  43. package/dist/src/broker/actor/authority-upgrades.js +8 -2
  44. package/dist/src/broker/actor/authority-watchdog.d.ts +6 -2
  45. package/dist/src/broker/actor/authority-watchdog.js +31 -9
  46. package/dist/src/broker/actor/authority.js +3 -1
  47. package/dist/src/broker/actor/delivery-intents.js +2 -0
  48. package/dist/src/broker/actor/effect-delivery.d.ts +1 -1
  49. package/dist/src/broker/actor/effect-delivery.js +15 -2
  50. package/dist/src/broker/actor/effect-plan.js +11 -2
  51. package/dist/src/broker/actor/effect-queries.d.ts +4 -0
  52. package/dist/src/broker/actor/effect-queries.js +9 -1
  53. package/dist/src/broker/actor/effect-turn.js +2 -0
  54. package/dist/src/broker/actor/projection-memory.d.ts +43 -0
  55. package/dist/src/broker/actor/projection-memory.js +207 -0
  56. package/dist/src/broker/actor/runtime-parts.d.ts +5 -0
  57. package/dist/src/broker/actor/runtime-parts.js +8 -3
  58. package/dist/src/broker/actor/stop-plan.js +9 -3
  59. package/dist/src/broker/actor/stop-turn.d.ts +2 -0
  60. package/dist/src/broker/actor/stop-turn.js +24 -11
  61. package/dist/src/broker/actor/turn-draft.d.ts +1 -0
  62. package/dist/src/broker/actor/turn-draft.js +4 -0
  63. package/dist/src/broker/actor/turn-state.js +5 -1
  64. package/dist/src/broker/authority-admission.js +60 -0
  65. package/dist/src/broker/authority-restore.d.ts +2 -0
  66. package/dist/src/broker/authority-restore.js +35 -1
  67. package/dist/src/broker/command-wait-restore.d.ts +31 -0
  68. package/dist/src/broker/command-wait-restore.js +86 -0
  69. package/dist/src/broker/decision-restore.d.ts +1 -1
  70. package/dist/src/broker/decision-restore.js +1 -0
  71. package/dist/src/broker/effect-upgrade.d.ts +3 -0
  72. package/dist/src/broker/effect-upgrade.js +11 -2
  73. package/dist/src/cli/arguments.d.ts +13 -0
  74. package/dist/src/cli/arguments.js +43 -3
  75. package/dist/src/cli/chat-stores.d.ts +2 -0
  76. package/dist/src/cli/chat-stores.js +113 -0
  77. package/dist/src/cli/client.d.ts +7 -2
  78. package/dist/src/cli/client.js +13 -7
  79. package/dist/src/cli/command-requests.d.ts +46 -0
  80. package/dist/src/cli/command-requests.js +84 -0
  81. package/dist/src/cli/command-waits.d.ts +9 -0
  82. package/dist/src/cli/command-waits.js +51 -0
  83. package/dist/src/cli/commands.js +70 -88
  84. package/dist/src/cli/config-file.d.ts +2 -2
  85. package/dist/src/cli/config-file.js +4 -2
  86. package/dist/src/cli/config-notice.js +5 -2
  87. package/dist/src/cli/doctor-retention.d.ts +2 -0
  88. package/dist/src/cli/doctor-retention.js +93 -0
  89. package/dist/src/cli/doctor-workflows.d.ts +5 -2
  90. package/dist/src/cli/doctor-workflows.js +12 -7
  91. package/dist/src/cli/doctor.js +11 -9
  92. package/dist/src/cli/harness-probes.d.ts +2 -0
  93. package/dist/src/cli/harness-probes.js +1 -1
  94. package/dist/src/cli/harness-processes.d.ts +6 -0
  95. package/dist/src/cli/harness-processes.js +36 -0
  96. package/dist/src/cli/init-command.d.ts +9 -0
  97. package/dist/src/cli/init-command.js +52 -0
  98. package/dist/src/cli/init-prompt-command.d.ts +10 -0
  99. package/dist/src/cli/init-prompt-command.js +145 -0
  100. package/dist/src/cli/init-prompt.d.ts +35 -0
  101. package/dist/src/cli/init-prompt.js +74 -0
  102. package/dist/src/cli/init-selection.d.ts +13 -0
  103. package/dist/src/cli/init-selection.js +75 -0
  104. package/dist/src/cli/main.d.ts +2 -0
  105. package/dist/src/cli/main.js +37 -7
  106. package/dist/src/cli/mcp-server.d.ts +1 -0
  107. package/dist/src/cli/mcp-server.js +156 -0
  108. package/dist/src/cli/mcp-tools.d.ts +15 -0
  109. package/dist/src/cli/mcp-tools.js +242 -0
  110. package/dist/src/cli/queue-arguments.d.ts +15 -0
  111. package/dist/src/cli/queue-arguments.js +31 -0
  112. package/dist/src/cli/queue-render.d.ts +3 -0
  113. package/dist/src/cli/queue-render.js +26 -0
  114. package/dist/src/cli/reload-render.d.ts +2 -0
  115. package/dist/src/cli/reload-render.js +12 -0
  116. package/dist/src/cli/render.d.ts +1 -1
  117. package/dist/src/cli/render.js +54 -38
  118. package/dist/src/cli/report-ci-jobs.d.ts +23 -0
  119. package/dist/src/cli/report-ci-jobs.js +103 -0
  120. package/dist/src/cli/report-ci-usage.d.ts +9 -0
  121. package/dist/src/cli/report-ci-usage.js +185 -0
  122. package/dist/src/cli/report-ci.d.ts +13 -0
  123. package/dist/src/cli/report-ci.js +74 -0
  124. package/dist/src/cli/report-closures.d.ts +6 -0
  125. package/dist/src/cli/report-closures.js +97 -0
  126. package/dist/src/cli/report-flow.d.ts +7 -0
  127. package/dist/src/cli/report-flow.js +122 -0
  128. package/dist/src/cli/report-github-reader.d.ts +29 -0
  129. package/dist/src/cli/report-github-reader.js +157 -0
  130. package/dist/src/cli/report-github.d.ts +15 -8
  131. package/dist/src/cli/report-github.js +131 -150
  132. package/dist/src/cli/report-operator.d.ts +3 -0
  133. package/dist/src/cli/report-operator.js +40 -0
  134. package/dist/src/cli/report-ready.d.ts +3 -0
  135. package/dist/src/cli/report-ready.js +96 -0
  136. package/dist/src/cli/report-text.d.ts +9 -0
  137. package/dist/src/cli/report-text.js +33 -0
  138. package/dist/src/cli/report.d.ts +1 -0
  139. package/dist/src/cli/report.js +104 -27
  140. package/dist/src/cli/runtime-arguments.d.ts +18 -3
  141. package/dist/src/cli/runtime-arguments.js +29 -20
  142. package/dist/src/cli/schedule-arguments.d.ts +14 -0
  143. package/dist/src/cli/schedule-arguments.js +26 -0
  144. package/dist/src/cli/schedule-render.d.ts +22 -0
  145. package/dist/src/cli/schedule-render.js +73 -0
  146. package/dist/src/cli/terminal-text.d.ts +3 -0
  147. package/dist/src/cli/terminal-text.js +28 -0
  148. package/dist/src/cli/toolchain.d.ts +1 -0
  149. package/dist/src/cli/toolchain.js +1 -0
  150. package/dist/src/cli/usage-render.d.ts +1 -0
  151. package/dist/src/cli/usage-render.js +28 -1
  152. package/dist/src/cli/usage.d.ts +2 -2
  153. package/dist/src/cli/usage.js +89 -11
  154. package/dist/src/cli/watch-actions.js +2 -2
  155. package/dist/src/cli/watch-api-document.d.ts +430 -0
  156. package/dist/src/cli/watch-api-document.js +291 -0
  157. package/dist/src/cli/watch-api-run.d.ts +56 -0
  158. package/dist/src/cli/watch-api-run.js +112 -0
  159. package/dist/src/cli/watch-api.d.ts +17 -0
  160. package/dist/src/cli/watch-api.js +230 -0
  161. package/dist/src/cli/watch-board-view.js +19 -2
  162. package/dist/src/cli/watch-board.d.ts +4 -2
  163. package/dist/src/cli/watch-board.js +53 -43
  164. package/dist/src/cli/watch-card-forms.d.ts +1 -1
  165. package/dist/src/cli/watch-card-forms.js +11 -10
  166. package/dist/src/cli/watch-client.d.ts +1 -1
  167. package/dist/src/cli/watch-client.js +2 -11
  168. package/dist/src/cli/watch-header-view.d.ts +1 -5
  169. package/dist/src/cli/watch-header-view.js +17 -21
  170. package/dist/src/cli/watch-model.d.ts +5 -1
  171. package/dist/src/cli/watch-model.js +20 -11
  172. package/dist/src/cli/watch-page.js +15 -15
  173. package/dist/src/cli/watch-phases.d.ts +12 -3
  174. package/dist/src/cli/watch-phases.js +68 -11
  175. package/dist/src/cli/watch-pr-board.js +1 -1
  176. package/dist/src/cli/watch-pr-command.d.ts +1 -0
  177. package/dist/src/cli/watch-pull-request.js +18 -8
  178. package/dist/src/cli/watch-reads.d.ts +3 -0
  179. package/dist/src/cli/watch-reads.js +22 -20
  180. package/dist/src/cli/watch-render.d.ts +15 -0
  181. package/dist/src/cli/watch-run-input.d.ts +0 -1
  182. package/dist/src/cli/watch-run-input.js +0 -13
  183. package/dist/src/cli/watch-server.js +24 -10
  184. package/dist/src/cli/watch-view.d.ts +0 -3
  185. package/dist/src/cli/watch-view.js +13 -13
  186. package/dist/src/cli.js +73 -12
  187. package/dist/src/command-wait.d.ts +4 -0
  188. package/dist/src/command-wait.js +45 -0
  189. package/dist/src/configuration-change.d.ts +7 -0
  190. package/dist/src/configuration-change.js +14 -0
  191. package/dist/src/configuration-display.js +2 -0
  192. package/dist/src/configuration-schema.d.ts +14 -0
  193. package/dist/src/configuration-schema.js +6 -2
  194. package/dist/src/daemon/attachment-file.d.ts +6 -0
  195. package/dist/src/daemon/attachment-file.js +86 -0
  196. package/dist/src/daemon/attachments.d.ts +14 -0
  197. package/dist/src/daemon/attachments.js +17 -0
  198. package/dist/src/daemon/claude-recovery.d.ts +50 -0
  199. package/dist/src/daemon/claude-recovery.js +208 -0
  200. package/dist/src/daemon/claude-stream.d.ts +27 -0
  201. package/dist/src/daemon/claude-stream.js +63 -0
  202. package/dist/src/daemon/claude-turn.d.ts +11 -25
  203. package/dist/src/daemon/claude-turn.js +64 -81
  204. package/dist/src/daemon/claude-worker.d.ts +5 -4
  205. package/dist/src/daemon/claude-worker.js +127 -126
  206. package/dist/src/daemon/daemon-adapters.d.ts +9 -0
  207. package/dist/src/daemon/daemon-adapters.js +33 -5
  208. package/dist/src/daemon/daemon-loops.d.ts +5 -1
  209. package/dist/src/daemon/daemon-loops.js +18 -10
  210. package/dist/src/daemon/daemon.js +80 -61
  211. package/dist/src/daemon/github-attach.d.ts +2 -0
  212. package/dist/src/daemon/github-attach.js +222 -0
  213. package/dist/src/daemon/github-calls.js +1 -1
  214. package/dist/src/daemon/github-ci-filters.d.ts +6 -0
  215. package/dist/src/daemon/github-ci-filters.js +138 -0
  216. package/dist/src/daemon/github-ci-workflows.d.ts +10 -0
  217. package/dist/src/daemon/github-ci-workflows.js +148 -0
  218. package/dist/src/daemon/github-ci.js +22 -4
  219. package/dist/src/daemon/github-issue-methods.d.ts +2 -0
  220. package/dist/src/daemon/github-issue-methods.js +37 -2
  221. package/dist/src/daemon/github-merge-call.d.ts +2 -1
  222. package/dist/src/daemon/github-merge-call.js +10 -3
  223. package/dist/src/daemon/github-merge.js +52 -24
  224. package/dist/src/daemon/github-methods.js +18 -4
  225. package/dist/src/daemon/github-operation.d.ts +4 -0
  226. package/dist/src/daemon/github-operation.js +6 -0
  227. package/dist/src/daemon/github-worker.d.ts +4 -0
  228. package/dist/src/daemon/github-worker.js +6 -0
  229. package/dist/src/daemon/issue-queue.d.ts +4 -1
  230. package/dist/src/daemon/issue-queue.js +76 -78
  231. package/dist/src/daemon/merge-turns.d.ts +10 -0
  232. package/dist/src/daemon/merge-turns.js +37 -0
  233. package/dist/src/daemon/notify-events.d.ts +6 -0
  234. package/dist/src/daemon/notify-events.js +84 -0
  235. package/dist/src/daemon/notify-journal.js +1 -1
  236. package/dist/src/daemon/notify-message.d.ts +4 -1
  237. package/dist/src/daemon/notify-message.js +36 -0
  238. package/dist/src/daemon/notify.d.ts +1 -1
  239. package/dist/src/daemon/notify.js +5 -77
  240. package/dist/src/daemon/operation-journal.d.ts +1 -0
  241. package/dist/src/daemon/queue-control.d.ts +13 -0
  242. package/dist/src/daemon/queue-control.js +86 -0
  243. package/dist/src/daemon/queue-journal.d.ts +20 -0
  244. package/dist/src/daemon/queue-journal.js +89 -0
  245. package/dist/src/daemon/queue-status.d.ts +9 -3
  246. package/dist/src/daemon/queue-status.js +17 -4
  247. package/dist/src/daemon/record-archive.d.ts +19 -0
  248. package/dist/src/daemon/record-archive.js +82 -0
  249. package/dist/src/daemon/record-sweep.d.ts +24 -0
  250. package/dist/src/daemon/record-sweep.js +147 -0
  251. package/dist/src/daemon/resume-index-lock.d.ts +13 -0
  252. package/dist/src/daemon/resume-index-lock.js +160 -0
  253. package/dist/src/daemon/resume-worktree.d.ts +7 -0
  254. package/dist/src/daemon/resume-worktree.js +29 -0
  255. package/dist/src/daemon/retrying-turn.d.ts +2 -12
  256. package/dist/src/daemon/retrying-turn.js +98 -172
  257. package/dist/src/daemon/schedule-control.d.ts +26 -0
  258. package/dist/src/daemon/schedule-control.js +110 -0
  259. package/dist/src/daemon/schedule-journal.d.ts +2 -15
  260. package/dist/src/daemon/schedule-journal.js +67 -4
  261. package/dist/src/daemon/settings-reload.d.ts +26 -0
  262. package/dist/src/daemon/settings-reload.js +82 -0
  263. package/dist/src/daemon/ticket-registration.d.ts +2 -7
  264. package/dist/src/daemon/ticket-registration.js +15 -81
  265. package/dist/src/daemon/turn-attempt-journal.d.ts +38 -0
  266. package/dist/src/daemon/turn-attempt-journal.js +136 -0
  267. package/dist/src/daemon/turn-attempts.d.ts +47 -0
  268. package/dist/src/daemon/turn-attempts.js +166 -0
  269. package/dist/src/daemon/turn-details.d.ts +4 -0
  270. package/dist/src/daemon/turn-details.js +33 -0
  271. package/dist/src/daemon/turn-report.d.ts +8 -1
  272. package/dist/src/daemon/turn-report.js +39 -0
  273. package/dist/src/daemon/work-tree.d.ts +9 -0
  274. package/dist/src/daemon/work-tree.js +20 -0
  275. package/dist/src/daemon/worker-profile.d.ts +9 -0
  276. package/dist/src/daemon/worker-profile.js +44 -0
  277. package/dist/src/daemon/workflow-generations.d.ts +7 -4
  278. package/dist/src/daemon/workflow-generations.js +22 -14
  279. package/dist/src/daemon/workflow-reload.d.ts +41 -0
  280. package/dist/src/daemon/workflow-reload.js +244 -0
  281. package/dist/src/daemon/workflow-replay.d.ts +2 -1
  282. package/dist/src/daemon/workflow-replay.js +7 -3
  283. package/dist/src/daemon/workflow-schedules.d.ts +3 -0
  284. package/dist/src/daemon/workflow-schedules.js +98 -45
  285. package/dist/src/daemon/worktree-processes.d.ts +9 -0
  286. package/dist/src/daemon/worktree-processes.js +151 -0
  287. package/dist/src/doctor-report.d.ts +4 -6
  288. package/dist/src/doctor-report.js +8 -13
  289. package/dist/src/harness-start.d.ts +15 -0
  290. package/dist/src/harness-start.js +37 -0
  291. package/dist/src/host/command-wait.d.ts +38 -0
  292. package/dist/src/host/command-wait.js +115 -0
  293. package/dist/src/host/start-delivery.d.ts +5 -7
  294. package/dist/src/host/start-delivery.js +3 -15
  295. package/dist/src/host/step-bridge-host.d.ts +2 -0
  296. package/dist/src/host/step-bridge-host.js +21 -0
  297. package/dist/src/operation-identity.d.ts +1 -0
  298. package/dist/src/operation-identity.js +4 -0
  299. package/dist/src/private-config.schema.json +71 -0
  300. package/dist/src/project-config.schema.json +40 -0
  301. package/dist/src/project-settings.d.ts +16 -2
  302. package/dist/src/project-settings.js +35 -1
  303. package/dist/src/queue-spend.d.ts +4 -0
  304. package/dist/src/queue-spend.js +21 -0
  305. package/dist/src/queue-state.d.ts +26 -0
  306. package/dist/src/queue-state.js +34 -0
  307. package/dist/src/record-retention.d.ts +46 -0
  308. package/dist/src/record-retention.js +81 -0
  309. package/dist/src/relay/relay-service.d.ts +3 -0
  310. package/dist/src/relay/relay-service.js +5 -3
  311. package/dist/src/report-ci.d.ts +164 -0
  312. package/dist/src/report-ci.js +32 -0
  313. package/dist/src/report-effects.d.ts +15 -0
  314. package/dist/src/report-effects.js +212 -0
  315. package/dist/src/report-flow-types.d.ts +38 -0
  316. package/dist/src/report-flow-types.js +7 -0
  317. package/dist/src/report-flow.d.ts +43 -0
  318. package/dist/src/report-flow.js +193 -0
  319. package/dist/src/report-operator.d.ts +67 -0
  320. package/dist/src/report-operator.js +25 -0
  321. package/dist/src/report-quality.d.ts +221 -0
  322. package/dist/src/report-quality.js +94 -0
  323. package/dist/src/report-ready.d.ts +23 -0
  324. package/dist/src/report-ready.js +117 -0
  325. package/dist/src/report-statistics.d.ts +2 -1
  326. package/dist/src/report-statistics.js +40 -4
  327. package/dist/src/report.d.ts +588 -47
  328. package/dist/src/report.js +156 -41
  329. package/dist/src/schedule-progress.d.ts +33 -0
  330. package/dist/src/schedule-progress.js +45 -0
  331. package/dist/src/service/active-tickets.js +11 -6
  332. package/dist/src/service/command-waits.d.ts +34 -0
  333. package/dist/src/service/command-waits.js +86 -0
  334. package/dist/src/service/dispatcher.d.ts +4 -0
  335. package/dist/src/service/dispatcher.js +33 -0
  336. package/dist/src/service/expiry.js +2 -0
  337. package/dist/src/service/gateway.js +3 -1
  338. package/dist/src/service/queue-handlers.d.ts +4 -0
  339. package/dist/src/service/queue-handlers.js +32 -0
  340. package/dist/src/service/queue-spend.d.ts +6 -0
  341. package/dist/src/service/queue-spend.js +68 -0
  342. package/dist/src/service/registry.d.ts +28 -2
  343. package/dist/src/service/registry.js +48 -0
  344. package/dist/src/service/replies.d.ts +22 -8
  345. package/dist/src/service/replies.js +16 -2
  346. package/dist/src/service/run-handlers.js +37 -12
  347. package/dist/src/service/run-metadata.d.ts +15 -1
  348. package/dist/src/service/run-metadata.js +93 -8
  349. package/dist/src/service/service.d.ts +11 -3
  350. package/dist/src/service/service.js +22 -37
  351. package/dist/src/service/submission-handler.js +18 -4
  352. package/dist/src/service/worker-port.js +9 -1
  353. package/dist/src/service/worker-totals.d.ts +6 -0
  354. package/dist/src/service/worker-totals.js +8 -1
  355. package/dist/src/service/workflow-reload.d.ts +35 -0
  356. package/dist/src/service/workflow-reload.js +52 -0
  357. package/dist/src/step-bridge.d.ts +20 -0
  358. package/dist/src/steps/command-wait.d.ts +12 -0
  359. package/dist/src/steps/command-wait.js +26 -0
  360. package/dist/src/steps/open-decision-wait.d.ts +2 -0
  361. package/dist/src/steps/{decision-gate.js → open-decision-wait.js} +0 -7
  362. package/dist/src/steps/review-by-person.js +4 -1
  363. package/dist/src/steps/wait-for-command.d.ts +3 -0
  364. package/dist/src/steps/wait-for-command.js +17 -0
  365. package/dist/src/steps/wait-for-decision.js +1 -1
  366. package/dist/src/storage/command-wait-rows.d.ts +30 -0
  367. package/dist/src/storage/command-wait-rows.js +96 -0
  368. package/dist/src/storage/decision-snapshots.d.ts +8 -2
  369. package/dist/src/storage/decision-snapshots.js +16 -8
  370. package/dist/src/storage/domain-changes.d.ts +3 -1
  371. package/dist/src/storage/domain-changes.js +4 -0
  372. package/dist/src/storage/domain-schema.d.ts +16 -1
  373. package/dist/src/storage/domain-schema.js +35 -4
  374. package/dist/src/storage/effect-schema.d.ts +2 -0
  375. package/dist/src/storage/effect-schema.js +9 -0
  376. package/dist/src/storage/projection-changes.d.ts +12 -0
  377. package/dist/src/storage/projection-changes.js +194 -0
  378. package/dist/src/storage/projection-lookups.d.ts +7 -0
  379. package/dist/src/storage/projection-lookups.js +30 -0
  380. package/dist/src/testing-requests.d.ts +15 -0
  381. package/dist/src/testing-requests.js +93 -0
  382. package/dist/src/testing.d.ts +4 -10
  383. package/dist/src/testing.js +33 -86
  384. package/dist/src/worker-usage.d.ts +1 -0
  385. package/dist/src/worker-usage.js +3 -0
  386. package/dist/src/workflow-candidate.d.ts +1 -0
  387. package/dist/src/workflow-candidate.js +12 -1
  388. package/dist/src/workflow-contracts.d.ts +1 -0
  389. package/dist/src/workflow-contracts.js +9 -2
  390. package/dist/src/workflow-declaration.d.ts +1 -0
  391. package/dist/src/workflow-declaration.js +3 -0
  392. package/dist/src/workflow-discovery.d.ts +2 -13
  393. package/dist/src/workflow-discovery.js +1 -13
  394. package/dist/src/workflow-refusals.js +0 -1
  395. package/dist/src/workflows.d.ts +1 -1
  396. package/dist/src/workflows.js +1 -1
  397. package/dist/tools/compile-workflows.js +3 -0
  398. package/dist/tools/project-configuration.d.ts +7 -2
  399. package/dist/tools/project-configuration.js +30 -1
  400. package/dist/tools/red-green-command.d.ts +1 -0
  401. package/dist/tools/red-green-command.js +174 -0
  402. package/dist/tools/red-green-process.d.ts +10 -0
  403. package/dist/tools/red-green-process.js +59 -0
  404. package/dist/tools/self-host-processes.d.ts +2 -0
  405. package/dist/tools/self-host-processes.js +69 -26
  406. package/dist/tools/self-host-project.d.ts +2 -0
  407. package/dist/tools/self-host-project.js +30 -77
  408. package/dist/tools/self-host-runtime.js +1 -1
  409. package/dist/tools/self-host.js +76 -34
  410. package/dist/tools/template-command.d.ts +1 -0
  411. package/dist/tools/template-command.js +160 -0
  412. package/dist/tools/template-copy.d.ts +11 -0
  413. package/dist/tools/template-copy.js +130 -0
  414. package/dist/tools/template-files.d.ts +17 -0
  415. package/dist/tools/template-files.js +74 -0
  416. package/dist/tools/workflow-bundles.js +1 -0
  417. package/dist/tools/workflow-candidate-counts.js +2 -2
  418. package/dist/tools/workflow-candidate-program.d.ts +4 -2
  419. package/dist/tools/workflow-candidate-program.js +30 -11
  420. package/dist/tools/workflow-candidate-shape.d.ts +3 -0
  421. package/dist/tools/workflow-candidate-shape.js +90 -0
  422. package/dist/tools/workflow-candidate-source.d.ts +1 -0
  423. package/dist/tools/workflow-candidate-source.js +26 -4
  424. package/dist/tools/workflow-candidate-syntax.d.ts +2 -2
  425. package/dist/tools/workflow-candidate-syntax.js +24 -94
  426. package/dist/tools/workflow-command.js +1 -2
  427. package/dist/tools/workflow-folders.d.ts +2 -3
  428. package/dist/tools/workflow-folders.js +1 -1
  429. package/package.json +17 -9
  430. package/templates/develop/README.md +93 -4
  431. package/templates/develop/develop/flow-tests.ts +38 -1
  432. package/templates/develop/develop/interruption-tests.ts +157 -0
  433. package/templates/develop/develop/local.ts +1 -0
  434. package/templates/develop/develop/option-tests.ts +138 -9
  435. package/templates/develop/develop/pull.ts +5 -1
  436. package/templates/develop/develop/red-green.ts +55 -0
  437. package/templates/develop/develop/refusal-tests.ts +77 -0
  438. package/templates/develop/develop/report.ts +31 -11
  439. package/templates/develop/develop/round.ts +1 -0
  440. package/templates/develop/develop/scenarios.ts +27 -0
  441. package/templates/develop/develop/turn.ts +28 -7
  442. package/templates/develop/develop.declaration.json +1 -1
  443. package/templates/develop/develop.test.ts +4 -0
  444. package/templates/develop/template.json +29 -2
  445. package/templates/idea-to-issue/README.md +27 -0
  446. package/templates/idea-to-issue/idea-to-issue/effects.ts +52 -0
  447. package/templates/idea-to-issue/idea-to-issue/leave.ts +10 -0
  448. package/templates/idea-to-issue/idea-to-issue/next.ts +29 -0
  449. package/templates/idea-to-issue/idea-to-issue/post-person.ts +18 -0
  450. package/templates/idea-to-issue/idea-to-issue/post.ts +50 -0
  451. package/templates/idea-to-issue/idea-to-issue/queue.ts +27 -0
  452. package/templates/idea-to-issue/idea-to-issue/review.ts +42 -0
  453. package/templates/idea-to-issue/idea-to-issue/scenarios.ts +50 -0
  454. package/templates/idea-to-issue/idea-to-issue/turn.ts +40 -0
  455. package/templates/idea-to-issue/idea-to-issue.declaration.json +16 -0
  456. package/templates/idea-to-issue/idea-to-issue.test.ts +79 -0
  457. package/templates/idea-to-issue/idea-to-issue.ts +49 -0
  458. package/templates/idea-to-issue/template.json +81 -0
  459. package/templates/review-day/README.md +97 -0
  460. package/templates/review-day/review-day/critique.ts +58 -0
  461. package/templates/review-day/review-day/decision.ts +29 -0
  462. package/templates/review-day/review-day/facts.ts +69 -0
  463. package/templates/review-day/review-day/label.ts +29 -0
  464. package/templates/review-day/review-day/next.ts +28 -0
  465. package/templates/review-day/review-day/post.ts +27 -0
  466. package/templates/review-day/review-day/report.ts +98 -0
  467. package/templates/review-day/review-day/rules.ts +12 -0
  468. package/templates/review-day/review-day/scenarios.ts +76 -0
  469. package/templates/review-day/review-day/turn.ts +73 -0
  470. package/templates/review-day/review-day.declaration.json +16 -0
  471. package/templates/review-day/review-day.test.ts +362 -0
  472. package/templates/review-day/review-day.ts +37 -0
  473. package/templates/review-day/template.json +56 -0
  474. package/dist/src/cli/watch-start-view.d.ts +0 -18
  475. package/dist/src/cli/watch-start-view.js +0 -77
  476. package/dist/src/steps/decision-gate.d.ts +0 -3
  477. package/dist/workflows/develop-prd.d.ts +0 -7
  478. package/dist/workflows/develop-prd.js +0 -165
  479. package/dist/workflows/develop-ticket.d.ts +0 -9
  480. package/dist/workflows/develop-ticket.js +0 -207
  481. package/dist/workflows/issue-labels.d.ts +0 -16
  482. package/dist/workflows/issue-labels.js +0 -70
  483. package/dist/workflows/ticket-prompts.d.ts +0 -35
  484. package/dist/workflows/ticket-prompts.js +0 -147
@@ -1,14 +1,10 @@
1
+ import { loadCommandWaits } from "./command-wait-rows.js";
1
2
  import { loadDecisions, loadDocuments, } from "./decision-rows.js";
2
- import { latestSequence, loadAttempts, loadSnapshot, outboxRow, projectionRows, text, } from "./domain-rows.js";
3
+ import { latestSequence, loadAttempts, loadSnapshot, projectionRows, text, } from "./domain-rows.js";
3
4
  import { loadEffects } from "./effect-rows.js";
4
- export async function loadOperationSnapshot(connection) {
5
- return {
6
- outbox: (await connection.all("SELECT operation_id, kind, run_id, created_sequence, released_sequence FROM outbox ORDER BY created_sequence, rowid")).map(outboxRow),
7
- deliveries: await loadAttempts(connection),
8
- };
9
- }
10
5
  export async function loadProjections(connection) {
11
6
  return {
7
+ waits: await loadCommandWaits(connection),
12
8
  ...(await projectionRows(connection)),
13
9
  ...(await loadDecisions(connection)),
14
10
  deliveries: await loadAttempts(connection),
@@ -23,9 +19,21 @@ export async function loadDecided(connection) {
23
19
  documents: await loadDocuments(connection),
24
20
  };
25
21
  }
26
- export async function loadCurrent(connection) {
22
+ export async function loadEffected(connection) {
27
23
  return {
28
24
  ...(await loadDecided(connection)),
29
25
  effects: await loadEffects(connection),
30
26
  };
31
27
  }
28
+ export async function loadCurrent(connection) {
29
+ return {
30
+ ...(await loadEffected(connection)),
31
+ waits: await loadCommandWaits(connection),
32
+ };
33
+ }
34
+ export async function loadWaiting(connection) {
35
+ return {
36
+ ...(await loadEffected(connection)),
37
+ waits: await loadCommandWaits(connection, { version: "opened" }),
38
+ };
39
+ }
@@ -1,3 +1,4 @@
1
+ import { type CommandWaitRow } from "./command-wait-rows.ts";
1
2
  import { type DetailRow, type DocumentRow, type GateRow } from "./decision-rows.ts";
2
3
  import { type CommandRow, type DefinitionRow, type EventRow, type RunRow, type SqlConnection } from "./domain-rows.ts";
3
4
  import { type EffectRows } from "./effect-rows.ts";
@@ -37,11 +38,12 @@ export interface DomainChange extends EffectRows {
37
38
  readonly staged: readonly StagedDelivery[];
38
39
  readonly closed: readonly ClosedDelivery[];
39
40
  readonly gates: readonly GateRow[];
41
+ readonly waits: readonly CommandWaitRow[];
40
42
  readonly details: readonly DetailRow[];
41
43
  readonly documents: readonly DocumentRow[];
42
44
  readonly completesAdoption: boolean;
43
45
  }
44
- export declare function persistChange(value: unknown, connection: SqlConnection): Promise<void>;
46
+ export declare function persistChange(value: unknown, connection: SqlConnection): Promise<DomainChange>;
45
47
  export declare function gateParameters(row: GateRow): readonly unknown[];
46
48
  export declare function detailParameters(row: DetailRow): readonly unknown[];
47
49
  export declare function decisionStatements(change: Pick<DomainChange, "gates" | "details" | "documents">): readonly Statement[];
@@ -1,3 +1,4 @@
1
+ import { commandWaitRow, commandWaitStatements, } from "./command-wait-rows.js";
1
2
  import { detailColumns, detailRow, documentRow, gateColumns, gateRow, } from "./decision-rows.js";
2
3
  import { commandRow, definitionRow, eventRow, integer, latestSequence, optionalInteger, optionalText, runRow, text, } from "./domain-rows.js";
3
4
  import { effectStatements } from "./effect-changes.js";
@@ -9,6 +10,7 @@ export async function persistChange(value, connection) {
9
10
  throw new Error("stale-authority-sequence");
10
11
  for (const statement of statements(change))
11
12
  await connection.run(statement.sql, statement.parameters);
13
+ return change;
12
14
  }
13
15
  function statements(change) {
14
16
  return [
@@ -48,6 +50,7 @@ function statements(change) {
48
50
  ...deliveryStatements(change),
49
51
  ...decisionStatements(change),
50
52
  ...effectStatements(change),
53
+ ...commandWaitStatements(change.waits),
51
54
  ...(change.completesAdoption
52
55
  ? [
53
56
  {
@@ -195,6 +198,7 @@ function parseChange(value) {
195
198
  receipt: optionalText(row, "receipt"),
196
199
  })),
197
200
  gates: list(value, "gates").map(gateRow),
201
+ waits: list(value, "waits").map(commandWaitRow),
198
202
  details: list(value, "details").map(detailRow),
199
203
  documents: list(value, "documents").map(documentRow),
200
204
  budgets: list(value, "budgets").map(budgetRow),
@@ -2,7 +2,12 @@ import { type SqlConnection } from "./domain-rows.ts";
2
2
  export declare const baselineVersion = 1;
3
3
  export declare const adoptedVersion = 2;
4
4
  export declare const decidedVersion = 3;
5
- export declare const currentVersion = 4;
5
+ export declare const effectedVersion = 4;
6
+ export declare const waitingVersion = 5;
7
+ export declare const checkedVersion = 6;
8
+ export declare const spendingVersion = 7;
9
+ export declare const eventIndexVersion = 8;
10
+ export declare const currentVersion = 9;
6
11
  export declare const baselineSchema = "\nCREATE TABLE schema_migrations (\n version INTEGER PRIMARY KEY,\n checksum TEXT NOT NULL\n) STRICT;\nCREATE TABLE events (\n sequence INTEGER PRIMARY KEY,\n type TEXT NOT NULL,\n run_id TEXT NOT NULL,\n command_id TEXT NOT NULL UNIQUE,\n recorded_at TEXT NOT NULL,\n request TEXT NOT NULL,\n payload TEXT NOT NULL\n) STRICT;\nCREATE TABLE definitions (\n pin TEXT PRIMARY KEY,\n manifest TEXT NOT NULL\n) STRICT;\nCREATE TABLE runs (\n run_id TEXT PRIMARY KEY,\n status TEXT NOT NULL,\n revision INTEGER NOT NULL,\n workflow TEXT NOT NULL REFERENCES definitions (pin) DEFERRABLE INITIALLY DEFERRED,\n paused_from TEXT,\n gates TEXT NOT NULL,\n sequence INTEGER NOT NULL REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED\n) STRICT;\nCREATE TABLE commands (\n command_id TEXT PRIMARY KEY,\n request TEXT NOT NULL,\n sequence INTEGER NOT NULL UNIQUE REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED\n) STRICT;\nCREATE TABLE outbox (\n operation_id TEXT PRIMARY KEY,\n kind TEXT NOT NULL,\n run_id TEXT NOT NULL REFERENCES runs (run_id) DEFERRABLE INITIALLY DEFERRED,\n created_sequence INTEGER NOT NULL REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED,\n released_sequence INTEGER REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED\n) STRICT;\n";
7
12
  export type SchemaRefusal = {
8
13
  readonly kind: "refused";
@@ -17,6 +22,16 @@ export type SchemaState = {
17
22
  readonly kind: "adopted";
18
23
  } | {
19
24
  readonly kind: "decided";
25
+ } | {
26
+ readonly kind: "effected";
27
+ } | {
28
+ readonly kind: "waiting";
29
+ } | {
30
+ readonly kind: "checked";
31
+ } | {
32
+ readonly kind: "indexed";
33
+ } | {
34
+ readonly kind: "event-indexed";
20
35
  } | {
21
36
  readonly kind: "current";
22
37
  } | SchemaRefusal;
@@ -1,11 +1,17 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
2
  import { DatabaseSync } from "node:sqlite";
3
3
  import { integer, optionalInteger, optionalText, text, } from "./domain-rows.js";
4
- import { effectSchema } from "./effect-schema.js";
4
+ import { commandWaitSchema, commandWaitCheckSchema, } from "./command-wait-rows.js";
5
+ import { effectSchema, runIndexes, spendingIndexes } from "./effect-schema.js";
5
6
  export const baselineVersion = 1;
6
7
  export const adoptedVersion = 2;
7
8
  export const decidedVersion = 3;
8
- export const currentVersion = 4;
9
+ export const effectedVersion = 4;
10
+ export const waitingVersion = 5;
11
+ export const checkedVersion = 6;
12
+ export const spendingVersion = 7;
13
+ export const eventIndexVersion = 8;
14
+ export const currentVersion = 9;
9
15
  export const baselineSchema = `
10
16
  CREATE TABLE schema_migrations (
11
17
  version INTEGER PRIMARY KEY,
@@ -102,9 +108,29 @@ CREATE TABLE documents (
102
108
  body TEXT NOT NULL
103
109
  ) STRICT;
104
110
  `;
105
- const schemas = [baselineSchema, adoption, decisions, effectSchema];
111
+ const schemas = [
112
+ baselineSchema,
113
+ adoption,
114
+ decisions,
115
+ effectSchema,
116
+ commandWaitSchema,
117
+ commandWaitCheckSchema,
118
+ spendingIndexes,
119
+ "CREATE INDEX events_run_type_sequence ON events (run_id, type, sequence);",
120
+ runIndexes,
121
+ ];
106
122
  const checksums = schemas.map((schema) => createHash("sha256").update(schema).digest("hex"));
107
- const versionKinds = ["baseline", "adopted", "decided", "current"];
123
+ const versionKinds = [
124
+ "baseline",
125
+ "adopted",
126
+ "decided",
127
+ "effected",
128
+ "waiting",
129
+ "checked",
130
+ "indexed",
131
+ "event-indexed",
132
+ "current",
133
+ ];
108
134
  export async function inspectSchema(connection) {
109
135
  const version = integer(await connection.get("PRAGMA user_version"), "user_version");
110
136
  const detail = String(version);
@@ -132,6 +158,11 @@ export async function createSchema(connection) {
132
158
  await recordVersion(connection, baselineVersion);
133
159
  await adoptSchema(connection, null);
134
160
  await upgradeSchema(connection, decidedVersion);
161
+ await upgradeSchema(connection, effectedVersion);
162
+ await upgradeSchema(connection, waitingVersion);
163
+ await upgradeSchema(connection, checkedVersion);
164
+ await upgradeSchema(connection, spendingVersion);
165
+ await upgradeSchema(connection, eventIndexVersion);
135
166
  await upgradeSchema(connection, currentVersion);
136
167
  }
137
168
  export async function upgradeSchema(connection, version) {
@@ -1 +1,3 @@
1
1
  export declare const effectSchema = "\nCREATE TABLE run_budgets (\n run_id TEXT PRIMARY KEY REFERENCES runs (run_id) DEFERRABLE INITIALLY DEFERRED,\n effect_limit INTEGER NOT NULL,\n spent INTEGER NOT NULL CHECK (spent <= effect_limit),\n capabilities TEXT NOT NULL,\n exhausted_sequence INTEGER REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED\n) STRICT;\nCREATE TABLE operations (\n operation_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL REFERENCES runs (run_id) DEFERRABLE INITIALLY DEFERRED,\n capability TEXT NOT NULL,\n method TEXT NOT NULL,\n target TEXT NOT NULL,\n payload TEXT NOT NULL,\n input_digest TEXT NOT NULL,\n units INTEGER NOT NULL,\n lease_key TEXT NOT NULL,\n recovery_limit INTEGER NOT NULL,\n status TEXT NOT NULL,\n reason TEXT,\n attempts INTEGER NOT NULL,\n receipt TEXT,\n worker TEXT,\n result TEXT,\n requested_sequence INTEGER NOT NULL REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED,\n wait_sequence INTEGER REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED,\n settled_sequence INTEGER REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED\n) STRICT;\nCREATE INDEX operations_run ON operations (run_id);\nCREATE INDEX operations_waiting ON operations (wait_sequence) WHERE status = 'waiting';\nCREATE TABLE leases (\n resource_key TEXT PRIMARY KEY,\n operation_id TEXT NOT NULL REFERENCES operations (operation_id) DEFERRABLE INITIALLY DEFERRED,\n generation INTEGER NOT NULL CHECK (generation > 0),\n expires_at TEXT NOT NULL,\n state TEXT NOT NULL CHECK (state IN ('held', 'expired', 'released')),\n granted_sequence INTEGER NOT NULL REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED\n) STRICT;\nCREATE INDEX leases_due ON leases (expires_at) WHERE state = 'held';\nCREATE TABLE effect_evidence (\n sequence INTEGER PRIMARY KEY REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED,\n run_id TEXT NOT NULL,\n operation_id TEXT NOT NULL,\n disposition TEXT NOT NULL,\n reason TEXT\n) STRICT;\nCREATE TABLE stopped_operations (\n operation_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL REFERENCES runs (run_id) DEFERRABLE INITIALLY DEFERRED,\n sequence INTEGER NOT NULL REFERENCES events (sequence) DEFERRABLE INITIALLY DEFERRED\n) STRICT;\nCREATE TABLE dispatch_attempts (\n effect_id TEXT PRIMARY KEY REFERENCES deliveries (effect_id) DEFERRABLE INITIALLY DEFERRED,\n purpose TEXT NOT NULL,\n lease_generation INTEGER,\n authority_epoch INTEGER NOT NULL\n) STRICT;\n";
2
+ export declare const spendingIndexes = "\nCREATE INDEX events_spend_window ON events (julianday(recorded_at));\nCREATE INDEX operations_worker_settled ON operations (settled_sequence) WHERE capability = 'claude';\nCREATE INDEX operations_worker_open ON operations (requested_sequence) WHERE capability = 'claude' AND settled_sequence IS NULL AND status NOT IN ('refused', 'completed', 'failed', 'stopped', 'cancelled');\n";
3
+ export declare const runIndexes = "\nCREATE INDEX effect_evidence_run_sequence ON effect_evidence (run_id, sequence);\nCREATE INDEX stopped_operations_run ON stopped_operations (run_id);\n";
@@ -57,3 +57,12 @@ CREATE TABLE dispatch_attempts (
57
57
  authority_epoch INTEGER NOT NULL
58
58
  ) STRICT;
59
59
  `;
60
+ export const spendingIndexes = `
61
+ CREATE INDEX events_spend_window ON events (julianday(recorded_at));
62
+ CREATE INDEX operations_worker_settled ON operations (settled_sequence) WHERE capability = 'claude';
63
+ CREATE INDEX operations_worker_open ON operations (requested_sequence) WHERE capability = 'claude' AND settled_sequence IS NULL AND status NOT IN ('refused', 'completed', 'failed', 'stopped', 'cancelled');
64
+ `;
65
+ export const runIndexes = `
66
+ CREATE INDEX effect_evidence_run_sequence ON effect_evidence (run_id, sequence);
67
+ CREATE INDEX stopped_operations_run ON stopped_operations (run_id);
68
+ `;
@@ -0,0 +1,12 @@
1
+ import type { ProjectionSnapshot } from "./decision-snapshots.ts";
2
+ import type { DomainChange } from "./domain-changes.ts";
3
+ import type { EventRow } from "./domain-rows.ts";
4
+ import type { OperationRow } from "./effect-rows.ts";
5
+ export declare function binaryOrder(left: string, right: string): number;
6
+ export interface ProjectedChange extends Pick<DomainChange, "previous" | "sequence" | "definitions" | "runs" | "commands" | "added" | "released" | "staged" | "closed" | "gates" | "details" | "waits"> {
7
+ readonly events: readonly Pick<EventRow, "sequence" | "recordedAt">[];
8
+ readonly operations: readonly Pick<OperationRow, "operationId" | "status">[];
9
+ }
10
+ export declare function projectedChange(change: DomainChange): ProjectedChange;
11
+ export declare function followingSequence(sequence: number, change: Pick<ProjectedChange, "events">): number;
12
+ export declare function changedProjection(snapshot: ProjectionSnapshot, changes: readonly ProjectedChange[]): ProjectionSnapshot;
@@ -0,0 +1,194 @@
1
+ export function binaryOrder(left, right) {
2
+ return Buffer.compare(Buffer.from(left), Buffer.from(right));
3
+ }
4
+ function upserted(rows, upsert) {
5
+ if (upsert.rows.length === 0)
6
+ return rows;
7
+ const next = [...rows];
8
+ const positions = new Map(next.map((row, index) => [upsert.key(row), index]));
9
+ for (const row of upsert.rows) {
10
+ const key = upsert.key(row);
11
+ const position = positions.get(key) ?? next.length;
12
+ positions.set(key, position);
13
+ next[position] = row;
14
+ }
15
+ return next.sort(upsert.order);
16
+ }
17
+ function definitions(rows, added) {
18
+ const known = new Set(rows.map((row) => row.pin));
19
+ const fresh = added.filter((row) => {
20
+ if (known.has(row.pin))
21
+ return false;
22
+ known.add(row.pin);
23
+ return true;
24
+ });
25
+ return upserted(rows, {
26
+ rows: fresh,
27
+ key: (row) => row.pin,
28
+ order: (left, right) => binaryOrder(left.pin, right.pin),
29
+ });
30
+ }
31
+ function runs(rows, change) {
32
+ return upserted(rows, {
33
+ rows: change,
34
+ key: (row) => row.runId,
35
+ order: (left, right) => binaryOrder(left.runId, right.runId),
36
+ });
37
+ }
38
+ function commands(rows, added) {
39
+ if (added.length === 0)
40
+ return rows;
41
+ return [...rows, ...added].sort((left, right) => left.sequence - right.sequence);
42
+ }
43
+ function appendGuarded(table, entry) {
44
+ const key = table.key(entry.row);
45
+ if (entry.open)
46
+ table.open.set(key, [...(table.open.get(key) ?? []), table.rows.length]);
47
+ table.rows.push(entry.row);
48
+ }
49
+ function guarded(rows, fields) {
50
+ const table = { rows: [], open: new Map(), key: fields.key };
51
+ for (const row of rows)
52
+ appendGuarded(table, { row, open: fields.open(row) });
53
+ return table;
54
+ }
55
+ function settleGuarded(table, settlement) {
56
+ for (const index of table.open.get(settlement.key) ?? []) {
57
+ const row = table.rows[index];
58
+ if (row === undefined)
59
+ continue;
60
+ table.rows[index] = settlement.update(row);
61
+ }
62
+ table.open.delete(settlement.key);
63
+ }
64
+ function outbox(rows, changes) {
65
+ if (changes.every((change) => change.added.length + change.released.length === 0))
66
+ return rows;
67
+ const table = guarded(rows, {
68
+ key: (row) => row.operationId,
69
+ open: (row) => row.releasedSequence === null,
70
+ });
71
+ for (const change of changes) {
72
+ for (const row of change.added)
73
+ appendGuarded(table, {
74
+ row: { ...row, releasedSequence: null },
75
+ open: true,
76
+ });
77
+ for (const { operationId, releasedSequence } of change.released)
78
+ settleGuarded(table, {
79
+ key: operationId,
80
+ update: (row) => ({ ...row, releasedSequence }),
81
+ });
82
+ }
83
+ return table.rows.sort((left, right) => left.createdSequence - right.createdSequence);
84
+ }
85
+ function stagedAttempt(row, sequence) {
86
+ return {
87
+ effectId: row.effectId,
88
+ operationId: row.operationId,
89
+ inputDigest: row.inputDigest,
90
+ stagedSequence: sequence,
91
+ outcome: null,
92
+ receipt: null,
93
+ purpose: row.purpose,
94
+ leaseGeneration: row.leaseGeneration,
95
+ epoch: row.authorityEpoch,
96
+ };
97
+ }
98
+ function deliveries(rows, changes) {
99
+ if (changes.every((change) => change.closed.length + change.staged.length === 0))
100
+ return rows;
101
+ const table = guarded(rows, {
102
+ key: (row) => row.effectId,
103
+ open: (row) => row.outcome === null,
104
+ });
105
+ for (const change of changes) {
106
+ for (const { effectId, outcome, receipt } of change.closed)
107
+ settleGuarded(table, {
108
+ key: effectId,
109
+ update: (row) => ({ ...row, outcome, receipt }),
110
+ });
111
+ for (const row of change.staged)
112
+ appendGuarded(table, {
113
+ row: stagedAttempt(row, change.sequence),
114
+ open: true,
115
+ });
116
+ }
117
+ return table.rows.sort((left, right) => left.stagedSequence - right.stagedSequence);
118
+ }
119
+ function gates(rows, change) {
120
+ return upserted(rows, {
121
+ rows: change,
122
+ key: (row) => JSON.stringify([row.runId, row.gateId]),
123
+ order: (left, right) => left.openedSequence - right.openedSequence ||
124
+ binaryOrder(left.gateId, right.gateId),
125
+ });
126
+ }
127
+ function details(rows, change) {
128
+ return upserted(rows, {
129
+ rows: change,
130
+ key: (row) => row.runId,
131
+ order: (left, right) => binaryOrder(left.runId, right.runId),
132
+ });
133
+ }
134
+ function waits(rows, change) {
135
+ return upserted(rows, {
136
+ rows: change,
137
+ key: (row) => JSON.stringify([row.runId, row.name]),
138
+ order: (left, right) => binaryOrder(left.runId, right.runId) ||
139
+ binaryOrder(left.name, right.name),
140
+ });
141
+ }
142
+ function pending(operations, change) {
143
+ if (change.length === 0)
144
+ return operations;
145
+ const next = new Set(operations);
146
+ for (const row of change)
147
+ if (row.status === "dispatch-pending")
148
+ next.add(row.operationId);
149
+ else
150
+ next.delete(row.operationId);
151
+ return [...next].sort(binaryOrder);
152
+ }
153
+ export function projectedChange(change) {
154
+ return {
155
+ previous: change.previous,
156
+ sequence: change.sequence,
157
+ definitions: change.definitions,
158
+ events: change.events.map(({ sequence, recordedAt }) => ({
159
+ sequence,
160
+ recordedAt,
161
+ })),
162
+ runs: change.runs,
163
+ commands: change.commands,
164
+ added: change.added,
165
+ released: change.released,
166
+ staged: change.staged,
167
+ closed: change.closed,
168
+ gates: change.gates,
169
+ details: change.details,
170
+ waits: change.waits,
171
+ operations: change.operations.map(({ operationId, status }) => ({
172
+ operationId,
173
+ status,
174
+ })),
175
+ };
176
+ }
177
+ export function followingSequence(sequence, change) {
178
+ return Math.max(sequence, ...change.events.map((event) => event.sequence));
179
+ }
180
+ export function changedProjection(snapshot, changes) {
181
+ const rows = (select) => changes.flatMap(select);
182
+ return {
183
+ definitions: definitions(snapshot.definitions, rows((change) => change.definitions)),
184
+ runs: runs(snapshot.runs, rows((change) => change.runs)),
185
+ commands: commands(snapshot.commands, rows((change) => change.commands)),
186
+ outbox: outbox(snapshot.outbox, changes),
187
+ gates: gates(snapshot.gates, rows((change) => change.gates)),
188
+ details: details(snapshot.details, rows((change) => change.details)),
189
+ waits: waits(snapshot.waits, rows((change) => change.waits)),
190
+ deliveries: deliveries(snapshot.deliveries, changes),
191
+ pending: pending(snapshot.pending, rows((change) => change.operations)),
192
+ sequence: changes.reduce(followingSequence, snapshot.sequence),
193
+ };
194
+ }
@@ -0,0 +1,7 @@
1
+ import { type SqlConnection } from "./domain-rows.ts";
2
+ export type MessageOutcome = "committed" | "rolled-back" | "missing";
3
+ export declare function messageOutcomes(connection: SqlConnection, messageIds: readonly string[]): Promise<ReadonlyMap<string, MessageOutcome>>;
4
+ export declare function runTimes(connection: SqlConnection): Promise<ReadonlyMap<string, string>>;
5
+ export declare function recordedTimes(connection: SqlConnection, sequences: readonly number[]): Promise<ReadonlyMap<number, string>>;
6
+ export declare function submittedWorkflows(connection: SqlConnection): Promise<ReadonlyMap<string, string>>;
7
+ export declare function storedWorkflows(connection: SqlConnection, digests: readonly string[]): Promise<ReadonlyMap<string, string | null>>;
@@ -0,0 +1,30 @@
1
+ import { integer, optionalText, text, } from "./domain-rows.js";
2
+ const workflowColumn = "json_extract(s.body, '$.workflowId') AS workflow_id FROM documents s";
3
+ const workflowFilter = "json_valid(s.body) AND json_type(s.body, '$.workflowId') = 'text'";
4
+ export async function messageOutcomes(connection, messageIds) {
5
+ const rows = await connection.all("SELECT id, completed_at_ms IS NOT NULL AND rejection IS NULL AND error IS NULL AS committed FROM solid_messages WHERE id IN (SELECT value FROM json_each(?))", [JSON.stringify(messageIds)]);
6
+ return new Map(rows.map((row) => [
7
+ text(row, "id"),
8
+ integer(row, "committed") === 1 ? "committed" : "rolled-back",
9
+ ]));
10
+ }
11
+ export async function runTimes(connection) {
12
+ const rows = await connection.all("SELECT r.run_id, e.recorded_at FROM runs r JOIN events e ON e.sequence = r.sequence");
13
+ return new Map(rows.map((row) => [text(row, "run_id"), text(row, "recorded_at")]));
14
+ }
15
+ export async function recordedTimes(connection, sequences) {
16
+ if (sequences.length === 0)
17
+ return new Map();
18
+ const rows = await connection.all("SELECT sequence, recorded_at FROM events WHERE sequence IN (SELECT value FROM json_each(?))", [JSON.stringify(sequences)]);
19
+ return new Map(rows.map((row) => [integer(row, "sequence"), text(row, "recorded_at")]));
20
+ }
21
+ export async function submittedWorkflows(connection) {
22
+ const rows = await connection.all(`SELECT DISTINCT s.digest, ${workflowColumn} JOIN run_details d ON d.submission = s.digest WHERE ${workflowFilter}`);
23
+ return new Map(rows.map((row) => [text(row, "digest"), text(row, "workflow_id")]));
24
+ }
25
+ export async function storedWorkflows(connection, digests) {
26
+ if (digests.length === 0)
27
+ return new Map();
28
+ const rows = await connection.all(`SELECT s.digest, ${workflowColumn} WHERE s.digest IN (SELECT value FROM json_each(?)) AND ${workflowFilter}`, [JSON.stringify(digests)]);
29
+ return new Map(rows.map((row) => [text(row, "digest"), optionalText(row, "workflow_id")]));
30
+ }
@@ -0,0 +1,15 @@
1
+ import type { ProtectedRequest, GateRequest, HandoffRequest, RunWaitRequest, CommandWaitRequest } from "./step-bridge.ts";
2
+ export type ScenarioRequest = readonly ["effect", ProtectedRequest] | readonly ["gate", GateRequest] | readonly ["waitForDecision", GateRequest] | readonly ["handoff", HandoffRequest] | readonly ["waitForRun", RunWaitRequest] | readonly ["waitForCommand", CommandWaitRequest] | readonly [
3
+ "sleep",
4
+ {
5
+ readonly seconds: number;
6
+ } | {
7
+ readonly until: string;
8
+ }
9
+ ];
10
+ export interface ScenarioResult {
11
+ readonly spent?: number;
12
+ readonly outcome: unknown;
13
+ readonly requests: readonly ScenarioRequest[];
14
+ }
15
+ export declare function scenarioResult(value: unknown): value is ScenarioResult;
@@ -0,0 +1,93 @@
1
+ import { isInstant } from "./authority/instants.js";
2
+ import { isCommandWaitRequest } from "./command-wait.js";
3
+ import { record } from "./protocol.js";
4
+ export function scenarioResult(value) {
5
+ const result = record(value);
6
+ return (result !== undefined &&
7
+ Object.hasOwn(result, "outcome") &&
8
+ Array.isArray(result["requests"]) &&
9
+ result["requests"].every(scenarioRequest) &&
10
+ (result["spent"] === undefined || typeof result["spent"] === "number"));
11
+ }
12
+ function scenarioRequest(value) {
13
+ if (!requestPair(value))
14
+ return false;
15
+ const request = record(value[1]);
16
+ if (request === undefined)
17
+ return false;
18
+ switch (value[0]) {
19
+ case "effect":
20
+ return protectedRequest(request);
21
+ case "gate":
22
+ case "waitForDecision":
23
+ return gateRequest(request);
24
+ case "handoff":
25
+ return handoffRequest(request);
26
+ case "waitForRun":
27
+ return runWaitRequest(request);
28
+ case "waitForCommand":
29
+ return isCommandWaitRequest(request);
30
+ case "sleep":
31
+ return sleepRequest(request);
32
+ default:
33
+ return false;
34
+ }
35
+ }
36
+ function requestPair(value) {
37
+ return Array.isArray(value) && value.length === 2;
38
+ }
39
+ function runWaitRequest(request) {
40
+ return (typeof request["runId"] === "string" &&
41
+ typeof request["maximumWaitSeconds"] === "number");
42
+ }
43
+ function sleepRequest(request) {
44
+ if (typeof request["until"] === "string")
45
+ return isInstant(request["until"]);
46
+ const seconds = request["seconds"];
47
+ return (typeof seconds === "number" &&
48
+ Number.isInteger(seconds) &&
49
+ seconds >= 1 &&
50
+ seconds <= 86400);
51
+ }
52
+ function gateRequest(request) {
53
+ return (typeof request["gateId"] === "string" &&
54
+ (request["kind"] === "question" || request["kind"] === "approval") &&
55
+ typeof request["prompt"] === "string" &&
56
+ optionalText(request["expiresAt"]));
57
+ }
58
+ function handoffRequest(request) {
59
+ const input = record(request["input"]);
60
+ return (typeof request["workflowId"] === "string" &&
61
+ input !== undefined &&
62
+ Object.values(input).every(handoffValue));
63
+ }
64
+ function protectedRequest(request) {
65
+ return (protectedScope(request["scope"]) &&
66
+ ["capability", "method", "target", "payload"].every((key) => typeof request[key] === "string") &&
67
+ typeof request["units"] === "number" &&
68
+ optionalText(request["resource"]));
69
+ }
70
+ function protectedScope(value) {
71
+ const scope = record(value);
72
+ if (scope === undefined)
73
+ return false;
74
+ const stage = record(scope["stage"]);
75
+ return (typeof scope["phase"] === "string" &&
76
+ typeof scope["operation"] === "string" &&
77
+ typeof scope["round"] === "number" &&
78
+ optionalText(scope["key"]) &&
79
+ (scope["stage"] === undefined ||
80
+ (stage !== undefined &&
81
+ ["id", "visit", "branch"].every((key) => typeof stage[key] === "string"))));
82
+ }
83
+ function optionalText(value) {
84
+ return value === undefined || typeof value === "string";
85
+ }
86
+ function handoffValue(value) {
87
+ if (value === null || ["string", "boolean", "number"].includes(typeof value))
88
+ return true;
89
+ if (Array.isArray(value))
90
+ return value.every(handoffValue);
91
+ const fields = record(value);
92
+ return fields !== undefined && Object.values(fields).every(handoffValue);
93
+ }
@@ -1,5 +1,7 @@
1
- import { type HandoffValue, type ProtectedResult, type GateResult, type DecisionResult, type RunWaitOutcome, type ProtectedRequest, type GateRequest, type HandoffRequest, type RunWaitRequest } from "./step-bridge.ts";
1
+ import { type ScenarioRequest, type ScenarioResult } from "./testing-requests.ts";
2
+ import { type HandoffValue, type ProtectedResult, type GateResult, type DecisionResult, type RunWaitOutcome, type CommandWaitProgress } from "./step-bridge.ts";
2
3
  export interface StepScenario {
4
+ readonly commandWaits?: Readonly<Record<string, readonly CommandWaitProgress[]>>;
3
5
  readonly turn?: ProtectedResult;
4
6
  readonly effects?: Readonly<Record<string, readonly ProtectedResult[]>>;
5
7
  readonly gate?: GateResult;
@@ -11,16 +13,8 @@ export interface WorkflowScenario extends StepScenario {
11
13
  readonly workflow: string;
12
14
  readonly exportName: string;
13
15
  readonly input: HandoffValue;
14
- readonly decision?: HandoffValue;
15
- }
16
- export type ScenarioRequest = readonly ["effect", ProtectedRequest] | readonly ["gate", GateRequest] | readonly ["waitForDecision", GateRequest] | readonly ["handoff", HandoffRequest] | readonly ["waitForRun", RunWaitRequest] | readonly ["sleep", {
17
- readonly seconds: number;
18
- }];
19
- export interface ScenarioResult {
20
- readonly spent?: number;
21
- readonly outcome: unknown;
22
- readonly requests: readonly ScenarioRequest[];
23
16
  }
17
+ export type { ScenarioRequest, ScenarioResult } from "./testing-requests.ts";
24
18
  export declare function fakeStepBridge(scenario: StepScenario): {
25
19
  requests: ScenarioRequest[];
26
20
  readonly spent: number;