@humwick/server 0.130.1 → 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 (437) hide show
  1. package/README.md +5 -0
  2. package/docs/guides/tools-administration.md +4 -0
  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-B_rFEbnL.js → fleet-C7jQWbw2.js} +2 -2
  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 +8 -0
  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 +3 -3
  128. package/src/config-store-write.ts +13 -1
  129. package/src/config-store.ts +25 -14
  130. package/src/db/activity-async.ts +6 -1
  131. package/src/db/activity-write-ops.ts +12 -1
  132. package/src/db/activity.ts +1 -14
  133. package/src/db/agent-search.ts +1 -15
  134. package/src/db/agents-async.ts +52 -5
  135. package/src/db/agents-write-ops.ts +12 -3
  136. package/src/db/agents.ts +81 -54
  137. package/src/db/ci-incidents-async.ts +5 -5
  138. package/src/db/ci-incidents-write-ops.ts +2 -2
  139. package/src/db/command-row.ts +10 -2
  140. package/src/db/commands-list-query.ts +2 -0
  141. package/src/db/commands-spawn-read.ts +1 -1
  142. package/src/db/config-store-write-ops.ts +7 -2
  143. package/src/db/continuation-archives-async.ts +5 -0
  144. package/src/db/continuation-archives-write-ops.ts +7 -0
  145. package/src/db/continuations.ts +2 -2
  146. package/src/db/db-writer-worker.ts +8 -1
  147. package/src/db/deploy-events-async.ts +1 -0
  148. package/src/db/deploy-events-read-ops.ts +2 -1
  149. package/src/db/deploy-events.ts +35 -4
  150. package/src/db/hosts-registration.ts +10 -2
  151. package/src/db/hosts.ts +9 -6
  152. package/src/db/inbox.ts +0 -14
  153. package/src/db/index.ts +2 -0
  154. package/src/db/integrations-async.ts +8 -0
  155. package/src/db/integrations-ops.ts +15 -0
  156. package/src/db/integrations.ts +15 -21
  157. package/src/db/issue-lifecycle.ts +3 -4
  158. package/src/db/issue-refs-async.ts +20 -0
  159. package/src/db/issue-refs-write-ops.ts +29 -0
  160. package/src/db/issue-refs.ts +7 -8
  161. package/src/db/long-running-work.ts +2 -2
  162. package/src/db/main-connection-writes.ts +23 -2
  163. package/src/db/maintenance-job-reconcile.ts +61 -0
  164. package/src/db/maintenance-job-runs-async.ts +14 -0
  165. package/src/db/maintenance-job-write-ops.ts +9 -0
  166. package/src/db/mappers.ts +2 -14
  167. package/src/db/merge-lease.ts +1 -15
  168. package/src/db/migrations.ts +7 -15
  169. package/src/db/orchestrators.ts +4 -72
  170. package/src/db/pairs.ts +1 -13
  171. package/src/db/project-profile-instructions.ts +50 -0
  172. package/src/db/prompt-versions.ts +9 -2
  173. package/src/db/provider-config-history.ts +8 -3
  174. package/src/db/provider-model-seed.ts +34 -0
  175. package/src/db/read-op-marshaling-fixtures.ts +5 -0
  176. package/src/db/read-ops.ts +4 -0
  177. package/src/db/routing-policy.ts +2 -3
  178. package/src/db/schema.ts +9 -3
  179. package/src/db/spawn-delegation-state.ts +11 -4
  180. package/src/db/stats-async.ts +4 -3
  181. package/src/db/task-entity.ts +23 -2
  182. package/src/db/task-list.ts +3 -1
  183. package/src/db/tasks.ts +1 -17
  184. package/src/db/timer-ingress.ts +7 -1
  185. package/src/db/token-db-write-ops.ts +17 -0
  186. package/src/db/token-standing.ts +15 -11
  187. package/src/db/workflow-contact.ts +1 -1
  188. package/src/db/workflow-task-read-ops.ts +30 -0
  189. package/src/db/write-ops.ts +6 -0
  190. package/src/db/writer-gateway.ts +17 -11
  191. package/src/dispatch-availability.ts +10 -6
  192. package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
  193. package/src/host/disk-alert.ts +121 -0
  194. package/src/lifecycle-manager.ts +3 -2
  195. package/src/maintenance/cd-watcher.ts +3 -3
  196. package/src/maintenance/critical-job-watchdog.ts +16 -17
  197. package/src/maintenance/index.ts +1 -0
  198. package/src/maintenance/jobs.ts +3 -2
  199. package/src/maintenance/scheduler.ts +84 -128
  200. package/src/maintenance/stalled-delivery-pager.ts +6 -5
  201. package/src/maintenance/workspaces.ts +1 -1
  202. package/src/managed-policy.ts +31 -27
  203. package/src/mcp/index.ts +5 -2
  204. package/src/mcp/output-descriptions.ts +8 -8
  205. package/src/mcp/presentation.ts +4 -4
  206. package/src/mcp/project-profile-instructions.ts +32 -0
  207. package/src/mcp/tool-groups.ts +1 -1
  208. package/src/mcp/tools-spawn.ts +4 -3
  209. package/src/mcp-agent-action.ts +1 -2
  210. package/src/mcp-issue-ref-tools.ts +12 -11
  211. package/src/mcp-maintenance-tools.ts +2 -2
  212. package/src/mcp-profile-trust-tools.ts +4 -4
  213. package/src/mcp-provider-catalog.ts +2 -2
  214. package/src/mcp-task-tools.ts +11 -5
  215. package/src/mcp-team-template-tools.ts +3 -3
  216. package/src/mcp-workflow-tools.ts +10 -3
  217. package/src/notification-types.ts +2 -1
  218. package/src/operator-alarm.ts +26 -11
  219. package/src/project-instructions.ts +4 -0
  220. package/src/project-profile-instruction-text.ts +6 -0
  221. package/src/project-profile-instructions.ts +20 -0
  222. package/src/provider-catalog-store.ts +3 -49
  223. package/src/provider-config-store.ts +12 -11
  224. package/src/provider-model-seed.ts +1 -18
  225. package/src/provider-quota-config-store.ts +5 -4
  226. package/src/provider-secrets.test-fixture.ts +3 -3
  227. package/src/recipe-runner.ts +2 -2
  228. package/src/repo-config-source.ts +10 -4
  229. package/src/routes/agent-profiles.ts +6 -6
  230. package/src/routes/agents-spawn.ts +1 -1
  231. package/src/routes/agents.ts +6 -6
  232. package/src/routes/commands-listing.ts +4 -0
  233. package/src/routes/commands.ts +2 -2
  234. package/src/routes/continuation-archives.ts +2 -2
  235. package/src/routes/index.ts +10 -1
  236. package/src/routes/integrations.ts +24 -50
  237. package/src/routes/issue-refs.ts +7 -7
  238. package/src/routes/orchestrator-bootstrap.ts +1 -1
  239. package/src/routes/orchestrator-host-registration.ts +2 -2
  240. package/src/routes/orchestrator-host-utilization.ts +3 -1
  241. package/src/routes/orchestrator-proxy.ts +2 -2
  242. package/src/routes/orchestrator.ts +2 -2
  243. package/src/routes/project-profile-instructions.ts +27 -0
  244. package/src/routes/project-trust.ts +2 -2
  245. package/src/routes/provider-config.ts +6 -6
  246. package/src/routes/provider-quota-config.ts +2 -2
  247. package/src/routes/settings.ts +5 -5
  248. package/src/routes/stats.ts +6 -6
  249. package/src/routes/task-http.ts +15 -1
  250. package/src/routes/task-issues.ts +11 -26
  251. package/src/routes/tasks.ts +22 -53
  252. package/src/routes/team-templates.ts +5 -5
  253. package/src/routes/teams-config.ts +2 -2
  254. package/src/routes/tokens.ts +12 -5
  255. package/src/routes/workflows.ts +20 -5
  256. package/src/routing-policy-normalize.ts +1 -2
  257. package/src/routing-step-defaults.ts +0 -2
  258. package/src/runner-token-mint-limit.ts +63 -0
  259. package/src/runtime-grant.ts +4 -2
  260. package/src/runtime-tokens.ts +39 -7
  261. package/src/security.ts +13 -20
  262. package/src/server-background.ts +1 -1
  263. package/src/server.ts +5 -2
  264. package/src/services/host-utilization.ts +23 -0
  265. package/src/services/idle-epics.ts +5 -6
  266. package/src/services/issue-lifecycle.ts +57 -61
  267. package/src/services/issue-refs.ts +9 -13
  268. package/src/services/kernel-timers-cutover-chaos-worker.ts +10 -7
  269. package/src/services/kernel-timers-ingress.ts +1 -1
  270. package/src/services/landed-ancestry.ts +19 -3
  271. package/src/services/memory-areas.ts +15 -51
  272. package/src/services/plan-ci-notice.ts +57 -0
  273. package/src/services/plan-ci-recovery.ts +2 -55
  274. package/src/services/plan-wake-digest.ts +1 -0
  275. package/src/services/profile-trust.ts +4 -3
  276. package/src/services/project-config-read.ts +70 -0
  277. package/src/services/project-profile-instructions.ts +54 -0
  278. package/src/services/provisioning-harness/budget-baseline.json +4 -4
  279. package/src/services/restart-spawn.ts +61 -49
  280. package/src/services/self-care-state.ts +2 -1
  281. package/src/services/self-effort.ts +5 -5
  282. package/src/services/send-message.ts +5 -1
  283. package/src/services/spawn-agent.ts +13 -2
  284. package/src/services/spawn-chain-inspector.ts +6 -13
  285. package/src/services/spawn-policy.ts +68 -0
  286. package/src/services/spawn-tree-cleanup.ts +2 -2
  287. package/src/services/task-dispatch.ts +3 -0
  288. package/src/services/task-state-reconcile.ts +6 -14
  289. package/src/services/team-templates.ts +9 -8
  290. package/src/services/transient-agent-reaper.ts +3 -1
  291. package/src/services/workflow-auto-start.ts +25 -13
  292. package/src/services/workflow-ci-main.ts +1 -1
  293. package/src/services/workflow-deferred-cleanup.ts +4 -2
  294. package/src/services/workflow-effect-driver.ts +2 -0
  295. package/src/services/workflow-effects.ts +18 -11
  296. package/src/services/workflow-land-notice.ts +10 -0
  297. package/src/services/workflow-pause-text.ts +43 -0
  298. package/src/services/workflow-reconcile.ts +13 -11
  299. package/src/services/workflow-run-view.ts +2 -0
  300. package/src/services/workflow-runs.ts +29 -13
  301. package/src/services/workflow-supervisor-state.ts +5 -0
  302. package/src/services/workflow-supervisor.ts +7 -3
  303. package/src/settings/registry.ts +1 -2
  304. package/src/spawn-command.ts +4 -4
  305. package/src/spawn-models.ts +10 -12
  306. package/src/spawn-placement.ts +1 -1
  307. package/src/spawn-targets.ts +1 -1
  308. package/src/startup-context-injection.ts +1 -0
  309. package/src/state-adoption/cd-cutover.ts +53 -7
  310. package/src/state-adoption/fleet-cutover.ts +35 -0
  311. package/src/state-adoption/fleet-plan.ts +36 -0
  312. package/src/state-adoption/index.ts +2 -2
  313. package/src/state-adoption/linux-plan.ts +2 -2
  314. package/src/state-adoption/linux.ts +2 -2
  315. package/src/state-adoption/macos-plan.ts +2 -2
  316. package/src/state-adoption/macos.ts +1 -1
  317. package/src/steward.ts +7 -6
  318. package/src/task-dispatch-live.ts +1 -1
  319. package/src/task-dispatcher.ts +1 -1
  320. package/src/teams-config-store.ts +4 -3
  321. package/src/token-db-write.ts +10 -0
  322. package/src/workspace-command-settle.ts +2 -1
  323. package/src/workspace-steward-wake.ts +2 -2
  324. package/node_modules/@humwick/kernel/LICENSE +0 -167
  325. package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
  326. package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
  327. package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
  328. package/node_modules/@humwick/kernel/config.ts +0 -111
  329. package/node_modules/@humwick/kernel/contract.ts +0 -572
  330. package/node_modules/@humwick/kernel/control-authz.ts +0 -281
  331. package/node_modules/@humwick/kernel/control.ts +0 -645
  332. package/node_modules/@humwick/kernel/effects.ts +0 -493
  333. package/node_modules/@humwick/kernel/event-log.ts +0 -319
  334. package/node_modules/@humwick/kernel/http-transport.ts +0 -384
  335. package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
  336. package/node_modules/@humwick/kernel/identity.ts +0 -248
  337. package/node_modules/@humwick/kernel/index.ts +0 -28
  338. package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
  339. package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
  340. package/node_modules/@humwick/kernel/landing.ts +0 -953
  341. package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
  342. package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
  343. package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
  344. package/node_modules/@humwick/kernel/message-authority.ts +0 -281
  345. package/node_modules/@humwick/kernel/module-host.ts +0 -722
  346. package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
  347. package/node_modules/@humwick/kernel/package.json +0 -39
  348. package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
  349. package/node_modules/@humwick/kernel/persistence.ts +0 -510
  350. package/node_modules/@humwick/kernel/registry.ts +0 -60
  351. package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
  352. package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
  353. package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
  354. package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
  355. package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
  356. package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
  357. package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
  358. package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
  359. package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
  360. package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
  361. package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
  362. package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
  363. package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
  364. package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
  365. package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
  366. package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
  367. package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
  368. package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
  369. package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
  370. package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
  371. package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
  372. package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
  373. package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
  374. package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
  375. package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
  376. package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
  377. package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
  378. package/node_modules/@humwick/offload/LICENSE +0 -167
  379. package/node_modules/@humwick/offload/README.md +0 -57
  380. package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
  381. package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
  382. package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
  383. package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
  384. package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
  385. package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
  386. package/node_modules/@humwick/offload/dist/envelope.js +0 -80
  387. package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
  388. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
  389. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
  390. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
  391. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
  392. package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
  393. package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
  394. package/node_modules/@humwick/offload/dist/index.js +0 -5
  395. package/node_modules/@humwick/offload/dist/index.js.map +0 -1
  396. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
  397. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
  398. package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
  399. package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
  400. package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
  401. package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
  402. package/node_modules/@humwick/offload/dist/types.js +0 -176
  403. package/node_modules/@humwick/offload/dist/types.js.map +0 -1
  404. package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
  405. package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
  406. package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
  407. package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
  408. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
  409. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
  410. package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
  411. package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
  412. package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
  413. package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
  414. package/node_modules/@humwick/offload/dist/worker.js +0 -1
  415. package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
  416. package/node_modules/@humwick/offload/package.json +0 -42
  417. package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
  418. package/node_modules/@humwick/offload/src/envelope.ts +0 -92
  419. package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
  420. package/node_modules/@humwick/offload/src/index.ts +0 -4
  421. package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
  422. package/node_modules/@humwick/offload/src/types.ts +0 -235
  423. package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
  424. package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
  425. package/node_modules/@humwick/offload/src/worker.ts +0 -5
  426. package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
  427. package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
  428. package/public/assets/index-B7ZerHLY.css +0 -2
  429. package/public/assets/index-BU3uWo2t.js +0 -15
  430. package/public/assets/projects-B_lmcqfO.js +0 -2
  431. package/public/assets/provider-display-DbLWpP3j.js +0 -2
  432. package/public/assets/run-card-CO_bguQf.js +0 -2
  433. package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
  434. package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
  435. package/runner/src/gate-run-lease-probe.ts +0 -38
  436. package/src/db/claude-catalog-reconcile.ts +0 -27
  437. package/src/routing-model-aliases.ts +0 -21
