@humwick/server 0.130.0 → 0.130.2

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 (486) hide show
  1. package/README.md +5 -0
  2. package/docs/guides/tools-administration.md +6 -1
  3. package/docs/guides/tools-coordination.md +1 -0
  4. package/docs/guides/tools-tasks.md +8 -0
  5. package/docs/guides/workflows.md +58 -0
  6. package/docs/openapi.json +414 -1
  7. package/package.json +8 -17
  8. package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-BWLqMGKG.js} +2 -2
  9. package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-3TlIQpjk.js} +2 -2
  10. package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-Wimm0Czv.js} +2 -2
  11. package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-Bau_vNax.js} +2 -2
  12. package/public/assets/{activity-yLztXEBt.js → activity-CrSurn-r.js} +2 -2
  13. package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-CknAJKcb.js} +2 -2
  14. package/public/assets/agent-liveness-CaNwK0Zf.js +2 -0
  15. package/public/assets/{agent-name-CTZBrSD9.js → agent-name-DKbiIhBo.js} +2 -2
  16. package/public/assets/agent-profiles-DwF6EQ4R.js +2 -0
  17. package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-Diz4Sjjb.js} +2 -2
  18. package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-CRhpRQza.js} +2 -2
  19. package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-LrUEU3lB.js} +2 -2
  20. package/public/assets/{agents-BYDslkJc.js → agents-B-v66C-4.js} +2 -2
  21. package/public/assets/{analytics-B-XSbEMC.js → analytics-BqCb-LKi.js} +2 -2
  22. package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-kf4pGuAR.js} +2 -2
  23. package/public/assets/{artifacts-oBOqks-2.js → artifacts-D32zyw4Y.js} +2 -2
  24. package/public/assets/{artifacts-DPN1q4pA.js → artifacts-DJevXcvg.js} +2 -2
  25. package/public/assets/{automation-4KcRFXEu.js → automation-BpRajx_5.js} +2 -2
  26. package/public/assets/{backlog-Cw9xPTCF.js → backlog-D_UjTdzX.js} +2 -2
  27. package/public/assets/{busy-health-CTu32MZt.js → busy-health-N3VEh4ao.js} +2 -2
  28. package/public/assets/{channels-BiXzg1G9.js → channels-9jopungq.js} +2 -2
  29. package/public/assets/{chat-Ctk2qwvA.js → chat-CSXrTB3C.js} +2 -2
  30. package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-p1NnmqK0.js} +2 -2
  31. package/public/assets/{connectors-C36ax4Vw.js → connectors-CZdqlDNL.js} +2 -2
  32. package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BgdsE4dG.js} +2 -2
  33. package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-30aXTKva.js} +2 -2
  34. package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-B_jvw2GE.js} +2 -2
  35. package/public/assets/{deploys-Bwfq146q.js → deploys-DoN6bAb5.js} +2 -2
  36. package/public/assets/{display-CfO7rTuF.js → display-BrKWFGJz.js} +2 -2
  37. package/public/assets/{files-DhhZI2Ih.js → files-D6XEu8Ng.js} +2 -2
  38. package/public/assets/fleet-C7jQWbw2.js +2 -0
  39. package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BiDs3MLx.js} +2 -2
  40. package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-CQBwc1fb.js} +3 -3
  41. package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-DyG0WsQS.js} +2 -2
  42. package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-DKaW31dN.js} +2 -2
  43. package/public/assets/index-CRHep3M9.js +15 -0
  44. package/public/assets/index-MYAIwYTX.css +2 -0
  45. package/public/assets/{insights-fH1EL-qZ.js → insights-CzrtkpOE.js} +2 -2
  46. package/public/assets/{integrations-C5Oix6ng.js → integrations-aVsUmigt.js} +2 -2
  47. package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-BnSlM_95.js} +2 -2
  48. package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-qe7Ee47Z.js} +2 -2
  49. package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-NfjqFZAk.js} +2 -2
  50. package/public/assets/{managed-agents-egllbpij.js → managed-agents-BiH0HgaE.js} +2 -2
  51. package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-BixaT3Xr.js} +3 -3
  52. package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-DNGlWIS3.js} +2 -2
  53. package/public/assets/{memory-C8WmXsyr.js → memory-DNsCl6UX.js} +2 -2
  54. package/public/assets/{messages-BzQdqlO6.js → messages-DopU1L1X.js} +2 -2
  55. package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Cq7ckLQT.js} +2 -2
  56. package/public/assets/{overview-DCUnI4Z7.js → overview-C1DCTzzV.js} +2 -2
  57. package/public/assets/{pairs-ftCd2XcD.js → pairs-DE_m6rrE.js} +2 -2
  58. package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-B3rfh77F.js} +2 -2
  59. package/public/assets/project-profile-instructions-DQWZE0kA.js +2 -0
  60. package/public/assets/projects-Br2Bd2h1.js +2 -0
  61. package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-BKvFsvGD.js} +2 -2
  62. package/public/assets/provider-display-DsuWMvVL.js +2 -0
  63. package/public/assets/{registry-DWCU5c8q.js → registry-Cw38_6gW.js} +2 -2
  64. package/public/assets/run-card-CpKqRbhg.js +2 -0
  65. package/public/assets/scroll-text-BKXS1ahr.js +2 -0
  66. package/public/assets/{secrets-C7GIUATz.js → secrets-DxI-vzSq.js} +2 -2
  67. package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-D9s_VJbd.js} +2 -2
  68. package/public/assets/{settings-C6sZ9eBa.js → settings-CKZTVGIx.js} +2 -2
  69. package/public/assets/{shipping-Bu8p1gEw.js → shipping-B9YtnwtG.js} +2 -2
  70. package/public/assets/{stats-V9Z-GxUd.js → stats-DyUBKyWI.js} +2 -2
  71. package/public/assets/{status-dot-CVv0iGHL.js → status-dot-DYqlEUhJ.js} +2 -2
  72. package/public/assets/{store-BvtFdlGX.js → store-DcClXLH0.js} +3 -3
  73. package/public/assets/{tasks-CXU75HRF.js → tasks-Bh7Chr4-.js} +2 -2
  74. package/public/assets/{teams-BPf976zb.js → teams-bowI7qVY.js} +2 -2
  75. package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-BgVLHdsU.js} +3 -3
  76. package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-Dz22UPy6.js} +2 -2
  77. package/public/assets/token-estimate-Co-Jdphh.js +2 -0
  78. package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-DSQQ-iY7.js} +2 -2
  79. package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-samMQhQf.js} +2 -2
  80. package/public/assets/use-project-list-59LheVP7.js +2 -0
  81. package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BZa25xEB.js} +2 -2
  82. package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-DHxlvUvV.js} +2 -2
  83. package/public/assets/versioned-prompt-editor-BmED5DnJ.js +8 -0
  84. package/public/assets/{work-queue-TCjJxeT-.js → work-queue-CSvpuNLz.js} +2 -2
  85. package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-DAZcj5qt.js} +2 -2
  86. package/public/assets/{workflows-CXQX20Qj.js → workflows-DdmxRSyg.js} +2 -2
  87. package/public/assets/{workspaces-qSYzKYMA.js → workspaces-BxeKfVuF.js} +2 -2
  88. package/public/cosmos.html +4 -4
  89. package/public/index.html +31 -29
  90. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  91. package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
  92. package/runner/src/adapters/claude-effort.ts +2 -4
  93. package/runner/src/adapters/codex-launch-config.ts +4 -5
  94. package/runner/src/adapters/codex.ts +1 -1
  95. package/runner/src/adapters/opencode-provider.ts +7 -22
  96. package/runner/src/adapters/opencode.ts +4 -4
  97. package/runner/src/agent-runner/credentials.ts +42 -12
  98. package/runner/src/agent-runner/inbox.ts +27 -0
  99. package/runner/src/agent-runner/lifecycle-milestones.ts +0 -2
  100. package/runner/src/bin/claude.ts +4 -0
  101. package/runner/src/bin/codex.ts +4 -0
  102. package/runner/src/bin/opencode.ts +4 -0
  103. package/runner/src/index.ts +5 -2
  104. package/runner/src/provider-setup.ts +34 -0
  105. package/runner/src/providers.ts +2 -1
  106. package/runner/src/runner-core.ts +18 -23
  107. package/runner/src/spawn-input.ts +2 -1
  108. package/runner/src/test-run-dedup.ts +59 -56
  109. package/scripts/cd-config.ts +24 -3
  110. package/scripts/gate-run-lease.ts +10 -7
  111. package/scripts/gate.sh +5 -1
  112. package/src/branch-land-notice.ts +93 -0
  113. package/src/branch-landed.ts +7 -76
  114. package/src/bus.ts +19 -20
  115. package/src/cd-deploy-notify.ts +30 -2
  116. package/src/cd-host-lag-notify.ts +7 -6
  117. package/src/ci/incidents.ts +2 -2
  118. package/src/ci/monitor.ts +5 -8
  119. package/src/ci/root-missing.ts +2 -7
  120. package/src/ci/transition-notify.ts +7 -39
  121. package/src/cli/cd-pauses.ts +19 -0
  122. package/src/cli/orchestrator.ts +1 -1
  123. package/src/cli/state.ts +2 -19
  124. package/src/cli/task-edit.ts +22 -0
  125. package/src/cli/task.ts +3 -1
  126. package/src/cli/workflow.ts +8 -2
  127. package/src/commands-db.ts +10 -6
  128. package/src/commands-write.ts +8 -0
  129. package/src/config-store-write.ts +13 -1
  130. package/src/config-store.ts +25 -14
  131. package/src/db/activity-async.ts +6 -1
  132. package/src/db/activity-write-ops.ts +13 -1
  133. package/src/db/activity.ts +1 -14
  134. package/src/db/agent-lifecycle-write-ops.ts +1 -0
  135. package/src/db/agent-meta.ts +2 -2
  136. package/src/db/agent-ownership-write-ops.ts +4 -0
  137. package/src/db/agent-search.ts +1 -15
  138. package/src/db/agents-async.ts +58 -7
  139. package/src/db/agents-write-ops.ts +28 -5
  140. package/src/db/agents.ts +81 -54
  141. package/src/db/artifacts-write-ops.ts +8 -3
  142. package/src/db/bus-outbox-write-ops.ts +1 -0
  143. package/src/db/channels-write-ops.ts +4 -0
  144. package/src/db/ci-incidents-async.ts +5 -5
  145. package/src/db/ci-incidents-write-ops.ts +2 -2
  146. package/src/db/claude-api-budget-ops.ts +5 -5
  147. package/src/db/claude-app-oauth.ts +4 -4
  148. package/src/db/codex-reset-consumes-write-ops.ts +3 -0
  149. package/src/db/command-row.ts +10 -2
  150. package/src/db/commands-list-query.ts +2 -0
  151. package/src/db/commands-spawn-read.ts +1 -1
  152. package/src/db/commands-write-ops.ts +21 -0
  153. package/src/db/config-store-write-ops.ts +9 -2
  154. package/src/db/continuation-archives-async.ts +5 -0
  155. package/src/db/continuation-archives-write-ops.ts +9 -0
  156. package/src/db/continuations.ts +2 -2
  157. package/src/db/db-writer-worker.ts +8 -1
  158. package/src/db/delivery-write-ops.ts +5 -0
  159. package/src/db/deploy-events-async.ts +1 -0
  160. package/src/db/deploy-events-read-ops.ts +2 -1
  161. package/src/db/deploy-events.ts +35 -4
  162. package/src/db/hosts-registration.ts +10 -2
  163. package/src/db/hosts-write-ops.ts +14 -0
  164. package/src/db/hosts.ts +9 -6
  165. package/src/db/inbox-write-ops.ts +4 -0
  166. package/src/db/inbox.ts +0 -14
  167. package/src/db/index.ts +2 -0
  168. package/src/db/insights-write-ops.ts +1 -0
  169. package/src/db/integrations-async.ts +8 -0
  170. package/src/db/integrations-ops.ts +15 -0
  171. package/src/db/integrations.ts +15 -21
  172. package/src/db/issue-lifecycle.ts +3 -4
  173. package/src/db/issue-refs-async.ts +20 -0
  174. package/src/db/issue-refs-write-ops.ts +29 -0
  175. package/src/db/issue-refs.ts +7 -8
  176. package/src/db/long-running-work.ts +2 -2
  177. package/src/db/macos-privacy.ts +1 -1
  178. package/src/db/main-connection-writes.ts +23 -2
  179. package/src/db/maintenance-job-reconcile.ts +61 -0
  180. package/src/db/maintenance-job-runs-async.ts +14 -0
  181. package/src/db/maintenance-job-write-ops.ts +9 -0
  182. package/src/db/mappers.ts +2 -14
  183. package/src/db/merge-lease.ts +1 -15
  184. package/src/db/message-reads-write-ops.ts +3 -0
  185. package/src/db/message-write-ops.ts +4 -0
  186. package/src/db/migrations.ts +7 -15
  187. package/src/db/orchestrators-async.ts +7 -3
  188. package/src/db/orchestrators-write-ops.ts +7 -1
  189. package/src/db/orchestrators.ts +21 -77
  190. package/src/db/pairs.ts +1 -13
  191. package/src/db/project-profile-instructions.ts +50 -0
  192. package/src/db/prompt-versions-ops.ts +1 -0
  193. package/src/db/prompt-versions.ts +9 -2
  194. package/src/db/provider-catalog-write-ops.ts +4 -4
  195. package/src/db/provider-config-history.ts +8 -3
  196. package/src/db/provider-flap-messages-write-ops.ts +1 -0
  197. package/src/db/provider-model-seed.ts +34 -0
  198. package/src/db/provider-quota-lease-write-ops.ts +1 -0
  199. package/src/db/provider-quota-write-ops.ts +2 -0
  200. package/src/db/provisioning-write-ops.ts +9 -8
  201. package/src/db/read-op-marshaling-fixtures.ts +5 -0
  202. package/src/db/read-ops.ts +4 -0
  203. package/src/db/routing-policy.ts +3 -4
  204. package/src/db/schema.ts +9 -3
  205. package/src/db/secrets-broker-write-ops.ts +5 -5
  206. package/src/db/secrets-vault-write.ts +7 -7
  207. package/src/db/services-write-ops.ts +3 -0
  208. package/src/db/spawn-delegation-state.ts +11 -4
  209. package/src/db/spawn-tree-cleanup.ts +3 -0
  210. package/src/db/stats-async.ts +4 -3
  211. package/src/db/task-entity.ts +23 -2
  212. package/src/db/task-list.ts +3 -1
  213. package/src/db/tasks.ts +1 -17
  214. package/src/db/team-spawn-delegation.ts +1 -1
  215. package/src/db/teams-write-ops.ts +4 -4
  216. package/src/db/timer-cutover-write-ops.ts +7 -0
  217. package/src/db/timer-ingress-write-ops.ts +9 -0
  218. package/src/db/timer-ingress.ts +7 -1
  219. package/src/db/timer-operator-write-ops.ts +14 -0
  220. package/src/db/timer-transfer-write-ops.ts +4 -0
  221. package/src/db/timer-write-ops.ts +14 -0
  222. package/src/db/token-db-write-ops.ts +21 -0
  223. package/src/db/token-standing.ts +15 -11
  224. package/src/db/user-settings-write-ops.ts +1 -0
  225. package/src/db/vault-backup.ts +2 -2
  226. package/src/db/vault-expiry.ts +2 -2
  227. package/src/db/vault-health.ts +3 -3
  228. package/src/db/vault-token-ops.ts +8 -8
  229. package/src/db/web-tool-call-ops.ts +3 -3
  230. package/src/db/workflow-contact.ts +1 -1
  231. package/src/db/workflow-task-read-ops.ts +30 -0
  232. package/src/db/write-ops.ts +15 -1
  233. package/src/db/writer-fault-seam.ts +5 -2
  234. package/src/db/writer-gateway.ts +21 -12
  235. package/src/dispatch-availability.ts +10 -6
  236. package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
  237. package/src/host/disk-alert.ts +121 -0
  238. package/src/lifecycle-manager.ts +3 -2
  239. package/src/maintenance/cd-watcher.ts +3 -3
  240. package/src/maintenance/critical-job-watchdog.ts +16 -17
  241. package/src/maintenance/index.ts +1 -0
  242. package/src/maintenance/jobs.ts +3 -2
  243. package/src/maintenance/scheduler.ts +84 -128
  244. package/src/maintenance/stalled-delivery-pager.ts +6 -5
  245. package/src/maintenance/workspaces.ts +1 -1
  246. package/src/managed-policy.ts +31 -27
  247. package/src/mcp/index.ts +5 -2
  248. package/src/mcp/output-descriptions.ts +8 -8
  249. package/src/mcp/presentation.ts +4 -4
  250. package/src/mcp/project-profile-instructions.ts +32 -0
  251. package/src/mcp/tool-groups.ts +1 -1
  252. package/src/mcp/tools-spawn.ts +4 -3
  253. package/src/mcp-agent-action.ts +1 -2
  254. package/src/mcp-host-tools.ts +1 -1
  255. package/src/mcp-issue-ref-tools.ts +12 -11
  256. package/src/mcp-maintenance-tools.ts +2 -2
  257. package/src/mcp-profile-trust-tools.ts +4 -4
  258. package/src/mcp-provider-catalog.ts +2 -2
  259. package/src/mcp-task-tools.ts +11 -5
  260. package/src/mcp-team-template-tools.ts +3 -3
  261. package/src/mcp-workflow-tools.ts +10 -3
  262. package/src/notification-types.ts +2 -1
  263. package/src/operator-alarm.ts +26 -11
  264. package/src/package-pack.ts +42 -39
  265. package/src/project-instructions.ts +4 -0
  266. package/src/project-profile-instruction-text.ts +6 -0
  267. package/src/project-profile-instructions.ts +20 -0
  268. package/src/provider-catalog-store.ts +3 -49
  269. package/src/provider-config-store.ts +12 -11
  270. package/src/provider-model-seed.ts +1 -18
  271. package/src/provider-quota-config-store.ts +5 -4
  272. package/src/provider-secrets.test-fixture.ts +3 -3
  273. package/src/recipe-runner.ts +2 -2
  274. package/src/repo-config-source.ts +10 -4
  275. package/src/routes/agent-profiles.ts +6 -6
  276. package/src/routes/agents-spawn.ts +1 -1
  277. package/src/routes/agents.ts +6 -6
  278. package/src/routes/commands-listing.ts +4 -0
  279. package/src/routes/commands.ts +2 -2
  280. package/src/routes/continuation-archives.ts +2 -2
  281. package/src/routes/host-resource-control.ts +4 -1
  282. package/src/routes/index.ts +10 -1
  283. package/src/routes/integrations.ts +24 -50
  284. package/src/routes/issue-refs.ts +7 -7
  285. package/src/routes/orchestrator-bootstrap.ts +3 -3
  286. package/src/routes/orchestrator-host-registration.ts +2 -2
  287. package/src/routes/orchestrator-host-utilization.ts +3 -1
  288. package/src/routes/orchestrator-proxy.ts +2 -2
  289. package/src/routes/orchestrator.ts +4 -4
  290. package/src/routes/project-profile-instructions.ts +27 -0
  291. package/src/routes/project-trust.ts +2 -2
  292. package/src/routes/provider-config.ts +9 -8
  293. package/src/routes/provider-quota-config.ts +2 -2
  294. package/src/routes/settings.ts +5 -5
  295. package/src/routes/stats.ts +6 -6
  296. package/src/routes/task-http.ts +15 -1
  297. package/src/routes/task-issues.ts +11 -26
  298. package/src/routes/tasks.ts +22 -53
  299. package/src/routes/team-templates.ts +5 -5
  300. package/src/routes/teams-config.ts +2 -2
  301. package/src/routes/tokens.ts +12 -5
  302. package/src/routes/workflows.ts +20 -5
  303. package/src/routing-policy-normalize.ts +1 -2
  304. package/src/routing-step-defaults.ts +0 -2
  305. package/src/runner-token-mint-limit.ts +63 -0
  306. package/src/runtime-grant.ts +4 -2
  307. package/src/runtime-tokens.ts +50 -9
  308. package/src/security.ts +13 -20
  309. package/src/server-background.ts +1 -1
  310. package/src/server.ts +5 -2
  311. package/src/services/host-utilization.ts +23 -0
  312. package/src/services/idle-epics.ts +5 -6
  313. package/src/services/issue-lifecycle.ts +57 -61
  314. package/src/services/issue-refs.ts +9 -13
  315. package/src/services/kernel-timers-cutover-chaos-worker.ts +12 -7
  316. package/src/services/kernel-timers-ingress.ts +1 -1
  317. package/src/services/kernel-timers-request-key-migration-chaos-worker.ts +4 -1
  318. package/src/services/landed-ancestry.ts +19 -3
  319. package/src/services/memory-areas.ts +15 -51
  320. package/src/services/plan-ci-notice.ts +57 -0
  321. package/src/services/plan-ci-recovery.ts +2 -55
  322. package/src/services/plan-wake-digest.ts +1 -0
  323. package/src/services/profile-trust.ts +4 -3
  324. package/src/services/project-config-read.ts +70 -0
  325. package/src/services/project-profile-instructions.ts +54 -0
  326. package/src/services/provisioning-harness/budget-baseline.json +4 -4
  327. package/src/services/restart-spawn.ts +61 -49
  328. package/src/services/self-care-state.ts +2 -1
  329. package/src/services/self-effort.ts +5 -5
  330. package/src/services/send-message.ts +5 -1
  331. package/src/services/spawn-agent.ts +13 -2
  332. package/src/services/spawn-chain-inspector.ts +6 -13
  333. package/src/services/spawn-policy.ts +68 -0
  334. package/src/services/spawn-tree-cleanup.ts +2 -2
  335. package/src/services/task-dispatch.ts +3 -0
  336. package/src/services/task-state-reconcile.ts +6 -14
  337. package/src/services/team-templates.ts +9 -8
  338. package/src/services/transient-agent-reaper.ts +3 -1
  339. package/src/services/workflow-auto-start.ts +25 -13
  340. package/src/services/workflow-ci-main.ts +1 -1
  341. package/src/services/workflow-deferred-cleanup.ts +4 -2
  342. package/src/services/workflow-effect-driver.ts +2 -0
  343. package/src/services/workflow-effects.ts +18 -11
  344. package/src/services/workflow-land-notice.ts +10 -0
  345. package/src/services/workflow-pause-text.ts +43 -0
  346. package/src/services/workflow-reconcile.ts +13 -11
  347. package/src/services/workflow-run-view.ts +2 -0
  348. package/src/services/workflow-runs.ts +29 -13
  349. package/src/services/workflow-supervisor-state.ts +5 -0
  350. package/src/services/workflow-supervisor.ts +7 -3
  351. package/src/settings/registry.ts +1 -2
  352. package/src/spawn-command.ts +4 -4
  353. package/src/spawn-models.ts +10 -12
  354. package/src/spawn-placement.ts +1 -1
  355. package/src/spawn-targets.ts +1 -1
  356. package/src/startup-context-injection.ts +1 -0
  357. package/src/state-adoption/cd-cutover.ts +53 -7
  358. package/src/state-adoption/fleet-cutover.ts +35 -0
  359. package/src/state-adoption/fleet-plan.ts +36 -0
  360. package/src/state-adoption/index.ts +2 -2
  361. package/src/state-adoption/linux-plan.ts +2 -2
  362. package/src/state-adoption/linux.ts +2 -2
  363. package/src/state-adoption/macos-plan.ts +2 -2
  364. package/src/state-adoption/macos.ts +1 -1
  365. package/src/steward.ts +7 -6
  366. package/src/task-dispatch-live.ts +1 -1
  367. package/src/task-dispatcher.ts +1 -1
  368. package/src/teams-config-store.ts +4 -3
  369. package/src/token-db-write.ts +10 -0
  370. package/src/workspace-command-settle.ts +2 -1
  371. package/src/workspace-steward-wake.ts +2 -2
  372. package/node_modules/@humwick/kernel/LICENSE +0 -167
  373. package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
  374. package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
  375. package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
  376. package/node_modules/@humwick/kernel/config.ts +0 -111
  377. package/node_modules/@humwick/kernel/contract.ts +0 -572
  378. package/node_modules/@humwick/kernel/control-authz.ts +0 -281
  379. package/node_modules/@humwick/kernel/control.ts +0 -645
  380. package/node_modules/@humwick/kernel/effects.ts +0 -493
  381. package/node_modules/@humwick/kernel/event-log.ts +0 -319
  382. package/node_modules/@humwick/kernel/http-transport.ts +0 -384
  383. package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
  384. package/node_modules/@humwick/kernel/identity.ts +0 -248
  385. package/node_modules/@humwick/kernel/index.ts +0 -28
  386. package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
  387. package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
  388. package/node_modules/@humwick/kernel/landing.ts +0 -953
  389. package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
  390. package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
  391. package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
  392. package/node_modules/@humwick/kernel/message-authority.ts +0 -281
  393. package/node_modules/@humwick/kernel/module-host.ts +0 -722
  394. package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
  395. package/node_modules/@humwick/kernel/package.json +0 -47
  396. package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
  397. package/node_modules/@humwick/kernel/persistence.ts +0 -510
  398. package/node_modules/@humwick/kernel/registry.ts +0 -60
  399. package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
  400. package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
  401. package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
  402. package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
  403. package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
  404. package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
  405. package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
  406. package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
  407. package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
  408. package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
  409. package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
  410. package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
  411. package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
  412. package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
  413. package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
  414. package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
  415. package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
  416. package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
  417. package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
  418. package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
  419. package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
  420. package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
  421. package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
  422. package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
  423. package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
  424. package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
  425. package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
  426. package/node_modules/@humwick/offload/LICENSE +0 -167
  427. package/node_modules/@humwick/offload/README.md +0 -57
  428. package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
  429. package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
  430. package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
  431. package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
  432. package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
  433. package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
  434. package/node_modules/@humwick/offload/dist/envelope.js +0 -80
  435. package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
  436. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
  437. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
  438. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
  439. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
  440. package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
  441. package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
  442. package/node_modules/@humwick/offload/dist/index.js +0 -5
  443. package/node_modules/@humwick/offload/dist/index.js.map +0 -1
  444. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
  445. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
  446. package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
  447. package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
  448. package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
  449. package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
  450. package/node_modules/@humwick/offload/dist/types.js +0 -176
  451. package/node_modules/@humwick/offload/dist/types.js.map +0 -1
  452. package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
  453. package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
  454. package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
  455. package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
  456. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
  457. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
  458. package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
  459. package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
  460. package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
  461. package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
  462. package/node_modules/@humwick/offload/dist/worker.js +0 -1
  463. package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
  464. package/node_modules/@humwick/offload/package.json +0 -46
  465. package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
  466. package/node_modules/@humwick/offload/src/envelope.ts +0 -92
  467. package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
  468. package/node_modules/@humwick/offload/src/index.ts +0 -4
  469. package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
  470. package/node_modules/@humwick/offload/src/types.ts +0 -235
  471. package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
  472. package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
  473. package/node_modules/@humwick/offload/src/worker.ts +0 -5
  474. package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
  475. package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
  476. package/public/assets/fleet-BL4UXS_k.js +0 -2
  477. package/public/assets/index-B7ZerHLY.css +0 -2
  478. package/public/assets/index-BK0WV6hF.js +0 -15
  479. package/public/assets/projects-B_lmcqfO.js +0 -2
  480. package/public/assets/provider-display-DbLWpP3j.js +0 -2
  481. package/public/assets/run-card-CO_bguQf.js +0 -2
  482. package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
  483. package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
  484. package/runner/src/gate-run-lease-probe.ts +0 -38
  485. package/src/db/claude-catalog-reconcile.ts +0 -27
  486. package/src/routing-model-aliases.ts +0 -21
