@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
@@ -16,7 +16,7 @@ import { workflowForBuilderSpawn } from "../services/workflow-auto-start";
16
16
  import { optionalEnum } from "../validation";
17
17
  import { cleanTaskDispatch } from "../db/task-entity";
18
18
  import { DISPATCH_SHAPE_SCHEMA } from "./dispatch-shape-schema";
19
- import { APPROVAL_MODES, AUTO_MERGE_POLICIES, LAUNCH_MODES, REPORT_VERBOSITIES, SPAWN_PROVIDERS, stringValue, VALID_AGENT_LIFECYCLES, VALID_EFFORTS, VALID_WORKSPACE_MODES } from "@humwick/sdk";
19
+ import { APPROVAL_MODES, AUTO_MERGE_POLICIES, LAUNCH_MODES, REPORT_VERBOSITIES, SPAWN_PROVIDERS, stringValue, VALID_AGENT_LIFECYCLES, VALID_WORKSPACE_MODES } from "@humwick/sdk";
20
20
  import type { ProviderEffort } from "@humwick/sdk/provider-catalog";
21
21
  import type { AgentCard, AgentLifecycle, Command, SpawnApprovalMode, SpawnProvider, WorkspaceAutoMergePolicy, WorkspaceLandingPolicy, WorkspaceLandMechanism, WorkspaceMode, WorkspaceRecord } from "../types";
22
22
  import { projectMyAgent, projectSpawnTargets, type MyAgentFullPresentation, type PresentationVerbosity } from "./presentation";
