@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,722 +0,0 @@
1
- import type { z } from "zod";
2
- import {
3
- type Clock,
4
- type CommandClient,
5
- type CommandTarget,
6
- type Grant,
7
- type HealthReporter,
8
- type HostCommandDecl,
9
- type HostIdentity,
10
- type HostCommandRun,
11
- type HostCommandStatus,
12
- type Logger,
13
- type JsonValue,
14
- type ModuleCtx,
15
- type ModuleDefinition,
16
- type ModuleManifest,
17
- type Principal,
18
- type ResolvedIdentity,
19
- type Rng,
20
- type Scope,
21
- type SecretsReader,
22
- type TraceContext,
23
- type Transport,
24
- type WaitCondition,
25
- type WorkflowClient,
26
- type WorkflowDecl,
27
- type WorkflowRun,
28
- type WorkflowStartOptions,
29
- OpError,
30
- } from "./contract";
31
- import { type ConfigResolveOptions, resolveConfig } from "./config";
32
- import { createNetTransport, createRealClock, createSilentLogger, createSystemRng } from "./effects";
33
- import { AuthorizationError, isAuthorized, resolveIdentity } from "./identity";
34
- import {
35
- EntityConflictError,
36
- EntityNotFoundError,
37
- } from "./persistence";
38
- import type { ControlModuleDeps } from "./control";
39
- import { createWorkflowRuntime, type PreparedWorkflowStart, type WaitEvaluator, type WorkflowRuntime } from "./workflow-runtime";
40
- import type { WorkflowStepCommitFaults } from "./workflow-step-commit";
41
- import {
42
- beginMessageAuthoritySession,
43
- type MessageAuthoritySession,
44
- } from "./message-authority";
45
- import { AsyncEntityPersistence, type AsyncEntitySession } from "./async-entity-persistence";
46
- import { AsyncEventLogPersistence, type AsyncEventSession } from "./async-event-log";
47
- import type { KernelPersistence } from "./kernel-persistence";
48
- import { recoverIndeterminate } from "./kernel-persistence";
49
- import { armCompatibilityOpFaults } from "./sqlite-kernel-persistence";
50
-
51
- /** The single owning scope on the single-tenant path (§2.0). The kernel injects it; modules
52
- * never see where it came from, and today it is always `local`. */
53
- export const LOCAL_SCOPE = "local";
54
-
55
- type AnyModuleDefinition = ModuleDefinition<ModuleManifest>;
56
-
57
- /** The caller identity for one invocation. The owning scope is kernel-injected (`local`), so
58
- * callers supply only who they are and what they may do. */
59
- export interface InvocationIdentity {
60
- readonly actor: string;
61
- readonly grants: readonly Grant[];
62
- /** Opaque server-resolved creator attributes the TRUSTED host binding attaches from the
63
- * authenticated token (scopes/constraints/kind) so a module can freeze a durable effect's
64
- * create-time identity under the creator's REAL reach (P2-7). Rides this identity — NOT the
65
- * client-facing op input — so a client cannot supply or widen it. See {@link ResolvedIdentity}. */
66
- readonly resolvedIdentity?: ResolvedIdentity;
67
- }
68
-
69
- /** Transport-owned commit identity for one mutation invocation. Supplying this lets an HTTP/MCP
70
- * boundary carry its stable request key all the way to Kernel opCommit; callers cannot influence
71
- * entity versions, only deduplicate an otherwise identical atomic commit. */
72
- export interface InvocationOptions {
73
- readonly requestKey?: string;
74
- }
75
-
76
- /** A capability the K6a in-process host does not yet provide (K6b / workflow-runtime milestones). */
77
- export class KernelNotAvailableError extends Error {
78
- constructor(readonly feature: string) {
79
- super(`kernel feature '${feature}' is not available in the K6a in-process host`);
80
- this.name = "KernelNotAvailableError";
81
- }
82
- }
83
-
84
- /** A module issued `ctx.commands.issue(name, …)` for a command its manifest never declared. Fail
85
- * closed: an undeclared command has no grant/target/idempotency mapping, so it can never dispatch. */
86
- export class UnknownHostCommandError extends Error {
87
- constructor(readonly moduleId: string, readonly commandName: string) {
88
- super(`module '${moduleId}' declares no command '${commandName}'`);
89
- this.name = "UnknownHostCommandError";
90
- }
91
- }
92
-
93
- /**
94
- * The single, resolved shape the kernel hands the src side for ONE `ctx.commands.issue(...)` call.
95
- * The kernel builds it from the module's {@link HostCommandDecl} (the declared `grant`/`timeoutMs`/
96
- * `target`/`whenDegraded` and the computed `idempotencyKey`) plus the issue call-site (`name`/`input`/
97
- * `target`). It is intentionally NARROW — everything the src adapter needs to route the issue through
98
- * `dispatchCommand(...)` and nothing more; the module cannot smuggle extra authority through it.
99
- */
100
- export interface HostCommandIssueRequest {
101
- /** The declaring module's id — namespaces the idempotency key so two modules cannot collide. */
102
- readonly moduleId: string;
103
- /** The declared command name (the key in the manifest's `commands` map). */
104
- readonly commandName: string;
105
- /** The caller's input, ALREADY validated against the decl's `input` schema by the kernel. */
106
- readonly input: unknown;
107
- /** The call-site target host (`ctx.commands.issue`'s third arg). */
108
- readonly target: CommandTarget;
109
- /** The decl's target CLASS — whether the command runs on the host-agent or a runner. */
110
- readonly targetKind: "host-agent" | "runner";
111
- /** The decl's `grant` (e.g. `command:run-command`). The src adapter maps this to — and must never
112
- * widen beyond — the legacy `command:write` + cwd-constrained authz that `dispatchCommand` gates. */
113
- readonly grant: Grant;
114
- /** `decl.idempotencyKey(input)` — the dedup token a re-drive re-presents so a crash before the
115
- * journal memo dispatches onto the SAME orchestrator command instead of double-dispatching. */
116
- readonly idempotencyKey: string;
117
- readonly timeoutMs: number;
118
- readonly whenDegraded: "queue" | "reject";
119
- }
120
-
121
- /**
122
- * The narrow host seam backing `ctx.commands`. The kernel declares it; the SRC side implements it by
123
- * mapping `issue` onto the authz-gated command dispatch (which runs `assertCommandAuthorized` → the
124
- * #968 cwd gate) and `status` onto a command read. The kernel never imports src: it only ever holds
125
- * this interface, so a module can reach the command bus ONLY through the authz-gated adapter.
126
- *
127
- * These command methods are ASYNC (#1910 K2): the src adapter routes both through the async DB gateway
128
- * (`issue` atomically find-or-creates the correlation-keyed command off the loop; `status` reads it via
129
- * the reader pool), so a command-timer firing workflow never touches a raw `Database` on the main loop.
130
- * `ctx.commands` awaits them under the contract's Promise-returning {@link CommandClient}.
131
- */
132
- export interface HostCommandDispatcher {
133
- issue(request: HostCommandIssueRequest): Promise<HostCommandRun>;
134
- status(commandId: string): Promise<HostCommandRun | undefined>;
135
- }
136
-
137
- /** A {@link HostCommandStatus} is TERMINAL once the orchestrator has settled the command — the only
138
- * point a `{kind:"command"}` wait is allowed to fire. `done`/`failed` are the two terminal projections
139
- * the src adapter maps every settled orchestrator status onto (succeeded → done; failed/timed_out/
140
- * rejected/canceled → failed). */
141
- const TERMINAL_HOST_COMMAND_STATUSES: ReadonlySet<HostCommandStatus> = new Set<HostCommandStatus>(["done", "failed"]);
142
-
143
- function isTerminalHostCommandStatus(status: HostCommandStatus): boolean {
144
- return TERMINAL_HOST_COMMAND_STATUSES.has(status);
145
- }
146
-
147
- /** An event-log record matches a `{kind:"event"}` wait's `correlationId` when its payload is an
148
- * object carrying a `correlationId` field equal to it. This is the single, documented convention the
149
- * automations pilot emits under; a wait with no `correlationId` matches on topic alone. */
150
- /** Whether the scoped event log holds ANY event matching a `{kind:"event"}` wait — its `topic` (the
151
- * event name) and, when present, its `correlationId`. Pages through the whole scope so a match late
152
- * in the log is still found; a pure, side-effect-free read the wakeup pass may run more than once. */
153
- /** The effect providers bound into every ModuleCtx. */
154
- export interface HostEffects {
155
- readonly clock: Clock;
156
- readonly rng: Rng;
157
- readonly net: Transport;
158
- readonly log: Logger;
159
- }
160
-
161
- interface ModuleHostBaseOptions {
162
- readonly clock?: Clock;
163
- readonly rng?: Rng;
164
- readonly net?: Transport;
165
- readonly log?: Logger;
166
- /** Executor lease TTL in ms for the workflow runtime; defaults to the runtime's own default. */
167
- readonly leaseTtlMs?: number;
168
- /** The src adapter backing `ctx.commands` — maps a module's `issue`/`status` onto the authz-gated
169
- * `dispatchCommand`/`getCommand` machinery (see {@link HostCommandDispatcher}). Omitted → the
170
- * in-process host has no command bus: `ctx.commands.issue`/`status` reject (fail-closed) and a
171
- * `{kind:"command"}` wait never fires. */
172
- readonly commands?: HostCommandDispatcher;
173
- /** Overrides the wait evaluator the M3 wakeup pass consults ({@link WorkflowRuntime.wakeup}). When
174
- * omitted the host builds the DEFAULT evaluator: a `{kind:"command"}` wait fires once the wired
175
- * {@link HostCommandDispatcher} reports the command terminal, and a `{kind:"event"}` wait fires once
176
- * the kernel event log holds a matching event. Provide this only to fully override that (tests). */
177
- readonly workflowWaitEvaluator?: WaitEvaluator;
178
- /** In-process step-commit fault injection (TEST/CHAOS only). The host arms the returned faults on the
179
- * persistence port under the step's internally-generated request key; it is a no-op for a persistence
180
- * backend that does not read the compatibility fault WeakMap (e.g. the async gateway adapter). */
181
- readonly workflowCommitFaults?: (instanceId: string, stepName: string) => WorkflowStepCommitFaults | undefined;
182
- /** In-process op-commit fault injection (TEST/CHAOS only). Same arming discipline as
183
- * {@link workflowCommitFaults}; a no-op for a non-SqliteKernelPersistence backend. */
184
- readonly opCommitFaults?: (moduleId: string, opName: string) => OpCommitFaults | undefined;
185
- }
186
-
187
- /**
188
- * The kernel host is ALWAYS built on an async {@link KernelPersistence} port (K3, #1910) — no raw
189
- * `Database` is ever handed to the host. Production builds the gateway-backed adapter
190
- * (`createGatewayKernelPersistence`); in-process unit tests and kill-9 chaos harnesses compose a
191
- * `SqliteKernelPersistence` through the `createSqliteModuleHost` test-support helper. The old
192
- * `{ db }` K0 compatibility branch is removed.
193
- */
194
- export interface ModuleHostOptions extends ModuleHostBaseOptions {
195
- readonly persistence: KernelPersistence;
196
- }
197
-
198
- /** The armable faults for ONE op invocation (see {@link ModuleHostOptions.opCommitFaults}). */
199
- export interface OpCommitFaults {
200
- /** Awaited between the handler/output-validation and the atomic commit. A throw aborts the op
201
- * pre-commit (sessions discarded, nothing persisted). */
202
- readonly beforeCommit?: () => void | Promise<void>;
203
- /** Fires in the tx after participant SQL and before the entity flush. */
204
- readonly afterParticipantBeforeEntities?: () => void;
205
- /** Fires in the tx between entity and event flushes. */
206
- readonly betweenEntitiesAndEvents?: () => void;
207
- /** Fires in the tx after event flush and before enlisted workflow seeds. */
208
- readonly afterEventsBeforeWorkflowSeeds?: () => void;
209
- /** Fires after enlisted workflow seed SQL, before COMMIT. */
210
- readonly afterWorkflowSeedsBeforeCommit?: () => void;
211
- /** Fires after the durable COMMIT and before the invocation ACK is returned. */
212
- readonly afterCommit?: () => void;
213
- }
214
-
215
- export interface ModuleRegisterOptions {
216
- readonly config?: ConfigResolveOptions;
217
- }
218
-
219
- interface HostedModule {
220
- readonly module: AnyModuleDefinition;
221
- readonly config: unknown;
222
- }
223
-
224
- function traceFor(rng: Rng): TraceContext {
225
- const build = (traceId: string, spanId: string): TraceContext => ({
226
- traceId,
227
- spanId,
228
- child: () => build(traceId, rng.uuid()),
229
- });
230
- return build(rng.uuid(), rng.uuid());
231
- }
232
-
233
- function errMessage(error: unknown): string {
234
- return error instanceof Error ? error.message : String(error);
235
- }
236
-
237
- /** One `enlist: "op-commit"` workflow start staged during an op handler: its prepared seed executes
238
- * inside the op's atomic commit; `instanceId` records the authoritative id the seed returned so the
239
- * post-commit drive targets the deduped instance, not the provisional stub. */
240
- interface PendingOpWorkflowStart {
241
- readonly prepared: PreparedWorkflowStart;
242
- instanceId?: string;
243
- }
244
-
245
- interface PendingOpWorkflowControl {
246
- readonly operation: "cancel" | "fail" | "reopen";
247
- readonly instanceId: string;
248
- readonly failure?: JsonValue;
249
- }
250
-
251
- function unavailableCommands(): CommandClient<unknown> {
252
- return {
253
- issue: () => Promise.reject(new KernelNotAvailableError("commands")),
254
- status: () => Promise.reject(new KernelNotAvailableError("commands")),
255
- } as unknown as CommandClient<unknown>;
256
- }
257
-
258
- /**
259
- * The real `ctx.commands` bound to one module + the wired {@link HostCommandDispatcher}. `issue`
260
- * looks up the named {@link HostCommandDecl}, validates the input against its schema (a parse failure
261
- * rejects — fail-closed), computes the decl's `idempotencyKey`, and hands the resolved
262
- * {@link HostCommandIssueRequest} to the dispatcher. The dispatcher is the ONLY path to the command
263
- * bus, so every issue routes through its authz gate; an undeclared command name rejects before any
264
- * dispatch. The contract's Promise-returning methods wrap the synchronous dispatcher.
265
- */
266
- function commandClientFor(module: AnyModuleDefinition, dispatcher: HostCommandDispatcher): CommandClient<unknown> {
267
- const decls = (module.commands ?? {}) as Record<string, HostCommandDecl>;
268
- const client = {
269
- issue: async (name: string, input: unknown, target: CommandTarget): Promise<HostCommandRun> => {
270
- const decl = decls[name];
271
- if (!decl) throw new UnknownHostCommandError(module.id, name);
272
- // Validate against the decl schema BEFORE computing the idempotency key or dispatching, so the
273
- // key is derived from a well-formed input and a malformed issue fails closed (never dispatches).
274
- const parsed = decl.input.parse(input) as unknown;
275
- const request: HostCommandIssueRequest = {
276
- moduleId: module.id,
277
- commandName: name,
278
- input: parsed,
279
- target,
280
- targetKind: decl.target,
281
- grant: decl.grant,
282
- idempotencyKey: decl.idempotencyKey(parsed),
283
- timeoutMs: decl.timeoutMs,
284
- whenDegraded: decl.whenDegraded ?? "reject",
285
- };
286
- return dispatcher.issue(request);
287
- },
288
- status: async (id: string): Promise<HostCommandRun | undefined> => dispatcher.status(id),
289
- };
290
- return client as unknown as CommandClient<unknown>;
291
- }
292
-
293
- function unavailableSecrets(): SecretsReader<unknown> {
294
- return { get: () => Promise.reject(new KernelNotAvailableError("secrets")) } as unknown as SecretsReader<unknown>;
295
- }
296
-
297
- /** No-op reporter: the host has nothing to serve health probes to yet, and no capabilities. */
298
- function inertHealth(): HealthReporter {
299
- return { report: () => {}, capability: () => Promise.resolve(false) };
300
- }
301
-
302
- function fieldsFromZodError(error: z.ZodError): Readonly<Record<string, readonly string[]>> {
303
- const fields: Record<string, string[]> = {};
304
- for (const issue of error.issues) {
305
- const key = issue.path.map(String).join(".") || "(root)";
306
- (fields[key] ??= []).push(issue.message);
307
- }
308
- return fields;
309
- }
310
-
311
- /** Translate the primitives' internal failures into the module-visible typed `OpError`. Unknown
312
- * handler errors propagate unchanged (the rollback has already happened by the time we get here). */
313
- function mapInvocationError(error: unknown): unknown {
314
- if (error instanceof OpError) return error;
315
- if (error instanceof AuthorizationError) return new OpError("unauthorized", 403, error.message);
316
- if (error instanceof EntityConflictError) return new OpError("conflict", 409, error.message);
317
- if (error instanceof EntityNotFoundError) return new OpError("not_found", 404, error.message);
318
- return error;
319
- }
320
-
321
- /**
322
- * The K6a in-process serving core. Registers `defineModule` manifests, resolves each one's
323
- * config once (no live-reload), and serves its ops through {@link ModuleHost.invoke}: identity
324
- * resolution with a kernel-injected `local` scope, default-deny authorization, Zod I/O
325
- * validation, and an atomic entity+event commit. Transport derivation (HTTP/MCP/CLI) is K6b.
326
- */
327
- export class ModuleHost {
328
- /**
329
- * This host's OPAQUE identity (#1506) — a JS-PRIVATE, set-once field, deliberately NOT a public
330
- * `readonly` property. A TS `readonly` field is writable at runtime, so it could be REASSIGNED
331
- * (`host.identity = …`) and a module that keyed private state by it would then bind to the replacement:
332
- * that is a second seam. `#identity` cannot be reassigned or shadowed from outside the class, and the
333
- * ctx below is built from it DIRECTLY, so shadowing the public {@link identity} getter can only produce
334
- * an inert binding — never one this host will ever present.
335
- *
336
- * It is frozen and carries nothing; its only meaningful property is REFERENCE identity, so a look-alike
337
- * object is never this host.
338
- */
339
- readonly #identity: HostIdentity = Object.freeze({ hostIdentity: true as const });
340
- readonly #kernelPersistence: KernelPersistence;
341
- readonly #effects: HostEffects;
342
- readonly #persistence: AsyncEntityPersistence;
343
- readonly #eventLog: AsyncEventLogPersistence;
344
- readonly #modules = new Map<string, HostedModule>();
345
- readonly #leaseTtlMs: number | undefined;
346
- readonly #commands: HostCommandDispatcher | undefined;
347
- /** The resolved wait evaluator handed to every runtime: the caller's override if given, else the
348
- * DEFAULT composite built from the command dispatcher (`command` waits) + event log (`event` waits). */
349
- readonly #waitEvaluator: WaitEvaluator;
350
- readonly #workflowCommitFaults: ((instanceId: string, stepName: string) => WorkflowStepCommitFaults | undefined) | undefined;
351
- readonly #opCommitFaults: ((moduleId: string, opName: string) => OpCommitFaults | undefined) | undefined;
352
- /** Per-module schema-install promises from {@link register}; {@link whenReady} awaits them all. */
353
- readonly #registrations: Promise<void>[] = [];
354
-
355
- /** Read-only view of {@link ModuleHost.#identity}, for a module that must bind private state to this
356
- * host (the #1506 admission capability). There is NO setter: the backing field is JS-private, so this
357
- * can be shadowed on an instance but never redirected — anything built from a shadow is inert, because
358
- * every ctx carries the private field's value. */
359
- get identity(): HostIdentity {
360
- return this.#identity;
361
- }
362
-
363
- constructor(options: ModuleHostOptions) {
364
- this.#leaseTtlMs = options.leaseTtlMs;
365
- this.#commands = options.commands;
366
- this.#workflowCommitFaults = options.workflowCommitFaults;
367
- this.#opCommitFaults = options.opCommitFaults;
368
- this.#effects = {
369
- clock: options.clock ?? createRealClock(),
370
- rng: options.rng ?? createSystemRng(),
371
- net: options.net ?? createNetTransport(),
372
- log: options.log ?? createSilentLogger(),
373
- };
374
- // The host holds ONLY the async persistence port — never a raw Database (K3, #1910). In-process
375
- // tests/chaos compose a SqliteKernelPersistence via `createSqliteModuleHost`; production injects the
376
- // gateway-backed adapter.
377
- this.#kernelPersistence = options.persistence;
378
- this.#persistence = new AsyncEntityPersistence(this.#kernelPersistence);
379
- this.#eventLog = new AsyncEventLogPersistence(this.#kernelPersistence);
380
- this.#waitEvaluator = this.#resolveWaitEvaluator(options.workflowWaitEvaluator);
381
- }
382
-
383
- /**
384
- * Build the wait evaluator the M3 wakeup pass consults. An explicit override wins verbatim
385
- * (tests / bespoke hosts). Otherwise the DEFAULT composite resolves the two ratified
386
- * {@link WaitCondition} kinds: a `{kind:"command"}` fires once the wired {@link HostCommandDispatcher}
387
- * reports the command terminal (never fires when no dispatcher is wired — fail-closed), and a
388
- * `{kind:"event"}` fires once the kernel's own event log holds a matching event. Kept
389
- * side-effect-free: the runtime re-invokes it while scanning AND under the acquired lease.
390
- */
391
- #resolveWaitEvaluator(override: WaitEvaluator | undefined): WaitEvaluator {
392
- if (override) return override;
393
- const dispatcher = this.#commands;
394
- const persistence = this.#kernelPersistence;
395
- return async (waitFor: WaitCondition): Promise<boolean> => {
396
- if (waitFor.kind === "command") {
397
- if (!dispatcher) return false;
398
- const run = await dispatcher.status(waitFor.commandId);
399
- return run !== undefined && isTerminalHostCommandStatus(run.status);
400
- }
401
- return persistence.eventHasMatch(LOCAL_SCOPE as unknown as Scope, waitFor.topic, waitFor.correlationId);
402
- };
403
- }
404
-
405
- /** Install a module: derive its tables (K4) and event schemas (K5) and resolve its config. Schema
406
- * installation is async (it routes through the persistence port's writer); {@link invoke} awaits the
407
- * per-module readiness before touching a table, so callers need not await `register`. A caller that
408
- * observes the installed schema OUT OF BAND (not through an op) awaits {@link whenReady} first. */
409
- register<M extends ModuleManifest>(module: ModuleDefinition<M>, options: ModuleRegisterOptions = {}): void {
410
- if (this.#modules.has(module.id)) throw new Error(`module '${module.id}' is already registered with the host`);
411
- this.#registrations.push(this.#persistence.register(module));
412
- this.#eventLog.register(module);
413
- const config = resolveConfig(module.config, options.config ?? {});
414
- this.#modules.set(module.id, { module: module as AnyModuleDefinition, config });
415
- }
416
-
417
- /** Resolve once every registered module's async schema install has committed. Callers that build a
418
- * host and then observe its tables OUT OF BAND (e.g. the control host's cross-module observability,
419
- * or a test asserting the ON-gated schema exists) await this so the sync read cannot race the writer.
420
- * Invocation self-gates on per-module readiness, so the op path does not need this. */
421
- async whenReady(): Promise<void> {
422
- await Promise.all(this.#registrations);
423
- }
424
-
425
- /** The resolved, validated config for a registered module (the value handed to `ctx.config`). */
426
- configFor<M extends ModuleManifest>(module: ModuleDefinition<M>): unknown {
427
- return this.#require(module.id).config;
428
- }
429
-
430
- /**
431
- * The kernel-wide read/control capabilities the `control` module (KAPI-1 Wave 2) closes over.
432
- * A module's `ctx` only ever sees its OWN entities/events, so cross-module observability +
433
- * control cannot ride `ctx`; the control module is built from these injected reader/controller
434
- * interfaces instead (KAPI-0 §6.1 decision 1 — "hang off the host"). Exposes the host's own
435
- * journal/event/entity persistence narrowed to the read + control-primitive surface; the control
436
- * module's ops apply owner-scoping (G-M1) + default-redact (K-C3) on top — these are raw/ungated.
437
- */
438
- kernelControlDeps(): ControlModuleDeps {
439
- const port = this.#kernelPersistence;
440
- const control = (operation: "cancel" | "pause" | "resume" | "reopen", id: string): Promise<boolean> => {
441
- const requestKey = this.#effects.rng.uuid();
442
- const now = this.#effects.clock.now();
443
- return recoverIndeterminate(() => port.controlWorkflow(requestKey, operation, id, now));
444
- };
445
- return {
446
- journal: {
447
- listInstances: (options) => port.listWorkflowInstances(options),
448
- getInstance: (id) => port.getWorkflowInstance(id),
449
- listSteps: (id) => port.listWorkflowSteps(id),
450
- cancelInstance: (id) => control("cancel", id),
451
- pauseInstance: (id) => control("pause", id),
452
- resumeInstance: (id) => control("resume", id),
453
- reopenInstance: (id) => control("reopen", id),
454
- },
455
- events: { replay: (scope, since, limit = 500, moduleId) => port.replayEvents(scope, since, limit, moduleId) },
456
- entities: this.#persistence,
457
- };
458
- }
459
-
460
- #require(moduleId: string): HostedModule {
461
- const hosted = this.#modules.get(moduleId);
462
- if (!hosted) throw new Error(`module '${moduleId}' is not registered with the host`);
463
- return hosted;
464
- }
465
-
466
- /**
467
- * A real {@link WorkflowClient} bound to one module's ctx/db/journal, replacing the K6a
468
- * `unavailableWorkflows` stub. Its `beginStepContext` assembles a fresh `ModuleCtx` + K4/K5
469
- * sessions per step exactly the way {@link ModuleHost.invoke} builds an op's ctx, so a workflow
470
- * step runs with the same principal/scope, config, and effects an op does. Each executed step
471
- * commits its effects + journal memo atomically through M0's `commitStepAttempt`.
472
- */
473
- #buildRuntime<M extends ModuleManifest>(
474
- module: ModuleDefinition<M>,
475
- principal: Principal,
476
- config: unknown,
477
- ): WorkflowRuntime {
478
- return createWorkflowRuntime({
479
- persistence: this.#kernelPersistence,
480
- ready: this.#persistence.ready(module.id),
481
- clock: this.#effects.clock,
482
- rng: this.#effects.rng,
483
- moduleName: module.id,
484
- // Stamp the generic owner column (KAPI-1 / decision 3) from the invoking principal, so a
485
- // `ctx.workflows.start` records who created the instance. A system-driven runtime carries the
486
- // system actor here (accepted creator-invisible divergence for migrated/system starts).
487
- createdBy: principal.actor,
488
- workflows: (module.workflows ?? {}) as Readonly<Record<string, WorkflowDecl>>,
489
- ...(this.#leaseTtlMs !== undefined ? { leaseTtlMs: this.#leaseTtlMs } : {}),
490
- isWaitSatisfied: this.#waitEvaluator,
491
- ...(this.#workflowCommitFaults !== undefined ? { commitFaults: this.#workflowCommitFaults } : {}),
492
- beginStepContext: () => {
493
- const entitySession = this.#persistence.begin(module, principal.scope);
494
- const eventSession = this.#eventLog.begin(module, principal.scope);
495
- const messageAuthoritySession = beginMessageAuthoritySession(this.#kernelPersistence.messageAuthorityAvailable);
496
- const ctx = this.#assembleCtx(module, principal, config, entitySession, eventSession, messageAuthoritySession);
497
- return {
498
- ctx,
499
- entitySession: entitySession as AsyncEntitySession<unknown>,
500
- eventSession: eventSession as AsyncEventSession<unknown>,
501
- messageAuthoritySession,
502
- };
503
- },
504
- });
505
- }
506
-
507
- #workflowClientFor<M extends ModuleManifest>(
508
- module: ModuleDefinition<M>,
509
- principal: Principal,
510
- config: unknown,
511
- ): WorkflowClient<NonNullable<M["workflows"]>> {
512
- return this.#buildRuntime(module, principal, config) as unknown as WorkflowClient<NonNullable<M["workflows"]>>;
513
- }
514
-
515
- /**
516
- * The module's {@link WorkflowClient} for a caller identity, for driving a workflow outside an
517
- * op invocation (e.g. a `run-now` trigger or a test). Scope is kernel-injected (`local`) exactly
518
- * as in {@link ModuleHost.invoke}; the caller supplies only who they are.
519
- */
520
- workflows<M extends ModuleManifest>(module: ModuleDefinition<M>, identity: InvocationIdentity): WorkflowClient<NonNullable<M["workflows"]>> {
521
- const hosted = this.#require(module.id);
522
- const principal = resolveIdentity({ actor: identity.actor, scope: LOCAL_SCOPE, grants: identity.grants, resolvedIdentity: identity.resolvedIdentity });
523
- return this.#workflowClientFor(module as ModuleDefinition<M>, principal, hosted.config);
524
- }
525
-
526
- /**
527
- * A workflow DRIVER handle (the supervisor role): the concrete {@link WorkflowRuntime}, which
528
- * adds the M2 recovery entry points ({@link WorkflowRuntime.resume} / {@link WorkflowRuntime.recover})
529
- * on top of start/status/cancel. A supervisor calls `recover()` on boot and on a tick to reclaim
530
- * instances orphaned by a crashed driver. Each call builds a fresh runtime with its own lease
531
- * owner/token, so two driver handles genuinely contend on the single-writer lease.
532
- */
533
- workflowDriver<M extends ModuleManifest>(module: ModuleDefinition<M>, identity: InvocationIdentity): WorkflowRuntime {
534
- const hosted = this.#require(module.id);
535
- const principal = resolveIdentity({ actor: identity.actor, scope: LOCAL_SCOPE, grants: identity.grants, resolvedIdentity: identity.resolvedIdentity });
536
- return this.#buildRuntime(module as ModuleDefinition<M>, principal, hosted.config);
537
- }
538
-
539
- /**
540
- * The workflow client an OP invocation sees: identical to the raw runtime, except that a start
541
- * carrying `enlist: "op-commit"` is STAGED instead of committed — validated eagerly (so a schema
542
- * failure still throws `invalid_input` from the handler), pushed onto the invocation's pending
543
- * list for {@link commitAtomically} to seed inside the op's transaction, and driven post-commit.
544
- * A start WITHOUT the option keeps the ratified immediate-commit semantics unchanged.
545
- */
546
- #enlistableClient(
547
- runtime: WorkflowRuntime,
548
- pendingStarts: PendingOpWorkflowStart[],
549
- pendingControls: PendingOpWorkflowControl[],
550
- ): WorkflowClient<unknown> {
551
- const client = {
552
- start: async (name: string, input: unknown, options: WorkflowStartOptions): Promise<WorkflowRun> => {
553
- if (options?.enlist !== "op-commit") return runtime.start(name, input, options);
554
- const prepared = await runtime.prepareStart(name, input, options);
555
- pendingStarts.push({ prepared });
556
- return prepared.provisional;
557
- },
558
- status: (id: string) => runtime.status(id),
559
- cancel: async (id: string) => {
560
- pendingControls.push({ operation: "cancel", instanceId: id });
561
- return true;
562
- },
563
- control: async (operation: "cancel" | "fail" | "reopen", instanceId: string, failure?: JsonValue) => {
564
- pendingControls.push({ operation, instanceId, ...(failure !== undefined ? { failure } : {}) });
565
- return true;
566
- },
567
- };
568
- return client as unknown as WorkflowClient<unknown>;
569
- }
570
-
571
- #assembleCtx<M extends ModuleManifest>(
572
- module: ModuleDefinition<M>,
573
- principal: Principal,
574
- config: unknown,
575
- entitySession: AsyncEntitySession<M["entities"]>,
576
- eventSession: AsyncEventSession<NonNullable<M["events"]>>,
577
- messageAuthoritySession: MessageAuthoritySession,
578
- pendingStarts?: PendingOpWorkflowStart[],
579
- pendingControls?: PendingOpWorkflowControl[],
580
- ): ModuleCtx<M> {
581
- // A step/standalone ctx (no pending list) gets the raw runtime, whose `start` fails closed on
582
- // `enlist: "op-commit"` — there is no op commit to join outside an op invocation.
583
- const runtime = this.#buildRuntime(module, principal, config);
584
- const ctx = {
585
- hostIdentity: this.#identity,
586
- principal,
587
- trace: traceFor(this.#effects.rng),
588
- config,
589
- entities: entitySession.entities,
590
- events: eventSession.events,
591
- workflows: pendingStarts
592
- ? this.#enlistableClient(runtime, pendingStarts, pendingControls ?? [])
593
- : (runtime as unknown as WorkflowClient<NonNullable<M["workflows"]>>),
594
- commands: this.#commands ? commandClientFor(module as AnyModuleDefinition, this.#commands) : unavailableCommands(),
595
- messageAuthority: messageAuthoritySession.participant,
596
- health: inertHealth(),
597
- secrets: unavailableSecrets(),
598
- clock: this.#effects.clock,
599
- rng: this.#effects.rng,
600
- net: this.#effects.net,
601
- log: this.#effects.log,
602
- };
603
- return ctx as unknown as ModuleCtx<M>;
604
- }
605
-
606
- /**
607
- * Serve one op in-process. Order is load-bearing: authorize (default-deny) → validate input →
608
- * open sessions → run handler → validate output → atomically commit. A denial, a validation
609
- * failure, a handler throw, or a version conflict all leave the store and event log untouched,
610
- * and surface as a typed {@link OpError} where the kernel owns the failure mode.
611
- */
612
- async invoke<M extends ModuleManifest>(
613
- module: ModuleDefinition<M>,
614
- opName: string,
615
- identity: InvocationIdentity,
616
- rawInput: unknown,
617
- options: InvocationOptions = {},
618
- ): Promise<unknown> {
619
- const hosted = this.#require(module.id);
620
- const op = module.ops?.[opName];
621
- if (!op) throw new OpError("unknown_op", 404, `module '${module.id}' declares no op '${opName}'`);
622
-
623
- // Scope is kernel-injected: the caller supplies identity, never ownership.
624
- const principal = resolveIdentity({ actor: identity.actor, scope: LOCAL_SCOPE, grants: identity.grants, resolvedIdentity: identity.resolvedIdentity });
625
-
626
- // Default-deny: an op is served only if the principal explicitly holds the op's grant.
627
- if (!isAuthorized(principal, { moduleId: module.id, grant: op.grant })) {
628
- throw new OpError(
629
- "unauthorized",
630
- 403,
631
- `actor '${principal.actor}' is not authorized for '${module.id}.${opName}' (requires '${op.grant}')`,
632
- );
633
- }
634
-
635
- const input = op.input.safeParse(rawInput);
636
- if (!input.success) throw new OpError("invalid_input", 400, `input validation failed for '${module.id}.${opName}'`, fieldsFromZodError(input.error));
637
-
638
- await this.#persistence.ready(module.id);
639
-
640
- const entitySession = this.#persistence.begin(module, principal.scope);
641
- const eventSession = this.#eventLog.begin(module, principal.scope);
642
- const messageAuthoritySession = beginMessageAuthoritySession(this.#kernelPersistence.messageAuthorityAvailable);
643
- const pendingStarts: PendingOpWorkflowStart[] = [];
644
- const pendingControls: PendingOpWorkflowControl[] = [];
645
- const ctx = this.#assembleCtx(module, principal, hosted.config, entitySession, eventSession, messageAuthoritySession, pendingStarts, pendingControls);
646
-
647
- let committing = false;
648
- try {
649
- const result = await op.handler(ctx, input.data);
650
- const output = op.output.safeParse(result);
651
- if (!output.success) {
652
- throw new OpError("invalid_output", 500, `output validation failed for '${module.id}.${opName}'`, fieldsFromZodError(output.error));
653
- }
654
- // The T-0 chaos seam: hold a LIVE op exactly between its reads and its flush, so a concurrent
655
- // process can commit first and this op's buffered writes lose their CAS. Test-only; a throw
656
- // here aborts pre-commit (sessions + staged seeds all discarded).
657
- const opFaults = this.#opCommitFaults?.(module.id, opName);
658
- if (opFaults?.beforeCommit) await opFaults.beforeCommit();
659
- committing = true;
660
- entitySession.seal();
661
- eventSession.seal();
662
- messageAuthoritySession.seal();
663
- const capturedAt = this.#effects.clock.now();
664
- const entities = entitySession.mutations();
665
- const events = eventSession.appends(capturedAt);
666
- const messageAuthority = messageAuthoritySession.operations();
667
- // Query/no-op attempts never enter the writer queue and therefore never take SQLite's write lock.
668
- if (entities.length || events.length || messageAuthority.length || pendingStarts.length || pendingControls.length) {
669
- const requestKey = options.requestKey?.trim() || this.#effects.rng.uuid();
670
- if (opFaults) armCompatibilityOpFaults(this.#kernelPersistence, requestKey, opFaults);
671
- const envelope = structuredClone({
672
- requestKey,
673
- capturedAt,
674
- entities,
675
- events,
676
- messageAuthority,
677
- workflowSeeds: pendingStarts.map((pending, resultIndex) => ({ seed: pending.prepared.seed, resultIndex })),
678
- workflowControls: pendingControls.map((pending) => ({
679
- operation: pending.operation,
680
- instanceId: pending.instanceId,
681
- ...(pending.failure !== undefined ? { failure: pending.failure } : {}),
682
- })),
683
- });
684
- const committed = await recoverIndeterminate(() => this.#kernelPersistence.opCommit(envelope));
685
- committed.workflowInstanceIds.forEach((id, index) => {
686
- const pending = pendingStarts[index];
687
- if (pending) pending.instanceId = id;
688
- });
689
- }
690
- opFaults?.afterCommit?.();
691
- // Drive enlisted instances only AFTER their seeds durably committed. A drive failure is a
692
- // runtime concern (the instance is durable and `recover()`/`wakeup()` converge it) — never a
693
- // false op failure: the op's state HAS committed, and throwing here would tell the caller the
694
- // opposite. Per-start isolation mirrors the runtime's drive passes.
695
- for (const pending of pendingStarts) {
696
- if (pending.instanceId === undefined) continue;
697
- try {
698
- await pending.prepared.drive(pending.instanceId);
699
- } catch (error) {
700
- this.#effects.log.warn(`post-commit workflow drive failed for '${module.id}.${opName}'`, {
701
- instanceId: pending.instanceId,
702
- error: errMessage(error),
703
- });
704
- }
705
- }
706
- return output.data;
707
- } catch (error) {
708
- // Only the pre-commit paths leave sessions open; a commit failure already finalized and
709
- // rolled them back inside the transaction, so discarding again would double-finalize.
710
- if (!committing) {
711
- entitySession.discard();
712
- eventSession.discard();
713
- messageAuthoritySession.discard();
714
- }
715
- throw mapInvocationError(error);
716
- }
717
- }
718
- }
719
-
720
- export function createModuleHost(options: ModuleHostOptions): ModuleHost {
721
- return new ModuleHost(options);
722
- }