@@ -1,200 +0,0 @@
1
- import { relayEnv } from "@humwick/sdk/env";
2
- /**
3
- * Real-process Stage-0 MESSAGE-authority crash fixture. This is intentionally a fake store: it
4
- * gives the dormant participant one CAS-shaped SQL statement without installing any production
5
- * timer table or call site.
6
- */
7
- import { existsSync, writeFileSync } from "node:fs";
8
- import { Database } from "bun:sqlite";
9
- import { z } from "zod";
10
- import {
11
- createSqliteModuleHost,
12
- createRealClock,
13
- defineModule,
14
- type MessageAuthorityOperation,
15
- type MessageAuthorityStore,
16
- type ModuleCtx,
17
- type OpCommitFaults,
18
- type WorkflowStepCommitFaults,
19
- } from "./index";
20
-
21
- const DB_PATH = required("AUTHORITY_CHAOS_DB");
22
- const COMMAND = required("AUTHORITY_CHAOS_COMMAND");
23
- const ID = process.env.AUTHORITY_CHAOS_ID ?? "sentinel";
24
- const TIMER_ID = process.env.AUTHORITY_CHAOS_TIMER_ID ?? "timer";
25
- const BOUNDARY = process.env.AUTHORITY_CHAOS_BOUNDARY ?? "none";
26
- const ROLE = process.env.AUTHORITY_CHAOS_ROLE ?? "winner";
27
- const READY_FILE = process.env.AUTHORITY_CHAOS_READY_FILE;
28
- const RELEASE_FILE = process.env.AUTHORITY_CHAOS_RELEASE_FILE;
29
-
30
- function required(name: string): string {
31
- const value = relayEnv(process.env, name);
32
- if (!value) throw new Error(`missing ${name}`);
33
- return value;
34
- }
35
-
36
- function selfKill(): never {
37
- process.kill(process.pid, "SIGKILL");
38
- throw new Error("unreachable");
39
- }
40
-
41
- function pausePreFlush(): void {
42
- if (!READY_FILE || !RELEASE_FILE) throw new Error("race loser needs marker paths");
43
- writeFileSync(READY_FILE, "ready");
44
- const deadline = Date.now() + 10_000;
45
- while (!existsSync(RELEASE_FILE)) {
46
- if (Date.now() >= deadline) throw new Error("race release timed out");
47
- Bun.sleepSync(5);
48
- }
49
- }
50
-
51
- function workflowFaults(): WorkflowStepCommitFaults | undefined {
52
- switch (BOUNDARY) {
53
- case "pre-tx": return { beforeCommit: selfKill };
54
- case "after-lease-fence": return { afterFenceBeforeParticipant: selfKill };
55
- case "after-participant-sql": return { afterParticipantBeforeEntities: selfKill };
56
- case "between-entity-event": return { betweenEntitiesAndEvents: selfKill };
57
- case "after-event-flush": return { insideTxBeforeJournal: selfKill };
58
- case "after-journal-sql": return { afterJournalBeforeCommit: selfKill };
59
- case "after-commit": return { afterCommit: selfKill };
60
- default: return undefined;
61
- }
62
- }
63
-
64
- function openDb(): Database {
65
- const db = new Database(DB_PATH);
66
- db.run("PRAGMA busy_timeout = 5000");
67
- db.run("PRAGMA journal_mode = WAL");
68
- db.run(`CREATE TABLE IF NOT EXISTS fake_message_authority (
69
- timer_id TEXT PRIMARY KEY,
70
- fence INTEGER NOT NULL,
71
- winner TEXT NOT NULL
72
- )`);
73
- return db;
74
- }
75
-
76
- class FakeStore implements MessageAuthorityStore {
77
- constructor(readonly winner: string) {}
78
-
79
- executeInTransaction(db: Database, operation: MessageAuthorityOperation) {
80
- if (!db.inTransaction) throw new Error("fake authority SQL escaped the caller transaction");
81
- const changes = db.query(`INSERT INTO fake_message_authority (timer_id, fence, winner)
82
- VALUES (?, ?, ?) ON CONFLICT(timer_id) DO UPDATE SET fence = excluded.fence, winner = excluded.winner
83
- WHERE fake_message_authority.fence < excluded.fence`)
84
- .run(operation.timer.timerId, operation.fence, this.winner).changes;
85
- return changes === 1
86
- ? { ok: true as const }
87
- : { ok: false as const, code: "contended" as const, reason: "participant CAS lost" };
88
- }
89
- }
90
-
91
- const inputSchema = z.object({ id: z.string(), timerId: z.string() });
92
- const stateSchema = z.object({ id: z.string(), timerId: z.string() });
93
-
94
- function stageSentinels(ctx: ModuleCtx, id: string, timerId: string): Promise<void> {
95
- ctx.messageAuthority.applyFence({ timer: { timerId, message: { body: id } }, fence: 1 });
96
- return Promise.all([
97
- (ctx.entities as unknown as { mark: { create(row: { id: string; owner: string }): Promise<unknown> } })
98
- .mark.create({ id, owner: id }),
99
- ctx.events.emit("authority-chaos.wrote", { id }),
100
- ]).then(() => undefined);
101
- }
102
-
103
- const module = defineModule({
104
- id: "authority-chaos",
105
- title: "MESSAGE authority chaos fixture",
106
- description: "Fake-store transaction-enlistment proof.",
107
- entities: { mark: { schema: z.object({ id: z.string(), owner: z.string() }) } },
108
- events: { "authority-chaos.wrote": z.object({ id: z.string() }) },
109
- workflows: {
110
- execute: {
111
- input: inputSchema,
112
- state: stateSchema,
113
- init: (input) => input,
114
- start: "commit",
115
- steps: {
116
- commit: {
117
- run: async (ctx, state) => {
118
- await stageSentinels(ctx, state.id, state.timerId);
119
- return { state, next: "done" as const };
120
- },
121
- },
122
- },
123
- },
124
- seed: {
125
- input: z.object({ id: z.string() }),
126
- state: z.object({ id: z.string() }),
127
- init: (input) => input,
128
- start: "park",
129
- steps: {
130
- // Park rather than finish so the seed itself remains easy to distinguish from an op's rows.
131
- park: { run: async (ctx, state) => ({ state, next: "park", sleepUntil: ctx.clock.now() + 60_000 }) },
132
- },
133
- },
134
- },
135
- ops: {
136
- write: {
137
- kind: "mutation",
138
- grant: "authority-chaos:write",
139
- summary: "Stage authority/entity/event/workflow-seed sentinels.",
140
- idempotent: false,
141
- emits: ["authority-chaos.wrote"],
142
- input: inputSchema,
143
- output: z.object({ ok: z.boolean() }),
144
- handler: async (ctx, input) => {
145
- await stageSentinels(ctx, input.id, input.timerId);
146
- await ctx.workflows.start("seed", { id: input.id }, {
147
- idempotencyKey: `seed-${input.id}`,
148
- enlist: "op-commit",
149
- });
150
- return { ok: true };
151
- },
152
- },
153
- },
154
- });
155
-
156
- function build(db: Database) {
157
- const opFaults: OpCommitFaults | undefined = ROLE === "loser" ? { beforeCommit: pausePreFlush } : undefined;
158
- const host = createSqliteModuleHost({
159
- db,
160
- clock: createRealClock(),
161
- leaseTtlMs: 100,
162
- busyTimeoutMs: 5_000,
163
- messageAuthority: new FakeStore(ID),
164
- workflowCommitFaults: () => ROLE === "loser" && COMMAND === "workflow"
165
- ? { beforeCommit: pausePreFlush }
166
- : workflowFaults(),
167
- ...(opFaults ? { opCommitFaults: () => opFaults } : {}),
168
- });
169
- host.register(module);
170
- return host;
171
- }
172
-
173
- async function recover(host: ReturnType<typeof build>, db: Database): Promise<void> {
174
- const driver = host.workflowDriver(module, { actor: "chaos", grants: [] });
175
- const deadline = Date.now() + 5_000;
176
- while (Date.now() < deadline) {
177
- await driver.recover();
178
- const open = (db.query(`SELECT COUNT(*) AS n FROM workflow_instances
179
- WHERE status NOT IN ('done','failed','canceled','sleeping','waiting')`).get() as { n: number }).n;
180
- if (open === 0) return;
181
- await Bun.sleep(10);
182
- }
183
- throw new Error("recovery timed out");
184
- }
185
-
186
- const db = openDb();
187
- const host = build(db);
188
-
189
- if (COMMAND === "workflow") {
190
- await host.workflowDriver(module, { actor: "chaos", grants: [] })
191
- .start("execute", { id: ID, timerId: TIMER_ID }, { idempotencyKey: `workflow-${ID}` });
192
- } else if (COMMAND === "op") {
193
- await host.invoke(module, "write", { actor: "chaos", grants: ["authority-chaos:write"] }, { id: ID, timerId: TIMER_ID });
194
- } else if (COMMAND === "recover") {
195
- await recover(host, db);
196
- } else {
197
- throw new Error(`unknown command ${COMMAND}`);
198
- }
199
-
200
- db.close();
@@ -1,281 +0,0 @@
1
- import type { Database } from "bun:sqlite";
2
-
3
- /**
4
- * The timer projection carried by every MESSAGE-authority operation. The host participant accepts
5
- * only pure-message timers: a message must be present and `command` must be absent/null. Keeping
6
- * this check at the participant boundary means a future caller cannot accidentally enlist a shell
7
- * timer in the MESSAGE authority protocol even if it bypasses a module-level schema.
8
- */
9
- export interface MessageAuthorityTimer {
10
- readonly timerId: string;
11
- readonly message: unknown;
12
- readonly command?: never;
13
- }
14
-
15
- export type MessageAuthorityEngine = "legacy" | "kernel";
16
- export type MessageAuthorityDecision = "dispatch" | "expired" | "terminal";
17
-
18
- export interface ApplyMessageAuthorityFence {
19
- readonly kind: "applyFence";
20
- readonly timer: MessageAuthorityTimer;
21
- readonly fence: number;
22
- readonly updatedAt?: number;
23
- }
24
-
25
- export interface DecideMessageAuthorityFire {
26
- readonly kind: "decideFire";
27
- readonly timer: MessageAuthorityTimer;
28
- readonly fence: number;
29
- readonly generation: number;
30
- readonly run: number;
31
- readonly engine: MessageAuthorityEngine;
32
- readonly decision: MessageAuthorityDecision;
33
- /** The deadline this exact generation/run woke for. It is part of the ownership predicate. */
34
- readonly fireAt: number;
35
- /** Authority lifecycle after this decision commits. */
36
- readonly lifecycle: "scheduled" | "fired" | "disabled";
37
- /** Immutable fire-row recurrence projection; null for a terminal decision. */
38
- readonly nextRun: number | null;
39
- readonly nextRunAt: number | null;
40
- readonly decidedAt: number;
41
- readonly sendPayload: unknown | null;
42
- readonly idempotencyKey: string | null;
43
- }
44
-
45
- export interface CommitMessageAuthorityTransfer {
46
- readonly kind: "commitTransfer";
47
- readonly timer: MessageAuthorityTimer;
48
- readonly fence: number;
49
- readonly cutoverEpoch: number;
50
- readonly generation: number;
51
- readonly nextRun: number;
52
- readonly from: "legacy";
53
- readonly to: "kernel";
54
- }
55
-
56
- export interface CommitMessageAuthorityReverseTransfer {
57
- readonly kind: "commitReverseTransfer";
58
- readonly timer: MessageAuthorityTimer;
59
- readonly fence: number;
60
- readonly cutoverEpoch: number;
61
- readonly generation: number;
62
- readonly nextRun: number;
63
- readonly from: "kernel";
64
- readonly to: "legacy";
65
- }
66
-
67
- /** The deliberately closed set of host-owned authority mutations available to a module attempt. */
68
- export type MessageAuthorityOperation =
69
- | ApplyMessageAuthorityFence
70
- | DecideMessageAuthorityFire
71
- | CommitMessageAuthorityTransfer
72
- | CommitMessageAuthorityReverseTransfer;
73
-
74
- export type MessageAuthorityRefusal = {
75
- readonly ok: false;
76
- /** `superseded` is terminal for the exact workflow generation that proposed the operation;
77
- * ordinary authority refusal/contention remains retryable. */
78
- readonly code: "contended" | "authority_refused" | "superseded";
79
- readonly reason: string;
80
- };
81
-
82
- export type MessageAuthorityStoreResult = { readonly ok: true } | MessageAuthorityRefusal;
83
-
84
- /**
85
- * Host-owned implementation boundary. Stage 0 intentionally provides no production store: tests
86
- * inject a fake SQL store. Implementations must execute on the same Database connection passed to
87
- * the participant and must not open a transaction of their own.
88
- */
89
- export interface MessageAuthorityStore {
90
- executeInTransaction(db: Database, operation: MessageAuthorityOperation): MessageAuthorityStoreResult;
91
- }
92
-
93
- /** The narrow module-visible staging surface. It exposes no SQL and no generic callback escape. */
94
- export interface MessageAuthorityParticipant {
95
- applyFence(input: Omit<ApplyMessageAuthorityFence, "kind">): void;
96
- decideFire(input: Omit<DecideMessageAuthorityFire, "kind">): void;
97
- commitTransfer(input: Omit<CommitMessageAuthorityTransfer, "kind">): void;
98
- commitReverseTransfer(input: Omit<CommitMessageAuthorityReverseTransfer, "kind">): void;
99
- }
100
-
101
- export class MessageAuthorityUnavailableError extends Error {
102
- constructor() {
103
- super("MESSAGE authority participation is not configured on this host");
104
- this.name = "MessageAuthorityUnavailableError";
105
- }
106
- }
107
-
108
- export class MessageAuthoritySessionClosedError extends Error {
109
- constructor() {
110
- super("MESSAGE authority participant session is closed");
111
- this.name = "MessageAuthoritySessionClosedError";
112
- }
113
- }
114
-
115
- export class MessageAuthorityShapeError extends TypeError {
116
- constructor(message: string) {
117
- super(message);
118
- this.name = "MessageAuthorityShapeError";
119
- }
120
- }
121
-
122
- /** A failed store predicate. Throwing this aborts the caller-owned transaction as one unit. */
123
- export class MessageAuthorityCommitRefusedError extends Error {
124
- constructor(readonly refusal: MessageAuthorityRefusal, readonly operation: MessageAuthorityOperation) {
125
- super(`MESSAGE authority ${refusal.code}: ${refusal.reason}`);
126
- this.name = "MessageAuthorityCommitRefusedError";
127
- }
128
- }
129
-
130
- export interface MessageAuthoritySession {
131
- readonly participant: MessageAuthorityParticipant;
132
- readonly pendingOperations: number;
133
- seal(): void;
134
- flush(): void;
135
- /** Consume the clone-safe participant operations for an async persistence envelope. */
136
- operations(): readonly MessageAuthorityOperation[];
137
- discard(): void;
138
- }
139
-
140
- function assertInteger(value: number, name: string, minimum: number): void {
141
- if (!Number.isSafeInteger(value) || value < minimum) {
142
- throw new MessageAuthorityShapeError(`${name} must be a safe integer >= ${minimum}`);
143
- }
144
- }
145
-
146
- function assertPureMessageTimer(timer: MessageAuthorityTimer): void {
147
- if (typeof timer !== "object" || timer === null) {
148
- throw new MessageAuthorityShapeError("MESSAGE authority requires a timer projection");
149
- }
150
- if (typeof timer.timerId !== "string" || timer.timerId.length === 0) {
151
- throw new MessageAuthorityShapeError("MESSAGE authority requires a non-empty timerId");
152
- }
153
- if (timer.message === undefined || timer.message === null) {
154
- throw new MessageAuthorityShapeError(`timer '${timer.timerId}' has no message payload`);
155
- }
156
- const command = (timer as unknown as { command?: unknown }).command;
157
- if (command !== undefined && command !== null) {
158
- throw new MessageAuthorityShapeError(`timer '${timer.timerId}' is command-shaped and cannot join MESSAGE authority`);
159
- }
160
- }
161
-
162
- function validateOperation(operation: MessageAuthorityOperation): void {
163
- assertPureMessageTimer(operation.timer);
164
- assertInteger(operation.fence, "fence", 0);
165
- if (operation.kind === "applyFence") {
166
- if (operation.updatedAt !== undefined) assertInteger(operation.updatedAt, "updatedAt", 0);
167
- return;
168
- }
169
- assertInteger(operation.generation, "generation", 0);
170
- if (operation.kind === "decideFire") {
171
- assertInteger(operation.run, "run", 1);
172
- if (operation.run === Number.MAX_SAFE_INTEGER) {
173
- throw new MessageAuthorityShapeError("run must leave room for the authority advance");
174
- }
175
- assertInteger(operation.fireAt, "fireAt", 0);
176
- assertInteger(operation.decidedAt, "decidedAt", 0);
177
- if (operation.nextRun !== null) assertInteger(operation.nextRun, "nextRun", 1);
178
- if (operation.nextRunAt !== null) assertInteger(operation.nextRunAt, "nextRunAt", 0);
179
- if ((operation.nextRun === null) !== (operation.nextRunAt === null)) {
180
- throw new MessageAuthorityShapeError("nextRun and nextRunAt must both be null or both be present");
181
- }
182
- if ((operation.lifecycle === "scheduled") !== (operation.nextRun !== null)) {
183
- throw new MessageAuthorityShapeError("scheduled lifecycle requires a next run/deadline");
184
- }
185
- if (operation.decision === "expired" && operation.lifecycle !== "disabled") {
186
- throw new MessageAuthorityShapeError("expired decisions must disable authority");
187
- }
188
- const dispatch = operation.decision === "dispatch";
189
- if (dispatch !== (operation.sendPayload !== null && operation.idempotencyKey !== null)) {
190
- throw new MessageAuthorityShapeError("dispatch decisions require sendPayload and idempotencyKey only");
191
- }
192
- return;
193
- }
194
- assertInteger(operation.cutoverEpoch, "cutoverEpoch", 0);
195
- assertInteger(operation.nextRun, "nextRun", 0);
196
- }
197
-
198
- class MessageAuthoritySessionRuntime implements MessageAuthoritySession {
199
- readonly participant: MessageAuthorityParticipant;
200
- readonly #operations: MessageAuthorityOperation[] = [];
201
- #closed = false;
202
- #finished = false;
203
-
204
- constructor(
205
- readonly available: boolean,
206
- readonly flushOperations?: (operations: readonly MessageAuthorityOperation[]) => void,
207
- ) {
208
- this.participant = Object.freeze({
209
- applyFence: (input: Omit<ApplyMessageAuthorityFence, "kind">) => this.#stage({ kind: "applyFence", ...input }),
210
- decideFire: (input: Omit<DecideMessageAuthorityFire, "kind">) => this.#stage({ kind: "decideFire", ...input }),
211
- commitTransfer: (input: Omit<CommitMessageAuthorityTransfer, "kind">) => this.#stage({ kind: "commitTransfer", ...input }),
212
- commitReverseTransfer: (input: Omit<CommitMessageAuthorityReverseTransfer, "kind">) =>
213
- this.#stage({ kind: "commitReverseTransfer", ...input }),
214
- });
215
- }
216
-
217
- get pendingOperations(): number {
218
- return this.#operations.length;
219
- }
220
-
221
- #stage(operation: MessageAuthorityOperation): void {
222
- if (this.#closed) throw new MessageAuthoritySessionClosedError();
223
- if (!this.available) throw new MessageAuthorityUnavailableError();
224
- validateOperation(operation);
225
- // Snapshot the validated projection. Holding the caller's mutable object would let detached
226
- // code add `command` after validation but before commit and smuggle a command-shaped timer to
227
- // the store. The participant needs only these two fields, so discard every other property.
228
- const timer = Object.freeze({ timerId: operation.timer.timerId, message: operation.timer.message });
229
- this.#operations.push(Object.freeze({ ...operation, timer }) as MessageAuthorityOperation);
230
- }
231
-
232
- seal(): void {
233
- if (this.#finished) throw new MessageAuthoritySessionClosedError();
234
- this.#closed = true;
235
- }
236
-
237
- flush(): void {
238
- if (!this.#closed || this.#finished) throw new MessageAuthoritySessionClosedError();
239
- try {
240
- if (!this.flushOperations) throw new Error("async MESSAGE authority operations must commit through KernelPersistence");
241
- this.flushOperations(this.#operations);
242
- this.#finished = true;
243
- } catch (error) {
244
- this.#finished = true;
245
- throw error;
246
- }
247
- }
248
-
249
- operations(): readonly MessageAuthorityOperation[] {
250
- if (!this.#closed || this.#finished) throw new MessageAuthoritySessionClosedError();
251
- this.#finished = true;
252
- return Object.freeze(this.#operations.map((operation) => structuredClone(operation)));
253
- }
254
-
255
- discard(): void {
256
- if (this.#finished) throw new MessageAuthoritySessionClosedError();
257
- this.#closed = true;
258
- this.#operations.length = 0;
259
- this.#finished = true;
260
- }
261
- }
262
-
263
- /** Begin one participant session, scoped to exactly one op or workflow-step attempt. */
264
- export function beginMessageAuthoritySession(db: Database, store?: MessageAuthorityStore): MessageAuthoritySession;
265
- export function beginMessageAuthoritySession(available: boolean): MessageAuthoritySession;
266
- export function beginMessageAuthoritySession(dbOrAvailable: Database | boolean, store?: MessageAuthorityStore): MessageAuthoritySession {
267
- return typeof dbOrAvailable === "boolean"
268
- ? new MessageAuthoritySessionRuntime(dbOrAvailable)
269
- : new MessageAuthoritySessionRuntime(store !== undefined, (operations) => {
270
- if (!dbOrAvailable.inTransaction) {
271
- throw new Error("MESSAGE authority operations must flush inside a caller-owned SQLite transaction");
272
- }
273
- for (const operation of operations) {
274
- // The caller-owned handle is passed explicitly. A store that tries to wrap this in another
275
- // BEGIN/COMMIT fails as a nested transaction instead of silently escaping the atomic commit.
276
- const result = store?.executeInTransaction(dbOrAvailable, operation);
277
- if (!result) throw new MessageAuthorityUnavailableError();
278
- if (!result.ok) throw new MessageAuthorityCommitRefusedError(result, operation);
279
- }
280
- });
281
- }