cloving 1.1.0 → 1.3.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 (568) hide show
  1. package/README.md +584 -144
  2. package/assets/watch-fonts/fira-code-OFL.md +93 -0
  3. package/assets/watch-fonts/fira-code-latin-400-normal.woff2 +0 -0
  4. package/assets/watch-fonts/fira-code-latin-500-normal.woff2 +0 -0
  5. package/assets/watch-fonts/heebo-OFL.md +93 -0
  6. package/assets/watch-fonts/heebo-latin-500-normal.woff2 +0 -0
  7. package/assets/watch-fonts/heebo-latin-700-normal.woff2 +0 -0
  8. package/assets/watch-fonts/heebo-latin-800-normal.woff2 +0 -0
  9. package/assets/watch-fonts/manifest.json +112 -0
  10. package/assets/watch-fonts/space-grotesk-OFL.md +93 -0
  11. package/assets/watch-fonts/space-grotesk-latin-400-normal.woff2 +0 -0
  12. package/assets/watch-fonts/space-grotesk-latin-500-normal.woff2 +0 -0
  13. package/assets/watch-fonts/space-grotesk-latin-600-normal.woff2 +0 -0
  14. package/assets/watch-fonts/space-grotesk-latin-700-normal.woff2 +0 -0
  15. package/dist/src/agent-harness-shell.d.ts +12 -0
  16. package/dist/src/agent-harness-shell.js +90 -0
  17. package/dist/src/agent-harness-versions.d.ts +8 -0
  18. package/dist/src/agent-harness-versions.js +49 -0
  19. package/dist/src/agent-harnesses.d.ts +4 -0
  20. package/dist/src/agent-harnesses.js +13 -0
  21. package/dist/src/authority/commands.d.ts +2 -0
  22. package/dist/src/authority/commands.js +49 -8
  23. package/dist/src/authority/dispatch-decision.d.ts +1 -0
  24. package/dist/src/authority/dispatch-decision.js +7 -4
  25. package/dist/src/authority/events.js +2 -2
  26. package/dist/src/authority/gate-reduction.d.ts +1 -0
  27. package/dist/src/authority/gate-reduction.js +18 -3
  28. package/dist/src/authority/gates.d.ts +2 -1
  29. package/dist/src/authority/gates.js +5 -1
  30. package/dist/src/authority/handoff-chain.d.ts +24 -0
  31. package/dist/src/authority/handoff-chain.js +46 -0
  32. package/dist/src/authority/operations.js +1 -1
  33. package/dist/src/authority/reconciliation.d.ts +1 -0
  34. package/dist/src/authority/reconciliation.js +18 -11
  35. package/dist/src/authority/reduction.d.ts +1 -1
  36. package/dist/src/authority/reduction.js +6 -1
  37. package/dist/src/authority/status-input.d.ts +1 -1
  38. package/dist/src/authority/status.d.ts +1 -0
  39. package/dist/src/authority/status.js +27 -3
  40. package/dist/src/authority/transitions.d.ts +5 -5
  41. package/dist/src/authority/transitions.js +9 -0
  42. package/dist/src/broker/actor/authority-delivery.js +1 -0
  43. package/dist/src/broker/actor/authority-queries.d.ts +11 -1
  44. package/dist/src/broker/actor/authority-queries.js +67 -3
  45. package/dist/src/broker/actor/authority-receipts.js +11 -1
  46. package/dist/src/broker/actor/authority-session.js +2 -2
  47. package/dist/src/broker/actor/authority-settings.js +4 -0
  48. package/dist/src/broker/actor/delivery-intents.d.ts +3 -1
  49. package/dist/src/broker/actor/delivery-intents.js +4 -4
  50. package/dist/src/broker/actor/effect-delivery.js +13 -1
  51. package/dist/src/broker/actor/effect-queries.d.ts +1 -0
  52. package/dist/src/broker/actor/effect-queries.js +7 -0
  53. package/dist/src/broker/actor/pin-check.js +1 -1
  54. package/dist/src/broker/actor/stop-plan.js +1 -1
  55. package/dist/src/broker/actor/turn-state.js +1 -1
  56. package/dist/src/broker/authority-admission.js +26 -5
  57. package/dist/src/broker/authority-restore.js +1 -0
  58. package/dist/src/broker/decision-restore.js +4 -4
  59. package/dist/src/broker/socket-address.d.ts +3 -1
  60. package/dist/src/broker/socket-address.js +2 -2
  61. package/dist/src/cli/arguments.d.ts +11 -13
  62. package/dist/src/cli/arguments.js +37 -107
  63. package/dist/src/cli/command-effects.d.ts +7 -0
  64. package/dist/src/cli/command-effects.js +39 -0
  65. package/dist/src/cli/commands.js +11 -4
  66. package/dist/src/cli/config-arguments.d.ts +11 -0
  67. package/dist/src/cli/config-arguments.js +59 -0
  68. package/dist/src/cli/config-command.d.ts +2 -0
  69. package/dist/src/cli/config-command.js +105 -0
  70. package/dist/src/cli/config-file.d.ts +3 -0
  71. package/dist/src/cli/config-file.js +50 -0
  72. package/dist/src/cli/config-lock.d.ts +7 -0
  73. package/dist/src/cli/config-lock.js +61 -0
  74. package/dist/src/cli/config-notice.d.ts +5 -0
  75. package/dist/src/cli/config-notice.js +46 -0
  76. package/dist/src/cli/doctor-github.d.ts +9 -0
  77. package/dist/src/cli/doctor-github.js +138 -0
  78. package/dist/src/cli/doctor-harness.d.ts +13 -0
  79. package/dist/src/cli/doctor-harness.js +242 -0
  80. package/dist/src/cli/doctor-local.d.ts +18 -0
  81. package/dist/src/cli/doctor-local.js +77 -0
  82. package/dist/src/cli/doctor-runtime.d.ts +15 -0
  83. package/dist/src/cli/doctor-runtime.js +176 -0
  84. package/dist/src/cli/doctor-service.d.ts +1 -0
  85. package/dist/src/cli/doctor-service.js +11 -0
  86. package/dist/src/cli/doctor-workflows.d.ts +3 -0
  87. package/dist/src/cli/doctor-workflows.js +45 -0
  88. package/dist/src/cli/doctor.d.ts +15 -0
  89. package/dist/src/cli/doctor.js +190 -0
  90. package/dist/src/cli/github-ci-progress.d.ts +8 -0
  91. package/dist/src/cli/github-ci-progress.js +83 -0
  92. package/dist/src/cli/github-retry.d.ts +6 -0
  93. package/dist/src/cli/github-retry.js +47 -0
  94. package/dist/src/cli/harness-probes.d.ts +22 -0
  95. package/dist/src/cli/harness-probes.js +183 -0
  96. package/dist/src/cli/main.d.ts +7 -1
  97. package/dist/src/cli/main.js +39 -61
  98. package/dist/src/cli/phone-arguments.d.ts +14 -0
  99. package/dist/src/cli/phone-arguments.js +37 -0
  100. package/dist/src/cli/phone-client.d.ts +2 -0
  101. package/dist/src/cli/phone-client.js +32 -0
  102. package/dist/src/cli/phone-command.d.ts +13 -0
  103. package/dist/src/cli/phone-command.js +101 -0
  104. package/dist/src/cli/probe-command.d.ts +36 -0
  105. package/dist/src/cli/probe-command.js +59 -0
  106. package/dist/src/cli/project-settings.d.ts +4 -0
  107. package/dist/src/cli/project-settings.js +33 -0
  108. package/dist/src/cli/render.d.ts +3 -1
  109. package/dist/src/cli/render.js +102 -39
  110. package/dist/src/cli/report-github.d.ts +18 -0
  111. package/dist/src/cli/report-github.js +200 -0
  112. package/dist/src/cli/report.d.ts +17 -0
  113. package/dist/src/cli/report.js +192 -0
  114. package/dist/src/cli/repository-arguments.d.ts +5 -0
  115. package/dist/src/cli/repository-arguments.js +34 -0
  116. package/dist/src/cli/runtime-arguments.d.ts +4 -0
  117. package/dist/src/cli/runtime-arguments.js +15 -0
  118. package/dist/src/cli/runtime-directory.d.ts +6 -2
  119. package/dist/src/cli/runtime-directory.js +72 -14
  120. package/dist/src/cli/toolchain.d.ts +2 -0
  121. package/dist/src/cli/toolchain.js +22 -2
  122. package/dist/src/cli/usage-render.d.ts +5 -0
  123. package/dist/src/cli/usage-render.js +40 -1
  124. package/dist/src/cli/usage.d.ts +3 -3
  125. package/dist/src/cli/usage.js +74 -45
  126. package/dist/src/cli/watch-actions.d.ts +2 -0
  127. package/dist/src/cli/watch-actions.js +4 -4
  128. package/dist/src/cli/watch-board-view.d.ts +12 -1
  129. package/dist/src/cli/watch-board-view.js +64 -12
  130. package/dist/src/cli/watch-board.d.ts +7 -1
  131. package/dist/src/cli/watch-board.js +61 -16
  132. package/dist/src/cli/watch-card-forms.js +2 -2
  133. package/dist/src/cli/watch-client.d.ts +1 -1
  134. package/dist/src/cli/watch-client.js +12 -3
  135. package/dist/src/cli/watch-header-view.d.ts +27 -0
  136. package/dist/src/cli/watch-header-view.js +116 -0
  137. package/dist/src/cli/watch-model.d.ts +10 -4
  138. package/dist/src/cli/watch-model.js +49 -59
  139. package/dist/src/cli/watch-page.js +67 -14
  140. package/dist/src/cli/watch-phases.js +3 -3
  141. package/dist/src/cli/watch-phone-client.d.ts +1 -0
  142. package/dist/src/cli/watch-phone-client.js +84 -0
  143. package/dist/src/cli/watch-phone-view.d.ts +56 -0
  144. package/dist/src/cli/watch-phone-view.js +113 -0
  145. package/dist/src/cli/watch-phone.d.ts +5 -0
  146. package/dist/src/cli/watch-phone.js +53 -0
  147. package/dist/src/cli/watch-pr-command.d.ts +5 -2
  148. package/dist/src/cli/watch-pr-command.js +41 -4
  149. package/dist/src/cli/watch-pr-identity.d.ts +14 -2
  150. package/dist/src/cli/watch-pr-identity.js +25 -0
  151. package/dist/src/cli/watch-pr-observer.d.ts +1 -0
  152. package/dist/src/cli/watch-pr-observer.js +48 -6
  153. package/dist/src/cli/watch-pull-request.d.ts +12 -0
  154. package/dist/src/cli/watch-pull-request.js +134 -0
  155. package/dist/src/cli/watch-reads.d.ts +7 -1
  156. package/dist/src/cli/watch-reads.js +42 -20
  157. package/dist/src/cli/watch-render.d.ts +23 -2
  158. package/dist/src/cli/watch-render.js +2 -1
  159. package/dist/src/cli/watch-server.js +56 -7
  160. package/dist/src/cli/watch-turn.d.ts +4 -1
  161. package/dist/src/cli/watch-turn.js +38 -2
  162. package/dist/src/cli/watch-usage.js +5 -1
  163. package/dist/src/cli/watch-view.d.ts +10 -17
  164. package/dist/src/cli/watch-view.js +33 -77
  165. package/dist/src/cli.js +106 -23
  166. package/dist/src/command-settings.d.ts +16 -0
  167. package/dist/src/command-settings.js +42 -0
  168. package/dist/src/configuration-change.d.ts +11 -0
  169. package/dist/src/configuration-change.js +62 -0
  170. package/dist/src/configuration-display.d.ts +21 -0
  171. package/dist/src/configuration-display.js +69 -0
  172. package/dist/src/configuration-schema.d.ts +49 -0
  173. package/dist/src/configuration-schema.js +159 -0
  174. package/dist/src/daemon/claude-turn.d.ts +20 -5
  175. package/dist/src/daemon/claude-turn.js +116 -53
  176. package/dist/src/daemon/claude-worker.d.ts +3 -5
  177. package/dist/src/daemon/claude-worker.js +64 -80
  178. package/dist/src/daemon/command-journal.d.ts +5 -0
  179. package/dist/src/daemon/command-journal.js +50 -0
  180. package/dist/src/daemon/command-process.d.ts +28 -0
  181. package/dist/src/daemon/command-process.js +164 -0
  182. package/dist/src/daemon/command-worker.d.ts +19 -0
  183. package/dist/src/daemon/command-worker.js +182 -0
  184. package/dist/src/daemon/cursor-stream.d.ts +4 -0
  185. package/dist/src/daemon/cursor-stream.js +154 -0
  186. package/dist/src/daemon/daemon-adapters.d.ts +58 -0
  187. package/dist/src/daemon/daemon-adapters.js +102 -0
  188. package/dist/src/daemon/daemon-loops.d.ts +14 -0
  189. package/dist/src/daemon/daemon-loops.js +39 -0
  190. package/dist/src/daemon/daemon.d.ts +3 -30
  191. package/dist/src/daemon/daemon.js +132 -110
  192. package/dist/src/daemon/declared-input.d.ts +3 -0
  193. package/dist/src/daemon/declared-input.js +9 -0
  194. package/dist/src/daemon/delivery-router.js +7 -1
  195. package/dist/src/daemon/gemini-stream.d.ts +4 -0
  196. package/dist/src/daemon/gemini-stream.js +129 -0
  197. package/dist/src/daemon/github-calls.d.ts +4 -0
  198. package/dist/src/daemon/github-calls.js +16 -7
  199. package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
  200. package/dist/src/daemon/github-ci-rerun.js +92 -0
  201. package/dist/src/daemon/github-ci.d.ts +6 -0
  202. package/dist/src/daemon/github-ci.js +251 -0
  203. package/dist/src/daemon/github-merge-call.d.ts +16 -0
  204. package/dist/src/daemon/github-merge-call.js +73 -0
  205. package/dist/src/daemon/github-merge.d.ts +3 -5
  206. package/dist/src/daemon/github-merge.js +59 -98
  207. package/dist/src/daemon/github-methods.d.ts +28 -0
  208. package/dist/src/daemon/github-methods.js +90 -16
  209. package/dist/src/daemon/github-operation.d.ts +3 -0
  210. package/dist/src/daemon/github-retry.d.ts +6 -0
  211. package/dist/src/daemon/github-retry.js +13 -0
  212. package/dist/src/daemon/github-ticket-status.js +27 -1
  213. package/dist/src/daemon/github-worker.js +2 -1
  214. package/dist/src/daemon/handoff-worker.d.ts +10 -0
  215. package/dist/src/daemon/handoff-worker.js +232 -0
  216. package/dist/src/daemon/issue-queue.d.ts +2 -0
  217. package/dist/src/daemon/issue-queue.js +92 -63
  218. package/dist/src/daemon/notify-journal.d.ts +18 -0
  219. package/dist/src/daemon/notify-journal.js +108 -0
  220. package/dist/src/daemon/notify-message.js +2 -1
  221. package/dist/src/daemon/notify.js +177 -37
  222. package/dist/src/daemon/opencode-stream.d.ts +5 -0
  223. package/dist/src/daemon/opencode-stream.js +87 -0
  224. package/dist/src/daemon/queue-status.d.ts +4 -0
  225. package/dist/src/daemon/queue-status.js +38 -0
  226. package/dist/src/daemon/retry-worktree.d.ts +18 -0
  227. package/dist/src/daemon/retry-worktree.js +139 -0
  228. package/dist/src/daemon/retrying-turn.d.ts +5 -0
  229. package/dist/src/daemon/retrying-turn.js +145 -21
  230. package/dist/src/daemon/schedule-journal.d.ts +19 -0
  231. package/dist/src/daemon/schedule-journal.js +57 -0
  232. package/dist/src/daemon/text-output.d.ts +18 -0
  233. package/dist/src/daemon/text-output.js +44 -0
  234. package/dist/src/daemon/ticket-dependency-waits.d.ts +18 -0
  235. package/dist/src/daemon/ticket-dependency-waits.js +60 -0
  236. package/dist/src/daemon/ticket-registration.d.ts +10 -8
  237. package/dist/src/daemon/ticket-registration.js +146 -47
  238. package/dist/src/daemon/ticket-source.d.ts +4 -1
  239. package/dist/src/daemon/ticket-source.js +8 -2
  240. package/dist/src/daemon/turn-command.d.ts +10 -0
  241. package/dist/src/daemon/turn-command.js +33 -0
  242. package/dist/src/daemon/turn-report.d.ts +18 -0
  243. package/dist/src/daemon/turn-report.js +79 -0
  244. package/dist/src/daemon/work-tree.d.ts +2 -1
  245. package/dist/src/daemon/work-tree.js +15 -12
  246. package/dist/src/daemon/workflow-generations.d.ts +32 -0
  247. package/dist/src/daemon/workflow-generations.js +57 -0
  248. package/dist/src/daemon/workflow-replay.d.ts +16 -0
  249. package/dist/src/daemon/workflow-replay.js +58 -0
  250. package/dist/src/daemon/workflow-schedules.d.ts +27 -0
  251. package/dist/src/daemon/workflow-schedules.js +185 -0
  252. package/dist/src/decision-visibility.d.ts +2 -0
  253. package/dist/src/decision-visibility.js +10 -0
  254. package/dist/src/decision-wait.d.ts +1 -0
  255. package/dist/src/decision-wait.js +3 -0
  256. package/dist/src/delivery-backoff.d.ts +1 -0
  257. package/dist/src/delivery-backoff.js +3 -0
  258. package/dist/src/doctor-report.d.ts +24 -0
  259. package/dist/src/doctor-report.js +70 -0
  260. package/dist/src/execution-pin.d.ts +9 -0
  261. package/dist/src/execution-pin.js +86 -2
  262. package/dist/src/grok-result.d.ts +12 -0
  263. package/dist/src/grok-result.js +61 -0
  264. package/dist/src/harness-defaults.d.ts +35 -0
  265. package/dist/src/harness-defaults.js +121 -0
  266. package/dist/src/host/decision-resume.d.ts +35 -0
  267. package/dist/src/host/decision-resume.js +86 -0
  268. package/dist/src/host/gate-bridge.d.ts +48 -0
  269. package/dist/src/host/gate-bridge.js +124 -0
  270. package/dist/src/host/run-wait.d.ts +26 -0
  271. package/dist/src/host/run-wait.js +37 -0
  272. package/dist/src/host/start-delivery.d.ts +3 -2
  273. package/dist/src/host/start-delivery.js +11 -4
  274. package/dist/src/host/step-bridge-host.d.ts +6 -19
  275. package/dist/src/host/step-bridge-host.js +57 -55
  276. package/dist/src/host/world-reconciliation.d.ts +1 -0
  277. package/dist/src/host/world-reconciliation.js +3 -0
  278. package/dist/src/host/world-runs.js +5 -0
  279. package/dist/src/issue-identity.d.ts +6 -0
  280. package/dist/src/issue-identity.js +23 -0
  281. package/dist/src/merge-request.d.ts +19 -0
  282. package/dist/src/merge-request.js +32 -0
  283. package/dist/src/phone/canonical-json.d.ts +1 -0
  284. package/dist/src/phone/canonical-json.js +16 -0
  285. package/dist/src/phone/phone-link.d.ts +7 -0
  286. package/dist/src/phone/phone-link.js +21 -0
  287. package/dist/src/phone/qr-data.d.ts +8 -0
  288. package/dist/src/phone/qr-data.js +133 -0
  289. package/dist/src/phone/qr-matrix.d.ts +6 -0
  290. package/dist/src/phone/qr-matrix.js +175 -0
  291. package/dist/src/phone/qr-penalty.d.ts +3 -0
  292. package/dist/src/phone/qr-penalty.js +67 -0
  293. package/dist/src/phone/qr-picture.d.ts +5 -0
  294. package/dist/src/phone/qr-picture.js +24 -0
  295. package/dist/src/private-config.schema.json +263 -0
  296. package/dist/src/project-config.schema.json +65 -0
  297. package/dist/src/project-settings.d.ts +19 -0
  298. package/dist/src/project-settings.js +131 -0
  299. package/dist/src/relay/answer-check.d.ts +24 -0
  300. package/dist/src/relay/answer-check.js +145 -0
  301. package/dist/src/relay/answer-inbox.d.ts +15 -0
  302. package/dist/src/relay/answer-inbox.js +173 -0
  303. package/dist/src/relay/daemon-keys.d.ts +16 -0
  304. package/dist/src/relay/daemon-keys.js +75 -0
  305. package/dist/src/relay/decision-check.d.ts +3 -0
  306. package/dist/src/relay/decision-check.js +77 -0
  307. package/dist/src/relay/decision-close.d.ts +6 -0
  308. package/dist/src/relay/decision-close.js +72 -0
  309. package/dist/src/relay/decision-envelopes.d.ts +29 -0
  310. package/dist/src/relay/decision-envelopes.js +93 -0
  311. package/dist/src/relay/decision-watch.d.ts +14 -0
  312. package/dist/src/relay/decision-watch.js +68 -0
  313. package/dist/src/relay/envelope-post.d.ts +8 -0
  314. package/dist/src/relay/envelope-post.js +71 -0
  315. package/dist/src/relay/envelope.d.ts +28 -0
  316. package/dist/src/relay/envelope.js +53 -0
  317. package/dist/src/relay/hpke.d.ts +25 -0
  318. package/dist/src/relay/hpke.js +108 -0
  319. package/dist/src/relay/pairing-checks.d.ts +42 -0
  320. package/dist/src/relay/pairing-checks.js +172 -0
  321. package/dist/src/relay/pairing-follow.d.ts +8 -0
  322. package/dist/src/relay/pairing-follow.js +95 -0
  323. package/dist/src/relay/pairing-session.d.ts +29 -0
  324. package/dist/src/relay/pairing-session.js +87 -0
  325. package/dist/src/relay/phone-delivery.d.ts +51 -0
  326. package/dist/src/relay/phone-delivery.js +139 -0
  327. package/dist/src/relay/phone-devices.d.ts +36 -0
  328. package/dist/src/relay/phone-devices.js +46 -0
  329. package/dist/src/relay/phone-inbox.d.ts +18 -0
  330. package/dist/src/relay/phone-inbox.js +17 -0
  331. package/dist/src/relay/phone-operations.d.ts +18 -0
  332. package/dist/src/relay/phone-operations.js +121 -0
  333. package/dist/src/relay/phone-outbox.d.ts +21 -0
  334. package/dist/src/relay/phone-outbox.js +25 -0
  335. package/dist/src/relay/phone-socket.d.ts +6 -0
  336. package/dist/src/relay/phone-socket.js +63 -0
  337. package/dist/src/relay/relay-control.d.ts +7 -0
  338. package/dist/src/relay/relay-control.js +24 -0
  339. package/dist/src/relay/relay-files.d.ts +2 -0
  340. package/dist/src/relay/relay-files.js +23 -0
  341. package/dist/src/relay/relay-heartbeat.d.ts +17 -0
  342. package/dist/src/relay/relay-heartbeat.js +81 -0
  343. package/dist/src/relay/relay-http.d.ts +14 -0
  344. package/dist/src/relay/relay-http.js +63 -0
  345. package/dist/src/relay/relay-registration.d.ts +15 -0
  346. package/dist/src/relay/relay-registration.js +63 -0
  347. package/dist/src/relay/relay-service.d.ts +25 -0
  348. package/dist/src/relay/relay-service.js +216 -0
  349. package/dist/src/relay/relay-store.d.ts +48 -0
  350. package/dist/src/relay/relay-store.js +131 -0
  351. package/dist/src/relay/sealed-post.d.ts +25 -0
  352. package/dist/src/relay/sealed-post.js +52 -0
  353. package/dist/src/relay.d.ts +1 -0
  354. package/dist/src/relay.js +8 -0
  355. package/dist/src/report-statistics.d.ts +50 -0
  356. package/dist/src/report-statistics.js +70 -0
  357. package/dist/src/report.d.ts +171 -0
  358. package/dist/src/report.js +119 -0
  359. package/dist/src/repository-identity.d.ts +4 -0
  360. package/dist/src/repository-identity.js +4 -0
  361. package/dist/src/review-subject.d.ts +41 -0
  362. package/dist/src/review-subject.js +91 -0
  363. package/dist/src/run-wait.d.ts +23 -0
  364. package/dist/src/run-wait.js +20 -0
  365. package/dist/src/service/active-tickets.d.ts +4 -0
  366. package/dist/src/service/active-tickets.js +49 -0
  367. package/dist/src/service/command-effects.d.ts +4 -0
  368. package/dist/src/service/command-effects.js +16 -0
  369. package/dist/src/service/decision-handler.d.ts +4 -0
  370. package/dist/src/service/decision-handler.js +39 -4
  371. package/dist/src/service/gateway.js +18 -3
  372. package/dist/src/service/queue-runs.d.ts +3 -0
  373. package/dist/src/service/queue-runs.js +39 -0
  374. package/dist/src/service/registry.d.ts +22 -3
  375. package/dist/src/service/registry.js +51 -8
  376. package/dist/src/service/replies.d.ts +10 -0
  377. package/dist/src/service/replies.js +12 -0
  378. package/dist/src/service/run-handlers.js +45 -54
  379. package/dist/src/service/run-metadata.d.ts +8 -0
  380. package/dist/src/service/run-metadata.js +53 -0
  381. package/dist/src/service/run-waits.d.ts +3 -0
  382. package/dist/src/service/run-waits.js +41 -0
  383. package/dist/src/service/service.d.ts +21 -2
  384. package/dist/src/service/service.js +23 -5
  385. package/dist/src/service/submission-handler.js +70 -19
  386. package/dist/src/service/worker-port.d.ts +1 -0
  387. package/dist/src/service/worker-totals.js +10 -1
  388. package/dist/src/step-bridge.d.ts +32 -0
  389. package/dist/src/steps/decision-gate.d.ts +2 -1
  390. package/dist/src/steps/decision-gate.js +7 -0
  391. package/dist/src/steps/handoff.d.ts +2 -0
  392. package/dist/src/steps/handoff.js +13 -0
  393. package/dist/src/steps/merge-by-person.d.ts +2 -0
  394. package/dist/src/steps/merge-by-person.js +18 -0
  395. package/dist/src/steps/merge-when-green.d.ts +2 -0
  396. package/dist/src/steps/merge-when-green.js +62 -0
  397. package/dist/src/steps/review-by-agent.d.ts +5 -0
  398. package/dist/src/steps/review-by-agent.js +124 -0
  399. package/dist/src/steps/review-by-person.d.ts +4 -0
  400. package/dist/src/steps/review-by-person.js +16 -0
  401. package/dist/src/steps/review-subject.d.ts +2 -0
  402. package/dist/src/steps/review-subject.js +11 -0
  403. package/dist/src/steps/run-command.d.ts +2 -0
  404. package/dist/src/steps/run-command.js +15 -0
  405. package/dist/src/steps/sleep.d.ts +3 -0
  406. package/dist/src/steps/sleep.js +19 -0
  407. package/dist/src/steps/wait-for-decision.d.ts +2 -0
  408. package/dist/src/steps/wait-for-decision.js +71 -0
  409. package/dist/src/steps/wait-for-run.d.ts +5 -0
  410. package/dist/src/steps/wait-for-run.js +9 -0
  411. package/dist/src/storage/decision-snapshots.d.ts +1 -0
  412. package/dist/src/storage/decision-snapshots.js +7 -1
  413. package/dist/src/submission.d.ts +4 -0
  414. package/dist/src/submission.js +6 -2
  415. package/dist/src/testing.d.ts +29 -0
  416. package/dist/src/testing.js +264 -0
  417. package/dist/src/ticket-dependencies.d.ts +1 -0
  418. package/dist/src/ticket-dependencies.js +15 -0
  419. package/dist/src/ticket-status-stream.d.ts +9 -0
  420. package/dist/src/ticket-status-stream.js +94 -0
  421. package/dist/src/ticket-status.js +7 -4
  422. package/dist/src/token-prices.d.ts +14 -4
  423. package/dist/src/token-prices.js +56 -11
  424. package/dist/src/turn-profile.d.ts +1 -0
  425. package/dist/src/turn-profile.js +8 -1
  426. package/dist/src/worker-usage.d.ts +25 -0
  427. package/dist/src/worker-usage.js +58 -1
  428. package/dist/src/workflow-admission.d.ts +6 -0
  429. package/dist/src/workflow-candidate.d.ts +7 -2
  430. package/dist/src/workflow-candidate.js +48 -5
  431. package/dist/src/workflow-contracts.d.ts +2 -0
  432. package/dist/src/workflow-contracts.js +8 -3
  433. package/dist/src/workflow-declaration.d.ts +31 -2
  434. package/dist/src/workflow-declaration.js +140 -16
  435. package/dist/src/workflow-discovery.d.ts +19 -0
  436. package/dist/src/workflow-discovery.js +36 -0
  437. package/dist/src/workflow-refusals.d.ts +6 -0
  438. package/dist/src/workflow-refusals.js +42 -0
  439. package/dist/src/workflow-schedule.d.ts +22 -0
  440. package/dist/src/workflow-schedule.js +53 -0
  441. package/dist/src/workflows.d.ts +12 -1
  442. package/dist/src/workflows.js +9 -0
  443. package/dist/tools/admit-workflow.d.ts +14 -0
  444. package/dist/tools/admit-workflow.js +107 -0
  445. package/dist/tools/doctor-adoption.d.ts +1 -0
  446. package/dist/tools/doctor-adoption.js +11 -0
  447. package/dist/tools/project-configuration.d.ts +4 -0
  448. package/dist/tools/project-configuration.js +47 -0
  449. package/dist/tools/self-host-processes.d.ts +1 -0
  450. package/dist/tools/self-host-processes.js +33 -22
  451. package/dist/tools/self-host-project.d.ts +21 -0
  452. package/dist/tools/self-host-project.js +224 -0
  453. package/dist/tools/self-host-runtime.d.ts +16 -0
  454. package/dist/tools/self-host-runtime.js +60 -0
  455. package/dist/tools/self-host-workflows.d.ts +1 -0
  456. package/dist/tools/self-host-workflows.js +36 -1
  457. package/dist/tools/self-host.js +106 -135
  458. package/dist/tools/workflow-bundle-dependencies.d.ts +5 -0
  459. package/dist/tools/workflow-bundle-dependencies.js +93 -0
  460. package/dist/tools/workflow-bundles.d.ts +20 -0
  461. package/dist/tools/workflow-bundles.js +173 -0
  462. package/dist/tools/workflow-candidate-counts.d.ts +12 -0
  463. package/dist/tools/workflow-candidate-counts.js +266 -0
  464. package/dist/tools/workflow-candidate-fields.d.ts +5 -0
  465. package/dist/tools/workflow-candidate-fields.js +24 -0
  466. package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
  467. package/dist/tools/workflow-candidate-helper-counts.js +129 -0
  468. package/dist/tools/workflow-candidate-program.d.ts +13 -0
  469. package/dist/tools/workflow-candidate-program.js +106 -0
  470. package/dist/tools/workflow-candidate-source.d.ts +6 -0
  471. package/dist/tools/workflow-candidate-source.js +169 -0
  472. package/dist/tools/workflow-candidate-syntax.d.ts +21 -0
  473. package/dist/tools/workflow-candidate-syntax.js +263 -0
  474. package/dist/tools/workflow-command.d.ts +1 -0
  475. package/dist/tools/workflow-command.js +143 -0
  476. package/dist/tools/workflow-folder-capture.d.ts +18 -0
  477. package/dist/tools/workflow-folder-capture.js +261 -0
  478. package/dist/tools/workflow-folders.d.ts +49 -0
  479. package/dist/tools/workflow-folders.js +203 -0
  480. package/dist/tools/workflow-source-effects.d.ts +10 -0
  481. package/dist/tools/workflow-source-effects.js +213 -0
  482. package/dist/tools/workflow-test-hook.d.ts +7 -0
  483. package/dist/tools/workflow-test-hook.js +16 -0
  484. package/dist/tools/workflow-test-loader.d.ts +1 -0
  485. package/dist/tools/workflow-test-loader.js +10 -0
  486. package/dist/workflows/develop-prd.js +71 -3
  487. package/dist/workflows/develop-ticket.js +6 -1
  488. package/dist/workflows/ticket-prompts.js +17 -3
  489. package/package.json +66 -6
  490. package/templates/develop/README.md +78 -0
  491. package/templates/develop/develop/accept.ts +11 -0
  492. package/templates/develop/develop/flow-tests.ts +357 -0
  493. package/templates/develop/develop/local.ts +40 -0
  494. package/templates/develop/develop/option-tests.ts +174 -0
  495. package/templates/develop/develop/partial-choice.ts +29 -0
  496. package/templates/develop/develop/partial.ts +28 -0
  497. package/templates/develop/develop/pull.ts +152 -0
  498. package/templates/develop/develop/queue-partial.ts +39 -0
  499. package/templates/develop/develop/refusal-tests.ts +174 -0
  500. package/templates/develop/develop/report.ts +156 -0
  501. package/templates/develop/develop/round.ts +40 -0
  502. package/templates/develop/develop/scenarios.ts +87 -0
  503. package/templates/develop/develop/turn.ts +67 -0
  504. package/templates/develop/develop.declaration.json +24 -0
  505. package/templates/develop/develop.test.ts +287 -0
  506. package/templates/develop/develop.ts +30 -0
  507. package/templates/develop/template.json +153 -0
  508. package/dist/src/chats/analysis-batches.d.ts +0 -24
  509. package/dist/src/chats/analysis-batches.js +0 -83
  510. package/dist/src/chats/analysis-contract.d.ts +0 -80
  511. package/dist/src/chats/analysis-contract.js +0 -16
  512. package/dist/src/chats/analysis-data.d.ts +0 -3
  513. package/dist/src/chats/analysis-data.js +0 -85
  514. package/dist/src/chats/analysis-input.d.ts +0 -12
  515. package/dist/src/chats/analysis-input.js +0 -83
  516. package/dist/src/chats/analysis-links.d.ts +0 -2
  517. package/dist/src/chats/analysis-links.js +0 -25
  518. package/dist/src/chats/analysis-prompt.d.ts +0 -10
  519. package/dist/src/chats/analysis-prompt.js +0 -16
  520. package/dist/src/chats/analysis-proposal.d.ts +0 -2
  521. package/dist/src/chats/analysis-proposal.js +0 -32
  522. package/dist/src/chats/analysis-provenance.d.ts +0 -4
  523. package/dist/src/chats/analysis-provenance.js +0 -99
  524. package/dist/src/chats/analysis-shape.d.ts +0 -3
  525. package/dist/src/chats/analysis-shape.js +0 -228
  526. package/dist/src/chats/analysis.d.ts +0 -3
  527. package/dist/src/chats/analysis.js +0 -42
  528. package/dist/src/chats/corpus-input.d.ts +0 -5
  529. package/dist/src/chats/corpus-input.js +0 -288
  530. package/dist/src/chats/destination.d.ts +0 -4
  531. package/dist/src/chats/destination.js +0 -96
  532. package/dist/src/chats/import.d.ts +0 -15
  533. package/dist/src/chats/import.js +0 -243
  534. package/dist/src/chats/input-file.d.ts +0 -3
  535. package/dist/src/chats/input-file.js +0 -32
  536. package/dist/src/chats/normalize.d.ts +0 -29
  537. package/dist/src/chats/normalize.js +0 -155
  538. package/dist/src/chats/previous-import.d.ts +0 -5
  539. package/dist/src/chats/previous-import.js +0 -34
  540. package/dist/src/chats/reader.d.ts +0 -21
  541. package/dist/src/chats/reader.js +0 -118
  542. package/dist/src/chats/redact-import.d.ts +0 -14
  543. package/dist/src/chats/redact-import.js +0 -141
  544. package/dist/src/chats/redaction.d.ts +0 -41
  545. package/dist/src/chats/redaction.js +0 -161
  546. package/dist/src/chats/revision-input.d.ts +0 -3
  547. package/dist/src/chats/revision-input.js +0 -180
  548. package/dist/src/chats/revision.d.ts +0 -48
  549. package/dist/src/chats/revision.js +0 -94
  550. package/dist/src/chats/selection.d.ts +0 -25
  551. package/dist/src/chats/selection.js +0 -109
  552. package/dist/src/chats/source.d.ts +0 -23
  553. package/dist/src/chats/source.js +0 -135
  554. package/dist/src/chats/structure.d.ts +0 -57
  555. package/dist/src/chats/structure.js +0 -216
  556. package/dist/src/daemon/analysis-launch.d.ts +0 -5
  557. package/dist/src/daemon/analysis-launch.js +0 -81
  558. package/dist/src/daemon/analysis-token.d.ts +0 -6
  559. package/dist/src/daemon/analysis-token.js +0 -88
  560. package/dist/src/daemon/analysis-worker.d.ts +0 -22
  561. package/dist/src/daemon/analysis-worker.js +0 -219
  562. package/dist/src/daemon/chats-files.d.ts +0 -15
  563. package/dist/src/daemon/chats-files.js +0 -113
  564. package/dist/src/daemon/chats-worker.d.ts +0 -12
  565. package/dist/src/daemon/chats-worker.js +0 -200
  566. package/dist/workflows/analyze-chats.d.ts +0 -10
  567. package/dist/workflows/analyze-chats.declaration.json +0 -9
  568. package/dist/workflows/analyze-chats.js +0 -73