@@ -43,7 +43,7 @@ export const SPAWN_TOOLS: ToolDefinition[] = [
43
43
  env: { type: "object", additionalProperties: { type: "string" }, description: "Vault refs: secret:<name>." },
44
44
  label: { type: "string" },
45
45
  model: { type: "string" },
46
- effort: { enum: VALID_EFFORTS },
46
+ effort: { type: "string" },
47
47
  approvalMode: { enum: APPROVAL_MODES, description: "Use open; read-only blocks reports/tests; guarded waits for prompts." },
48
48
  prompt: { type: "string" },
49
49
  taskId: { oneOf: [{ type: "integer", minimum: 1 }, { type: "string" }], description: "Task id or TNNNN; loads its spec." },
@@ -70,7 +70,7 @@ export const SPAWN_TOOLS: ToolDefinition[] = [
70
70
  hostPinned: { type: "boolean" },
71
71
  landBlocked: { type: "boolean", description: "Permanent ban; for review use a Task hold." },
72
72
  selfEffort: { type: "boolean" },
73
- selfEffortCeiling: { enum: VALID_EFFORTS },
73
+ selfEffortCeiling: { type: "string" },
74
74
  profile: { type: "string" },
75
75
  role: { type: "string", description: "Default-branch project role; mutually exclusive with profile." },
76
76
  tags: { type: "array", items: { type: "string" } },
@@ -229,6 +229,7 @@ export async function relaySpawnAgent(auth: McpAuthContext, args: Record<string,
229
229
  ...(result.taskId !== undefined ? { taskId: result.taskId } : {}),
230
230
  ...(result.task ? { task: result.task } : {}),
231
231
  ...(result.warnings ? { warnings: result.warnings } : {}),
232
+ ...(result.spawnPolicy ? { spawnPolicy: result.spawnPolicy } : {}),
232
233
  ...(result.dispatchDecision ? { dispatchDecision: { target: result.dispatchDecision.target, rationale: result.dispatchDecision.rationale, warnings: result.dispatchDecision.warnings } } : {}),
233
234
  ...(workflow.reason ? { workflow: { started: false, reason: workflow.reason } } : {}),
234
235
  };
@@ -1,7 +1,6 @@
1
1
  import { REPORT_VERBOSITIES } from "@humwick/sdk";
2
2
  import { setAgentReportVerbosity } from "./services/agent-reporting";
3
3
  import { INCLUDED_TOOL_SCOPE_NEEDS } from "./mcp/tool-groups";
4
- import { VALID_EFFORTS } from "@humwick/sdk/provider-catalog";
5
4
  import { cleanEnum, cleanString } from "./validation";
6
5
  import { AgentActionTargetError, dispatchAgentAction, type AgentAction } from "./services/agent-action";
7
6
  import { authContextFromMcp } from "./services/auth-context";
@@ -37,7 +36,7 @@ export const SET_EFFORT_TOOL = {
37
36
  inputSchema: {
38
37
  type: "object",
39
38
  properties: {
40
- effort: { type: "string", enum: VALID_EFFORTS },
39
+ effort: { type: "string" },
41
40
  reason: { type: "string" },
42
41
  requestId: { type: "string" },
43
42
  },
@@ -1,9 +1,10 @@
1
- import { deleteIssueRef, getIssueRef, getIssueRefByExternalKey, issueRefClosedCompleted, issueRefForRefString, listIssueRefs, resolveIssueRefByExternalKey, resolveIssueRefFromString, updateIssueRef, upsertIssueRef } from "./db/issue-refs";
1
+ import { getIssueRef, getIssueRefByExternalKey, issueRefClosedCompleted, issueRefForRefString, listIssueRefs } from "./db/issue-refs";
2
+ import { deleteIssueRefAsync, resolveIssueRefByExternalKeyAsync, resolveIssueRefFromStringAsync, updateIssueRefAsync, upsertIssueRefAsync } from "./db/issue-refs-async";
2
3
  import { McpNotFoundError } from "./mcp-errors";
3
4
  import { cleanEnum, cleanString, optionalEnum } from "./validation";
4
5
  import { ISSUE_REF_CLOSE_REASONS, ISSUE_PROVIDERS, ISSUE_REF_STATUSES, isRecord, type IssueProvider, type IssueRef, type IssueRefCloseReason, type IssueRefStatus } from "./types";
5
6
  import { ValidationError } from "./db";
6
- import { advanceTerminalPlanRefs } from "./services/plan-terminal-refs";
7
+ import { advanceTerminalPlanRefsAsync } from "./services/plan-terminal-refs";
7
8
 
8
9
  export const ISSUE_REF_TOOLS = [
9
10
  {
@@ -126,11 +127,11 @@ function currentRefFor(args: Record<string, unknown>) {
126
127
  return null;
127
128
  }
128
129
 
129
- export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: Record<string, unknown>): Record<string, unknown> {
130
+ export async function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: Record<string, unknown>): Promise<Record<string, unknown>> {
130
131
  if (!isRecord(args)) throw new ValidationError("arguments must be an object");
131
132
  if (name === "relay_issue_ref_upsert") {
132
133
  const before = currentRefFor(args);
133
- const issueRef = upsertIssueRef({
134
+ const issueRef = await upsertIssueRefAsync({
134
135
  provider: providerArg(args.provider),
135
136
  repo: cleanString(args.repo, "repo", { required: true, max: 500 })!,
136
137
  externalKey: cleanString(args.externalKey, "externalKey", { required: true, max: 240 })!,
@@ -141,7 +142,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
141
142
  statusSyncedAt: timestampArg(args.statusSyncedAt),
142
143
  });
143
144
  // #2520 — the cached ref flipped to a completed close: propagate to bound plan nodes.
144
- if (issueRefClosedCompleted(before, issueRef)) advanceTerminalPlanRefs({ issueRefId: issueRef.id, actor: _auth.actor });
145
+ if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id, actor: _auth.actor });
145
146
  return issueRef as unknown as Record<string, unknown>;
146
147
  }
147
148
  if (name === "relay_issue_ref_resolve") {
@@ -153,7 +154,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
153
154
  ? issueRefForRefString(ref, cleanString(args.defaultRepo ?? args.repo, "defaultRepo", { max: 500 }))
154
155
  : currentRefFor(args);
155
156
  const issueRef = (ref
156
- ? resolveIssueRefFromString({
157
+ ? await resolveIssueRefFromStringAsync({
157
158
  ref,
158
159
  defaultRepo: cleanString(args.defaultRepo ?? args.repo, "defaultRepo", { max: 500 }),
159
160
  provider: optionalEnum(args.provider, "provider", ISSUE_PROVIDERS, "github") as IssueProvider,
@@ -162,7 +163,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
162
163
  closeReason: closeReasonArg(args.closeReason),
163
164
  statusSyncedAt: timestampArg(args.statusSyncedAt),
164
165
  })
165
- : resolveIssueRefByExternalKey({
166
+ : await resolveIssueRefByExternalKeyAsync({
166
167
  provider: providerArg(args.provider),
167
168
  repo: cleanString(args.repo, "repo", { required: true, max: 500 })!,
168
169
  externalKey: cleanString(args.externalKey, "externalKey", { required: true, max: 240 })!,
@@ -172,7 +173,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
172
173
  closeReason: closeReasonArg(args.closeReason),
173
174
  statusSyncedAt: timestampArg(args.statusSyncedAt),
174
175
  })) as unknown as IssueRef;
175
- if (issueRefClosedCompleted(before, issueRef)) advanceTerminalPlanRefs({ issueRefId: issueRef.id, actor: _auth.actor });
176
+ if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id, actor: _auth.actor });
176
177
  return issueRef as unknown as Record<string, unknown>;
177
178
  }
178
179
  if (name === "relay_issue_ref_get") {
@@ -192,7 +193,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
192
193
  }
193
194
  if (name === "relay_issue_ref_update") {
194
195
  const before = currentRefFor(args);
195
- const issueRef = updateIssueRef(cleanString(args.id, "id", { required: true, max: 120 })!, {
196
+ const issueRef = await updateIssueRefAsync(cleanString(args.id, "id", { required: true, max: 120 })!, {
196
197
  url: cleanString(args.url, "url", { max: 2000 }),
197
198
  title: cleanString(args.title, "title", { max: 500 }),
198
199
  status: statusArg(args.status),
@@ -201,11 +202,11 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
201
202
  });
202
203
  if (!issueRef) throw new McpNotFoundError("issue ref not found");
203
204
  // #2520 — the cached ref flipped to a completed close: propagate to bound plan nodes.
204
- if (issueRefClosedCompleted(before, issueRef)) advanceTerminalPlanRefs({ issueRefId: issueRef.id, actor: _auth.actor });
205
+ if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id, actor: _auth.actor });
205
206
  return { issueRef };
206
207
  }
207
208
  if (name === "relay_issue_ref_delete") {
208
- const deleted = deleteIssueRef(cleanString(args.id, "id", { required: true, max: 120 })!);
209
+ const deleted = await deleteIssueRefAsync(cleanString(args.id, "id", { required: true, max: 120 })!);
209
210
  if (!deleted) throw new McpNotFoundError("issue ref not found");
210
211
  return { deleted };
211
212
  }
@@ -11,7 +11,7 @@
11
11
 
12
12
  import { ValidationError } from "./db";
13
13
  import { McpNotFoundError } from "./mcp-errors";
14
- import { listMaintenanceJobs } from "./maintenance";
14
+ import { listMaintenanceJobsAsync } from "./maintenance";
15
15
  import { listPauses, pauseJob, resumeJobAsync } from "./maintenance/pauses";
16
16
  import { authContextFromMcp } from "./services/auth-context";
17
17
  import { cleanString } from "./validation";
@@ -72,7 +72,7 @@ export async function relayMaintenanceTool(auth: McpAuthLike, name: string, args
72
72
  }
73
73
 
74
74
  if (name === "relay_maintenance_jobs") {
75
- const jobs = listMaintenanceJobs();
75
+ const jobs = await listMaintenanceJobsAsync();
76
76
  const jobId = cleanString(args.jobId, "jobId", { max: 120 });
77
77
  if (!jobId) return { jobs, count: jobs.length };
78
78
  const job = jobs.find(candidate => candidate.id === jobId);
@@ -3,7 +3,7 @@ import { INCLUDED_TOOL_SCOPE_NEEDS } from "./mcp/tool-groups";
3
3
  import { ValidationError } from "./db";
4
4
  import { callerAgentId } from "./mcp/identity";
5
5
  import { optionalEnum } from "./validation";
6
- import { approveProfileProjectTrust, PROJECT_REVIEW_MODES, PROJECT_TRUST_CAPABILITIES, updateProfileProjectTrust } from "./services/profile-trust";
6
+ import { approveProfileProjectTrust, PROJECT_REVIEW_MODES, PROJECT_TRUST_CAPABILITIES, updateProfileProjectTrustAsync } from "./services/profile-trust";
7
7
  import type { McpAuthContext, ToolDefinition } from "./mcp/types";
8
8
 
9
9
  export const PROFILE_TRUST_TOOL: ToolDefinition = {
@@ -31,17 +31,17 @@ function text(args: Record<string, unknown>, field: string): string {
31
31
  return value.trim();
32
32
  }
33
33
 
34
- export function relayProfileTrust(auth: McpAuthContext, args: Record<string, unknown>): unknown {
34
+ export async function relayProfileTrust(auth: McpAuthContext, args: Record<string, unknown>): Promise<unknown> {
35
35
  const name = text(args, "profile");
36
36
  const by = callerAgentId(auth) ?? auth.actor;
37
37
  if (args.action === "set-review") {
38
38
  const review = optionalEnum(args.review, "review", PROJECT_REVIEW_MODES);
39
39
  if (!review) throw new ValidationError("review is required");
40
- return { trust: updateProfileProjectTrust(name, { review }, by).value.sources?.project?.trust };
40
+ return { trust: (await updateProfileProjectTrustAsync(name, { review }, by)).value.sources?.project?.trust };
41
41
  }
42
42
  const capability = optionalEnum(args.capability, "capability", PROJECT_TRUST_CAPABILITIES);
43
43
  if (!capability) throw new ValidationError("capability is required");
44
- if (args.action === "ack") return { ack: updateProfileProjectTrust(name, { ack: [capability] }, by).value.sources?.project?.[capability]?.ack };
44
+ if (args.action === "ack") return { ack: (await updateProfileProjectTrustAsync(name, { ack: [capability] }, by)).value.sources?.project?.[capability]?.ack };
45
45
  if (args.action === "approve") return { approval: approveProfileProjectTrust({ name, capability, repoKey: text(args, "repoKey"), value: text(args, "value"), by }) };
46
46
  throw new ValidationError("action must be set-review, ack or approve");
47
47
  }
@@ -1,9 +1,9 @@
1
- import { VALID_EFFORTS, isRecord } from "@humwick/sdk";
1
+ import { isRecord } from "@humwick/sdk";
2
2
  import { effectiveProviderEffortLevelsAsync } from "./db";
3
3
 
4
4
  export async function providerCatalogToolInputSchema(name: string, inputSchema: Record<string, unknown>): Promise<Record<string, unknown>> {
5
5
  if (name !== "relay_spawn_agent") return inputSchema;
6
6
  const efforts = await effectiveProviderEffortLevelsAsync();
7
7
  const properties = isRecord(inputSchema.properties) ? inputSchema.properties : {};
8
- return { ...inputSchema, properties: { ...properties, effort: { type: "string", enum: efforts.length ? efforts : VALID_EFFORTS } } };
8
+ return { ...inputSchema, properties: { ...properties, effort: { type: "string", enum: efforts }, selfEffortCeiling: { type: "string", enum: efforts } } };
9
9
  }
@@ -74,7 +74,7 @@ const TASK_ID_PROP = { oneOf: [{ type: "integer", minimum: 1 }, { type: "string"
74
74
  export const TASK_TOOLS = [
75
75
  {
76
76
  name: "relay_task_create",
77
- description: "Create a durable Task. fromIssue digests GitHub title, body, acceptance, labels and references; explicit fields win.",
77
+ description: "Create Task; fromIssue imports GitHub content; explicit fields win.",
78
78
  requiredScopes: ["task:write"],
79
79
  inputSchema: {
80
80
  type: "object",
@@ -84,9 +84,11 @@ export const TASK_TOOLS = [
84
84
  intent: { type: "string" },
85
85
  fromIssue: { type: "string", description: "GitHub URL or owner/repo#number. Fetch once before atomic create." },
86
86
  tags: { type: "array", items: { type: "string" } },
87
+ paths: { type: "array", items: { type: "string" } },
87
88
  complexity: { type: "string", enum: TASK_DISPATCH_COMPLEXITIES },
88
89
  context: { type: "string" },
89
- terminalStage: { type: "string", enum: TASK_TERMINAL_STAGES },
90
+ terminalStage: { enum: TASK_TERMINAL_STAGES },
91
+ onDeploy: { type: "string" },
90
92
  doneWhen: { type: "string" },
91
93
  teamId: { type: "string" },
92
94
  projectId: { type: "string" },
@@ -108,8 +110,8 @@ export const TASK_TOOLS = [
108
110
  },
109
111
  },
110
112
  { name: "relay_task_get", description: "Read a lean Task hydration; verbose:true includes full intent, gates and history projections.", requiredScopes: ["task:read"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, verbose: { type: "boolean" } }, required: ["taskId"], additionalProperties: false } },
111
- { name: "relay_task_list", description: "List your Tasks by default; mine:false lists all. mode:brief is id/label/status; lean is default.", requiredScopes: ["task:read"], inputSchema: { type: "object", properties: { status: { type: "string", enum: DELIVERABLE_STATUS_ENUM }, deliverableStage: { type: "string", enum: TASK_DELIVERABLE_STAGES }, teamId: { type: "string" }, projectId: { type: "string" }, repo: { type: "string" }, mine: { type: "boolean" }, inFlight: { type: "boolean" }, staleOwnerGone: { type: "boolean" }, limit: { type: "integer", minimum: 1, maximum: 500 }, mode: { type: "string", enum: ["brief", "lean", "full"] }, verbose: { type: "boolean" } }, additionalProperties: false } },
112
- { name: "relay_task_update", description: "Update Task intent, steer, criteria or dispatch.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, refreshIssue: { type: "object", description: "Explicit source refresh: {expectedRevision, resolutions?: {title|intent|doneWhen|tags: source|local}}. Conflicts require resolution." }, verbose: { type: "boolean" }, title: { type: "string" }, label: { type: "string" }, intent: { type: "string" }, complexity: { type: "string", enum: TASK_DISPATCH_COMPLEXITIES }, context: { type: "string" }, latestSteer: { type: "string" }, doneWhen: { type: "string" }, terminalStage: { anyOf: [{ type: "string", enum: TASK_TERMINAL_STAGES }, { type: "null" }] }, dispatch: DISPATCH_SHAPE_SCHEMA, teamId: { type: "string" }, projectId: { type: "string" }, repo: { type: "string" } }, required: ["taskId"], additionalProperties: false } },
113
+ { name: "relay_task_list", description: "List your Tasks by default; mine:false lists all. mode:brief is id/label/status; lean is default.", requiredScopes: ["task:read"], inputSchema: { type: "object", properties: { status: { enum: DELIVERABLE_STATUS_ENUM }, deliverableStage: { enum: [...TASK_DELIVERABLE_STAGES, "awaiting-deploy"] }, teamId: { type: "string" }, projectId: { type: "string" }, repo: { type: "string" }, mine: { type: "boolean" }, inFlight: { type: "boolean" }, staleOwnerGone: { type: "boolean" }, limit: { type: "integer", minimum: 1, maximum: 500 }, mode: { type: "string", enum: ["brief", "lean", "full"] }, verbose: { type: "boolean" } }, additionalProperties: false } },
114
+ { name: "relay_task_update", description: "Update Task intent, steer, criteria or dispatch.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, refreshIssue: { type: "object", description: "{expectedRevision, resolutions?: {title|intent|doneWhen|tags: source|local}}." }, verbose: { type: "boolean" }, title: { type: "string" }, label: { type: "string" }, intent: { type: "string" }, complexity: { type: "string", enum: TASK_DISPATCH_COMPLEXITIES }, context: { type: "string" }, latestSteer: { type: "string" }, onDeploy: { type: "string" }, doneWhen: { type: "string" }, terminalStage: { enum: [...TASK_TERMINAL_STAGES, null] }, dispatch: DISPATCH_SHAPE_SCHEMA, teamId: { type: "string" }, projectId: { type: "string" }, repo: { type: "string" }, paths: { type: "array", items: { type: "string" } } }, required: ["taskId"], additionalProperties: false } },
113
115
  { name: "relay_task_set_status", description: "Transition Task execution status. done requires met validation; force requires explicit override authority.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, status: { type: "string", enum: DELIVERABLE_STATUS_ENUM }, force: { type: "boolean" }, blockedBy: { type: "array", items: BLOCKER_SCHEMA }, note: { type: "string" }, verbose: { type: "boolean" } }, required: ["taskId", "status"], additionalProperties: false } },
114
116
  { name: "relay_task_set_stage", description: "Set Task delivery stage/branch/commit; normally maintained by the land/deploy pipeline.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, deliverableStage: { type: "string", enum: TASK_DELIVERABLE_STAGES }, branch: { type: "string" }, commit: COMMIT_SCHEMA }, required: ["taskId", "deliverableStage"], additionalProperties: false } },
115
117
  { name: "relay_task_confirm_carry", description: "Confirm a protected-tip revert's delivered change was carried to current main; clears only carry-pending.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, commit: COMMIT_SCHEMA, branch: { type: "string" }, note: { type: "string" } }, required: ["taskId"], additionalProperties: false } },
@@ -175,6 +177,7 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
175
177
  complexity: optionalEnum(args.complexity, "complexity", TASK_DISPATCH_COMPLEXITIES),
176
178
  context: cleanString(args.context, "context", { max: 1_000_000 }),
177
179
  terminalStage: optionalEnum(args.terminalStage, "terminalStage", TASK_TERMINAL_STAGES),
180
+ onDeploy: cleanString(args.onDeploy, "onDeploy", { max: 500 }),
178
181
  doneWhen: cleanString(args.doneWhen, "doneWhen", { max: 1_000_000 }),
179
182
  teamId: cleanString(args.teamId, "teamId", { max: 200 }),
180
183
  projectId: cleanString(args.projectId, "projectId", { max: 120 }),
@@ -182,6 +185,7 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
182
185
  branch: cleanString(args.branch, "branch", { max: 500 }),
183
186
  dispatch: args.dispatch as TaskDispatch | undefined,
184
187
  tags: args.tags as string[] | undefined,
188
+ paths: args.paths as string[] | undefined,
185
189
  // Alias-tolerant (#2214): a ref passed as `refs`/`issues`/`externalKey`/… used to be dropped
186
190
  // silently, leaving the Task's issues[] empty and its spawn brief without the linked spec.
187
191
  issueRefs: issueRefsFromArgs(args),
@@ -218,7 +222,7 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
218
222
  if (name === "relay_task_list") {
219
223
  const tasks = await listTaskEntitySummariesAsync({
220
224
  status: optionalEnum(args.status, "status", DELIVERABLE_STATUS_ENUM),
221
- deliverableStage: optionalEnum(args.deliverableStage, "deliverableStage", TASK_DELIVERABLE_STAGES),
225
+ deliverableStage: optionalEnum(args.deliverableStage, "deliverableStage", [...TASK_DELIVERABLE_STAGES, "awaiting-deploy"] as const),
222
226
  teamId: cleanString(args.teamId, "teamId", { max: 200 }),
223
227
  projectId: cleanString(args.projectId, "projectId", { max: 120 }),
224
228
  repo: cleanString(args.repo, "repo", { max: 500 }),
@@ -246,12 +250,14 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
246
250
  ...(args.complexity !== undefined ? { complexity: optionalEnum(args.complexity, "complexity", TASK_DISPATCH_COMPLEXITIES) } : {}),
247
251
  ...(args.context !== undefined ? { context: cleanString(args.context, "context", { max: 1_000_000 }) ?? "" } : {}),
248
252
  ...(args.latestSteer !== undefined ? { latestSteer: cleanString(args.latestSteer, "latestSteer", { max: 1_000_000 }) ?? "" } : {}),
253
+ ...(args.onDeploy !== undefined ? { onDeploy: cleanString(args.onDeploy, "onDeploy", { max: 500 }) ?? "" } : {}),
249
254
  ...(args.doneWhen !== undefined ? { doneWhen: cleanString(args.doneWhen, "doneWhen", { max: 1_000_000 }) ?? "" } : {}),
250
255
  ...(args.terminalStage !== undefined ? { terminalStage: args.terminalStage === null ? null : optionalEnum(args.terminalStage, "terminalStage", TASK_TERMINAL_STAGES) } : {}),
251
256
  ...(args.dispatch !== undefined ? { dispatch: args.dispatch as TaskDispatch } : {}),
252
257
  ...(args.teamId !== undefined ? { teamId: cleanString(args.teamId, "teamId", { max: 200 }) ?? "" } : {}),
253
258
  ...(args.projectId !== undefined ? { projectId: cleanString(args.projectId, "projectId", { max: 120 }) ?? "" } : {}),
254
259
  ...(args.repo !== undefined ? { repo: cleanString(args.repo, "repo", { max: 500 }) ?? "" } : {}),
260
+ ...(args.paths !== undefined ? { paths: args.paths as string[] | null } : {}),
255
261
  };
256
262
  const task = await updateTaskEntityAsync(taskIdArg(args.taskId), { ...patch, actor });
257
263
  if (args.verbose === true) return task as unknown as Record<string, unknown>;
@@ -2,7 +2,7 @@ import { INCLUDED_TOOL_SCOPE_NEEDS } from "./mcp/tool-groups";
2
2
  import { APPROVAL_MODES, SPAWN_PROVIDERS, VALID_AGENT_LIFECYCLES, VALID_WORKSPACE_MODES } from "@humwick/sdk";
3
3
  import { McpAuthError } from "./mcp-errors";
4
4
  import { authContextFromMcp } from "./services/auth-context";
5
- import { deleteTeamTemplate, getTeamTemplate, instantiateTeamTemplate, listTeamTemplates, saveTeamTemplate } from "./services/team-templates";
5
+ import { deleteTeamTemplateAsync, getTeamTemplate, instantiateTeamTemplate, listTeamTemplates, saveTeamTemplateAsync } from "./services/team-templates";
6
6
  import { summarizeSpawnCommandForCaller } from "./services/spawn-agent";
7
7
  import { ValidationError } from "./db";
8
8
 
@@ -111,7 +111,7 @@ function slugArg(args: Record<string, unknown>): string {
111
111
  export async function relayTeamTemplateTool(auth: McpAuthLike, name: string, args: Record<string, unknown>): Promise<Record<string, unknown>> {
112
112
  if (name === "relay_team_template_save") {
113
113
  requireScope(auth, "teams:write");
114
- return saveTeamTemplate(args, auth.actor) as unknown as Record<string, unknown>;
114
+ return await saveTeamTemplateAsync(args, auth.actor) as unknown as Record<string, unknown>;
115
115
  }
116
116
  if (name === "relay_team_template_list") return { templates: listTeamTemplates() };
117
117
  if (name === "relay_team_template_get") {
@@ -121,7 +121,7 @@ export async function relayTeamTemplateTool(auth: McpAuthLike, name: string, arg
121
121
  }
122
122
  if (name === "relay_team_template_delete") {
123
123
  requireScope(auth, "teams:write");
124
- return { slug: slugArg(args), deleted: deleteTeamTemplate(slugArg(args), auth.actor) };
124
+ return { slug: slugArg(args), deleted: await deleteTeamTemplateAsync(slugArg(args), auth.actor) };
125
125
  }
126
126
  if (name === "relay_team_spawn_from_template") {
127
127
  requireScope(auth, "teams:write");
@@ -5,7 +5,7 @@ import { McpAuthError } from "./mcp-errors";
5
5
  import { ValidationError } from "./db";
6
6
  import { authContextFromMcp } from "./services/auth-context";
7
7
  import { ServiceAuthError } from "./services/errors";
8
- import { cancelWorkflowRun, getWorkflowRun, resumeWorkflowRun, startWorkflowRun } from "./services/workflow-runs";
8
+ import { cancelWorkflowRun, getWorkflowRun, pauseWorkflowRun, resumeWorkflowRun, startWorkflowRun } from "./services/workflow-runs";
9
9
  import { parseWorkflowPins } from "./services/workflow-pins";
10
10
  import { cleanString, taskIdField } from "./validation";
11
11
 
@@ -48,7 +48,7 @@ export const WORKFLOW_TOOLS = [
48
48
  {
49
49
  name: "relay_workflow_resume",
50
50
  description:
51
- "Resume or answer/escalate a decision.",
51
+ "Resume, pause/unpause, or answer/escalate a decision.",
52
52
  requiredScopes: ["task:write"],
53
53
  inputSchema: {
54
54
  type: "object",
@@ -66,6 +66,7 @@ export const WORKFLOW_TOOLS = [
66
66
  activationId: { type: "string" },
67
67
  step: { type: "string" },
68
68
  note: { type: "string" },
69
+ pause: { type: "boolean" },
69
70
  pins: PINS_PROP,
70
71
  },
71
72
  required: ["runId"],
@@ -112,7 +113,7 @@ type McpAuthLike = Parameters<typeof authContextFromMcp>[0];
112
113
 
113
114
  function mutationReceipt(full: Record<string, unknown>, verbose: unknown): Record<string, unknown> {
114
115
  if (verbose === true) return full;
115
- const fields = ["runId", "taskId", "workflow", "status", "step", "round", "callerAgentId", "budget", "existing", "resumed", "cancelled", "reason", "warnings"];
116
+ const fields = ["runId", "taskId", "workflow", "status", "step", "round", "callerAgentId", "budget", "existing", "resumed", "cancelled", "paused", "reason", "warnings"];
116
117
  return Object.fromEntries(fields.filter(key => full[key] !== undefined).map(key => [key, full[key]]));
117
118
  }
118
119
 
@@ -132,6 +133,12 @@ export async function relayWorkflowTool(auth: McpAuthLike, name: string, args: R
132
133
  if (!runId) throw new ValidationError("runId is required");
133
134
  const step = cleanString(args.step, "step", { max: 64 });
134
135
  const note = cleanString(args.note, "note", { max: 8000 });
136
+ if (args.pause !== undefined) {
137
+ // #3757 — pause (note is the required reason) or unpause; nothing else rides along.
138
+ if (typeof args.pause !== "boolean") throw new ValidationError("pause must be a boolean");
139
+ if (step || args.pins !== undefined || args.decision !== undefined || args.activationId !== undefined) throw new ValidationError("pause takes only runId and, to pause, note as the reason");
140
+ return mutationReceipt(await pauseWorkflowRun({ runId, pause: args.pause, ...(note ? { reason: note } : {}) }, ctx), args.verbose);
141
+ }
135
142
  const pins = parseWorkflowPins(args.pins);
136
143
  return mutationReceipt(await resumeWorkflowRun({ runId, decision: parseWorkflowDecisionResponse(args.decision), activationId: cleanString(args.activationId, "activationId", { max: 2000 }), ...(step ? { step } : {}), ...(note ? { note } : {}), ...(pins ? { pins } : {}) }, ctx), args.verbose);
137
144
  }
@@ -97,7 +97,8 @@ export type NotificationType =
97
97
  | "ci.config_mismatch"
98
98
  | "ci.root_missing"
99
99
  // #1645 — a critical maintenance job is not running (disabled, held indefinitely, a lapsed pause
100
- // nobody resumed, or simply silent past several of its own intervals).
100
+ // nobody resumed, or simply silent past several of its own intervals). Also carries host disk
101
+ // alerts (#3762) — a new type would grow three MCP tool schemas past their pinned budgets.
101
102
  | "maintenance.degraded";
102
103
 
103
104
  /**
@@ -1,4 +1,5 @@
1
1
  import { createActivityEventWithResult } from "./db";
2
+ import { createActivityEventByClientIdAsync } from "./db/activity-async";
2
3
  import { emitRelayEvent } from "./events";
3
4
 
4
5
  export interface OperatorAlarmInput {
@@ -20,22 +21,36 @@ export interface OperatorAlarmInput {
20
21
  // done. This raises a distinct `operator.alarm` relay event (dashboard banner) plus a
21
22
  // persisted `operator`-kind activity event, so a relay with no reachable escalation target
22
23
  // is observable instead of looping forever in the dark.
23
- export function raiseOperatorAlarm(input: OperatorAlarmInput): boolean {
24
- const { created } = createActivityEventWithResult({
25
- clientId: input.clientId,
26
- kind: "operator",
27
- title: input.subject,
28
- body: input.detail,
29
- icon: "ti-alert-octagon",
30
- view: input.view ?? "orchestrators",
31
- metadata: { source: input.source, operatorAlarm: true, ...(input.metadata ?? {}) },
32
- });
33
- if (input.dedupeEvent && !created) return false;
24
+ const alarmEvent = (input: OperatorAlarmInput) => ({
25
+ clientId: input.clientId,
26
+ kind: "operator" as const,
27
+ title: input.subject,
28
+ body: input.detail,
29
+ icon: "ti-alert-octagon",
30
+ view: input.view ?? "orchestrators",
31
+ metadata: { source: input.source, operatorAlarm: true, ...(input.metadata ?? {}) },
32
+ });
33
+
34
+ function emitAlarm(input: OperatorAlarmInput): void {
34
35
  emitRelayEvent({
35
36
  type: "operator.alarm",
36
37
  source: input.source,
37
38
  subject: input.subject,
38
39
  data: { subject: input.subject, detail: input.detail, ...(input.metadata ?? {}) },
39
40
  });
41
+ }
42
+
43
+ export function raiseOperatorAlarm(input: OperatorAlarmInput): boolean {
44
+ const { created } = createActivityEventWithResult(alarmEvent(input));
45
+ if (input.dedupeEvent && !created) return false;
46
+ emitAlarm(input);
47
+ return true;
48
+ }
49
+
50
+ /** Same as `raiseOperatorAlarm`, with the activity row written on the writer thread. */
51
+ export async function raiseOperatorAlarmAsync(input: OperatorAlarmInput): Promise<boolean> {
52
+ const { created } = await createActivityEventByClientIdAsync(alarmEvent(input));
53
+ if (input.dedupeEvent && !created) return false;
54
+ emitAlarm(input);
40
55
  return true;
41
56
  }
@@ -2,6 +2,7 @@ import { composeMemoryPreambleAsync } from "./memory-preamble-async";
2
2
  import { composeHostAwareness } from "./host-awareness";
3
3
  import { composeGuideIndex } from "./guides";
4
4
  import { profileInstructionBlocks } from "./profile-instruction-blocks";
5
+ import { projectProfileInstructionBlock } from "./project-profile-instructions";
5
6
  // Spawn-time instruction sources (#557) — the relay-owned composer that assembles what a spawned
6
7
  // agent's systemPromptAppend says, from declared sources only, never from host CLAUDE.md.
7
8
  //
@@ -283,6 +284,7 @@ export function composeSpawnInstructionsWithEvents(input: {
283
284
  * host → project`, audience-filtered by `profile`). Absent → no memory block at all, so a
284
285
  * caller that does not know the identity produces a byte-identical pre-#1565 spawn. */
285
286
  memoryIdentity?: MemoryIdentity;
287
+ projectId?: string;
286
288
  profile?: Pick<AgentProfile, "instructions" | "maxSpawnedAgents" | "hostAwareness" | "roleAssets"> & { name?: string; relay?: AgentProfile["relay"] };
287
289
  spawnedBy?: string;
288
290
  /** #3045 — a workflow step agent: its step reporting block replaces the spawned-child report-up. */
@@ -475,6 +477,8 @@ export function composeSpawnInstructionsWithEvents(input: {
475
477
  const { system: profileSystem, append: profileAppend } = profileInstructionBlocks(input.profile, input.memoryIdentity?.provider);
476
478
  if (profileSystem) appendBlocks.push(profileSystem);
477
479
  appendBlocks.push(...profileAppend);
480
+ const projectProfile = projectProfileInstructionBlock(input.projectId ?? input.memoryIdentity?.projectId, input.profile?.name ?? input.memoryIdentity?.profile);
481
+ if (projectProfile) { appendBlocks.push(projectProfile.content); relayInjectionEvents.push(projectProfile.event); }
478
482
  // After the profile, so the step rule is the last word over a charter's report-to-spawner text.
479
483
  if (input.workflowRunId) {
480
484
  const instruction = renderTemplate("spawn.reportup.workflow-step", { runId: input.workflowRunId });
@@ -0,0 +1,6 @@
1
+ import { assertNoControlBytes, ValidationError } from "@humwick/sdk";
2
+
3
+ export function validateProjectProfileInstructionText(value: unknown, source: string): asserts value is string {
4
+ if (typeof value !== "string" || value.length > 16_000) throw new ValidationError(`${source} must be a string up to 16000 characters`);
5
+ assertNoControlBytes(value, source);
6
+ }
@@ -0,0 +1,20 @@
1
+ import { errMessage } from "@humwick/sdk";
2
+ import { getProjectProfileInstructions } from "./db/project-profile-instructions";
3
+ import { validateProjectProfileInstructionText } from "./project-profile-instruction-text";
4
+
5
+ /** #3515 — one optional block at the charter seam, independent of project memory's switch. */
6
+ export function projectProfileInstructionBlock(projectId: string | undefined, profile: string | undefined) {
7
+ if (!projectId || !profile) return;
8
+ const source = `project ${projectId} profile ${profile} instructions`;
9
+ try {
10
+ const entry = getProjectProfileInstructions({ projectId, profile });
11
+ validateProjectProfileInstructionText(entry.template, source);
12
+ const content = entry.template.trim();
13
+ if (!content) return;
14
+ return { content, event: { category: "instructions" as const,
15
+ summary: `injected ${source} v${entry.version}`,
16
+ detail: { source: "project-profile-instructions", projectId, profile, version: entry.version, content } } };
17
+ } catch (error) {
18
+ console.warn(`[launch] skipped ${source}: ${errMessage(error)}`);
19
+ }
20
+ }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  deriveProviderDisabledState,
3
3
  disabledProviderSet,
4
- providerCatalogList,
4
+ providerMetadataList,
5
5
  type ProviderCatalogEntry,
6
6
  type ProviderContextThreshold,
7
7
  type ProviderEnablementSetting,
@@ -44,7 +44,7 @@ export interface ProviderModelOverrideInput {
44
44
 
45
45
  function listProviderModelOverrides(): ProviderModelOverride[] {
46
46
  const rows = getDb()
47
- .query("SELECT * FROM provider_model_overrides ORDER BY provider ASC, alias ASC")
47
+ .query("SELECT * FROM provider_model_overrides ORDER BY provider ASC, rowid ASC")
48
48
  .all() as ProviderModelOverrideRow[];
49
49
  return rows.map(rowToOverride).filter((entry): entry is ProviderModelOverride => Boolean(entry));
50
50
  }
@@ -120,7 +120,7 @@ export function setProviderDefaultModel(provider: SpawnProvider, alias: string,
120
120
  }
121
121
 
122
122
  export function effectiveProviderCatalogList(now = Date.now()): ProviderCatalogEntry[] {
123
- const catalog = mergeProviderCatalog(providerCatalogList(), listProviderModelOverrides());
123
+ const catalog = mergeProviderCatalog(providerMetadataList(), listProviderModelOverrides());
124
124
  const defaults = getDb().query("SELECT provider, alias FROM provider_model_defaults").all() as Array<{ provider: string; alias: string }>;
125
125
  for (const { provider, alias } of defaults) {
126
126
  const entry = catalog.find((item) => item.provider === provider);
@@ -215,9 +215,6 @@ function normalizeOverrideInput(input: ProviderModelOverrideInput): ProviderMode
215
215
  if (limits) entry.limits = limits;
216
216
  else delete entry.limits;
217
217
  delete entry.disabled;
218
- // #368 — unavailable is a static catalog fact (provider-side suspension), not an operator toggle;
219
- // strip it from DB overrides so an admin can't accidentally clear a catalog-level suspension.
220
- delete entry.unavailable;
221
218
  // #2598 — `deleted` is a row-level tombstone column, never part of a stored entry blob.
222
219
  delete (entry as unknown as Record<string, unknown>).deleted;
223
220
  return {
@@ -288,49 +285,6 @@ function allowlistedLimitConfidence(value: unknown): ProviderModelLimitWindow["c
288
285
  : "declared";
289
286
  }
290
287
 
291
- /**
292
- * #2598 — additive, idempotent backfill of every static-catalog model into `provider_model_overrides`,
293
- * so the whole catalogue is uniformly DB-backed and operator-editable. Rules:
294
- * - INSERT-ONLY-IF-ABSENT (`ON CONFLICT DO NOTHING`): an existing row — a prior seed OR an operator
295
- * edit OR an operator delete-tombstone — is never touched, so operator edits ALWAYS win and a
296
- * deleted static model is never resurrected. Re-runnable; a re-run inserts only genuinely NEW
297
- * static models (e.g. added by a later release).
298
- * - SKIP disabled/unavailable static models: materializing them would strip those flags at the
299
- * write chokepoint (#368/#643) and resurrect a suspended model as spawnable. They stay
300
- * static-only until an operator explicitly adds them.
301
- * Stamped `updated_by = <stamp>` (e.g. `seed:<version>`) purely for provenance; precedence is decided
302
- * by row EXISTENCE, not by parsing the stamp.
303
- */
304
- export function seedProviderModelOverrides(stamp: string, now = Date.now()): { inserted: number } {
305
- const db = getDb();
306
- const existing = new Map<string, Set<string>>();
307
- for (const row of db.query("SELECT provider, alias FROM provider_model_overrides").all() as Array<{ provider: string; alias: string }>) {
308
- let aliases = existing.get(row.provider);
309
- if (!aliases) existing.set(row.provider, (aliases = new Set()));
310
- aliases.add(row.alias);
311
- }
312
- let inserted = 0;
313
- const insert = db.query(`
314
- INSERT INTO provider_model_overrides (provider, alias, entry, deleted, disabled, updated_at, updated_by)
315
- VALUES (?, ?, ?, 0, 0, ?, ?)
316
- ON CONFLICT(provider, alias) DO NOTHING
317
- `);
318
- const seed = db.transaction(() => {
319
- for (const providerEntry of providerCatalogList()) {
320
- const seen = existing.get(providerEntry.provider);
321
- for (const model of providerEntry.models) {
322
- if (model.disabled || model.unavailable) continue;
323
- if (seen?.has(model.alias)) continue;
324
- const normalized = normalizeOverrideInput({ provider: providerEntry.provider, alias: model.alias, entry: model, updatedBy: stamp });
325
- const result = insert.run(normalized.provider, normalized.alias, JSON.stringify(normalized.entry), now, normalized.updatedBy ?? null);
326
- if (result.changes > 0) inserted++;
327
- }
328
- }
329
- });
330
- seed();
331
- return { inserted };
332
- }
333
-
334
288
  function rowToOverride(row: ProviderModelOverrideRow): ProviderModelOverride | undefined {
335
289
  const parsed = parseJson<ProviderModelCatalogEntry | undefined>(row.entry, undefined);
336
290
  if (!parsed || typeof parsed.alias !== "string") return undefined;