@humwick/server 0.130.1 → 0.130.3

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 (811) hide show
  1. package/README.md +5 -0
  2. package/bundled/prompts/manifest.json +1 -0
  3. package/bundled/prompts/task.hydration.md +1 -1
  4. package/bundled/roles/builder.md +1 -1
  5. package/docs/guides/sub-coordinators.md +12 -5
  6. package/docs/guides/tools-administration.md +4 -0
  7. package/docs/guides/tools-coordination.md +2 -0
  8. package/docs/guides/tools-tasks.md +8 -0
  9. package/docs/guides/workflows.md +74 -0
  10. package/docs/openapi.json +486 -4
  11. package/package.json +10 -18
  12. package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-Bq9kr21N.js} +2 -2
  13. package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-Dqiroy06.js} +2 -2
  14. package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-DYU962-H.js} +2 -2
  15. package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-DhPfzioE.js} +2 -2
  16. package/public/assets/{activity-yLztXEBt.js → activity-DzCcQTee.js} +2 -2
  17. package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-SgDt9i3T.js} +2 -2
  18. package/public/assets/agent-liveness-Bq-s73jW.js +2 -0
  19. package/public/assets/{agent-name-CTZBrSD9.js → agent-name-CcY3Aijy.js} +2 -2
  20. package/public/assets/agent-profiles-cxtRBn6O.js +2 -0
  21. package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-DGYbIhaI.js} +2 -2
  22. package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-DHbftV0N.js} +2 -2
  23. package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-CY113sp-.js} +2 -2
  24. package/public/assets/{agents-BYDslkJc.js → agents-BPzY7IlQ.js} +2 -2
  25. package/public/assets/{analytics-B-XSbEMC.js → analytics-DENFPv_a.js} +2 -2
  26. package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-KRvSc7sl.js} +2 -2
  27. package/public/assets/{artifacts-DPN1q4pA.js → artifacts-C9gSmL3s.js} +2 -2
  28. package/public/assets/{artifacts-oBOqks-2.js → artifacts-DT-HkI5O.js} +2 -2
  29. package/public/assets/{automation-4KcRFXEu.js → automation-BsmjQhKD.js} +2 -2
  30. package/public/assets/{backlog-Cw9xPTCF.js → backlog-8NYH_62t.js} +2 -2
  31. package/public/assets/{busy-health-CTu32MZt.js → busy-health-D3hwvYb4.js} +2 -2
  32. package/public/assets/{channels-BiXzg1G9.js → channels-DCJ5WL7O.js} +2 -2
  33. package/public/assets/{chat-Ctk2qwvA.js → chat-DAIl357U.js} +3 -3
  34. package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-CzrZfr9U.js} +2 -2
  35. package/public/assets/{connectors-C36ax4Vw.js → connectors-xTxtlyou.js} +2 -2
  36. package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BpebFLK2.js} +2 -2
  37. package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-BHvI5wXC.js} +2 -2
  38. package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-DGT0o3wJ.js} +2 -2
  39. package/public/assets/{deploys-Bwfq146q.js → deploys-hqWOHSHE.js} +2 -2
  40. package/public/assets/{display-CfO7rTuF.js → display-CDeH4I8T.js} +2 -2
  41. package/public/assets/{files-DhhZI2Ih.js → files-BTeGVmTg.js} +2 -2
  42. package/public/assets/{fleet-B_rFEbnL.js → fleet-DgXtNgCa.js} +2 -2
  43. package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BHEt5yc_.js} +2 -2
  44. package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-MLtodyPp.js} +3 -3
  45. package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-CAe664Z8.js} +2 -2
  46. package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-mapF4Fj9.js} +2 -2
  47. package/public/assets/index-CqqgOI5R.js +15 -0
  48. package/public/assets/index-MYAIwYTX.css +2 -0
  49. package/public/assets/{insights-fH1EL-qZ.js → insights-DNyf7IzF.js} +2 -2
  50. package/public/assets/{integrations-C5Oix6ng.js → integrations-DlYOHq7T.js} +2 -2
  51. package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-CeWBNWn7.js} +2 -2
  52. package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-Cib8nqdE.js} +2 -2
  53. package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-DSn1cPm7.js} +2 -2
  54. package/public/assets/{managed-agents-egllbpij.js → managed-agents-C3CkM81m.js} +2 -2
  55. package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-W4VQQPAv.js} +3 -3
  56. package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-CMsTdhjq.js} +2 -2
  57. package/public/assets/{memory-C8WmXsyr.js → memory-BV17qtO4.js} +2 -2
  58. package/public/assets/{messages-BzQdqlO6.js → messages-Bm_1AqSA.js} +2 -2
  59. package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Dg-vfP09.js} +2 -2
  60. package/public/assets/{overview-DCUnI4Z7.js → overview-DcYCrvlr.js} +2 -2
  61. package/public/assets/{pairs-ftCd2XcD.js → pairs-8o9nuG3V.js} +2 -2
  62. package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-BsRyBMea.js} +2 -2
  63. package/public/assets/project-profile-instructions-DETKFn_E.js +2 -0
  64. package/public/assets/projects-M_m6AHws.js +2 -0
  65. package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-C_mNCgeL.js} +2 -2
  66. package/public/assets/provider-display-BEeLXC_D.js +2 -0
  67. package/public/assets/{registry-DWCU5c8q.js → registry-DDHHHE5N.js} +2 -2
  68. package/public/assets/run-card-Dt4I4jaP.js +2 -0
  69. package/public/assets/scroll-text-BKXS1ahr.js +2 -0
  70. package/public/assets/{secrets-C7GIUATz.js → secrets-BkVwxI5O.js} +2 -2
  71. package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-Crq-6a-B.js} +2 -2
  72. package/public/assets/{settings-C6sZ9eBa.js → settings-CYcavMFu.js} +2 -2
  73. package/public/assets/shipping-H6gzEeZB.js +2 -0
  74. package/public/assets/{stats-V9Z-GxUd.js → stats-BJVeWkpV.js} +2 -2
  75. package/public/assets/{status-dot-CVv0iGHL.js → status-dot-BcHyw1Vw.js} +2 -2
  76. package/public/assets/store-DKPDIZBe.js +9 -0
  77. package/public/assets/{tasks-CXU75HRF.js → tasks-qJjlQPpx.js} +2 -2
  78. package/public/assets/{teams-BPf976zb.js → teams-Cd5Sk1uX.js} +2 -2
  79. package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-CpY5_m7W.js} +3 -3
  80. package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-DI_2llFR.js} +2 -2
  81. package/public/assets/token-estimate-Co-Jdphh.js +2 -0
  82. package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-0yJA_buM.js} +2 -2
  83. package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-uJXHf34W.js} +2 -2
  84. package/public/assets/use-project-list-CpWl6eHQ.js +2 -0
  85. package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BdxBW8mL.js} +2 -2
  86. package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-3IndfpOc.js} +2 -2
  87. package/public/assets/versioned-prompt-editor-CIVg7XB1.js +8 -0
  88. package/public/assets/{work-queue-TCjJxeT-.js → work-queue-B9rnLwHZ.js} +2 -2
  89. package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-X8wxyhzC.js} +2 -2
  90. package/public/assets/{workflows-CXQX20Qj.js → workflows-o5YyMFW7.js} +2 -2
  91. package/public/assets/{workspaces-qSYzKYMA.js → workspaces-CzEGoAng.js} +2 -2
  92. package/public/cosmos.html +4 -4
  93. package/public/index.html +31 -29
  94. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  95. package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
  96. package/runner/src/adapters/claude-effort.ts +2 -4
  97. package/runner/src/adapters/claude-headless.ts +1 -1
  98. package/runner/src/adapters/claude-launch-exit.ts +26 -0
  99. package/runner/src/adapters/claude-session-probe.ts +1 -1
  100. package/runner/src/adapters/claude-tmux.ts +38 -10
  101. package/runner/src/adapters/claude.ts +28 -75
  102. package/runner/src/adapters/codex-launch-config.ts +4 -5
  103. package/runner/src/adapters/codex.ts +1 -1
  104. package/runner/src/adapters/opencode-provider.ts +7 -22
  105. package/runner/src/adapters/opencode.ts +4 -4
  106. package/runner/src/adapters/provider-quota-harvest.ts +20 -71
  107. package/runner/src/agent-runner/credentials.ts +42 -12
  108. package/runner/src/agent-runner/inbox.ts +27 -0
  109. package/runner/src/agent-runner/lifecycle-milestones.ts +2 -4
  110. package/runner/src/agent-runner/liveness-exchange.ts +104 -0
  111. package/runner/src/bin/claude.ts +4 -0
  112. package/runner/src/bin/codex.ts +4 -0
  113. package/runner/src/bin/opencode.ts +4 -0
  114. package/runner/src/claude-system-prompt.ts +49 -0
  115. package/runner/src/index.ts +5 -2
  116. package/runner/src/launch-assembly.ts +14 -10
  117. package/runner/src/profile-home.ts +1 -1
  118. package/runner/src/project-instructions.ts +2 -2
  119. package/runner/src/provider-command.ts +18 -0
  120. package/runner/src/provider-setup.ts +35 -0
  121. package/runner/src/providers.ts +2 -1
  122. package/runner/src/runner-core.ts +32 -38
  123. package/runner/src/runner-helpers.ts +0 -8
  124. package/runner/src/session-scratch.ts +6 -2
  125. package/runner/src/spawn-input.ts +2 -1
  126. package/runner/src/test-run-dedup.ts +59 -56
  127. package/runner/test-support/provisioning-context.ts +4 -2
  128. package/runner/test-support/runner-harness.ts +2 -1
  129. package/scripts/cd-config.ts +8 -0
  130. package/scripts/gate-run-lease.ts +10 -7
  131. package/scripts/gate.sh +5 -1
  132. package/scripts/steward-policy-cleanup.ts +2 -2
  133. package/src/agent-authz.ts +2 -2
  134. package/src/agent-drive-arbiter.ts +3 -8
  135. package/src/agent-exit-cleanup-async.ts +2 -2
  136. package/src/agent-exit-cleanup.ts +23 -19
  137. package/src/agent-lifecycle-events.ts +112 -85
  138. package/src/agent-ref.ts +3 -2
  139. package/src/agent-status-events.ts +43 -14
  140. package/src/auth/password.ts +4 -3
  141. package/src/auth/session-refresh.ts +1 -1
  142. package/src/auth/session.test-fixture.ts +2 -2
  143. package/src/auth/session.ts +7 -7
  144. package/src/automations/crud.ts +8 -81
  145. package/src/automations/dispatch.ts +33 -58
  146. package/src/automations/index.ts +1 -1
  147. package/src/automations/persistence.ts +65 -0
  148. package/src/automations/precheck.ts +18 -16
  149. package/src/automations/read-async.ts +11 -0
  150. package/src/automations/reconcile.ts +30 -39
  151. package/src/automations/storage.ts +33 -10
  152. package/src/automations/write-async.ts +33 -0
  153. package/src/branch-land-notice.ts +93 -0
  154. package/src/branch-landed.ts +31 -98
  155. package/src/bus.ts +40 -39
  156. package/src/cd-deploy-notify.ts +32 -4
  157. package/src/cd-host-lag-notify.ts +7 -6
  158. package/src/ci/incidents.ts +2 -2
  159. package/src/ci/monitor.ts +5 -8
  160. package/src/ci/notifications.ts +4 -4
  161. package/src/ci/root-missing.ts +4 -9
  162. package/src/ci/transition-notify.ts +12 -44
  163. package/src/claude-app/oauth-http.ts +3 -3
  164. package/src/cli/cd-pauses.ts +19 -0
  165. package/src/cli/orchestrator.ts +1 -1
  166. package/src/cli/state.ts +2 -19
  167. package/src/cli/task-edit.ts +22 -0
  168. package/src/cli/task.ts +3 -1
  169. package/src/cli/workflow.ts +19 -4
  170. package/src/commands-db.ts +7 -7
  171. package/src/commands-write.ts +8 -0
  172. package/src/compaction-watch.ts +10 -8
  173. package/src/config-store-write.ts +13 -1
  174. package/src/config-store.ts +25 -14
  175. package/src/config.ts +4 -11
  176. package/src/connectors.ts +10 -8
  177. package/src/context-advisory.ts +22 -21
  178. package/src/db/activity-async.ts +6 -1
  179. package/src/db/activity-write-ops.ts +12 -1
  180. package/src/db/activity.ts +1 -14
  181. package/src/db/agent-action-write.ts +36 -0
  182. package/src/db/agent-control-async.ts +9 -0
  183. package/src/db/agent-control-write.ts +49 -0
  184. package/src/db/agent-effort-observe.ts +22 -0
  185. package/src/db/agent-meta.ts +14 -3
  186. package/src/db/agent-search.ts +1 -15
  187. package/src/db/agents-async.ts +59 -9
  188. package/src/db/agents-write-ops.ts +12 -3
  189. package/src/db/agents.ts +95 -65
  190. package/src/db/auth-identities.ts +2 -2
  191. package/src/db/automation-read-ops.ts +11 -0
  192. package/src/db/automation-write-ops.ts +46 -0
  193. package/src/db/blackboard.ts +2 -2
  194. package/src/db/browser-session-write.ts +32 -0
  195. package/src/db/bus-outbox-write-ops.ts +3 -1
  196. package/src/db/checkout-refresh-schema.ts +47 -0
  197. package/src/db/checkout-refresh.ts +5 -5
  198. package/src/db/ci-incidents-async.ts +5 -5
  199. package/src/db/ci-incidents-write-ops.ts +2 -2
  200. package/src/db/command-agent-profile-backfill.ts +39 -0
  201. package/src/db/command-agent-profiles.ts +5 -1
  202. package/src/db/command-retention.ts +126 -0
  203. package/src/db/command-row.ts +10 -2
  204. package/src/db/commands-list-query.ts +2 -0
  205. package/src/db/commands-planner-stats.test-fixture.ts +8 -0
  206. package/src/db/commands-read-ops.ts +16 -0
  207. package/src/db/commands-spawn-read.ts +1 -1
  208. package/src/db/config-store-write-ops.ts +7 -2
  209. package/src/db/connection.ts +1 -182
  210. package/src/db/context-carry-write.ts +74 -0
  211. package/src/db/continuation-archives-async.ts +5 -0
  212. package/src/db/continuation-archives-write-ops.ts +7 -0
  213. package/src/db/continuations.ts +6 -6
  214. package/src/db/db-error-registry.ts +12 -0
  215. package/src/db/db-writer-worker.ts +8 -1
  216. package/src/db/deploy-events-async.ts +1 -0
  217. package/src/db/deploy-events-read-ops.ts +2 -1
  218. package/src/db/deploy-events.ts +35 -4
  219. package/src/db/gateway.ts +26 -133
  220. package/src/db/history-retention-ops.ts +13 -0
  221. package/src/db/hosts-registration.ts +10 -2
  222. package/src/db/hosts.ts +9 -6
  223. package/src/db/inbox-async.ts +2 -2
  224. package/src/db/inbox-read-ops.ts +1 -1
  225. package/src/db/inbox.ts +9 -17
  226. package/src/db/index.ts +2 -0
  227. package/src/db/integrations-async.ts +8 -0
  228. package/src/db/integrations-ops.ts +15 -0
  229. package/src/db/integrations.ts +15 -21
  230. package/src/db/issue-associations.ts +2 -2
  231. package/src/db/issue-lifecycle.ts +3 -4
  232. package/src/db/issue-refs-async.ts +23 -0
  233. package/src/db/issue-refs-read-ops.ts +6 -0
  234. package/src/db/issue-refs-write-ops.ts +29 -0
  235. package/src/db/issue-refs.ts +15 -16
  236. package/src/db/kernel-event-log-schema.ts +2 -0
  237. package/src/db/land-boundaries.ts +51 -5
  238. package/src/db/land-gate-attestations.ts +2 -2
  239. package/src/db/landing-receipts.ts +2 -2
  240. package/src/db/lifecycle-context-write.ts +5 -0
  241. package/src/db/lifecycle-tail-async.ts +76 -0
  242. package/src/db/lifecycle-tail-write-ops.ts +62 -0
  243. package/src/db/lifecycle-write-window.ts +2 -1
  244. package/src/db/lineage-pair-dedupe-sql.ts +3 -3
  245. package/src/db/long-running-work.ts +2 -2
  246. package/src/db/main-connection-mode.ts +11 -0
  247. package/src/db/main-connection-writes.ts +41 -2
  248. package/src/db/maintenance-job-reconcile.ts +61 -0
  249. package/src/db/maintenance-job-runs-async.ts +14 -0
  250. package/src/db/maintenance-job-write-ops.ts +9 -0
  251. package/src/db/maintenance-pauses.ts +2 -2
  252. package/src/db/mappers.ts +2 -14
  253. package/src/db/merge-lease.ts +1 -15
  254. package/src/db/message-send.ts +4 -0
  255. package/src/db/messages.ts +31 -25
  256. package/src/db/migrations.ts +25 -16
  257. package/src/db/notification-write-ops.ts +19 -0
  258. package/src/db/operator-answer-write.ts +19 -0
  259. package/src/db/orchestrators.ts +14 -76
  260. package/src/db/pairs-async.ts +22 -1
  261. package/src/db/pairs-write-ops.ts +8 -3
  262. package/src/db/pairs.ts +42 -61
  263. package/src/db/plan-dispatch-schema.ts +5 -1
  264. package/src/db/plan-ready-notices.ts +43 -0
  265. package/src/db/plan-tools-include-migration.ts +36 -0
  266. package/src/db/plans-write-ops.ts +2 -0
  267. package/src/db/presence-buffer.ts +5 -0
  268. package/src/db/presence-loop.ts +18 -23
  269. package/src/db/presence-write.ts +0 -6
  270. package/src/db/project-entries-async.ts +14 -0
  271. package/src/db/project-entries-read-ops.ts +5 -1
  272. package/src/db/project-entries-write-ops.ts +8 -0
  273. package/src/db/project-entries.ts +15 -12
  274. package/src/db/project-journal.ts +2 -2
  275. package/src/db/project-profile-instructions.ts +50 -0
  276. package/src/db/project-trust-approvals.ts +2 -2
  277. package/src/db/prompt-templates.ts +4 -4
  278. package/src/db/prompt-versions.ts +9 -2
  279. package/src/db/provider-config-history.ts +8 -3
  280. package/src/db/provider-model-seed.ts +34 -0
  281. package/src/db/read-op-marshaling-fixtures.ts +23 -0
  282. package/src/db/read-ops.ts +8 -0
  283. package/src/db/retention.ts +13 -2
  284. package/src/db/review-publish-write.ts +8 -0
  285. package/src/db/routing-policy.ts +2 -3
  286. package/src/db/runtime-admin-async.ts +19 -0
  287. package/src/db/runtime-admin-write-ops.ts +36 -0
  288. package/src/db/runtime-tail-async.ts +288 -0
  289. package/src/db/runtime-tail-write-ops.ts +97 -0
  290. package/src/db/schema.ts +13 -4
  291. package/src/db/spawn-budget.ts +5 -0
  292. package/src/db/spawn-delegation-state.ts +11 -4
  293. package/src/db/spawn-delegation.ts +1 -11
  294. package/src/db/sql-audit-indexes.ts +3 -0
  295. package/src/db/stats-async.ts +9 -6
  296. package/src/db/task-entity.ts +28 -6
  297. package/src/db/task-list.ts +3 -1
  298. package/src/db/tasks.ts +1 -17
  299. package/src/db/team-claim-policy.ts +60 -0
  300. package/src/db/teams-async.ts +4 -0
  301. package/src/db/teams-write-ops.ts +4 -0
  302. package/src/db/terminal-events.ts +15 -0
  303. package/src/db/timer-cutover-bodies.ts +292 -0
  304. package/src/db/timer-cutover-core.ts +37 -278
  305. package/src/db/timer-cutover-state.ts +40 -0
  306. package/src/db/timer-cutover-write-ops.ts +1 -40
  307. package/src/db/timer-ingress.ts +7 -1
  308. package/src/db/token-db-write-ops.ts +19 -0
  309. package/src/db/token-standing-async.ts +12 -0
  310. package/src/db/token-standing.ts +21 -20
  311. package/src/db/token-usage-retention.ts +33 -0
  312. package/src/db/token-usage-write-ops.ts +1 -1
  313. package/src/db/token-usage.ts +4 -1
  314. package/src/db/user-invites-async.ts +13 -0
  315. package/src/db/user-invites.ts +3 -3
  316. package/src/db/users.ts +14 -6
  317. package/src/db/workflow-contact.ts +1 -1
  318. package/src/db/workflow-task-read-ops.ts +30 -0
  319. package/src/db/workspaces.ts +8 -5
  320. package/src/db/write-ops.ts +37 -12
  321. package/src/db/writer-fault-seam.ts +2 -9
  322. package/src/db/writer-fault-test-ops.ts +18 -0
  323. package/src/db/writer-gateway.ts +58 -56
  324. package/src/dev.ts +8 -3
  325. package/src/dispatch-availability.ts +10 -6
  326. package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
  327. package/src/event-loop-lag.ts +4 -2
  328. package/src/event-loop-yield.ts +2 -2
  329. package/src/events.ts +10 -8
  330. package/src/host/disk-alert.ts +121 -0
  331. package/src/host-provider-store.ts +5 -4
  332. package/src/hub-metrics-report.ts +5 -1
  333. package/src/hub-metrics.ts +38 -18
  334. package/src/injection-sweep-pacing.ts +6 -8
  335. package/src/land-gate-notifications.ts +11 -10
  336. package/src/land-gate-queue-progress.ts +3 -3
  337. package/src/land-settle-dispatch.ts +52 -92
  338. package/src/lifecycle-context-pressure.ts +11 -10
  339. package/src/lifecycle-manager.ts +107 -100
  340. package/src/maintenance/breaker.ts +18 -16
  341. package/src/maintenance/cd-watcher.ts +3 -3
  342. package/src/maintenance/checkout-refresh.ts +18 -1
  343. package/src/maintenance/critical-job-watchdog.ts +19 -20
  344. package/src/maintenance/events.ts +3 -3
  345. package/src/maintenance/history-retention-job.ts +30 -0
  346. package/src/maintenance/index.ts +1 -0
  347. package/src/maintenance/jobs.ts +32 -69
  348. package/src/maintenance/long-running-work.ts +3 -1
  349. package/src/maintenance/offline-agent-prune-job.ts +28 -0
  350. package/src/maintenance/orphaned-sessions.ts +5 -4
  351. package/src/maintenance/pauses.ts +4 -10
  352. package/src/maintenance/plan-ready-notice-job.ts +71 -0
  353. package/src/maintenance/scheduler.ts +98 -137
  354. package/src/maintenance/stalled-delivery-pager.ts +10 -9
  355. package/src/maintenance/teams.ts +19 -30
  356. package/src/maintenance/workspaces.ts +18 -28
  357. package/src/managed-policy-escalation.ts +7 -7
  358. package/src/managed-policy.ts +32 -28
  359. package/src/managed-provider-gate.ts +5 -4
  360. package/src/managed-spawn-reservation.ts +5 -4
  361. package/src/mcp/index.ts +12 -9
  362. package/src/mcp/output-descriptions.ts +8 -8
  363. package/src/mcp/presentation.ts +6 -5
  364. package/src/mcp/project-profile-instructions.ts +32 -0
  365. package/src/mcp/runtime-output.ts +6 -1
  366. package/src/mcp/self-care-visibility.ts +2 -2
  367. package/src/mcp/spawn-targets-matrix.ts +10 -1
  368. package/src/mcp/tool-groups.ts +4 -3
  369. package/src/mcp/tool-roles.ts +81 -0
  370. package/src/mcp/tools-spawn.ts +4 -3
  371. package/src/mcp/tools-workspace.ts +1 -1
  372. package/src/mcp-agent-action.ts +1 -2
  373. package/src/mcp-blackboard-tools.ts +6 -5
  374. package/src/mcp-decision-tools.ts +7 -7
  375. package/src/mcp-egress-tools.ts +10 -9
  376. package/src/mcp-issue-activity-tools.ts +2 -2
  377. package/src/mcp-issue-association-tools.ts +4 -4
  378. package/src/mcp-issue-ref-tools.ts +13 -12
  379. package/src/mcp-maintenance-tools.ts +2 -2
  380. package/src/mcp-merge-tools.ts +5 -5
  381. package/src/mcp-notification-subscription-tools.ts +14 -15
  382. package/src/mcp-output-levels.test-fixture.ts +1 -1
  383. package/src/mcp-profile-trust-tools.ts +5 -5
  384. package/src/mcp-project-journal-tools.ts +4 -12
  385. package/src/mcp-project-tools.ts +17 -18
  386. package/src/mcp-provider-catalog.ts +2 -2
  387. package/src/mcp-routing-policy-tools.ts +3 -2
  388. package/src/mcp-task-tools.ts +11 -5
  389. package/src/mcp-team-template-tools.ts +3 -3
  390. package/src/mcp-team-tools.ts +6 -6
  391. package/src/mcp-workflow-tools.ts +13 -4
  392. package/src/memory-area-injection.ts +13 -12
  393. package/src/memory-boundary-capture.ts +6 -6
  394. package/src/memory-injection.ts +45 -43
  395. package/src/merge-pause-maintenance.ts +5 -4
  396. package/src/notification-router.ts +44 -17
  397. package/src/notification-types.ts +2 -1
  398. package/src/notify.ts +5 -5
  399. package/src/observed-reset-refresh.ts +4 -4
  400. package/src/operator-alarm.ts +23 -11
  401. package/src/project-ingest.ts +6 -6
  402. package/src/project-instructions.ts +12 -1
  403. package/src/project-profile-instruction-text.ts +6 -0
  404. package/src/project-profile-instructions.ts +20 -0
  405. package/src/project-trust.ts +12 -11
  406. package/src/prompt-resolver.ts +3 -3
  407. package/src/provider-catalog-store.ts +3 -49
  408. package/src/provider-config-store.ts +12 -11
  409. package/src/provider-model-seed.ts +1 -18
  410. package/src/provider-quota-async.ts +5 -7
  411. package/src/provider-quota-config-store.ts +5 -4
  412. package/src/provider-secrets.test-fixture.ts +3 -3
  413. package/src/provider-timeline-event.ts +4 -7
  414. package/src/quota-band-delivery.ts +2 -2
  415. package/src/recipe-runner.ts +6 -5
  416. package/src/repo-config-source.ts +10 -4
  417. package/src/retention-config-store.ts +4 -3
  418. package/src/reviewer-pipeline.ts +11 -10
  419. package/src/routes/_route.ts +4 -4
  420. package/src/routes/_shared.ts +13 -12
  421. package/src/routes/agent-effort.ts +5 -5
  422. package/src/routes/agent-heartbeat-quota.ts +23 -0
  423. package/src/routes/agent-keep.ts +1 -1
  424. package/src/routes/agent-profiles.ts +6 -6
  425. package/src/routes/agent-reporting.ts +1 -1
  426. package/src/routes/agent-self-effort.ts +5 -5
  427. package/src/routes/agent-sessions.ts +24 -24
  428. package/src/routes/agents-spawn.ts +2 -2
  429. package/src/routes/agents.ts +19 -121
  430. package/src/routes/auth.ts +14 -15
  431. package/src/routes/authority-audit.ts +2 -2
  432. package/src/routes/automations.ts +6 -5
  433. package/src/routes/channel-binding-delete.ts +1 -1
  434. package/src/routes/channel-output.ts +3 -3
  435. package/src/routes/claude-api-budget.ts +5 -5
  436. package/src/routes/commands-listing.ts +5 -1
  437. package/src/routes/commands.ts +31 -29
  438. package/src/routes/context-resets.ts +2 -2
  439. package/src/routes/continuation-archives.ts +2 -2
  440. package/src/routes/coordinator-teams.ts +1 -1
  441. package/src/routes/decisions.ts +2 -2
  442. package/src/routes/host-secret-files.ts +1 -1
  443. package/src/routes/hosts.ts +11 -11
  444. package/src/routes/inbox.ts +3 -2
  445. package/src/routes/index.ts +12 -2
  446. package/src/routes/integrations.ts +32 -56
  447. package/src/routes/issue-activity.ts +2 -2
  448. package/src/routes/issue-associations.ts +4 -4
  449. package/src/routes/issue-refs.ts +9 -9
  450. package/src/routes/kernel-timers-operator.ts +1 -1
  451. package/src/routes/memory.ts +1 -1
  452. package/src/routes/merges.ts +11 -11
  453. package/src/routes/messages.ts +23 -17
  454. package/src/routes/orchestrator-bootstrap.ts +2 -2
  455. package/src/routes/orchestrator-host-registration.ts +4 -2
  456. package/src/routes/orchestrator-host-utilization.ts +5 -3
  457. package/src/routes/orchestrator-proxy.ts +4 -4
  458. package/src/routes/orchestrator.ts +28 -19
  459. package/src/routes/pairs.ts +8 -8
  460. package/src/routes/project-profile-instructions.ts +27 -0
  461. package/src/routes/project-trust.ts +3 -3
  462. package/src/routes/projects.ts +16 -16
  463. package/src/routes/prompt-templates.ts +12 -12
  464. package/src/routes/provider-config.ts +6 -6
  465. package/src/routes/provider-quota-config.ts +2 -2
  466. package/src/routes/provider-quotas.ts +10 -10
  467. package/src/routes/run-command.ts +1 -1
  468. package/src/routes/secrets-backup.ts +2 -2
  469. package/src/routes/secrets-import.ts +1 -1
  470. package/src/routes/secrets-vault.ts +7 -7
  471. package/src/routes/settings.ts +6 -6
  472. package/src/routes/shipping.ts +9 -1
  473. package/src/routes/spawn-policy.ts +8 -7
  474. package/src/routes/sse.ts +2 -2
  475. package/src/routes/stats.ts +6 -6
  476. package/src/routes/task-http.ts +15 -1
  477. package/src/routes/task-issues.ts +11 -26
  478. package/src/routes/tasks.ts +22 -53
  479. package/src/routes/team-templates.ts +12 -12
  480. package/src/routes/teams-config.ts +2 -2
  481. package/src/routes/teams.ts +10 -10
  482. package/src/routes/tokens.ts +30 -22
  483. package/src/routes/users.ts +24 -24
  484. package/src/routes/viewer-read.ts +3 -3
  485. package/src/routes/web-tool-calls.ts +4 -4
  486. package/src/routes/workflows.ts +22 -7
  487. package/src/routes/workspaces.ts +17 -16
  488. package/src/routing-policy-normalize.ts +1 -2
  489. package/src/routing-policy-push.ts +6 -6
  490. package/src/routing-step-defaults.ts +0 -2
  491. package/src/runner-token-mint-limit.ts +63 -0
  492. package/src/runtime-grant.ts +21 -13
  493. package/src/runtime-tokens.ts +59 -35
  494. package/src/secrets-broker/config.ts +1 -1
  495. package/src/secrets-broker/service.ts +2 -2
  496. package/src/security.ts +16 -21
  497. package/src/self-resume-carry.ts +21 -110
  498. package/src/self-resume-supersede.ts +4 -3
  499. package/src/self-resume.ts +54 -66
  500. package/src/server-background.ts +2 -2
  501. package/src/server.ts +26 -24
  502. package/src/services/agent-action.ts +12 -31
  503. package/src/services/agent-effort.ts +7 -32
  504. package/src/services/agent-hang-watchdog-job.ts +2 -2
  505. package/src/services/agent-heartbeat.ts +166 -0
  506. package/src/services/agent-reporting.ts +1 -1
  507. package/src/services/browser-inventory.ts +3 -3
  508. package/src/services/browser-session-state.ts +3 -2
  509. package/src/services/browser-session.ts +21 -27
  510. package/src/services/bus-command-update.ts +9 -9
  511. package/src/services/checkout-refresh-state.ts +1 -0
  512. package/src/services/checkout-refresh.test-fixture.ts +3 -2
  513. package/src/services/command-host.ts +7 -2
  514. package/src/services/coordinator-digest.ts +3 -2
  515. package/src/services/dispatch-command.ts +12 -13
  516. package/src/services/effective-launch-driver.ts +14 -9
  517. package/src/services/host-changed-paths.test-fixture.ts +5 -6
  518. package/src/services/host-project-readiness.ts +2 -2
  519. package/src/services/host-providers.ts +1 -1
  520. package/src/services/host-utilization.ts +27 -4
  521. package/src/services/idle-agent-digest.ts +17 -12
  522. package/src/services/idle-epics.ts +9 -10
  523. package/src/services/interrupt-agent.ts +12 -9
  524. package/src/services/issue-activity.ts +3 -3
  525. package/src/services/issue-associations.ts +15 -18
  526. package/src/services/issue-lifecycle-comments.ts +3 -2
  527. package/src/services/issue-lifecycle.ts +69 -72
  528. package/src/services/issue-refs.ts +10 -15
  529. package/src/services/kernel-timers-cutover-chaos-worker.ts +11 -8
  530. package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
  531. package/src/services/kernel-timers-ingress.ts +4 -4
  532. package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
  533. package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
  534. package/src/services/kernel-timers-outbox.ts +1 -1
  535. package/src/services/kernel-timers-stage10-operator.ts +1 -1
  536. package/src/services/kernel-timers.ts +4 -3
  537. package/src/services/land-gate-placement.ts +11 -2
  538. package/src/services/land-issue-relations.ts +5 -4
  539. package/src/services/land-restart-retry.ts +7 -6
  540. package/src/services/landed-ancestry.ts +25 -8
  541. package/src/services/legacy-landing-host.ts +4 -1
  542. package/src/services/legacy-landing-recovery.ts +8 -6
  543. package/src/services/managed-running.ts +17 -17
  544. package/src/services/memory-areas.ts +17 -53
  545. package/src/services/merge-pause.ts +9 -15
  546. package/src/services/operator-decisions.ts +37 -41
  547. package/src/services/orchestrator-registration-recovery.ts +6 -2
  548. package/src/services/orchestrator-upgrade.ts +14 -12
  549. package/src/services/permission-decision.ts +4 -3
  550. package/src/services/plan-ci-notice.ts +57 -0
  551. package/src/services/plan-ci-recovery.ts +2 -55
  552. package/src/services/plan-conformance.ts +4 -4
  553. package/src/services/plan-dispatch-policy.ts +10 -3
  554. package/src/services/plan-dispatch.ts +35 -14
  555. package/src/services/plan-graph.ts +39 -261
  556. package/src/services/plan-import.ts +1 -1
  557. package/src/services/plan-live-bindings.ts +8 -37
  558. package/src/services/plan-task-create.ts +1 -1
  559. package/src/services/plan-terminal-refs.ts +2 -12
  560. package/src/services/plan-wake-digest.ts +9 -3
  561. package/src/services/profile-trust.ts +6 -5
  562. package/src/services/project-config-read.ts +70 -0
  563. package/src/services/project-profile-instructions.ts +54 -0
  564. package/src/services/project.ts +11 -10
  565. package/src/services/prompt-templates.ts +6 -5
  566. package/src/services/provider-hold-nudge.ts +9 -9
  567. package/src/services/provider-hold-record.ts +13 -12
  568. package/src/services/provider-state-audit.ts +19 -18
  569. package/src/services/provisioning-harness/budget-baseline.json +4 -4
  570. package/src/services/provisioning-harness/driver.ts +1 -1
  571. package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
  572. package/src/services/provisioning-harness/lifecycle.ts +24 -22
  573. package/src/services/provisioning-harness/prepare.ts +16 -17
  574. package/src/services/rate-limit-resume.ts +10 -9
  575. package/src/services/red-main-auto-revert.ts +7 -5
  576. package/src/services/red-main-controller-deps.ts +20 -3
  577. package/src/services/red-main-incident.ts +3 -1
  578. package/src/services/red-main-quarantine.ts +2 -3
  579. package/src/services/register-agent.ts +22 -22
  580. package/src/services/restart-project-role.ts +1 -1
  581. package/src/services/restart-spawn.ts +74 -61
  582. package/src/services/review-publish.ts +7 -24
  583. package/src/services/review-ref-reconcile.ts +29 -38
  584. package/src/services/runtime-dependency-alert.ts +27 -0
  585. package/src/services/scheduler-command.ts +11 -9
  586. package/src/services/scheduler.ts +5 -5
  587. package/src/services/self-care-state.ts +2 -1
  588. package/src/services/self-effort-grant.ts +5 -25
  589. package/src/services/self-effort.ts +5 -5
  590. package/src/services/send-message.ts +21 -34
  591. package/src/services/shutdown-agent.ts +17 -14
  592. package/src/services/spawn-agent.ts +25 -43
  593. package/src/services/spawn-chain-inspector.ts +7 -14
  594. package/src/services/spawn-cwd-placement.ts +21 -5
  595. package/src/services/spawn-issue-activity.ts +8 -6
  596. package/src/services/spawn-launch.ts +17 -1
  597. package/src/services/spawn-loss-escalation.ts +1 -1
  598. package/src/services/spawn-policy.ts +68 -0
  599. package/src/services/spawn-registration-watchdog.ts +2 -2
  600. package/src/services/spawn-repo-probe.ts +7 -5
  601. package/src/services/spawn-tree-cleanup.ts +8 -9
  602. package/src/services/steward-reaper.ts +4 -4
  603. package/src/services/task-context-hydration.ts +25 -1
  604. package/src/services/task-delivery.ts +20 -34
  605. package/src/services/task-dispatch.ts +3 -0
  606. package/src/services/task-entity.ts +40 -203
  607. package/src/services/task-issue-link.ts +13 -20
  608. package/src/services/task-issue-weave.ts +12 -11
  609. package/src/services/task-lifecycle.ts +27 -31
  610. package/src/services/task-repo-cwd.ts +37 -0
  611. package/src/services/task-review-hold.ts +4 -17
  612. package/src/services/task-semantic-events.ts +13 -11
  613. package/src/services/task-state-reconcile.ts +8 -17
  614. package/src/services/task-validation.ts +2 -2
  615. package/src/services/team-templates.ts +12 -11
  616. package/src/services/team.ts +31 -98
  617. package/src/services/terminal-provider-exit.ts +6 -5
  618. package/src/services/timer-message-fire-chaos-worker.ts +7 -3
  619. package/src/services/timer-message-fire-outbox.ts +1 -1
  620. package/src/services/transient-agent-reaper.ts +25 -20
  621. package/src/services/turn-reconcile-audit.ts +9 -9
  622. package/src/services/user-onboarding.ts +8 -6
  623. package/src/services/user-profile.ts +6 -9
  624. package/src/services/work-finality.ts +16 -4
  625. package/src/services/workflow-auto-start.ts +26 -13
  626. package/src/services/workflow-caller.ts +61 -4
  627. package/src/services/workflow-child-proof-worker.ts +1 -1
  628. package/src/services/workflow-ci-main.ts +1 -1
  629. package/src/services/workflow-control-proof-worker.ts +1 -1
  630. package/src/services/workflow-coordinator.ts +8 -2
  631. package/src/services/workflow-decisions.ts +5 -5
  632. package/src/services/workflow-deferred-cleanup.ts +5 -3
  633. package/src/services/workflow-effect-driver.ts +42 -17
  634. package/src/services/workflow-effects.ts +58 -37
  635. package/src/services/workflow-land-notice.ts +10 -0
  636. package/src/services/workflow-pause-text.ts +43 -0
  637. package/src/services/workflow-pins.ts +7 -4
  638. package/src/services/workflow-reconcile.ts +14 -11
  639. package/src/services/workflow-resume-pins.ts +3 -3
  640. package/src/services/workflow-routing-defaults.ts +18 -0
  641. package/src/services/workflow-run-view.ts +6 -3
  642. package/src/services/workflow-run.test-fixture.ts +1 -1
  643. package/src/services/workflow-runs.ts +61 -33
  644. package/src/services/workflow-supervisor-state.ts +26 -1
  645. package/src/services/workflow-supervisor.ts +11 -6
  646. package/src/services/workspace-recovery.ts +4 -3
  647. package/src/settings/registry.ts +1 -2
  648. package/src/spawn-admission.ts +10 -2
  649. package/src/spawn-command.ts +4 -4
  650. package/src/spawn-models.ts +10 -12
  651. package/src/spawn-placement.ts +28 -10
  652. package/src/spawn-targets.ts +9 -9
  653. package/src/sse-agent-status.ts +15 -6
  654. package/src/sse.ts +49 -24
  655. package/src/startup-context-injection.ts +62 -57
  656. package/src/state-adoption/cd-cutover.ts +53 -7
  657. package/src/state-adoption/fleet-cutover.ts +35 -0
  658. package/src/state-adoption/fleet-plan.ts +36 -0
  659. package/src/state-adoption/index.ts +2 -2
  660. package/src/state-adoption/linux-plan.ts +2 -2
  661. package/src/state-adoption/linux.ts +2 -2
  662. package/src/state-adoption/macos-plan.ts +2 -2
  663. package/src/state-adoption/macos.ts +1 -1
  664. package/src/steward-handoff.ts +4 -3
  665. package/src/steward-policy-cleanup.ts +9 -8
  666. package/src/steward.ts +9 -8
  667. package/src/task-dispatch-live.ts +6 -3
  668. package/src/task-dispatcher.ts +3 -3
  669. package/src/teams-config-store.ts +4 -3
  670. package/src/token-db-write.ts +10 -0
  671. package/src/token-db.ts +2 -2
  672. package/src/token-usage-async.ts +2 -4
  673. package/src/user-awaiting-reply.ts +5 -5
  674. package/src/workspace-actions.ts +24 -29
  675. package/src/workspace-auto-merge.ts +14 -12
  676. package/src/workspace-changed-paths-client.ts +16 -5
  677. package/src/workspace-cleanup-stale.ts +30 -7
  678. package/src/workspace-command-settle.ts +26 -17
  679. package/src/workspace-config.ts +1 -1
  680. package/src/workspace-conflict-resolver.ts +9 -7
  681. package/src/workspace-dead-owner-recovery.ts +5 -4
  682. package/src/workspace-escalation.ts +12 -11
  683. package/src/workspace-human-escalation.ts +3 -3
  684. package/src/workspace-land-gate-watchdog.ts +3 -3
  685. package/src/workspace-land-refusal.ts +20 -0
  686. package/src/workspace-land-stopped.ts +1 -0
  687. package/src/workspace-merge.ts +10 -26
  688. package/src/workspace-nothing-to-land-notice.ts +2 -2
  689. package/src/workspace-orphans.ts +18 -37
  690. package/src/workspace-pr-completion.ts +10 -8
  691. package/src/workspace-rekey.ts +3 -3
  692. package/src/workspace-steward-failure.ts +2 -2
  693. package/src/workspace-steward-wake.ts +4 -4
  694. package/node_modules/@humwick/kernel/LICENSE +0 -167
  695. package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
  696. package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
  697. package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
  698. package/node_modules/@humwick/kernel/config.ts +0 -111
  699. package/node_modules/@humwick/kernel/contract.ts +0 -572
  700. package/node_modules/@humwick/kernel/control-authz.ts +0 -281
  701. package/node_modules/@humwick/kernel/control.ts +0 -645
  702. package/node_modules/@humwick/kernel/effects.ts +0 -493
  703. package/node_modules/@humwick/kernel/event-log.ts +0 -319
  704. package/node_modules/@humwick/kernel/http-transport.ts +0 -384
  705. package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
  706. package/node_modules/@humwick/kernel/identity.ts +0 -248
  707. package/node_modules/@humwick/kernel/index.ts +0 -28
  708. package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
  709. package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
  710. package/node_modules/@humwick/kernel/landing.ts +0 -953
  711. package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
  712. package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
  713. package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
  714. package/node_modules/@humwick/kernel/message-authority.ts +0 -281
  715. package/node_modules/@humwick/kernel/module-host.ts +0 -722
  716. package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
  717. package/node_modules/@humwick/kernel/package.json +0 -39
  718. package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
  719. package/node_modules/@humwick/kernel/persistence.ts +0 -510
  720. package/node_modules/@humwick/kernel/registry.ts +0 -60
  721. package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
  722. package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
  723. package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
  724. package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
  725. package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
  726. package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
  727. package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
  728. package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
  729. package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
  730. package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
  731. package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
  732. package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
  733. package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
  734. package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
  735. package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
  736. package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
  737. package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
  738. package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
  739. package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
  740. package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
  741. package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
  742. package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
  743. package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
  744. package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
  745. package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
  746. package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
  747. package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
  748. package/node_modules/@humwick/offload/LICENSE +0 -167
  749. package/node_modules/@humwick/offload/README.md +0 -57
  750. package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
  751. package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
  752. package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
  753. package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
  754. package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
  755. package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
  756. package/node_modules/@humwick/offload/dist/envelope.js +0 -80
  757. package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
  758. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
  759. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
  760. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
  761. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
  762. package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
  763. package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
  764. package/node_modules/@humwick/offload/dist/index.js +0 -5
  765. package/node_modules/@humwick/offload/dist/index.js.map +0 -1
  766. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
  767. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
  768. package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
  769. package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
  770. package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
  771. package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
  772. package/node_modules/@humwick/offload/dist/types.js +0 -176
  773. package/node_modules/@humwick/offload/dist/types.js.map +0 -1
  774. package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
  775. package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
  776. package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
  777. package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
  778. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
  779. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
  780. package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
  781. package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
  782. package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
  783. package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
  784. package/node_modules/@humwick/offload/dist/worker.js +0 -1
  785. package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
  786. package/node_modules/@humwick/offload/package.json +0 -42
  787. package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
  788. package/node_modules/@humwick/offload/src/envelope.ts +0 -92
  789. package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
  790. package/node_modules/@humwick/offload/src/index.ts +0 -4
  791. package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
  792. package/node_modules/@humwick/offload/src/types.ts +0 -235
  793. package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
  794. package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
  795. package/node_modules/@humwick/offload/src/worker.ts +0 -5
  796. package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
  797. package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
  798. package/public/assets/index-B7ZerHLY.css +0 -2
  799. package/public/assets/index-BU3uWo2t.js +0 -15
  800. package/public/assets/projects-B_lmcqfO.js +0 -2
  801. package/public/assets/provider-display-DbLWpP3j.js +0 -2
  802. package/public/assets/run-card-CO_bguQf.js +0 -2
  803. package/public/assets/shipping-Bu8p1gEw.js +0 -2
  804. package/public/assets/store-BvtFdlGX.js +0 -9
  805. package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
  806. package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
  807. package/runner/src/agent-runner/http-liveness.ts +0 -85
  808. package/runner/src/gate-run-lease-probe.ts +0 -38
  809. package/src/db/claude-catalog-reconcile.ts +0 -27
  810. package/src/db/on-loop-write-transaction.ts +0 -34
  811. package/src/routing-model-aliases.ts +0 -21