@@ -1,6 +1,7 @@
1
1
  import { isTicketStatus } from "../ticket-status.js";
2
+ import { operationScope } from "../operation-identity.js";
2
3
  import { isInstant } from "./instants.js";
3
- import { isBlockedReason } from "../workflow-contracts.js";
4
+ import { isBlockedReason, isPromotionId } from "../workflow-contracts.js";
4
5
  import { numberFields, textFields, } from "./transitions.js";
5
6
  const identifier = /^[A-Za-z0-9._:/-]{1,128}$/;
6
7
  const digest = /^sha256:[0-9a-f]{64}$/;
@@ -24,12 +25,19 @@ export const commandEvents = {
24
25
  "expire-lease": "lease.expired",
25
26
  "report-effect": "effect.reported",
26
27
  "record-outcome": "operation.reconciled",
28
+ "record-schedule-skip": "schedule.skipped",
27
29
  };
28
30
  const revised = { required: ["expectedRevision"] };
29
31
  const shapes = {
32
+ "record-schedule-skip": {
33
+ required: ["workflowId", "slot"],
34
+ validators: { slot: positive },
35
+ },
30
36
  "admit-run": {
31
37
  required: ["workflow"],
32
38
  optional: [
39
+ "parentRunId",
40
+ "chainId",
33
41
  "submission",
34
42
  "input",
35
43
  "resolver",
@@ -37,6 +45,7 @@ const shapes = {
37
45
  "capabilities",
38
46
  ],
39
47
  groups: [
48
+ ["parentRunId", "chainId"],
40
49
  ["submission", "input", "resolver"],
41
50
  ["effectLimit", "capabilities"],
42
51
  ],
@@ -44,14 +53,16 @@ const shapes = {
44
53
  "mark-started": revised,
45
54
  "open-gate": {
46
55
  required: ["gateId", "expectedRevision"],
47
- optional: ["gateKind", "subject", "prompt", "expiresAt"],
56
+ optional: ["gateKind", "subject", "prompt", "expiresAt", "waitMode"],
57
+ validators: { waitMode: (value) => value === "hook" },
48
58
  groups: [["gateKind", "subject", "prompt"]],
49
- consistent: (fields) => fields["expiresAt"] === undefined || fields["gateKind"] !== undefined,
59
+ consistent: (fields) => (fields["expiresAt"] === undefined && fields["waitMode"] === undefined) ||
60
+ fields["gateKind"] !== undefined,
50
61
  },
51
62
  "register-wait": { required: ["gateId"] },
52
63
  "decide-gate": {
53
64
  required: ["gateId", "decision", "expectedRevision"],
54
- optional: ["generation", "subject", "answer"],
65
+ optional: ["generation", "subject", "answer", "actor"],
55
66
  groups: [["generation", "subject"]],
56
67
  consistent: (fields) => {
57
68
  const typed = fields["generation"] !== undefined;
@@ -66,15 +77,24 @@ const shapes = {
66
77
  "resume-run": revised,
67
78
  "complete-run": {
68
79
  required: ["expectedRevision"],
69
- optional: ["outcome", "outcomeReason", "ticketStatus", "issueUpdate"],
80
+ optional: [
81
+ "outcome",
82
+ "outcomeReason",
83
+ "promotionId",
84
+ "ticketStatus",
85
+ "issueUpdate",
86
+ ],
70
87
  validators: {
71
88
  outcome: (value) => value === "handoff_requested" || value === "blocked",
72
89
  outcomeReason: isBlockedReason,
90
+ promotionId: isPromotionId,
73
91
  ticketStatus: isTicketStatus,
74
92
  issueUpdate: (value) => value === "failed",
75
93
  },
76
94
  consistent: (fields) => (fields["outcomeReason"] === undefined ||
77
- fields["outcome"] === "blocked") &&
95
+ fields["outcome"] !== undefined) &&
96
+ (fields["promotionId"] === undefined ||
97
+ fields["outcome"] === "handoff_requested") &&
78
98
  (fields["ticketStatus"] === undefined ||
79
99
  fields["outcome"] === "handoff_requested") &&
80
100
  (fields["issueUpdate"] === undefined ||
@@ -84,7 +104,14 @@ const shapes = {
84
104
  "cancel-run": revised,
85
105
  "report-observation": {
86
106
  required: ["condition", "reason"],
87
- optional: ["evidence", "retryAt", "attempt", "limit", "operationId"],
107
+ optional: [
108
+ "evidence",
109
+ "retryAt",
110
+ "attempt",
111
+ "limit",
112
+ "operationId",
113
+ "expectedObservation",
114
+ ],
88
115
  groups: [["attempt", "limit"]],
89
116
  },
90
117
  "record-dispatch": { required: ["operationId", "receipt"] },
@@ -137,6 +164,7 @@ const reportedOutcomes = ["completed", "failed", "stopped"];
137
164
  const outcomes = [...reportedOutcomes, "accepted", "not-started", "unknown"];
138
165
  const conditions = [
139
166
  "working",
167
+ "waiting-run",
140
168
  "quota-wait",
141
169
  "infrastructure-failure",
142
170
  "code-failure",
@@ -147,7 +175,7 @@ export function parseCommand(value) {
147
175
  return null;
148
176
  const fields = Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
149
177
  const { kind, commandId, runId } = fields;
150
- if (!knownKind(kind) || !isRecordKey(commandId) || !isRecordKey(runId))
178
+ if (!knownKind(kind) || !isCommandId(commandId) || !isRecordKey(runId))
151
179
  return null;
152
180
  if (!completeFields(kind, fields))
153
181
  return null;
@@ -237,6 +265,7 @@ export function isCapabilityList(value) {
237
265
  }
238
266
  const validators = {
239
267
  expectedRevision: positive,
268
+ expectedObservation: whole,
240
269
  generation: positive,
241
270
  attempt: positive,
242
271
  limit: positive,
@@ -261,7 +290,11 @@ const validators = {
261
290
  condition: (value) => typeof value === "string" && conditions.includes(value),
262
291
  expiresAt: isInstant,
263
292
  retryAt: isInstant,
293
+ actor: isDeviceActor,
264
294
  };
295
+ export function isDeviceActor(value) {
296
+ return (typeof value === "string" && /^device:[A-Za-z0-9_-]{1,64}$/.test(value));
297
+ }
265
298
  export function isIdentifier(value) {
266
299
  return typeof value === "string" && identifier.test(value);
267
300
  }
@@ -269,3 +302,11 @@ const plainRecord = {};
269
302
  export function isRecordKey(value) {
270
303
  return isIdentifier(value) && !(value in plainRecord);
271
304
  }
305
+ export function isCommandId(value) {
306
+ if (isRecordKey(value))
307
+ return true;
308
+ return (typeof value === "string" &&
309
+ value.startsWith("handoff:") &&
310
+ printable(value.slice(8)) &&
311
+ operationScope(value.slice(8)) !== null);
312
+ }
@@ -35,6 +35,7 @@ export interface DispatchCheck {
35
35
  readonly leaseGeneration?: number;
36
36
  };
37
37
  readonly now: string;
38
+ readonly mode?: "retry";
38
39
  }
39
40
  export type DispatchDecision = "stale" | "withheld" | "refused" | "blocked" | "send";
40
41
  export declare function dispatchDecision(read: DispatchRead, check: DispatchCheck): DispatchDecision;
@@ -15,13 +15,16 @@ function bound(read, intent) {
15
15
  lease.state !== "released",
16
16
  ].every(Boolean);
17
17
  }
18
- function sendable(read, now) {
18
+ function sendable(read, check) {
19
+ const statuses = check.mode === "retry"
20
+ ? ["dispatch-pending", "recovering", "blocked"]
21
+ : ["dispatch-pending"];
19
22
  return [
20
23
  !read.released,
21
24
  read.runStatus === "running",
22
- read.operation?.status === "dispatch-pending",
25
+ statuses.includes(read.operation?.status ?? ""),
23
26
  read.lease?.state === "held",
24
- isAfter(read.lease?.expiresAt ?? "", now),
27
+ isAfter(read.lease?.expiresAt ?? "", check.now),
25
28
  ].every(Boolean);
26
29
  }
27
30
  function authorized(read) {
@@ -39,7 +42,7 @@ function authorized(read) {
39
42
  export function dispatchDecision(read, check) {
40
43
  if (!bound(read, check.intent))
41
44
  return "stale";
42
- if (!sendable(read, check.now))
45
+ if (!sendable(read, check))
43
46
  return "withheld";
44
47
  if (!authorized(read))
45
48
  return "refused";
@@ -1,4 +1,4 @@
1
- import { isRecordKey } from "./commands.js";
1
+ import { isCommandId, isRecordKey } from "./commands.js";
2
2
  import { eventTypes } from "./transitions.js";
3
3
  export function parseEvent(value) {
4
4
  const fields = record(value);
@@ -11,7 +11,7 @@ export function parseEvent(value) {
11
11
  !Number.isSafeInteger(sequence) ||
12
12
  eventType === undefined ||
13
13
  !isRecordKey(runId) ||
14
- !isRecordKey(commandId) ||
14
+ !isCommandId(commandId) ||
15
15
  typeof recordedAt !== "string" ||
16
16
  typeof request !== "string" ||
17
17
  !payload)
@@ -2,6 +2,7 @@ import { type SettledGate } from "./gates.ts";
2
2
  import { type Recorded, type Reduction } from "./reduction-state.ts";
3
3
  import { type AuthorityState, type EffectIntent } from "./transitions.ts";
4
4
  export declare function gateContinuation(gate: SettledGate): EffectIntent;
5
+ export declare function gateDelivery(gate: SettledGate): EffectIntent;
5
6
  export declare function opened(state: AuthorityState, recorded: Recorded): Reduction;
6
7
  export declare function decided(state: AuthorityState, recorded: Recorded): Reduction;
7
8
  export declare function expired(state: AuthorityState, recorded: Recorded): Reduction;
@@ -1,4 +1,4 @@
1
- import { continues, decisionRefusal, expiryRefusal, gateKey, openedGate, reusable, settled, } from "./gates.js";
1
+ import { delivers, decisionRefusal, expiryRefusal, gateKey, openedGate, reusable, settled, } from "./gates.js";
2
2
  import { applied, identity, invalid, text, } from "./reduction-state.js";
3
3
  import { terminal, transition, } from "./transitions.js";
4
4
  export function gateContinuation(gate) {
@@ -14,8 +14,23 @@ export function gateContinuation(gate) {
14
14
  }),
15
15
  };
16
16
  }
17
+ export function gateDelivery(gate) {
18
+ if (gate.wait !== "hook")
19
+ return gateContinuation(gate);
20
+ return {
21
+ kind: "resume-hook",
22
+ runId: gate.runId,
23
+ operationId: identity({
24
+ run: gate.runId,
25
+ phase: "gate",
26
+ round: gate.outcome.sequence,
27
+ operation: "resume-hook",
28
+ key: gate.gateId,
29
+ }),
30
+ };
31
+ }
17
32
  function continuations(gate) {
18
- return continues(gate) ? [gateContinuation(gate)] : [];
33
+ return delivers(gate) ? [gateDelivery(gate)] : [];
19
34
  }
20
35
  export function opened(state, recorded) {
21
36
  const { event, run } = recorded;
@@ -98,7 +113,7 @@ export function registered(state, recorded) {
98
113
  const gate = gateOf(state, event);
99
114
  if (gate === undefined)
100
115
  return invalid("unknown-gate");
101
- if (gate.wait === "registered")
116
+ if (gate.wait !== "pending")
102
117
  return invalid("wait-already-registered");
103
118
  const next = { ...gate, wait: "registered" };
104
119
  return applied(state, {
@@ -14,7 +14,7 @@ export interface GateState {
14
14
  readonly expiresAt: string | null;
15
15
  readonly generation: number;
16
16
  readonly revision: number;
17
- readonly wait: "registered" | "pending";
17
+ readonly wait: "registered" | "pending" | "hook";
18
18
  readonly outcome: GateOutcome | null;
19
19
  readonly openedSequence: number;
20
20
  }
@@ -45,4 +45,5 @@ export type ContinuingGate = GateState & {
45
45
  };
46
46
  };
47
47
  export declare function continues(gate: GateState): gate is ContinuingGate;
48
+ export declare function delivers(gate: GateState): gate is ContinuingGate;
48
49
  export {};
@@ -22,6 +22,7 @@ export function gateKey(runId, gateId) {
22
22
  export function openedGate(opening) {
23
23
  const { payload } = opening;
24
24
  const kind = kinds[payload["gateKind"] ?? ""] ?? "untyped";
25
+ const wait = kind === "untyped" ? "registered" : "pending";
25
26
  return {
26
27
  runId: opening.runId,
27
28
  gateId: payload["gateId"] ?? "",
@@ -32,7 +33,7 @@ export function openedGate(opening) {
32
33
  expiresAt: payload["expiresAt"] ?? null,
33
34
  generation: opening.generation,
34
35
  revision: 1,
35
- wait: kind === "untyped" ? "registered" : "pending",
36
+ wait: payload["waitMode"] === "hook" ? "hook" : wait,
36
37
  outcome: null,
37
38
  openedSequence: opening.sequence,
38
39
  };
@@ -75,3 +76,6 @@ export function continues(gate) {
75
76
  isSettled(gate) &&
76
77
  gate.outcome.decision !== null);
77
78
  }
79
+ export function delivers(gate) {
80
+ return (gate.wait !== "pending" && isSettled(gate) && gate.outcome.decision !== null);
81
+ }
@@ -0,0 +1,24 @@
1
+ export interface RunOrigin {
2
+ readonly parentRunId: string | null;
3
+ readonly chainId: string;
4
+ }
5
+ export type RunOrigins = Readonly<Record<string, RunOrigin>>;
6
+ export interface RunLinks extends RunOrigin {
7
+ readonly childRunIds: readonly string[];
8
+ }
9
+ export declare function linksOf(run: {
10
+ readonly runId: string;
11
+ } & Partial<RunLinks>): RunLinks;
12
+ export declare function runLinks(origins: RunOrigins): Readonly<Record<string, RunLinks>>;
13
+ export declare function childRuns(origins: RunOrigins): Readonly<Record<string, readonly string[]>>;
14
+ export type HandoffChain = {
15
+ readonly kind: "root";
16
+ } | {
17
+ readonly kind: "handoff";
18
+ readonly parentRunId: string;
19
+ readonly chainId: string;
20
+ } | {
21
+ readonly kind: "refused";
22
+ readonly reason: string;
23
+ };
24
+ export declare function handoffChain(commandId: string, origins: RunOrigins): HandoffChain;
@@ -0,0 +1,46 @@
1
+ import { operationScope } from "../operation-identity.js";
2
+ export function linksOf(run) {
3
+ return {
4
+ parentRunId: run.parentRunId ?? null,
5
+ chainId: run.chainId ?? run.runId,
6
+ childRunIds: run.childRunIds ?? [],
7
+ };
8
+ }
9
+ export function runLinks(origins) {
10
+ const children = childRuns(origins);
11
+ return Object.fromEntries(Object.entries(origins).map(([runId, origin]) => [
12
+ runId,
13
+ {
14
+ ...origin,
15
+ childRunIds: children[runId] ?? [],
16
+ },
17
+ ]));
18
+ }
19
+ export function childRuns(origins) {
20
+ const children = {};
21
+ for (const [runId, origin] of Object.entries(origins)) {
22
+ if (origin.parentRunId === null)
23
+ continue;
24
+ const siblings = children[origin.parentRunId] ?? [];
25
+ siblings.push(runId);
26
+ children[origin.parentRunId] = siblings;
27
+ }
28
+ return children;
29
+ }
30
+ export function handoffChain(commandId, origins) {
31
+ if (!commandId.startsWith("handoff:"))
32
+ return { kind: "root" };
33
+ const parentRunId = operationScope(commandId.slice(8))?.run;
34
+ const parent = parentRunId === undefined ? undefined : origins[parentRunId];
35
+ if (parent === undefined || parentRunId === undefined)
36
+ return { kind: "refused", reason: "unknown-handoff-parent" };
37
+ let current = parent;
38
+ for (let length = 1; current !== undefined; length += 1) {
39
+ if (length >= 5)
40
+ return { kind: "refused", reason: "chain-limit" };
41
+ if (current.parentRunId === null)
42
+ return { kind: "handoff", parentRunId, chainId: parent.chainId };
43
+ current = origins[current.parentRunId];
44
+ }
45
+ return { kind: "refused", reason: "unknown-handoff-parent" };
46
+ }
@@ -24,7 +24,7 @@ const finalStatuses = [
24
24
  "stopped",
25
25
  "cancelled",
26
26
  ];
27
- export const runOperations = ["start-run", "continue-run"];
27
+ export const runOperations = ["start-run", "continue-run", "resume-hook"];
28
28
  export function namesRunIntent(operationId, runId) {
29
29
  const scope = operationScope(operationId);
30
30
  return scope?.run === runId && runOperations.includes(scope.operation);
@@ -4,6 +4,7 @@ export interface WorldRun {
4
4
  readonly receipt: string;
5
5
  readonly status: string;
6
6
  readonly outcome?: string;
7
+ readonly promotionId?: string;
7
8
  readonly outcomeReason?: string;
8
9
  readonly issueUpdate?: "failed";
9
10
  readonly ticketStatus?: "complete" | "partial";
@@ -1,6 +1,6 @@
1
1
  import { isTicketStatus } from "../ticket-status.js";
2
2
  import { gateContinuation } from "./gate-reduction.js";
3
- import { isBlockedReason } from "../workflow-contracts.js";
3
+ import { isBlockedReason, isPromotionId } from "../workflow-contracts.js";
4
4
  import { continues } from "./gates.js";
5
5
  import { startOperation } from "./reduction.js";
6
6
  import { terminal, } from "./transitions.js";
@@ -111,19 +111,26 @@ function moved(kind, observed) {
111
111
  }
112
112
  function completionOutcome(world) {
113
113
  const { outcome, outcomeReason } = world;
114
- if (outcome !== "handoff_requested" && outcome !== "blocked")
115
- return {};
116
- if (outcome !== "blocked" || !isBlockedReason(outcomeReason))
114
+ if (outcome === "blocked")
117
115
  return {
118
116
  outcome,
119
- ...(outcome === "handoff_requested" && world.issueUpdate === "failed"
120
- ? { issueUpdate: world.issueUpdate }
121
- : {}),
122
- ...(outcome === "handoff_requested" && isTicketStatus(world.ticketStatus)
123
- ? { ticketStatus: world.ticketStatus }
124
- : {}),
117
+ ...(isBlockedReason(outcomeReason) ? { outcomeReason } : {}),
125
118
  };
126
- return { outcome, outcomeReason };
119
+ if (outcome !== "handoff_requested")
120
+ return {};
121
+ return {
122
+ outcome,
123
+ ...(isBlockedReason(outcomeReason) ? { outcomeReason } : {}),
124
+ ...(isPromotionId(world.promotionId)
125
+ ? { promotionId: world.promotionId }
126
+ : {}),
127
+ ...(world.issueUpdate === "failed"
128
+ ? { issueUpdate: world.issueUpdate }
129
+ : {}),
130
+ ...(isTicketStatus(world.ticketStatus)
131
+ ? { ticketStatus: world.ticketStatus }
132
+ : {}),
133
+ };
127
134
  }
128
135
  function noted(observed, evidence) {
129
136
  const { run, world, reason } = observed;
@@ -1,6 +1,6 @@
1
1
  import { type Reduction } from "./reduction-state.ts";
2
2
  import { type AuthorityEvent, type AuthorityState } from "./transitions.ts";
3
- export { gateContinuation } from "./gate-reduction.ts";
3
+ export { gateContinuation, gateDelivery } from "./gate-reduction.ts";
4
4
  export type { Reduction } from "./reduction-state.ts";
5
5
  export declare function startOperation(runId: string): string;
6
6
  export declare function reduce(state: AuthorityState, event: AuthorityEvent): Reduction;
@@ -7,7 +7,7 @@ import { decided, expired, opened, registered } from "./gate-reduction.js";
7
7
  import { expired as leaseExpired, granted } from "./leases.js";
8
8
  import { applied, identity, invalid, text, } from "./reduction-state.js";
9
9
  import { transition, } from "./transitions.js";
10
- export { gateContinuation } from "./gate-reduction.js";
10
+ export { gateContinuation, gateDelivery } from "./gate-reduction.js";
11
11
  function moved(type) {
12
12
  return (state, recorded) => {
13
13
  const result = transition(recorded.run, {
@@ -36,6 +36,10 @@ function closed(type) {
36
36
  };
37
37
  }
38
38
  function observation(state, recorded) {
39
+ const expected = recorded.event.payload["expectedObservation"];
40
+ if (expected !== undefined &&
41
+ expected !== String(recorded.details.observation?.sequence ?? 0))
42
+ return invalid("stale-observation");
39
43
  return applied(state, {
40
44
  ...recorded,
41
45
  observed: observed(recorded.details, recorded.event),
@@ -75,6 +79,7 @@ function effect(rule) {
75
79
  };
76
80
  }
77
81
  const handlers = {
82
+ "schedule.skipped": applied,
78
83
  "effect.requested": effect(requested),
79
84
  "lease.granted": effect(granted),
80
85
  "lease.expired": effect(leaseExpired),
@@ -4,7 +4,7 @@ import type { RunClosure } from "./stop-sequence.ts";
4
4
  import type { RunState } from "./transitions.ts";
5
5
  export interface OperationSummary {
6
6
  readonly operationId: string;
7
- readonly kind: "start-run" | "continue-run" | "protected-effect";
7
+ readonly kind: "start-run" | "continue-run" | "resume-hook" | "protected-effect";
8
8
  readonly releasedSequence: number | null;
9
9
  readonly outcomes: readonly (string | null)[];
10
10
  }
@@ -9,6 +9,7 @@ export interface RunView {
9
9
  readonly workflow: string;
10
10
  readonly state: RunStatus;
11
11
  readonly condition: string;
12
+ readonly awaitedRunId: string | null;
12
13
  readonly revision: number;
13
14
  readonly latestSequence: number;
14
15
  readonly pendingDecisions: readonly string[];
@@ -88,8 +88,10 @@ const unavailablePin = assessed("infrastructure-failure", {
88
88
  nextAction: "restore-pinned-workflow",
89
89
  humanInputCanHelp: true,
90
90
  });
91
- function worldConflict(input) {
91
+ function workflowFailure(input) {
92
92
  const code = input.details?.observation?.reason;
93
+ if (code === "pinned-workflow-unavailable")
94
+ return unavailablePin;
93
95
  if (code !== "world-run-conflict")
94
96
  return undefined;
95
97
  return assessed("infrastructure-failure", {
@@ -103,7 +105,7 @@ function queued(input) {
103
105
  return unknownEffect;
104
106
  if (blocked(input.operations))
105
107
  return unavailablePin;
106
- const conflict = worldConflict(input);
108
+ const conflict = workflowFailure(input);
107
109
  if (conflict !== undefined)
108
110
  return conflict;
109
111
  if (dispatched(input.operations))
@@ -141,10 +143,13 @@ function running(input) {
141
143
  return effect;
142
144
  if (blocked(input.operations))
143
145
  return unavailablePin;
144
- return worldConflict(input) ?? observed(input);
146
+ return workflowFailure(input) ?? observed(input);
145
147
  }
146
148
  function observed(input) {
147
149
  const observation = input.details?.observation ?? null;
150
+ const wait = runWaitAssessment(observation);
151
+ if (wait !== undefined)
152
+ return wait;
148
153
  if (observation !== null &&
149
154
  Object.hasOwn(observedActions, observation.condition))
150
155
  return observedWork(observation);
@@ -160,7 +165,20 @@ function observed(input) {
160
165
  humanInputCanHelp: false,
161
166
  });
162
167
  }
168
+ function runWaitAssessment(observation) {
169
+ if (observation?.condition === "waiting-run")
170
+ return assessed("waiting-run", {
171
+ code: "awaiting-run",
172
+ detail: `The run waits for run ${observation.evidence ?? "unknown"}.`,
173
+ nextAction: "await-run",
174
+ nextActionAt: observation.retryAt,
175
+ humanInputCanHelp: false,
176
+ });
177
+ return undefined;
178
+ }
163
179
  function waiting(input) {
180
+ if (input.details?.observation?.reason === "pinned-workflow-unavailable")
181
+ return unavailablePin;
164
182
  const pending = input.gates.filter((gate) => gate.outcome === null);
165
183
  const question = pending.some((gate) => gate.kind === "question");
166
184
  const approval = pending.some((gate) => gate.kind === "approval");
@@ -226,6 +244,7 @@ export function runView(input) {
226
244
  workflow: run.workflow,
227
245
  state: run.status,
228
246
  condition: assessment.condition,
247
+ awaitedRunId: awaitedRun(assessment, observation),
229
248
  revision: run.revision,
230
249
  latestSequence: input.latestSequence,
231
250
  pendingDecisions: input.gates
@@ -254,3 +273,8 @@ export function runView(input) {
254
273
  humanInputCanHelp: assessment.humanInputCanHelp,
255
274
  };
256
275
  }
276
+ function awaitedRun(assessment, observation) {
277
+ return assessment.condition === "waiting-run"
278
+ ? (observation?.evidence ?? null)
279
+ : null;
280
+ }
@@ -11,7 +11,7 @@ export interface RunState {
11
11
  readonly gates: readonly string[];
12
12
  }
13
13
  export interface EffectIntent {
14
- readonly kind: "start-run" | "continue-run" | "protected-effect";
14
+ readonly kind: "start-run" | "continue-run" | "resume-hook" | "protected-effect";
15
15
  readonly runId: string;
16
16
  readonly operationId: string;
17
17
  }
@@ -28,7 +28,7 @@ export interface AuthorityState {
28
28
  readonly questions: number;
29
29
  readonly effects: EffectState;
30
30
  }
31
- export declare const eventTypes: readonly ["run.created", "run.started", "gate.opened", "gate.wait-registered", "gate.decided", "gate.expired", "run.paused", "run.resumed", "run.completed", "run.failed", "run.cancelled", "run.observed", "step.dispatched", "effect.requested", "lease.granted", "lease.expired", "effect.reported", "operation.reconciled"];
31
+ export declare const eventTypes: readonly ["run.created", "run.started", "gate.opened", "gate.wait-registered", "gate.decided", "gate.expired", "run.paused", "run.resumed", "run.completed", "run.failed", "run.cancelled", "run.observed", "step.dispatched", "effect.requested", "lease.granted", "lease.expired", "effect.reported", "operation.reconciled", "schedule.skipped"];
32
32
  export type EventType = (typeof eventTypes)[number];
33
33
  export interface AuthorityEvent {
34
34
  readonly sequence: number;
@@ -39,8 +39,8 @@ export interface AuthorityEvent {
39
39
  readonly request: string;
40
40
  readonly payload: Readonly<Record<string, string>>;
41
41
  }
42
- export declare const numberFields: readonly ["expectedRevision", "generation", "attempt", "limit", "effectLimit", "units", "recoveryLimit", "leaseGeneration", "sourceGeneration", "capacity"];
43
- export declare const textFields: readonly ["workflow", "submission", "input", "resolver", "gateId", "gateKind", "subject", "prompt", "expiresAt", "decision", "answer", "condition", "reason", "evidence", "retryAt", "operationId", "receipt", "capabilities", "capability", "method", "target", "payload", "inputDigest", "resource", "transport", "source", "worker", "outcome", "outcomeReason", "ticketStatus", "issueUpdate", "result"];
42
+ export declare const numberFields: readonly ["expectedRevision", "expectedObservation", "generation", "attempt", "limit", "effectLimit", "units", "recoveryLimit", "leaseGeneration", "sourceGeneration", "capacity", "slot"];
43
+ export declare const textFields: readonly ["parentRunId", "chainId", "workflow", "workflowId", "submission", "input", "resolver", "gateId", "gateKind", "waitMode", "subject", "prompt", "expiresAt", "decision", "answer", "condition", "reason", "evidence", "retryAt", "operationId", "receipt", "capabilities", "capability", "method", "target", "payload", "inputDigest", "resource", "transport", "source", "worker", "outcome", "outcomeReason", "promotionId", "ticketStatus", "issueUpdate", "result", "actor"];
44
44
  export type NumberField = (typeof numberFields)[number];
45
45
  export type TextField = (typeof textFields)[number];
46
46
  export type AuthorityCommand = {
@@ -48,7 +48,7 @@ export type AuthorityCommand = {
48
48
  readonly commandId: string;
49
49
  readonly runId: string;
50
50
  } & Readonly<Partial<Record<NumberField, number>>> & Readonly<Partial<Record<TextField, string>>>;
51
- export type Move = Exclude<EventType, "run.created" | "step.dispatched" | "gate.wait-registered" | "run.observed" | "effect.requested" | "lease.granted" | "lease.expired" | "effect.reported" | "operation.reconciled">;
51
+ export type Move = Exclude<EventType, "run.created" | "step.dispatched" | "gate.wait-registered" | "run.observed" | "effect.requested" | "lease.granted" | "lease.expired" | "effect.reported" | "operation.reconciled" | "schedule.skipped">;
52
52
  export declare const terminal: readonly RunStatus[];
53
53
  export type Transition = {
54
54
  readonly kind: "moved";
@@ -17,9 +17,11 @@ export const eventTypes = [
17
17
  "lease.expired",
18
18
  "effect.reported",
19
19
  "operation.reconciled",
20
+ "schedule.skipped",
20
21
  ];
21
22
  export const numberFields = [
22
23
  "expectedRevision",
24
+ "expectedObservation",
23
25
  "generation",
24
26
  "attempt",
25
27
  "limit",
@@ -29,14 +31,19 @@ export const numberFields = [
29
31
  "leaseGeneration",
30
32
  "sourceGeneration",
31
33
  "capacity",
34
+ "slot",
32
35
  ];
33
36
  export const textFields = [
37
+ "parentRunId",
38
+ "chainId",
34
39
  "workflow",
40
+ "workflowId",
35
41
  "submission",
36
42
  "input",
37
43
  "resolver",
38
44
  "gateId",
39
45
  "gateKind",
46
+ "waitMode",
40
47
  "subject",
41
48
  "prompt",
42
49
  "expiresAt",
@@ -60,9 +67,11 @@ export const textFields = [
60
67
  "worker",
61
68
  "outcome",
62
69
  "outcomeReason",
70
+ "promotionId",
63
71
  "ticketStatus",
64
72
  "issueUpdate",
65
73
  "result",
74
+ "actor",
66
75
  ];
67
76
  export const terminal = [
68
77
  "completed",
@@ -8,6 +8,7 @@ import { pinned } from "./pin-check.js";
8
8
  const eligibleStatus = {
9
9
  "start-run": "queued",
10
10
  "continue-run": "running",
11
+ "resume-hook": "running",
11
12
  };
12
13
  function admission(parts, attempt) {
13
14
  const { intent, effectId } = attempt;