@@ -1,499 +0,0 @@
1
- import type { Database } from "bun:sqlite";
2
- import type { Clock, Scope } from "./contract";
3
- import { reclaimDeadWorkflowLeases, type WorkflowLeaseOwnerProbe } from "./workflow-lease-owner";
4
- import { ensureEventLogSchema, type EmittedEvent, type EventReplaySlice } from "./event-log";
5
- import type {
6
- KernelEntityCatalog,
7
- KernelEntityListRead,
8
- KernelEntityMutation,
9
- KernelEntityPointRead,
10
- KernelEntityStoredRow,
11
- KernelJournalOnlyCommitEnvelope,
12
- KernelModuleCatalog,
13
- KernelOpCommitEnvelope,
14
- KernelOpCommitResult,
15
- KernelPersistence,
16
- KernelStepCommitEnvelope,
17
- KernelStoredValue,
18
- } from "./kernel-persistence";
19
- import {
20
- MessageAuthorityCommitRefusedError,
21
- type MessageAuthorityOperation,
22
- type MessageAuthorityStore,
23
- } from "./message-authority";
24
- import { EntityConflictError } from "./persistence";
25
- import { quoteIdentifier, type StorageKind } from "./persistence-schema";
26
- import {
27
- WorkflowContendedError,
28
- WorkflowJournalPersistence,
29
- isSqliteBusy,
30
- type AcquireLeaseParams,
31
- type ListInstancesOptions,
32
- type RenewLeaseParams,
33
- type WorkflowInstancePage,
34
- type WorkflowInstanceRow,
35
- type WorkflowInstanceSeed,
36
- type WorkflowStepJournalRow,
37
- } from "./workflow-journal";
38
- import type { WorkflowStepCommitFaults } from "./workflow-step-commit";
39
-
40
- const EVENTS_TABLE = "kernel_events";
41
- const SEQ_TABLE = "kernel_event_scope_seq";
42
- // The table is the idempotency authority; these bounded maps are only a hot-result optimization.
43
- const DEDUP_TABLE = "kernel_compat_request_results";
44
- export const SQLITE_COMPAT_DEDUP_MAX_ENTRIES = 1_024;
45
-
46
- class BoundedResultMap<V> {
47
- readonly #entries = new Map<string, V>();
48
-
49
- get size(): number { return this.#entries.size; }
50
- get(key: string): V | undefined {
51
- const value = this.#entries.get(key);
52
- if (value !== undefined) {
53
- this.#entries.delete(key);
54
- this.#entries.set(key, value);
55
- }
56
- return value;
57
- }
58
- set(key: string, value: V): void {
59
- this.#entries.delete(key);
60
- this.#entries.set(key, value);
61
- while (this.#entries.size > SQLITE_COMPAT_DEDUP_MAX_ENTRIES) this.#entries.delete(this.#entries.keys().next().value!);
62
- }
63
- }
64
-
65
- interface CompatibilityOpFaults {
66
- readonly afterParticipantBeforeEntities?: () => void;
67
- readonly betweenEntitiesAndEvents?: () => void;
68
- readonly afterEventsBeforeWorkflowSeeds?: () => void;
69
- readonly afterWorkflowSeedsBeforeCommit?: () => void;
70
- }
71
-
72
- const opFaults = new WeakMap<KernelPersistence, Map<string, CompatibilityOpFaults>>();
73
- const stepFaults = new WeakMap<KernelPersistence, Map<string, WorkflowStepCommitFaults>>();
74
-
75
- /** Private compatibility-only side channel for existing in-process chaos hooks. */
76
- export function armCompatibilityOpFaults(port: KernelPersistence, requestKey: string, faults: CompatibilityOpFaults): void {
77
- const entries = opFaults.get(port) ?? new Map();
78
- entries.set(requestKey, faults);
79
- opFaults.set(port, entries);
80
- }
81
-
82
- /** Private compatibility-only side channel for existing in-process chaos hooks. */
83
- export function armCompatibilityStepFaults(port: KernelPersistence, requestKey: string, faults: WorkflowStepCommitFaults): void {
84
- const entries = stepFaults.get(port) ?? new Map();
85
- entries.set(requestKey, faults);
86
- stepFaults.set(port, entries);
87
- }
88
-
89
- function sqlType(kind: StorageKind): string {
90
- if (kind === "integer" || kind === "boolean" || kind === "date") return "INTEGER";
91
- if (kind === "real") return "REAL";
92
- return "TEXT";
93
- }
94
-
95
- function installEntity(db: Database, entity: KernelEntityCatalog): void {
96
- const table = quoteIdentifier(entity.tableName);
97
- const fields = entity.fields.map((field) => `${quoteIdentifier(field.name)} ${sqlType(field.kind)}${field.nullable ? "" : " NOT NULL"}`);
98
- const references = Object.entries(entity.references).map(([field, ref]) =>
99
- `FOREIGN KEY (scope, ${quoteIdentifier(field)}) REFERENCES ${quoteIdentifier(`kernel_entity__${ref.module}__${ref.entity}`)}`,
100
- );
101
- db.run(`CREATE TABLE IF NOT EXISTS ${table} (
102
- scope TEXT NOT NULL,
103
- ${fields.join(",\n ")},
104
- version INTEGER NOT NULL,
105
- created_at INTEGER NOT NULL,
106
- updated_at INTEGER NOT NULL,
107
- PRIMARY KEY (scope, ${quoteIdentifier(entity.key)})${references.length ? `,\n ${references.join(",\n ")}` : ""}
108
- )`);
109
- const info = db.query(`PRAGMA table_info(${table})`).all() as Array<{ name: string; type: string; notnull: number; pk: number }>;
110
- for (const [name, type] of [["scope", "TEXT"], ["version", "INTEGER"], ["created_at", "INTEGER"], ["updated_at", "INTEGER"]] as const) {
111
- const stored = info.find((row) => row.name === name);
112
- if (!stored || stored.type.toUpperCase() !== type || stored.notnull !== 1) {
113
- throw new Error(`entity table '${entity.tableName}' has incompatible kernel column '${name}'`);
114
- }
115
- }
116
- const primaryKey = info.filter((row) => row.pk > 0).sort((a, b) => a.pk - b.pk).map((row) => row.name);
117
- if (primaryKey.length !== 2 || primaryKey[0] !== "scope" || primaryKey[1] !== entity.key) {
118
- throw new Error(`entity table '${entity.tableName}' must have primary key (scope, ${entity.key})`);
119
- }
120
- for (const field of entity.fields) {
121
- const stored = info.find((row) => row.name === field.name);
122
- if (!stored) {
123
- if (!field.nullable) throw new Error(`cannot add required field '${field.name}' to existing entity table '${entity.tableName}'`);
124
- db.run(`ALTER TABLE ${table} ADD COLUMN ${quoteIdentifier(field.name)} ${sqlType(field.kind)}`);
125
- } else if (stored.type.toUpperCase() !== sqlType(field.kind)) {
126
- throw new Error(`entity field '${entity.moduleId}.${entity.entityName}.${field.name}' changed SQLite type`);
127
- }
128
- }
129
- entity.indexes.forEach((names, index) => db.run(
130
- `CREATE INDEX IF NOT EXISTS ${quoteIdentifier(`${entity.tableName}__idx_${index}`)} ON ${table} (scope, ${names.map(quoteIdentifier).join(", ")})`,
131
- ));
132
- }
133
-
134
- function columns(entity: KernelEntityCatalog): string {
135
- return entity.fields.map((field) => quoteIdentifier(field.name)).join(", ");
136
- }
137
-
138
- function storedRow(entity: KernelEntityCatalog, row: Record<string, unknown> | null): KernelEntityStoredRow | undefined {
139
- if (!row) return undefined;
140
- return {
141
- values: Object.fromEntries(entity.fields.map((field) => [field.name, row[field.name] as KernelStoredValue])),
142
- version: row.version as number,
143
- createdAt: row.created_at as number,
144
- updatedAt: row.updated_at as number,
145
- };
146
- }
147
-
148
- function applyAuthority(db: Database, store: MessageAuthorityStore | undefined, operations: readonly MessageAuthorityOperation[]): void {
149
- for (const operation of operations) {
150
- const result = store?.executeInTransaction(db, operation);
151
- if (!result) throw new Error("MESSAGE authority participation is not configured on this host");
152
- if (!result.ok) throw new MessageAuthorityCommitRefusedError(result, operation);
153
- }
154
- }
155
-
156
- function applyEntities(db: Database, mutations: readonly KernelEntityMutation[], now: number): void {
157
- for (const mutation of mutations) {
158
- const table = quoteIdentifier(mutation.entity.tableName);
159
- const key = quoteIdentifier(mutation.entity.key);
160
- let changes: number;
161
- if (mutation.kind === "delete") {
162
- changes = db.query(`DELETE FROM ${table} WHERE scope = ? AND ${key} = ? AND version = ?`)
163
- .run(mutation.scope, mutation.key, mutation.expectedVersion).changes;
164
- } else if (mutation.expectedVersion === null) {
165
- const names = mutation.entity.fields.map((field) => field.name);
166
- const values = names.map((name) => mutation.values?.[name] ?? null);
167
- changes = db.query(`INSERT INTO ${table} (scope, ${names.map(quoteIdentifier).join(", ")}, version, created_at, updated_at)
168
- VALUES (?, ${names.map(() => "?").join(", ")}, 0, ?, ?) ON CONFLICT DO NOTHING`)
169
- .run(mutation.scope, ...values, now, now).changes;
170
- } else {
171
- const names = mutation.entity.fields.map((field) => field.name);
172
- changes = db.query(`UPDATE ${table} SET ${names.map((name) => `${quoteIdentifier(name)} = ?`).join(", ")}, version = version + 1, updated_at = ?
173
- WHERE scope = ? AND ${key} = ? AND version = ?`).run(
174
- ...names.map((name) => mutation.values?.[name] ?? null), now, mutation.scope, mutation.key, mutation.expectedVersion,
175
- ).changes;
176
- }
177
- if (changes !== 1) throw new EntityConflictError(mutation.entity.moduleId, mutation.entity.entityName, mutation.logicalKey);
178
- }
179
- }
180
-
181
- function appendEvents(db: Database, events: KernelOpCommitEnvelope["events"]): void {
182
- if (events.length === 0) return;
183
- const groups = new Map<Scope, typeof events>();
184
- for (const event of events) groups.set(event.scope, [...(groups.get(event.scope) ?? []), event]);
185
- for (const [scope, scoped] of groups) {
186
- const bumped = db.query(`INSERT INTO ${SEQ_TABLE} (scope, high_water) VALUES (?, ?)
187
- ON CONFLICT(scope) DO UPDATE SET high_water = high_water + excluded.high_water RETURNING high_water`)
188
- .get(scope, scoped.length) as { high_water: number };
189
- const first = bumped.high_water - scoped.length + 1;
190
- scoped.forEach((event, index) => db.run(
191
- `INSERT INTO ${EVENTS_TABLE} (scope, seq, module_id, name, payload, created_at) VALUES (?, ?, ?, ?, ?, ?)`,
192
- [scope, first + index, event.moduleId, event.name, event.payload, event.createdAt],
193
- ));
194
- }
195
- }
196
-
197
- /** Private K0 adapter. Production src gateway registration replaces this in K1. */
198
- export class SqliteKernelPersistence implements KernelPersistence {
199
- readonly #journal: WorkflowJournalPersistence;
200
- readonly #opResults = new BoundedResultMap<KernelOpCommitResult>();
201
- readonly #stepResults = new BoundedResultMap<number>();
202
- readonly #writeResults = new BoundedResultMap<unknown>();
203
- readonly messageAuthorityAvailable: boolean;
204
-
205
- constructor(
206
- readonly db: Database,
207
- readonly clock: Clock,
208
- readonly messageAuthority: MessageAuthorityStore | undefined,
209
- /** `null`: a borrowed connection whose owner sets busy_timeout (see WorkflowJournalOptions). */
210
- busyTimeoutMs?: number | null,
211
- bootstrap = true,
212
- readonly leaseOwnerProbe?: WorkflowLeaseOwnerProbe,
213
- ) {
214
- db.run("PRAGMA foreign_keys = ON");
215
- const foreignKeys = db.query("PRAGMA foreign_keys").get() as { foreign_keys: number } | undefined;
216
- if (foreignKeys?.foreign_keys !== 1) throw new Error("kernel SQLite compatibility adapter requires foreign keys to be enabled");
217
- if (bootstrap) ensureEventLogSchema(db);
218
- if (bootstrap) db.run(`CREATE TABLE IF NOT EXISTS ${DEDUP_TABLE} (
219
- operation TEXT NOT NULL,
220
- request_key TEXT NOT NULL,
221
- result TEXT NOT NULL,
222
- PRIMARY KEY (operation, request_key)
223
- )`);
224
- this.#journal = new WorkflowJournalPersistence({ db, clock, installSchema: bootstrap, ...(busyTimeoutMs !== undefined ? { busyTimeoutMs } : {}) });
225
- this.messageAuthorityAvailable = messageAuthority !== undefined;
226
- }
227
-
228
- installModule(catalog: KernelModuleCatalog): Promise<void> {
229
- this.installModuleSync(catalog);
230
- return Promise.resolve();
231
- }
232
-
233
- installModuleSync(catalog: KernelModuleCatalog): void {
234
- const install = () => {
235
- for (const entity of catalog.entities) installEntity(this.db, entity);
236
- };
237
- if (this.db.inTransaction) install();
238
- else this.db.transaction(install).immediate();
239
- }
240
-
241
- moduleTableExistsSync(tableName: string): boolean {
242
- return this.db.query("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(tableName) != null;
243
- }
244
-
245
- entityPointSync(input: KernelEntityPointRead): KernelEntityStoredRow | undefined {
246
- const row = this.db.query(`SELECT ${columns(input.entity)}, version, created_at, updated_at FROM ${quoteIdentifier(input.entity.tableName)}
247
- WHERE scope = ? AND ${quoteIdentifier(input.entity.key)} = ?`).get(input.scope, input.key) as Record<string, unknown> | null;
248
- return storedRow(input.entity, row);
249
- }
250
-
251
- entityListSync(input: KernelEntityListRead): readonly KernelEntityStoredRow[] {
252
- const clauses = ["scope = ?"];
253
- const bindings: KernelStoredValue[] = [input.scope];
254
- for (const [name, value] of Object.entries(input.where)) {
255
- clauses.push(value === null ? `${quoteIdentifier(name)} IS NULL` : `${quoteIdentifier(name)} = ?`);
256
- if (value !== null) bindings.push(value);
257
- }
258
- if (input.after !== undefined) { clauses.push(`${quoteIdentifier(input.entity.key)} > ?`); bindings.push(input.after); }
259
- const rows = this.db.query(`SELECT ${columns(input.entity)}, version, created_at, updated_at FROM ${quoteIdentifier(input.entity.tableName)}
260
- WHERE ${clauses.join(" AND ")} ORDER BY ${quoteIdentifier(input.entity.key)} ASC LIMIT ?`)
261
- .all(...bindings, input.limit) as Array<Record<string, unknown>>;
262
- return rows.map((row) => storedRow(input.entity, row)!);
263
- }
264
-
265
- replayEventsSync(scope: Scope, since: number, limit: number, moduleId?: string): EventReplaySlice {
266
- const pageSize = Math.min(Math.max(Math.trunc(limit), 1), 5_000);
267
- const rows = (moduleId === undefined
268
- ? this.db.query(`SELECT scope, seq, module_id, name, payload, created_at FROM ${EVENTS_TABLE} WHERE scope = ? AND seq > ? ORDER BY seq LIMIT ?`).all(scope, since, pageSize)
269
- : this.db.query(`SELECT scope, seq, module_id, name, payload, created_at FROM ${EVENTS_TABLE} WHERE scope = ? AND module_id = ? AND seq > ? ORDER BY seq LIMIT ?`).all(scope, moduleId, since, pageSize)) as Array<Record<string, unknown>>;
270
- const events = rows.map((row) => ({ scope: row.scope as Scope, seq: row.seq as number, moduleId: row.module_id as string, name: row.name as EmittedEvent["name"], payload: JSON.parse(row.payload as string), createdAt: row.created_at as number }));
271
- const lastSeq = events.at(-1)?.seq ?? since;
272
- const more = moduleId === undefined
273
- ? this.eventHighWaterSync(scope) > lastSeq
274
- : this.db.query(`SELECT 1 FROM ${EVENTS_TABLE} WHERE scope = ? AND module_id = ? AND seq > ? LIMIT 1`).get(scope, moduleId, lastSeq) != null;
275
- return { events, lastSeq, truncated: rows.length === pageSize && more };
276
- }
277
-
278
- eventHighWaterSync(scope: Scope): number {
279
- return (this.db.query(`SELECT high_water FROM ${SEQ_TABLE} WHERE scope = ?`).get(scope) as { high_water: number } | undefined)?.high_water ?? 0;
280
- }
281
-
282
- eventHasMatchSync(scope: Scope, topic: string, correlationId?: string): boolean {
283
- let since = 0;
284
- for (;;) {
285
- const page = this.replayEventsSync(scope, since, 5_000);
286
- if (page.events.some((event) => event.name === topic && (correlationId === undefined || (event.payload as { correlationId?: unknown } | null)?.correlationId === correlationId))) return true;
287
- if (!page.truncated) return false;
288
- since = page.lastSeq;
289
- }
290
- }
291
-
292
- getWorkflowInstanceSync(id: string) { return this.#journal.getInstance(id); }
293
- getWorkflowInstanceByIdentitySync(moduleName: string, workflowName: string, idempotencyKey: string) { return this.#journal.getInstanceByIdentity(moduleName, workflowName, idempotencyKey); }
294
- listWorkflowInstancesSync(options?: ListInstancesOptions): WorkflowInstancePage { return this.#journal.listInstances(options); }
295
- listWorkflowStepsSync(instanceId: string): WorkflowStepJournalRow[] { return this.#journal.listSteps(instanceId); }
296
- listResumableWorkflowsSync(moduleName: string, now: number) { return this.#journal.listResumable(moduleName, now); }
297
- listDueWorkflowsSync(moduleName: string, now: number) { return this.#journal.listDueSleepers(moduleName, now); }
298
- listWaitingWorkflowsSync(moduleName: string, now: number) { return this.#journal.listWaiters(moduleName, now); }
299
- snapshotWorkflowResidualSync(moduleName: string, now: number) { return this.#journal.snapshotReconcileResidual(moduleName, now); }
300
- seedWorkflowSync(requestKey: string, seed: WorkflowInstanceSeed, capturedAt: number) {
301
- return this.#cachedWrite(requestKey, "seedWorkflow", () => this.#journal.createInstanceIfAbsent(seed, capturedAt));
302
- }
303
- acquireWorkflowLeaseSync(requestKey: string, params: AcquireLeaseParams) {
304
- return this.#cachedWrite(requestKey, "acquireLease", () => this.#journal.acquireLease(params), params.instanceId);
305
- }
306
- reclaimDeadWorkflowLeasesSync(moduleName: string, now: number): void {
307
- reclaimDeadWorkflowLeases(this.db, moduleName, now, this.leaseOwnerProbe);
308
- }
309
- renewWorkflowLeaseSync(requestKey: string, params: RenewLeaseParams) {
310
- return this.#cachedWrite(requestKey, "renewLease", () => this.#journal.renewLease(params), params.instanceId);
311
- }
312
- releaseWorkflowLeaseSync(requestKey: string, instanceId: string, token: string, now: number) {
313
- try {
314
- return this.#cachedWrite(requestKey, "releaseWorkflowLease", () => this.#journal.releaseLease(instanceId, token, now));
315
- } catch (error) {
316
- if (isSqliteBusy(error)) return false;
317
- throw error;
318
- }
319
- }
320
- controlWorkflowSync(requestKey: string, operation: "cancel" | "pause" | "resume" | "reopen" | "fail", id: string, now: number, failure?: unknown) {
321
- return this.#cachedWrite(requestKey, `controlWorkflow:${operation}`, () => {
322
- if (operation === "cancel") return this.#journal.cancelInstance(id, now);
323
- if (operation === "pause") return this.#journal.pauseInstance(id, now);
324
- if (operation === "resume") return this.#journal.resumeInstance(id, now);
325
- if (operation === "reopen") return this.#journal.reopenInstance(id, now);
326
- return this.#journal.failInstance(id, failure as never, now);
327
- });
328
- }
329
-
330
- opCommitSync(envelope: KernelOpCommitEnvelope): KernelOpCommitResult {
331
- const operation = "opCommit";
332
- const cacheKey = this.#cacheKey(operation, envelope.requestKey);
333
- const prior = this.#knownResult(this.#opResults, operation, envelope.requestKey);
334
- if (prior) return prior;
335
- const faults = opFaults.get(this)?.get(envelope.requestKey);
336
- const result = this.db.transaction(() => {
337
- const durable = this.#durableResult<KernelOpCommitResult>(operation, envelope.requestKey);
338
- if (durable !== undefined) return durable;
339
- const workflowInstanceIds: string[] = [];
340
- applyAuthority(this.db, this.messageAuthority, envelope.messageAuthority);
341
- faults?.afterParticipantBeforeEntities?.();
342
- applyEntities(this.db, envelope.entities, envelope.capturedAt);
343
- faults?.betweenEntitiesAndEvents?.();
344
- appendEvents(this.db, envelope.events);
345
- faults?.afterEventsBeforeWorkflowSeeds?.();
346
- for (const item of envelope.workflowSeeds) workflowInstanceIds[item.resultIndex] = this.#journal.createInstanceIfAbsent(item.seed, envelope.capturedAt).instance.id;
347
- for (const control of envelope.workflowControls ?? []) {
348
- const changed = control.operation === "cancel"
349
- ? this.#journal.cancelInstance(control.instanceId, envelope.capturedAt)
350
- : control.operation === "reopen"
351
- ? this.#journal.reopenInstance(control.instanceId, envelope.capturedAt)
352
- : this.#journal.failInstance(control.instanceId, control.failure ?? { code: "landing_controlled_failure" }, envelope.capturedAt);
353
- if (!changed) {
354
- throw new Error(`workflow control '${control.operation}' refused for instance '${control.instanceId}'`);
355
- }
356
- }
357
- faults?.afterWorkflowSeedsBeforeCommit?.();
358
- const committed = Object.freeze({ workflowInstanceIds: Object.freeze(workflowInstanceIds) });
359
- this.#storeDurableResult(operation, envelope.requestKey, committed);
360
- return committed;
361
- }).immediate();
362
- this.#opResults.set(cacheKey, result);
363
- opFaults.get(this)?.delete(envelope.requestKey);
364
- return result;
365
- }
366
-
367
- stepCommitSync(envelope: KernelStepCommitEnvelope): number {
368
- const faults = stepFaults.get(this)?.get(envelope.requestKey);
369
- const result = this.#commitStep(envelope.requestKey, envelope.lease.instanceId, "stepCommit", faults?.beforeCommit, () => {
370
- this.#journal.fenceLeaseInTransaction(envelope.lease.instanceId, envelope.lease.token, envelope.lease.now);
371
- faults?.afterFenceBeforeParticipant?.();
372
- applyAuthority(this.db, this.messageAuthority, envelope.messageAuthority);
373
- faults?.afterParticipantBeforeEntities?.(); faults?.afterFenceBeforeEntities?.();
374
- applyEntities(this.db, envelope.entities, envelope.capturedAt);
375
- faults?.betweenEntitiesAndEvents?.();
376
- appendEvents(this.db, envelope.events);
377
- faults?.insideTxBeforeJournal?.();
378
- const seq = this.#journal.recordStepInTransaction(envelope.record, envelope.capturedAt);
379
- faults?.afterJournalBeforeCommit?.();
380
- return seq;
381
- });
382
- faults?.afterCommit?.();
383
- return result;
384
- }
385
-
386
- failedStepCommitSync(envelope: KernelJournalOnlyCommitEnvelope): number { return this.#journalCommit(envelope, "failedStepCommit"); }
387
- supersededStepCommitSync(envelope: KernelJournalOnlyCommitEnvelope): number { return this.#journalCommit(envelope, "supersededStepCommit"); }
388
-
389
- async seedWorkflow(requestKey: string, seed: WorkflowInstanceSeed, capturedAt: number) { return this.seedWorkflowSync(requestKey, seed, capturedAt); }
390
- async acquireWorkflowLease(requestKey: string, params: AcquireLeaseParams) { return this.acquireWorkflowLeaseSync(requestKey, params); }
391
- async reclaimDeadWorkflowLeases(moduleName: string, now: number) { this.reclaimDeadWorkflowLeasesSync(moduleName, now); }
392
- async renewWorkflowLease(requestKey: string, params: RenewLeaseParams) { return this.renewWorkflowLeaseSync(requestKey, params); }
393
- async releaseWorkflowLease(requestKey: string, instanceId: string, token: string, now: number) { return this.releaseWorkflowLeaseSync(requestKey, instanceId, token, now); }
394
- async controlWorkflow(requestKey: string, operation: "cancel" | "pause" | "resume" | "reopen" | "fail", id: string, now: number, failure?: unknown) { return this.controlWorkflowSync(requestKey, operation, id, now, failure); }
395
- async opCommit(envelope: KernelOpCommitEnvelope): Promise<KernelOpCommitResult> { return this.opCommitSync(envelope); }
396
- async stepCommit(envelope: KernelStepCommitEnvelope): Promise<number> { return this.stepCommitSync(envelope); }
397
- async failedStepCommit(envelope: KernelJournalOnlyCommitEnvelope): Promise<number> { return this.failedStepCommitSync(envelope); }
398
- async supersededStepCommit(envelope: KernelJournalOnlyCommitEnvelope): Promise<number> { return this.supersededStepCommitSync(envelope); }
399
-
400
- #journalCommit(envelope: KernelJournalOnlyCommitEnvelope, operation: string): number {
401
- const faults = stepFaults.get(this)?.get(envelope.requestKey);
402
- return this.#commitStep(envelope.requestKey, envelope.lease.instanceId, operation, faults?.beforeCommit, () => {
403
- this.#journal.fenceLeaseInTransaction(envelope.lease.instanceId, envelope.lease.token, envelope.lease.now);
404
- faults?.insideTxBeforeJournal?.();
405
- const seq = this.#journal.recordStepInTransaction(envelope.record, envelope.capturedAt);
406
- faults?.afterJournalBeforeCommit?.();
407
- return seq;
408
- });
409
- }
410
-
411
- #commitStep(requestKey: string, instanceId: string, operation: string, beforeWrite: (() => void) | undefined, write: () => number): number {
412
- const cacheKey = this.#cacheKey(operation, requestKey);
413
- const prior = this.#knownResult(this.#stepResults, operation, requestKey);
414
- if (prior !== undefined) return prior;
415
- try {
416
- beforeWrite?.();
417
- const result = this.db.transaction(() => {
418
- const durable = this.#durableResult<number>(operation, requestKey);
419
- if (durable !== undefined) return durable;
420
- const committed = write();
421
- this.#storeDurableResult(operation, requestKey, committed);
422
- return committed;
423
- }).immediate();
424
- this.#stepResults.set(cacheKey, result);
425
- stepFaults.get(this)?.delete(requestKey);
426
- return result;
427
- } catch (error) {
428
- stepFaults.get(this)?.delete(requestKey);
429
- if (isSqliteBusy(error)) throw new WorkflowContendedError(instanceId, operation, { cause: error });
430
- throw error;
431
- }
432
- }
433
-
434
- #cachedWrite<T>(requestKey: string, operation: string, write: () => T, contendedInstanceId?: string): T {
435
- const cacheKey = this.#cacheKey(operation, requestKey);
436
- const prior = this.#knownResult(this.#writeResults as BoundedResultMap<T>, operation, requestKey);
437
- if (prior !== undefined) return prior;
438
- try {
439
- const result = this.db.transaction(() => {
440
- const durable = this.#durableResult<T>(operation, requestKey);
441
- if (durable !== undefined) return durable;
442
- const committed = write();
443
- this.#storeDurableResult(operation, requestKey, committed);
444
- return committed;
445
- }).immediate();
446
- this.#writeResults.set(cacheKey, result);
447
- return result;
448
- } catch (error) {
449
- if (contendedInstanceId !== undefined && isSqliteBusy(error)) {
450
- throw new WorkflowContendedError(contendedInstanceId, operation, { cause: error });
451
- }
452
- throw error;
453
- }
454
- }
455
-
456
- #cacheKey(operation: string, requestKey: string): string {
457
- return `${operation}\0${requestKey}`;
458
- }
459
-
460
- #knownResult<T>(cache: BoundedResultMap<T>, operation: string, requestKey: string): T | undefined {
461
- const cacheKey = this.#cacheKey(operation, requestKey);
462
- const cached = cache.get(cacheKey) as T | undefined;
463
- if (cached !== undefined) return cached;
464
- const durable = this.#durableResult<T>(operation, requestKey);
465
- if (durable !== undefined) cache.set(cacheKey, durable);
466
- return durable;
467
- }
468
-
469
- #durableResult<T>(operation: string, requestKey: string): T | undefined {
470
- const row = this.db.query(`SELECT result FROM ${DEDUP_TABLE} WHERE operation = ? AND request_key = ?`)
471
- .get(operation, requestKey) as { result: string } | undefined;
472
- return row == null ? undefined : JSON.parse(row.result) as T;
473
- }
474
-
475
- #storeDurableResult(operation: string, requestKey: string, result: unknown): void {
476
- if (!this.db.inTransaction) throw new Error("kernel compatibility request result must be stored inside its writer transaction");
477
- this.db.run(`INSERT INTO ${DEDUP_TABLE} (operation, request_key, result) VALUES (?, ?, ?)`, [operation, requestKey, JSON.stringify(result)]);
478
- }
479
-
480
- async moduleTableExists(tableName: string): Promise<boolean> { return this.moduleTableExistsSync(tableName); }
481
- async entityPoint(input: KernelEntityPointRead): Promise<KernelEntityStoredRow | undefined> { return this.entityPointSync(input); }
482
- async entityList(input: KernelEntityListRead): Promise<readonly KernelEntityStoredRow[]> { return this.entityListSync(input); }
483
- async replayEvents(scope: Scope, since: number, limit: number, moduleId?: string): Promise<EventReplaySlice> { return this.replayEventsSync(scope, since, limit, moduleId); }
484
- async eventHighWater(scope: Scope): Promise<number> { return this.eventHighWaterSync(scope); }
485
- async eventHasMatch(scope: Scope, topic: string, correlationId?: string): Promise<boolean> { return this.eventHasMatchSync(scope, topic, correlationId); }
486
- async getWorkflowInstance(id: string) { return this.getWorkflowInstanceSync(id); }
487
- async getWorkflowInstanceByIdentity(moduleName: string, workflowName: string, idempotencyKey: string) { return this.getWorkflowInstanceByIdentitySync(moduleName, workflowName, idempotencyKey); }
488
- async listWorkflowInstances(options?: ListInstancesOptions): Promise<WorkflowInstancePage> { return this.listWorkflowInstancesSync(options); }
489
- async listWorkflowSteps(instanceId: string): Promise<WorkflowStepJournalRow[]> { return this.listWorkflowStepsSync(instanceId); }
490
- async listResumableWorkflows(moduleName: string, now: number) { return this.listResumableWorkflowsSync(moduleName, now); }
491
- async listDueWorkflows(moduleName: string, now: number) { return this.listDueWorkflowsSync(moduleName, now); }
492
- async listWaitingWorkflows(moduleName: string, now: number) { return this.listWaitingWorkflowsSync(moduleName, now); }
493
- async snapshotWorkflowResidual(moduleName: string, now: number) { return this.snapshotWorkflowResidualSync(moduleName, now); }
494
-
495
- /** @internal Compatibility-adapter telemetry used to prove retry caches stay bounded. */
496
- compatibilityDedupEntryCounts(): Readonly<{ op: number; step: number; write: number }> {
497
- return { op: this.#opResults.size, step: this.#stepResults.size, write: this.#writeResults.size };
498
- }
499
- }
@@ -1,87 +0,0 @@
1
- import type { Database } from "bun:sqlite";
2
- import { createRealClock } from "./effects";
3
- import type { EventSession } from "./event-log";
4
- import type { MessageAuthoritySession, MessageAuthorityStore } from "./message-authority";
5
- import { createModuleHost, type ModuleHost, type ModuleHostOptions, type OpCommitFaults } from "./module-host";
6
- import type { EntitySession } from "./persistence";
7
- import { SqliteKernelPersistence } from "./sqlite-kernel-persistence";
8
-
9
- /**
10
- * TEST / CHAOS SUPPORT ONLY (#1910 K3). Compose an in-process {@link SqliteKernelPersistence} with a
11
- * {@link createModuleHost} host against a raw `Database`.
12
- *
13
- * Production code builds hosts on the ASYNC gateway persistence (`createGatewayKernelPersistence`, in
14
- * src/db) — the {@link ModuleHost} itself never holds a `Database`. This helper exists so unit tests
15
- * and kill-9 chaos harnesses can still drive a host directly against a `:memory:`/file handle, now that
16
- * the `createModuleHost({ db })` K0 compatibility branch is gone. The raw handle is confined to the
17
- * `SqliteKernelPersistence` constructed here — the legitimate in-process persistence implementation
18
- * that the src gateway worker ops also use.
19
- *
20
- * The clock is resolved ONCE and shared by both the persistence and the host so their timestamps agree,
21
- * exactly as the removed `{ db }` path did (which built the compat persistence with the host's own
22
- * resolved clock). `messageAuthority`/`busyTimeoutMs` are the SqliteKernelPersistence construction
23
- * params the old branch accepted; every other option is forwarded to the host unchanged (including the
24
- * in-process `opCommitFaults`/`workflowCommitFaults` fault-injection callbacks).
25
- */
26
- export interface SqliteModuleHostOptions extends Omit<ModuleHostOptions, "persistence"> {
27
- readonly db: Database;
28
- /** Stage-0 MESSAGE authority store for the in-process persistence (timers authority tests). */
29
- readonly messageAuthority?: MessageAuthorityStore;
30
- /** SQLite busy timeout for the in-process persistence. */
31
- readonly busyTimeoutMs?: number;
32
- }
33
-
34
- export function createSqliteModuleHost(options: SqliteModuleHostOptions): ModuleHost {
35
- const { db, messageAuthority, busyTimeoutMs, ...hostOptions } = options;
36
- const clock = hostOptions.clock ?? createRealClock();
37
- const persistence = new SqliteKernelPersistence(db, clock, messageAuthority, busyTimeoutMs);
38
- return createModuleHost({ ...hostOptions, clock, persistence });
39
- }
40
-
41
- /**
42
- * TEST / CHAOS SUPPORT ONLY (#1910 K3). Atomically commit an entity session (K4) and an event
43
- * session (K5) into ONE synchronous SQLite transaction against a RAW `Database` handle. Both sessions
44
- * buffer their intent asynchronously and flush synchronously; sealing them and flushing inside a
45
- * single `db.transaction` means a version conflict (or any throw) in either flush rolls BOTH back
46
- * together — entities are never written without their events, and events are never written without
47
- * their entities.
48
- *
49
- * `seedWorkflowsInTx` (T-0 #1409 finding 1) executes any ENLISTED workflow-instance seeds INSIDE
50
- * the same transaction, AFTER both flushes: an op whose entity flush loses its optimistic-version
51
- * CAS therefore rolls its workflow seeds back with everything else — a fence-losing op leaves no
52
- * orphaned instance behind, and an op's instance can only exist alongside the entities it
53
- * committed with.
54
- *
55
- * This lives in the test-only module (NOT the public {@link createModuleHost} barrel) and is NOT
56
- * re-exported from the `@humwick/kernel` root: it takes a raw `Database` and runs a synchronous
57
- * transaction, so exposing it publicly would reintroduce a main-loop SQLite bypass around the async
58
- * {@link import("./kernel-persistence").KernelPersistence} gateway (#1910 K3 review). Production code
59
- * commits through the gateway writer op; only kernel unit tests drive this directly against a
60
- * `:memory:`/file handle to assert the raw atomic-commit semantics the gateway op is built on.
61
- */
62
- export function commitAtomically(
63
- db: Database,
64
- entitySession: EntitySession<unknown>,
65
- eventSession: EventSession<unknown>,
66
- seedWorkflowsInTx?: () => void,
67
- messageAuthoritySession?: MessageAuthoritySession,
68
- faults?: Omit<OpCommitFaults, "beforeCommit" | "afterCommit">,
69
- ): void {
70
- entitySession.seal();
71
- eventSession.seal();
72
- messageAuthoritySession?.seal();
73
- db.transaction(() => {
74
- // Authority first matches the workflow commit order. A later entity/event/seed failure still
75
- // rolls this SQL back because the participant never owns a side transaction.
76
- messageAuthoritySession?.flush();
77
- faults?.afterParticipantBeforeEntities?.();
78
- // Entities first: an optimistic-version conflict here aborts the transaction before any
79
- // event row is inserted, so a rejected mutation emits nothing.
80
- entitySession.flush();
81
- faults?.betweenEntitiesAndEvents?.();
82
- eventSession.flush();
83
- faults?.afterEventsBeforeWorkflowSeeds?.();
84
- seedWorkflowsInTx?.();
85
- faults?.afterWorkflowSeedsBeforeCommit?.();
86
- })();
87
- }