@@ -42,17 +42,16 @@ import { WriterDrain } from "./writer-drain";
42
42
 
43
43
  import { errMessage } from "@humwick/sdk";
44
44
  import { createWorkerPool, type WorkerPool } from "@humwick/offload";
45
- import { getDbGeneration, getDbPath } from "./connection.ts";
46
- import { armedWriterFaultCount } from "./writer-fault-seam.ts";
47
- import { onLoopWriteTransaction } from "./on-loop-write-transaction.ts";
45
+ import { getDbPath } from "./connection.ts";
48
46
  // On-loop-block attribution (#1882 / ADR §5). `resolveLoopCallsite` pins the effective callsite onto a
49
47
  // submission in the CALLER's context; `captureSyncFrame` times the op body where it actually runs — in
50
48
  // the in-process drain microtask, NOT the synchronous enqueue. One-way import (loop-block-attribution
51
49
  // imports only event-loop-lag + config), so no cycle.
52
50
  import { captureSyncFrame, resolveLoopCallsite } from "../loop-block-attribution.ts";
51
+ import { markCallerResume } from "../hub-metrics.ts";
53
52
  import { reconstructDbError, serializeDbError } from "./db-error-registry.ts";
54
53
  import {
55
- isIdempotentWriterOp,
54
+ writerOpAllowsKeyless,
56
55
  isOffLoopWriterOp,
57
56
  runWriterBatch,
58
57
  runWriterOp,
@@ -110,7 +109,7 @@ export class WriteIndeterminateError extends Error {
110
109
  // ── Options & per-call opts ───────────────────────────────────────────────────────────────────────
111
110
 
112
111
  export interface InitWriterOptions {
113
- /** Overrides the path from `getDbPath()`; `:memory:`/undefined selects the in-process backend. */
112
+ /** File path to attach. A live file DB always uses its worker, including legacy :memory: requests. */
114
113
  path?: string;
115
114
  /** Soft high-water mark on the writer queue; past it, non-critical writes shed (§3.6). */
116
115
  queueHighWater?: number;
@@ -174,14 +173,18 @@ export interface WriterStats {
174
173
  * SQLite lock (H4 §3.6.1). A wedged writer is NOT idle — this is deliberately distinct from
175
174
  * `busy:0`, which is how the naive pool-replace path mis-reported the stall. New non-critical
176
175
  * writes shed and critical writes are held until the wedged op completes and the FIFO resumes.
176
+ * #3776 — names the op holding the writer and how long it has run, so health says WHICH job; null when not wedged.
177
177
  */
178
- wedged: boolean;
178
+ wedged: { op: string; runningMs: number } | null;
179
179
  /**
180
180
  * #2276 — how many times the IN-PROCESS drain has yielded the event loop mid-convoy because its
181
181
  * time slice was spent. 0 on the worker backend (nothing to slice). A steadily climbing count is
182
182
  * the observable signal that write convoys are long enough to need the throttle.
183
183
  */
184
184
  drainYields: number;
185
+ /** #3798 — writes executed since boot on the main thread and on a writer thread (a batch counts its entries). */
186
+ onLoopOps: number;
187
+ writerThreadOps: number;
185
188
  }
186
189
 
187
190
  // ── Backend state ─────────────────────────────────────────────────────────────────────────────────
@@ -242,8 +245,6 @@ interface InProcessBackend {
242
245
  kind: "in-process";
243
246
  stop: AbortController;
244
247
  busy: boolean;
245
- offLoop?: WorkerBackend;
246
- offLoopGeneration?: number;
247
248
  }
248
249
  type Backend = WorkerBackend | InProcessBackend;
249
250
 
@@ -255,26 +256,28 @@ let writerTimeoutMs = DEFAULT_WRITER_TIMEOUT_MS;
255
256
  let drainSliceMs = DEFAULT_DRAIN_SLICE_MS;
256
257
  // Monotonic across re-inits (like any counter): a test that wants a delta reads it before and after.
257
258
  let drainYields = 0;
259
+ let onLoopOps = 0;
260
+ let writerThreadOps = 0;
258
261
  // Set while a writer job has blown its gateway deadline and the sole writer is stalled holding the
259
262
  // lock (§3.6.1). Cleared when that in-flight job finally settles (the op completed and released the
260
263
  // lock), which re-kicks the FIFO drain. Worker backend only — an in-process op runs synchronously on
261
264
  // the main thread, so it cannot be observed mid-stall.
262
- let wedged = false;
265
+ let wedgedOp: { op: string; startedAt: number } | undefined;
263
266
 
264
267
  // Test-only fault injection for the precise H5 window: the op has COMMITTED, but its
265
268
  // acknowledgement is lost before the caller observes the result. One-shot by design so a retry
266
269
  // exercises the persisted idempotency ledger rather than repeatedly failing at the transport edge.
267
- let postCommitAckLossForTests: { op: string; remaining: number } | undefined;
270
+ let postCommitAckLossForTests: { op: string } | undefined;
268
271
 
269
272
  export function rejectNextWriterAckAfterCommitForTests(op: string): void {
270
- postCommitAckLossForTests = { op, remaining: 1 };
273
+ postCommitAckLossForTests = { op };
271
274
  }
272
275
 
273
- function losePostCommitAckForTests(op: string): boolean {
274
- if (!postCommitAckLossForTests || postCommitAckLossForTests.op !== op) return false;
275
- postCommitAckLossForTests.remaining -= 1;
276
- if (postCommitAckLossForTests.remaining <= 0) postCommitAckLossForTests = undefined;
277
- return true;
276
+ function resolveWriterOp(entry: Extract<Submission, { kind: "op" }>, result: unknown): void {
277
+ if (postCommitAckLossForTests?.op === entry.op) {
278
+ postCommitAckLossForTests = undefined;
279
+ entry.reject(new WriteIndeterminateError(entry.op, new Error("injected post-commit lost acknowledgement"), entry.opts?.idempotencyKey));
280
+ } else entry.resolve(result);
278
281
  }
279
282
 
280
283
  /**
@@ -283,7 +286,8 @@ function losePostCommitAckForTests(op: string): boolean {
283
286
  * size-1 writer pool.
284
287
  */
285
288
  export function initWriter(options: InitWriterOptions = {}): void {
286
- const path = options.path ?? getDbPath();
289
+ // A file-backed main handle never executes writer bodies, even when an old caller requests memory.
290
+ const path = options.path && options.path !== ":memory:" ? options.path : getDbPath() ?? options.path;
287
291
  // EVERY caller-supplied number is validated BEFORE any of them is assigned: a RangeError thrown
288
292
  // after an earlier field was already written would leave the module in a half-applied config the
289
293
  // caller never asked for.
@@ -355,14 +359,14 @@ function createFileWriter(dbPath: string): WorkerBackend {
355
359
 
356
360
  /** Server shutdown keeps already-admitted writes; test/reset teardown remains immediate. */
357
361
  export async function drainWriterOnShutdown(): Promise<void> {
358
- try { await shutdownDrain.start(() => !draining && !wedged && pendingWriteDepth() === 0 && inFlightWrites() === 0); }
362
+ try { await shutdownDrain.start(() => !draining && !wedgedOp && pendingWriteDepth() === 0 && inFlightWrites() === 0); }
359
363
  finally { await shutdownWriter(); }
360
364
  }
361
365
 
362
366
  export async function shutdownWriter(): Promise<void> {
363
367
  const current = backend;
364
368
  backend = undefined;
365
- wedged = false;
369
+ wedgedOp = undefined;
366
370
  // Reject anything still queued at the gateway so no caller hangs across a teardown.
367
371
  const stranded = submissionQueue.splice(0, submissionQueue.length);
368
372
  for (const entry of stranded) {
@@ -370,7 +374,6 @@ export async function shutdownWriter(): Promise<void> {
370
374
  }
371
375
  if (current?.kind === "in-process") current.stop.abort(new Error("writer gateway shut down"));
372
376
  if (current?.kind === "worker") await current.pool.destroy();
373
- if (current?.kind === "in-process") await current.offLoop?.pool.destroy();
374
377
  }
375
378
 
376
379
  /** Whether the gateway is initialized (some callers guard bootstrap ordering on this). */
@@ -379,12 +382,14 @@ export function isWriterInitialized(): boolean {
379
382
  }
380
383
 
381
384
  export function writerStats(): WriterStats {
382
- if (!backend) return { backend: "uninitialized", queued: 0, busy: 0, highWater: queueHighWater, wedged: false, drainYields };
385
+ const ops = { drainYields, onLoopOps, writerThreadOps };
386
+ if (!backend) return { backend: "uninitialized", queued: 0, busy: 0, highWater: queueHighWater, wedged: null, ...ops };
387
+ const wedged = wedgedOp ? { op: wedgedOp.op, runningMs: Math.round(performance.now() - wedgedOp.startedAt) } : null;
383
388
  if (backend.kind === "in-process") {
384
- return { backend: "in-process", queued: pendingWriteDepth(), busy: inFlightWrites(), highWater: queueHighWater, wedged, drainYields };
389
+ return { backend: "in-process", queued: pendingWriteDepth(), busy: inFlightWrites(), highWater: queueHighWater, wedged, ...ops };
385
390
  }
386
391
  const stats = backend.pool.stats;
387
- return { backend: "worker", queued: pendingWriteDepth(), busy: stats.busy, highWater: queueHighWater, wedged, drainYields };
392
+ return { backend: "worker", queued: pendingWriteDepth(), busy: stats.busy, highWater: queueHighWater, wedged, ...ops };
388
393
  }
389
394
 
390
395
  function requireBackend(): Backend {
@@ -448,7 +453,7 @@ function pendingWriteDepth(): number {
448
453
 
449
454
  /** Includes an in-process writer waiting asynchronously for BEGIN. */
450
455
  function inFlightWrites(): number {
451
- return backend?.kind === "worker" ? backend.pool.stats.busy : Math.max(Number(backend?.busy ?? false), backend?.offLoop?.pool.stats.busy ?? 0);
456
+ return backend?.kind === "worker" ? backend.pool.stats.busy : Number(backend?.busy ?? false);
452
457
  }
453
458
 
454
459
  /** Reject every caller attached to a submission (used for teardown / dispatch-time backend loss). */
@@ -461,7 +466,7 @@ function rejectEntry(entry: Submission, error: unknown): void {
461
466
  * before the write is ever submitted, so a keyless non-idempotent write can never be retried into a
462
467
  * duplicate. `key` is the per-write key (the batch/coalesce paths pass each entry's own key). */
463
468
  function guardIdempotency(op: string, key: string | undefined): void {
464
- if (key === undefined && !isIdempotentWriterOp(op)) throw new WriteRetrySafetyError(op);
469
+ if (key === undefined && !writerOpAllowsKeyless(op)) throw new WriteRetrySafetyError(op);
465
470
  }
466
471
 
467
472
  /** Backpressure admission (§3.6/§3.6.1). `count` is the number of writes this submission would ADD (1
@@ -480,7 +485,7 @@ function admitOrThrow(op: string, opts: WriteOpts | undefined, count: number): v
480
485
  const occupancy = pendingWriteDepth() + inFlightWrites();
481
486
  if (occupancy + count > queueHardCap) throw new WriterOverloadedError(op, occupancy);
482
487
  if (opts?.critical) return;
483
- const workerWedged = wedged;
488
+ const workerWedged = wedgedOp !== undefined;
484
489
  if (workerWedged || occupancy + count > queueHighWater) throw new WriterOverloadedError(op, occupancy);
485
490
  }
486
491
 
@@ -511,7 +516,7 @@ async function drainLoop(): Promise<void> {
511
516
  // second concurrent drain and anything submitted meanwhile is picked up by this same loop when
512
517
  // it resumes — FIFO is preserved, the queue is only PAUSED.
513
518
  let sliceStartedAt = performance.now();
514
- while (submissionQueue.length > 0 && !wedged) {
519
+ while (submissionQueue.length > 0 && !wedgedOp) {
515
520
  const entry = submissionQueue.shift()!;
516
521
  const onLoop = backend?.kind === "in-process";
517
522
  await dispatchEntry(entry);
@@ -521,7 +526,7 @@ async function drainLoop(): Promise<void> {
521
526
  sliceStartedAt = performance.now();
522
527
  continue;
523
528
  }
524
- if (submissionQueue.length === 0 || wedged) continue;
529
+ if (submissionQueue.length === 0 || wedgedOp) continue;
525
530
  if (performance.now() - sliceStartedAt < drainSliceMs) continue;
526
531
  drainYields += 1;
527
532
  await yieldEventLoop();
@@ -529,7 +534,7 @@ async function drainLoop(): Promise<void> {
529
534
  }
530
535
  } finally {
531
536
  draining = false;
532
- shutdownDrain.notify(!wedged && pendingWriteDepth() === 0 && inFlightWrites() === 0);
537
+ shutdownDrain.notify(!wedgedOp && pendingWriteDepth() === 0 && inFlightWrites() === 0);
533
538
  }
534
539
  }
535
540
 
@@ -551,19 +556,9 @@ async function dispatchEntry(entry: Submission): Promise<void> {
551
556
  if (back.kind === "in-process") {
552
557
  back.busy = true;
553
558
  try {
554
- const path = getDbPath();
555
- // An armed crash seam is a closure on THIS thread, so while one is armed the op runs here instead
556
- // of on the file-DB worker (tests only; production never arms). Otherwise the fault would never fire.
557
- if (path && path !== ":memory:" && isOffLoopWriterOp(entry.op) && armedWriterFaultCount() === 0) {
558
- if (back.offLoop && back.offLoopGeneration !== getDbGeneration()) {
559
- await back.offLoop.pool.destroy();
560
- back.offLoop = undefined;
561
- }
562
- back.stop.signal.throwIfAborted();
563
- back.offLoop ??= createFileWriter(path);
564
- back.offLoopGeneration = getDbGeneration();
565
- await dispatchWorker(entry, back.offLoop);
566
- } else await dispatchInProcess(entry, back.stop.signal);
559
+ back.stop.signal.throwIfAborted();
560
+ onLoopOps += entryWrites(entry);
561
+ await dispatchInProcess(entry);
567
562
  } catch (error) { rejectEntry(entry, error); }
568
563
  finally { back.busy = false; }
569
564
  return;
@@ -571,6 +566,10 @@ async function dispatchEntry(entry: Submission): Promise<void> {
571
566
  await dispatchWorker(entry, back);
572
567
  }
573
568
 
569
+ function entryWrites(entry: Submission): number {
570
+ return entry.kind === "op" ? 1 : entry.argsList.length;
571
+ }
572
+
574
573
  /**
575
574
  * The per-entry dedup keys for a batch/coalesce job (H5 §3.7.1). A dbWriteBatch carries ONE key for
576
575
  * the whole call and derives a stable per-entry key `${key}#${i}`, so a blind retry of the same batch
@@ -598,18 +597,12 @@ function entryKeys(entry: Extract<Submission, { kind: "batch" | "coalesce" }>):
598
597
  * (`dispatchWorker`) is deliberately NOT wrapped: its op body runs off-thread, so there is no on-loop
599
598
  * block to attribute (only the sub-floor enqueue, which the record floor drops).
600
599
  */
601
- async function dispatchInProcess(entry: Submission, signal: AbortSignal): Promise<void> {
602
- const execute = <T>(fn: () => T) => onLoopWriteTransaction(
603
- fn, (attempt) => captureSyncFrame({ op: entry.op, callsite: entry.callsite }, attempt), writerTimeoutMs, signal,
604
- );
600
+ async function dispatchInProcess(entry: Submission): Promise<void> {
601
+ const execute = <T>(fn: () => T) => captureSyncFrame({ op: entry.op, callsite: entry.callsite }, fn);
605
602
  if (entry.kind === "op") {
606
603
  try {
607
- const result = cloneIn(await execute(() => runWriterOp(entry.op, cloneIn(entry.args), { now: entry.now, presence: cloneIn(entry.presence) }, entry.opts?.idempotencyKey)));
608
- if (losePostCommitAckForTests(entry.op)) {
609
- entry.reject(new WriteIndeterminateError(entry.op, new Error("injected post-commit lost acknowledgement"), entry.opts?.idempotencyKey));
610
- return;
611
- }
612
- entry.resolve(result);
604
+ const result = cloneIn(execute(() => runWriterOp(entry.op, cloneIn(entry.args), { now: entry.now, presence: cloneIn(entry.presence) }, entry.opts?.idempotencyKey)));
605
+ resolveWriterOp(entry, result);
613
606
  } catch (error) {
614
607
  entry.reject(reconstructInProcess(error));
615
608
  }
@@ -618,7 +611,7 @@ async function dispatchInProcess(entry: Submission, signal: AbortSignal): Promis
618
611
  // batch + coalesce share the SAVEPOINT-per-caller executor; only the fan-out differs.
619
612
  let coalesced: CoalescedEntry[];
620
613
  try {
621
- const entries: BatchEntry[] = await execute(() => runWriterBatch(
614
+ const entries: BatchEntry[] = execute(() => runWriterBatch(
622
615
  entry.op,
623
616
  entry.argsList.map((a) => cloneIn(a)),
624
617
  entryKeys(entry),
@@ -650,6 +643,11 @@ async function dispatchWorker(entry: Submission, back: WorkerBackend): Promise<v
650
643
 
651
644
  // retrySafe stays false (default): a write must NEVER be auto-re-dispatched (it would repeat its
652
645
  // effect). No pool timeout is armed — the deadline is the gateway's own (§3.6.1).
646
+ const startedAt = performance.now();
647
+ // #3798 — the drain runs outside any caller, so its dispatch and result handling are charged to the
648
+ // caller that submitted this entry (the reader pool does the same per read).
649
+ markCallerResume(entry.callsite);
650
+ writerThreadOps += entryWrites(entry);
653
651
  const poolPromise = back.pool.run<WriterJobInput, WriterJobResult>(WRITER_TASK_NAME, input, { labels });
654
652
 
655
653
  let timer: ReturnType<typeof setTimeout> | undefined;
@@ -660,18 +658,22 @@ async function dispatchWorker(entry: Submission, back: WorkerBackend): Promise<v
660
658
  }),
661
659
  ]);
662
660
  if (timer) clearTimeout(timer);
661
+ markCallerResume(entry.callsite);
663
662
 
664
663
  if (raced.done === "timeout") {
665
664
  // WEDGED (§3.6.1). The op is still running and still holds the lock; do NOT replace the worker.
666
665
  // Surface the caller's INDETERMINATE outcome, hold the FIFO, and resume when the op finally
667
666
  // settles (it commits/rolls back and releases the lock on the SAME warm connection).
668
- wedged = true;
667
+ // #3776 — name the op: "writer wedged" alone left an incident to guess which job held the lock.
668
+ wedgedOp = { op: entry.op, startedAt };
669
+ console.warn(`[writer-gateway] writer op ${entry.op} has held the writer past its ${writerTimeoutMs}ms deadline; writes are held until it settles`);
669
670
  rejectIndeterminate(entry);
670
671
  poolPromise.then(
671
672
  () => {},
672
673
  () => {},
673
674
  ).finally(() => {
674
- wedged = false;
675
+ console.warn(`[writer-gateway] wedged writer op ${entry.op} settled after ${Math.round(performance.now() - startedAt)}ms`);
676
+ wedgedOp = undefined;
675
677
  kickDrain();
676
678
  }).catch((error) => console.error(`[writer-gateway] resume after wedge failed: ${errMessage(error)}`));
677
679
  return;
@@ -701,7 +703,7 @@ function fanOutWorker(entry: Submission, result: WriterJobResult): void {
701
703
  entry.reject(new Error(`writer worker returned a ${result.kind} result for a single op`));
702
704
  return;
703
705
  }
704
- if (result.ok) entry.resolve(result.result);
706
+ if (result.ok) resolveWriterOp(entry, result.result);
705
707
  else entry.reject(reconstructDbError(result.error));
706
708
  return;
707
709
  }
package/src/dev.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { writeChildEnv } from "@humwick/sdk/env";
2
+ import { instanceDirectoryEnv } from "@humwick/sdk/isolated-env";
2
3
  import { execFile } from "node:child_process";
3
4
  import { shellQuote } from "@humwick/sdk/shell-utils";
4
5
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
@@ -209,7 +210,8 @@ export function createDevServicePlan(options: {
209
210
  }
210
211
  const envContent = `# ${DEV_MARKER}\n` + renderEnvFile(writeChildEnv({}, {
211
212
  AGENT_RELAY_TOKEN: token,
212
- AGENT_RELAY_HOME: rootDir,
213
+ ...instanceDirectoryEnv(rootDir, prefix),
214
+ AGENT_RELAY_DEV_PROFILE: "1",
213
215
  DB_PATH: join(rootDir, "state", "agent-relay.db"),
214
216
  HOST: host,
215
217
  PORT: String(port),
@@ -229,6 +231,7 @@ export function createDevServicePlan(options: {
229
231
  apiPort,
230
232
  tmuxPrefix: "ar-dev",
231
233
  env: writeChildEnv({}, {
234
+ ...instanceDirectoryEnv(rootDir, prefix),
232
235
  AGENT_RELAY_DEV_PROFILE: "1",
233
236
  }),
234
237
  };
@@ -296,8 +299,10 @@ export async function executeDevServicePlan(plan: DevServicePlan, options: { dry
296
299
  const output: string[] = [];
297
300
  if (plan.action === "start" || plan.action === "restart") {
298
301
  // Upgrade installed environments before either service can adopt execution records (#3139).
299
- const existing = readFileSync(plan.envFile, "utf8").replace(/^(?:export\s+)?AGENT_RELAY_HOME=.*$/gm, "").trimEnd();
300
- await writeFile(plan.envFile, `${existing}\n${Object.entries(writeChildEnv({}, { AGENT_RELAY_HOME: plan.rootDir })).map(([key, value]) => `${key}=${shellQuote(value)}\n`).join("")}`, "utf8");
302
+ const paths = writeChildEnv(instanceDirectoryEnv(plan.rootDir, plan.prefix), { AGENT_RELAY_DEV_PROFILE: "1" });
303
+ const keys = Object.keys(paths).map((key) => key.replace("AGENT_RELAY_", "(?:AGENT_RELAY_|HUMWICK_)"));
304
+ const existing = readFileSync(plan.envFile, "utf8").replace(new RegExp(`^(?:export\\s+)?(?:${keys.join("|")})=.*$`, "gm"), "").trimEnd();
305
+ await writeFile(plan.envFile, `${existing}\n${Object.entries(paths).map(([key, value]) => `${key}=${shellQuote(value)}\n`).join("")}`, "utf8");
301
306
  }
302
307
  if (plan.action === "install") {
303
308
  for (const file of plan.files) {
@@ -1,5 +1,5 @@
1
- import type { HostView, Orchestrator } from "@humwick/sdk";
2
- import type { ProviderCatalogEntry } from "@humwick/sdk/provider-catalog";
1
+ import { errMessage, type HostView, type Orchestrator } from "@humwick/sdk";
2
+ import { resolveProviderSelection, type ProviderCatalogEntry } from "@humwick/sdk/provider-catalog";
3
3
  import type { DispatchTarget } from "./task-dispatcher";
4
4
  import { spawnPlacementRefusal, hostSpawnAdmission, hostIdentitiesById, spawnHostCapAdmission, type SpawnCapOptions } from "./spawn-placement";
5
5
  import { liveHostDisabledProviders } from "./host-provider-store";
@@ -17,13 +17,15 @@ export interface LiveTargetAdmission {
17
17
  targetUnavailableReason: (target: DispatchTarget) => string | undefined;
18
18
  }
19
19
 
20
- export function liveTargetAdmission(orchestrators: readonly Orchestrator[], views: readonly HostView[], orchestratorId?: string, capOpts: SpawnCapOptions = {}): LiveTargetAdmission {
20
+ export function liveTargetAdmission(orchestrators: readonly Orchestrator[], views: readonly HostView[], catalog: ProviderCatalogEntry[], orchestratorId?: string, capOpts: SpawnCapOptions = {}): LiveTargetAdmission {
21
21
  const identities = hostIdentitiesById(views);
22
22
  const byId = new Map(views.map((view) => [view.id, view]));
23
23
  const disabled = liveHostDisabledProviders();
24
24
  const capBlock = spawnHostCapAdmission(capOpts);
25
25
  const hosts = orchestrators.filter((host) => !orchestratorId || host.id === orchestratorId);
26
26
  const targetAdmission = ({ provider, model, effort }: DispatchTarget): TargetAdmission => {
27
+ try { resolveProviderSelection({ provider, model, effort }, catalog); }
28
+ catch { return { eligible: false, uncertainties: [] }; }
27
29
  let eligible = false;
28
30
  const uncertainties: TargetUncertainty[] = [];
29
31
  for (const host of hosts) {
@@ -34,9 +36,11 @@ export function liveTargetAdmission(orchestrators: readonly Orchestrator[], view
34
36
  }
35
37
  return { eligible, uncertainties };
36
38
  };
37
- const targetUnavailableReason = (target: DispatchTarget) => spawnPlacementRefusal(
38
- orchestrators, views, target.provider, target.model, target.effort, orchestratorId, capOpts,
39
- );
39
+ const targetUnavailableReason = (target: DispatchTarget) => {
40
+ try { resolveProviderSelection(target, catalog); }
41
+ catch (error) { return errMessage(error); }
42
+ return spawnPlacementRefusal(orchestrators, views, target.provider, target.model, target.effort, orchestratorId, capOpts);
43
+ };
40
44
  return { targetAdmission, targetUnavailableReason };
41
45
  }
42
46
 
@@ -1,7 +1,7 @@
1
1
  /** Precondition setup for the packaged-ephemeral landing-ingress Proof of Life.
2
2
  * Delivery and both crash boundaries run through the packaged Relay; this fixture only registers
3
3
  * the disposable workspace that its real ephemeral orchestrator will probe. */
4
- import { initDb } from "../db/schema.ts";
4
+ import { closeDb, openExistingDb } from "../db/connection.ts";
5
5
  import { upsertWorkspace } from "../db/workspaces.ts";
6
6
 
7
7
  const dbPath = process.env.DB_PATH;
@@ -13,7 +13,8 @@ if (!dbPath || !worktreePath || !orchestratorId || !baseSha) {
13
13
  throw new Error("usage: landing-ingress-proof-worker <worktree-path> <orchestrator-id> <base-sha>");
14
14
  }
15
15
 
16
- initDb(dbPath);
16
+ // The installed Relay already owns the schema; a fixture must not migrate its live DB (#3715).
17
+ openExistingDb(dbPath);
17
18
  upsertWorkspace({
18
19
  id: workspaceId,
19
20
  repoRoot: worktreePath,
@@ -27,4 +28,5 @@ upsertWorkspace({
27
28
  orchestratorId,
28
29
  metadata: {},
29
30
  });
31
+ closeDb();
30
32
  console.log(JSON.stringify({ workspaceId }));
@@ -1,3 +1,4 @@
1
+ import { trackRelayEvent } from "./relay-event-drain";
1
2
  import { errMessage } from "@humwick/sdk";
2
3
  import type { HealthCheck } from "./types";
3
4
  import {
@@ -166,7 +167,7 @@ export function setLagRegressionObserver(fn: EventLoopLagRegressionObserver | un
166
167
  * threshold rather than the diagnostic log threshold, and is a separate registration a caller can
167
168
  * leave unset (e.g. ephemeral mode) with no effect.
168
169
  */
169
- export type EventLoopLagBreakerObserver = (gapStartAt: number, gapEndAt: number, lagMs: number) => void;
170
+ export type EventLoopLagBreakerObserver = (gapStartAt: number, gapEndAt: number, lagMs: number) => void | Promise<void>;
170
171
 
171
172
  let breakerObserver: EventLoopLagBreakerObserver | undefined;
172
173
 
@@ -283,7 +284,8 @@ export function recordEventLoopLagSample(
283
284
  // timer callback, so a throw here would become an uncaught exception in the interval — guard it:
284
285
  // the breaker degrading is never worth killing the loop-lag sampler that watches for the freeze.
285
286
  try {
286
- breakerObserver(sampledAt - Math.max(0, elapsedMs), sampledAt, normalized);
287
+ const outcome = breakerObserver(sampledAt - Math.max(0, elapsedMs), sampledAt, normalized);
288
+ if (outcome) trackRelayEvent(outcome, "maintenance.lag-breaker");
287
289
  } catch (error) {
288
290
  console.warn(`[health] event-loop-lag breaker observer threw: ${errMessage(error)}`);
289
291
  }
@@ -11,7 +11,7 @@ export function yieldToEventLoop(): Promise<void> {
11
11
  * `moreWork`, so a backlog drains over runs instead of overrunning the deadline (a breaker strike). */
12
12
  export async function forEachPaced<T>(
13
13
  items: () => Iterable<T>,
14
- unit: (item: T) => void,
14
+ unit: (item: T) => unknown,
15
15
  opts: { signal?: AbortSignal; budgetMs: number; ready?: () => boolean },
16
16
  ): Promise<{ moreWork: boolean }> {
17
17
  await yieldToEventLoop();
@@ -20,7 +20,7 @@ export async function forEachPaced<T>(
20
20
  for (const item of items()) {
21
21
  if (opts.signal?.aborted) return { moreWork: false };
22
22
  if (performance.now() >= stopAt || opts.ready?.() === false) return { moreWork: true };
23
- unit(item);
23
+ await unit(item);
24
24
  await yieldToEventLoop();
25
25
  }
26
26
  return { moreWork: false };
package/src/events.ts CHANGED
@@ -19,7 +19,7 @@ export interface RelayEvent {
19
19
 
20
20
  type Listener = (event: RelayEvent) => void;
21
21
 
22
- const listeners = new Set<Listener>();
22
+ const listeners = new Map<Listener, string>();
23
23
  const fanoutQueue: Array<{ event: RelayEvent; lastSeq: number }> = [];
24
24
  let notifying = false;
25
25
 
@@ -33,12 +33,13 @@ export function emitRelayEvent(input: Omit<RelayEvent, "seq" | "timestamp">): Pr
33
33
  const appended = appendRelayEventInternal(input.type, input.source, input.data, input.subject, timestamp)!;
34
34
  return Promise.resolve(fanOutAppendedEvent(input, appended, timestamp));
35
35
  }
36
- return emitRelayEventAsync(structuredClone(input), { idempotencyKey: crypto.randomUUID() });
36
+ // #3614 — keyless: nothing resubmits this append, so a ledger row would only cost writes.
37
+ return trackRelayEvent(appendAndFanOut(structuredClone(input), {}), input.type);
37
38
  });
38
39
  }
39
40
 
40
41
  /** #3606 — fan out to the current listeners only: no bus_outbox row, no idempotency-ledger row, no
41
- * replay. For state the next tick supersedes anyway (dashboard viewer presence). */
42
+ * replay. For state the next tick supersedes anyway (dashboard viewer presence, agent liveness ticks). */
42
43
  export function emitEphemeralRelayEvent(input: Omit<RelayEvent, "seq" | "timestamp" | "ephemeral">): RelayEvent {
43
44
  return fanOutAppendedEvent({ ...input, ephemeral: true }, { seq: 0, lastSeq: 0 }, Date.now());
44
45
  }
@@ -71,7 +72,8 @@ async function appendAndFanOut(
71
72
  } catch (error) {
72
73
  // H5: a lost acknowledgement says nothing about commit. Re-submit the exact logical append
73
74
  // with the same durable key; the writer returns the first result without a second insert.
74
- if (!(error instanceof WriteIndeterminateError)) throw error;
75
+ // A keyless emit is at-most-once: it surfaces the error, and a committed row stays replayable.
76
+ if (!(error instanceof WriteIndeterminateError) || !options.idempotencyKey) throw error;
75
77
  appended = await getGateway().write("bus.append", args, { critical: true, idempotencyKey: options.idempotencyKey }) as unknown as typeof appended;
76
78
  }
77
79
  // A retry ledger result proves durable storage, not that this process owns a fresh live edge.
@@ -122,19 +124,19 @@ export function fanOutAppendedEvent(
122
124
 
123
125
  function notify(event: RelayEvent): void {
124
126
  measureEmit(event.type, true, () => {
125
- for (const listener of listeners) {
127
+ for (const [listener, name] of listeners) {
126
128
  try {
127
129
  listener(event);
128
130
  } catch (error) {
129
131
  // Event projections are isolated so one transport cannot block another; a failed one (e.g. a
130
132
  // BUSY write in a projection, #3643) is logged, not swallowed.
131
- console.warn(`[events] ${event.type} listener failed: ${errMessage(error)}`);
133
+ console.warn(`[events] ${event.type} listener ${name} failed: ${errMessage(error)}`, error instanceof Error ? error.stack : error);
132
134
  }
133
135
  }
134
136
  });
135
137
  }
136
138
 
137
- export function subscribeRelayEvents(listener: Listener): () => void {
138
- listeners.add(listener);
139
+ export function subscribeRelayEvents(listener: Listener, name = listener.name || "<anonymous>"): () => void {
140
+ listeners.set(listener, name);
139
141
  return () => listeners.delete(listener);
140
142
  }
@@ -0,0 +1,121 @@
1
+ // #3762 — warn before a host disk fills. Pure: the single-writer utilization op settles each beat
2
+ // against the stored one (same seam as gate-capacity-alert.ts), so each level change alerts once.
3
+ // Two triggers, one level ladder: used% crossing 85/92/97, or the free-space history projecting
4
+ // full within 24 h (6 h = high). An episode alerts once per worse level and clears with a notice.
5
+ import type { HostDiskWatch, HostMachineSample } from "@humwick/sdk";
6
+
7
+ export type DiskLevel = 1 | 2 | 3;
8
+
9
+ /** Used-share rungs: warn / high / critical. */
10
+ export const DISK_USED_PCT_LEVELS: readonly [number, number, number] = [85, 92, 97];
11
+ /** An episode only clears below this, so a disk hovering on a rung does not flap. */
12
+ export const DISK_CLEAR_USED_PCT = 82;
13
+ export const DISK_ETA_WARN_H = 24;
14
+ export const DISK_ETA_HIGH_H = 6;
15
+ /** Growth needs this much history before it is a rate rather than a blip. */
16
+ export const DISK_MIN_TREND_SPAN_MS = 3 * 3_600_000;
17
+ const HISTORY_SPACING_MS = 30 * 60_000;
18
+ const HISTORY_MAX_SPAN_MS = 25 * 3_600_000;
19
+ const TREND_WINDOW_MS = 24 * 3_600_000;
20
+
21
+ export type DiskAlert =
22
+ | {
23
+ kind: "low"; level: DiskLevel; since: number; freeMb: number; totalMb: number; path?: string;
24
+ /** Free-space decline over the trend window, MB/h; present only while declining. */
25
+ rateMbPerHour?: number; etaHours?: number; spanHours?: number;
26
+ }
27
+ | { kind: "recovered"; since: number; freeMb: number; totalMb: number; path?: string };
28
+
29
+ export interface DiskNotice {
30
+ subject: string;
31
+ body: string;
32
+ priority: "low" | "default" | "high" | "urgent";
33
+ idempotencyKey: string;
34
+ }
35
+
36
+ function usageLevel(usedPct: number): number {
37
+ return DISK_USED_PCT_LEVELS.filter((rung) => usedPct >= rung).length;
38
+ }
39
+
40
+ function growthLevel(etaHours: number | undefined): number {
41
+ if (etaHours === undefined) return 0;
42
+ return etaHours < DISK_ETA_HIGH_H ? 2 : etaHours < DISK_ETA_WARN_H ? 1 : 0;
43
+ }
44
+
45
+ function nextHistory(prev: HostDiskWatch["history"], at: number, freeMb: number): Array<[number, number]> {
46
+ const kept = (prev ?? []).filter(([t]) => t >= at - HISTORY_MAX_SPAN_MS && t < at);
47
+ const last = kept[kept.length - 1];
48
+ if (!last || at - last[0] >= HISTORY_SPACING_MS) kept.push([at, freeMb]);
49
+ return kept;
50
+ }
51
+
52
+ /** Decline rate over the oldest point inside the trend window, or undefined (too little history / not declining). */
53
+ function trend(history: Array<[number, number]>, at: number, freeMb: number): { rateMbPerHour: number; etaHours: number; spanHours: number } | undefined {
54
+ const oldest = history.find(([t]) => t >= at - TREND_WINDOW_MS);
55
+ if (!oldest || at - oldest[0] < DISK_MIN_TREND_SPAN_MS) return undefined;
56
+ const declineMb = oldest[1] - freeMb;
57
+ if (declineMb <= 0) return undefined;
58
+ const spanHours = (at - oldest[0]) / 3_600_000;
59
+ const rateMbPerHour = declineMb / spanHours;
60
+ return { rateMbPerHour, etaHours: freeMb / rateMbPerHour, spanHours };
61
+ }
62
+
63
+ /**
64
+ * Stamps the relay-owned disk watch onto the stored sample and names the one alert owed, if any.
65
+ * A beat with no disk pair keeps the previous watch (missing telemetry is not a state change).
66
+ */
67
+ export function settleDiskWatch(prev: HostMachineSample | undefined, next: HostMachineSample): { machine: HostMachineSample; alert?: DiskAlert } {
68
+ const before = prev?.diskWatch;
69
+ const { diskFreeMb: freeMb, diskTotalMb: totalMb } = next;
70
+ if (freeMb === undefined || totalMb === undefined || totalMb <= 0) {
71
+ return { machine: before ? { ...next, diskWatch: before } : next };
72
+ }
73
+ const history = nextHistory(before?.history, next.at, freeMb);
74
+ const projected = trend(history, next.at, freeMb);
75
+ const usedPct = ((totalMb - freeMb) / totalMb) * 100;
76
+ const level = Math.max(usageLevel(usedPct), growthLevel(projected?.etaHours));
77
+ const prevLevel = before?.level ?? 0;
78
+ const where = next.diskPath ? { path: next.diskPath } : {};
79
+
80
+ if (level > prevLevel) {
81
+ const since = before?.since ?? next.at;
82
+ const watch: HostDiskWatch = { level: level as DiskLevel, since, history };
83
+ return {
84
+ machine: { ...next, diskWatch: watch },
85
+ alert: {
86
+ kind: "low", level: level as DiskLevel, since, freeMb, totalMb, ...where,
87
+ ...(projected ? { rateMbPerHour: projected.rateMbPerHour, etaHours: projected.etaHours, spanHours: projected.spanHours } : {}),
88
+ },
89
+ };
90
+ }
91
+ if (prevLevel > 0 && level === 0 && usedPct < DISK_CLEAR_USED_PCT) {
92
+ return { machine: { ...next, diskWatch: { history } }, alert: { kind: "recovered", since: before!.since ?? next.at, freeMb, totalMb, ...where } };
93
+ }
94
+ return { machine: { ...next, diskWatch: { ...(before?.level ? { level: before.level, since: before.since } : {}), history } } };
95
+ }
96
+
97
+ const gb = (mb: number) => `${(mb / 1024).toFixed(mb >= 10_240 ? 0 : 1)} GB`;
98
+
99
+ export function composeDiskNotice(hostId: string, label: string, alert: DiskAlert): DiskNotice {
100
+ const volume = alert.path ? ` (${alert.path})` : "";
101
+ const usedPct = Math.round(((alert.totalMb - alert.freeMb) / alert.totalMb) * 100);
102
+ if (alert.kind === "recovered") {
103
+ return {
104
+ subject: `Disk recovered on ${label}`,
105
+ body: `${label}${volume} has ${gb(alert.freeMb)} free of ${gb(alert.totalMb)} (${usedPct}% used); the low-disk episode is over. (#3762)`,
106
+ priority: "low",
107
+ idempotencyKey: `host-disk:${hostId}:${alert.since}:recovered`,
108
+ };
109
+ }
110
+ const word = alert.level === 3 ? "CRITICAL" : alert.level === 2 ? "very low" : "low";
111
+ const growth = alert.rateMbPerHour !== undefined && alert.etaHours !== undefined
112
+ ? ` Free space fell ~${gb(alert.rateMbPerHour * 24)}/day over the last ${Math.round(alert.spanHours ?? 0)} h; at that rate it is full in ~${Math.max(1, Math.round(alert.etaHours))} h.`
113
+ : "";
114
+ return {
115
+ subject: `Disk ${word} on ${label}: ${gb(alert.freeMb)} free (${usedPct}% used)`,
116
+ body: `${label}${volume} has ${gb(alert.freeMb)} free of ${gb(alert.totalMb)} (${usedPct}% used).${growth} `
117
+ + "Check workspaces, runtime logs and caches on that host before agents start failing with ENOSPC. (#3762)",
118
+ priority: alert.level === 3 ? "urgent" : alert.level === 2 ? "high" : "default",
119
+ idempotencyKey: `host-disk:${hostId}:${alert.since}:${alert.level}`,
120
+ };
121
+ }