@humwick/server 0.130.2 → 0.130.4

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 (587) hide show
  1. package/bundled/prompts/manifest.json +1 -0
  2. package/bundled/prompts/task.hydration.md +1 -1
  3. package/bundled/roles/builder.md +1 -1
  4. package/docs/guides/sub-coordinators.md +12 -5
  5. package/docs/guides/tools-coordination.md +1 -0
  6. package/docs/guides/workflows.md +16 -0
  7. package/docs/openapi.json +175 -4
  8. package/package.json +8 -7
  9. package/public/assets/{MessageBubble-BWLqMGKG.js → MessageBubble-BOkmEvgZ.js} +2 -2
  10. package/public/assets/{PlanGraphPanel-3TlIQpjk.js → PlanGraphPanel-BkaDJp0r.js} +2 -2
  11. package/public/assets/{TraceView-Wimm0Czv.js → TraceView-B99Uu2yT.js} +2 -2
  12. package/public/assets/{VaultDecisionCard-Bau_vNax.js → VaultDecisionCard-DUIfTTFF.js} +2 -2
  13. package/public/assets/{activity-CrSurn-r.js → activity-ZIX0N1El.js} +2 -2
  14. package/public/assets/{agent-lineage-CknAJKcb.js → agent-lineage-kq9TPYFw.js} +2 -2
  15. package/public/assets/agent-liveness-DSQY1Aa_.js +2 -0
  16. package/public/assets/{agent-name-DKbiIhBo.js → agent-name-C_7F4DFR.js} +2 -2
  17. package/public/assets/{agent-profiles-DwF6EQ4R.js → agent-profiles-BNOcrGcY.js} +2 -2
  18. package/public/assets/{agent-project-badge-Diz4Sjjb.js → agent-project-badge-B6yAh70a.js} +2 -2
  19. package/public/assets/{agent-tools-CRhpRQza.js → agent-tools-CcrhmOzF.js} +2 -2
  20. package/public/assets/{agent-type-icon-LrUEU3lB.js → agent-type-icon-CXSLrKiq.js} +2 -2
  21. package/public/assets/{agents-B-v66C-4.js → agents-DIZG97_X.js} +2 -2
  22. package/public/assets/{analytics-BqCb-LKi.js → analytics-rasmoPjR.js} +2 -2
  23. package/public/assets/{artifact-viewer-kf4pGuAR.js → artifact-viewer-tBpTrEPb.js} +2 -2
  24. package/public/assets/{artifacts-DJevXcvg.js → artifacts-BNkrynP1.js} +2 -2
  25. package/public/assets/{artifacts-D32zyw4Y.js → artifacts-Bjq-ZyBA.js} +2 -2
  26. package/public/assets/{automation-BpRajx_5.js → automation-Cx422L3L.js} +2 -2
  27. package/public/assets/{backlog-D_UjTdzX.js → backlog-RuFQ8PUu.js} +2 -2
  28. package/public/assets/{busy-health-N3VEh4ao.js → busy-health-BvNQ9g5x.js} +2 -2
  29. package/public/assets/{channels-9jopungq.js → channels-DNbKAS0I.js} +2 -2
  30. package/public/assets/{chat-CSXrTB3C.js → chat-Bp3Fx73h.js} +3 -3
  31. package/public/assets/{code-preview-p1NnmqK0.js → code-preview-KIRZA6cz.js} +2 -2
  32. package/public/assets/{connectors-CZdqlDNL.js → connectors-k7vO4vvc.js} +2 -2
  33. package/public/assets/{cosmos-BgdsE4dG.js → cosmos-BuVoq1aw.js} +2 -2
  34. package/public/assets/{crate-agent-30aXTKva.js → crate-agent-irqlt4NH.js} +2 -2
  35. package/public/assets/{dependency-graph-B_jvw2GE.js → dependency-graph-D_rurNBz.js} +2 -2
  36. package/public/assets/{deploys-DoN6bAb5.js → deploys-yzZqIpxE.js} +2 -2
  37. package/public/assets/{display-BrKWFGJz.js → display-BemJG1f_.js} +2 -2
  38. package/public/assets/{files-D6XEu8Ng.js → files-DXWcrxOz.js} +2 -2
  39. package/public/assets/{fleet-C7jQWbw2.js → fleet-TEuOCZXE.js} +2 -2
  40. package/public/assets/{fleet-metrics-BiDs3MLx.js → fleet-metrics-BGoDAFI-.js} +2 -2
  41. package/public/assets/{formatted-body-impl-DyG0WsQS.js → formatted-body-impl-BB9eq9nN.js} +2 -2
  42. package/public/assets/{formatted-body-CQBwc1fb.js → formatted-body-qy2nTD_1.js} +3 -3
  43. package/public/assets/{host-providers-dialog-DKaW31dN.js → host-providers-dialog-BGPHxuwT.js} +2 -2
  44. package/public/assets/{index-CRHep3M9.js → index-BC5XZc0z.js} +5 -5
  45. package/public/assets/{index-MYAIwYTX.css → index-D8Rp9pz2.css} +1 -1
  46. package/public/assets/{insights-CzrtkpOE.js → insights-C-KQG0h-.js} +2 -2
  47. package/public/assets/{integrations-aVsUmigt.js → integrations-ClPRPyKU.js} +2 -2
  48. package/public/assets/{issue-ref-chip-BnSlM_95.js → issue-ref-chip-DbH8J9Ak.js} +2 -2
  49. package/public/assets/{log-viewer-qe7Ee47Z.js → log-viewer-PH4zVn24.js} +2 -2
  50. package/public/assets/{maintenance-NfjqFZAk.js → maintenance-5lV43uTL.js} +2 -2
  51. package/public/assets/{managed-agents-BiH0HgaE.js → managed-agents-BdgU35aX.js} +2 -2
  52. package/public/assets/{markdown-preview-BixaT3Xr.js → markdown-preview-DNT4OUwQ.js} +3 -3
  53. package/public/assets/{markdown-preview-impl-DNGlWIS3.js → markdown-preview-impl-CnCcPy0A.js} +2 -2
  54. package/public/assets/{memory-DNsCl6UX.js → memory--GgWH1gH.js} +2 -2
  55. package/public/assets/{messages-DopU1L1X.js → messages-CzFl_97O.js} +2 -2
  56. package/public/assets/{orchestrators-Cq7ckLQT.js → orchestrators-CVvJVkzv.js} +2 -2
  57. package/public/assets/overview-DsrZvE86.js +2 -0
  58. package/public/assets/{pairs-DE_m6rrE.js → pairs-D2d0d2py.js} +2 -2
  59. package/public/assets/{profile-icon-B3rfh77F.js → profile-icon-_SMuSbYF.js} +2 -2
  60. package/public/assets/{project-profile-instructions-DQWZE0kA.js → project-profile-instructions-Apn15y43.js} +2 -2
  61. package/public/assets/{projects-Br2Bd2h1.js → projects-D3B6kto5.js} +2 -2
  62. package/public/assets/{prompt-settings-BKvFsvGD.js → prompt-settings-DnPB6Ez6.js} +2 -2
  63. package/public/assets/provider-display-bWwiuedV.js +2 -0
  64. package/public/assets/{registry-Cw38_6gW.js → registry-D790cIhN.js} +2 -2
  65. package/public/assets/run-card-BCro-Odj.js +2 -0
  66. package/public/assets/{secrets-DxI-vzSq.js → secrets-CVXvfvbU.js} +2 -2
  67. package/public/assets/{service-access-settings-D9s_VJbd.js → service-access-settings-D3Xxqb9w.js} +2 -2
  68. package/public/assets/{settings-CKZTVGIx.js → settings-CoUC7Jci.js} +2 -2
  69. package/public/assets/shipping-D_Lp9n_J.js +2 -0
  70. package/public/assets/{stats-DyUBKyWI.js → stats-CXiNjB9S.js} +2 -2
  71. package/public/assets/{status-dot-DYqlEUhJ.js → status-dot-C703YIy1.js} +2 -2
  72. package/public/assets/store-BgDALGIX.js +9 -0
  73. package/public/assets/{tasks-Bh7Chr4-.js → tasks-DO0WpJCx.js} +2 -2
  74. package/public/assets/{teams-bowI7qVY.js → teams-FGkdi_tL.js} +2 -2
  75. package/public/assets/{terminal-viewer-BgVLHdsU.js → terminal-viewer-Dh8dSC7e.js} +3 -3
  76. package/public/assets/{terminal-viewer-impl-Dz22UPy6.js → terminal-viewer-impl-B5Zriip3.js} +2 -2
  77. package/public/assets/{use-agent-terminal-DSQQ-iY7.js → use-agent-terminal-CRUVDvLC.js} +2 -2
  78. package/public/assets/{use-decisions-samMQhQf.js → use-decisions-CoaqRh4l.js} +2 -2
  79. package/public/assets/{use-project-list-59LheVP7.js → use-project-list-X-BgT53X.js} +2 -2
  80. package/public/assets/{use-selectors-BZa25xEB.js → use-selectors-0X_UZkk-.js} +2 -2
  81. package/public/assets/{user-avatar-DHxlvUvV.js → user-avatar-CkLhVBGu.js} +2 -2
  82. package/public/assets/{versioned-prompt-editor-BmED5DnJ.js → versioned-prompt-editor-BkTi7eim.js} +2 -2
  83. package/public/assets/{work-queue-CSvpuNLz.js → work-queue-DDOLEyKo.js} +2 -2
  84. package/public/assets/{workflow-marker-DAZcj5qt.js → workflow-marker-CzOsB8BM.js} +2 -2
  85. package/public/assets/{workflows-DdmxRSyg.js → workflows-DJilvmRM.js} +2 -2
  86. package/public/assets/{workspaces-BxeKfVuF.js → workspaces-CHcfbLR3.js} +2 -2
  87. package/public/cosmos.html +4 -4
  88. package/public/index.html +29 -29
  89. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  90. package/runner/src/adapters/claude-api.ts +1 -1
  91. package/runner/src/adapters/claude-headless.ts +1 -1
  92. package/runner/src/adapters/claude-launch-exit.ts +26 -0
  93. package/runner/src/adapters/claude-session-probe.ts +1 -1
  94. package/runner/src/adapters/claude-tmux.ts +38 -10
  95. package/runner/src/adapters/claude.ts +28 -75
  96. package/runner/src/adapters/provider-quota-harvest.ts +20 -71
  97. package/runner/src/agent-runner/lifecycle-milestones.ts +2 -2
  98. package/runner/src/agent-runner/liveness-exchange.ts +104 -0
  99. package/runner/src/claude-system-prompt.ts +49 -0
  100. package/runner/src/launch-assembly.ts +14 -10
  101. package/runner/src/profile-home.ts +1 -1
  102. package/runner/src/project-instructions.ts +2 -2
  103. package/runner/src/provider-command.ts +18 -0
  104. package/runner/src/provider-setup.ts +3 -2
  105. package/runner/src/runner-core.ts +14 -15
  106. package/runner/src/runner-helpers.ts +0 -8
  107. package/runner/src/session-scratch.ts +6 -2
  108. package/runner/test-support/provisioning-context.ts +4 -2
  109. package/runner/test-support/runner-harness.ts +2 -1
  110. package/scripts/steward-policy-cleanup.ts +2 -2
  111. package/src/agent-authz.ts +2 -2
  112. package/src/agent-drive-arbiter.ts +3 -8
  113. package/src/agent-exit-cleanup-async.ts +2 -2
  114. package/src/agent-exit-cleanup.ts +23 -19
  115. package/src/agent-lifecycle-events.ts +112 -85
  116. package/src/agent-ref.ts +3 -2
  117. package/src/agent-status-events.ts +43 -14
  118. package/src/auth/login-link.ts +35 -0
  119. package/src/auth/password.ts +4 -3
  120. package/src/auth/session-refresh.ts +1 -1
  121. package/src/auth/session.test-fixture.ts +2 -2
  122. package/src/auth/session.ts +7 -7
  123. package/src/automations/crud.ts +8 -81
  124. package/src/automations/dispatch.ts +33 -58
  125. package/src/automations/index.ts +1 -1
  126. package/src/automations/persistence.ts +65 -0
  127. package/src/automations/precheck.ts +18 -16
  128. package/src/automations/read-async.ts +11 -0
  129. package/src/automations/reconcile.ts +30 -39
  130. package/src/automations/storage.ts +33 -10
  131. package/src/automations/write-async.ts +33 -0
  132. package/src/branch-land-notice.ts +3 -3
  133. package/src/branch-landed.ts +25 -23
  134. package/src/bus.ts +21 -19
  135. package/src/cd-deploy-notify.ts +2 -2
  136. package/src/ci/notifications.ts +4 -4
  137. package/src/ci/root-missing.ts +3 -3
  138. package/src/ci/transition-notify.ts +5 -5
  139. package/src/claude-app/oauth-http.ts +3 -3
  140. package/src/cli/index.ts +7 -1
  141. package/src/cli/init.ts +53 -0
  142. package/src/cli/orchestrator.ts +1 -7
  143. package/src/cli/setup.ts +6 -4
  144. package/src/cli/workflow.ts +12 -3
  145. package/src/commands-db.ts +4 -4
  146. package/src/commands-write.ts +8 -0
  147. package/src/compaction-watch.ts +10 -8
  148. package/src/config-store-write.ts +2 -2
  149. package/src/config.ts +4 -11
  150. package/src/connectors.ts +10 -8
  151. package/src/context-advisory.ts +22 -21
  152. package/src/db/agent-action-write.ts +36 -0
  153. package/src/db/agent-control-async.ts +9 -0
  154. package/src/db/agent-control-write.ts +49 -0
  155. package/src/db/agent-effort-observe.ts +22 -0
  156. package/src/db/agent-meta.ts +14 -3
  157. package/src/db/agents-async.ts +8 -5
  158. package/src/db/agents.ts +15 -12
  159. package/src/db/auth-identities.ts +2 -2
  160. package/src/db/automation-read-ops.ts +11 -0
  161. package/src/db/automation-write-ops.ts +46 -0
  162. package/src/db/blackboard.ts +2 -2
  163. package/src/db/browser-session-write.ts +32 -0
  164. package/src/db/bus-outbox-write-ops.ts +3 -1
  165. package/src/db/checkout-refresh-schema.ts +47 -0
  166. package/src/db/checkout-refresh.ts +5 -5
  167. package/src/db/command-agent-profile-backfill.ts +39 -0
  168. package/src/db/command-agent-profiles.ts +5 -1
  169. package/src/db/command-retention.ts +126 -0
  170. package/src/db/commands-planner-stats.test-fixture.ts +8 -0
  171. package/src/db/commands-read-ops.ts +16 -0
  172. package/src/db/connection.ts +1 -182
  173. package/src/db/context-carry-write.ts +74 -0
  174. package/src/db/continuations.ts +4 -4
  175. package/src/db/db-error-registry.ts +12 -0
  176. package/src/db/gateway.ts +26 -133
  177. package/src/db/history-retention-ops.ts +13 -0
  178. package/src/db/inbox-async.ts +2 -2
  179. package/src/db/inbox-read-ops.ts +1 -1
  180. package/src/db/inbox.ts +9 -3
  181. package/src/db/issue-associations.ts +2 -2
  182. package/src/db/issue-refs-async.ts +4 -1
  183. package/src/db/issue-refs-read-ops.ts +6 -0
  184. package/src/db/issue-refs.ts +8 -8
  185. package/src/db/kernel-event-log-schema.ts +2 -0
  186. package/src/db/land-boundaries.ts +51 -5
  187. package/src/db/land-gate-attestations.ts +2 -2
  188. package/src/db/landing-receipts.ts +2 -2
  189. package/src/db/lifecycle-context-write.ts +5 -0
  190. package/src/db/lifecycle-tail-async.ts +76 -0
  191. package/src/db/lifecycle-tail-write-ops.ts +62 -0
  192. package/src/db/lifecycle-write-window.ts +2 -1
  193. package/src/db/lineage-pair-dedupe-sql.ts +3 -3
  194. package/src/db/main-connection-mode.ts +11 -0
  195. package/src/db/main-connection-writes.ts +20 -2
  196. package/src/db/maintenance-job-runs-async.ts +2 -2
  197. package/src/db/maintenance-job-write-ops.ts +1 -1
  198. package/src/db/maintenance-pauses.ts +2 -2
  199. package/src/db/message-send.ts +4 -0
  200. package/src/db/messages.ts +31 -25
  201. package/src/db/migrations.ts +18 -1
  202. package/src/db/notification-write-ops.ts +19 -0
  203. package/src/db/operator-answer-write.ts +19 -0
  204. package/src/db/orchestrators.ts +10 -4
  205. package/src/db/pairs-async.ts +22 -1
  206. package/src/db/pairs-write-ops.ts +8 -3
  207. package/src/db/pairs.ts +41 -48
  208. package/src/db/plan-dispatch-schema.ts +5 -1
  209. package/src/db/plan-ready-notices.ts +43 -0
  210. package/src/db/plan-tools-include-migration.ts +36 -0
  211. package/src/db/plans-write-ops.ts +2 -0
  212. package/src/db/presence-buffer.ts +5 -0
  213. package/src/db/presence-loop.ts +18 -23
  214. package/src/db/presence-write.ts +0 -6
  215. package/src/db/project-entries-async.ts +14 -0
  216. package/src/db/project-entries-read-ops.ts +5 -1
  217. package/src/db/project-entries-write-ops.ts +8 -0
  218. package/src/db/project-entries.ts +15 -12
  219. package/src/db/project-journal.ts +2 -2
  220. package/src/db/project-trust-approvals.ts +2 -2
  221. package/src/db/prompt-templates.ts +4 -4
  222. package/src/db/read-op-marshaling-fixtures.ts +18 -0
  223. package/src/db/read-ops.ts +4 -0
  224. package/src/db/retention.ts +13 -2
  225. package/src/db/review-publish-write.ts +8 -0
  226. package/src/db/runtime-admin-async.ts +19 -0
  227. package/src/db/runtime-admin-write-ops.ts +36 -0
  228. package/src/db/runtime-tail-async.ts +288 -0
  229. package/src/db/runtime-tail-write-ops.ts +97 -0
  230. package/src/db/schema.ts +4 -1
  231. package/src/db/spawn-budget.ts +5 -0
  232. package/src/db/spawn-delegation.ts +3 -12
  233. package/src/db/sql-audit-indexes.ts +3 -0
  234. package/src/db/stats-async.ts +5 -3
  235. package/src/db/task-entity.ts +5 -4
  236. package/src/db/team-claim-policy.ts +60 -0
  237. package/src/db/teams-async.ts +4 -0
  238. package/src/db/teams-write-ops.ts +4 -0
  239. package/src/db/terminal-events.ts +15 -0
  240. package/src/db/timer-cutover-bodies.ts +292 -0
  241. package/src/db/timer-cutover-core.ts +37 -278
  242. package/src/db/timer-cutover-state.ts +40 -0
  243. package/src/db/timer-cutover-write-ops.ts +1 -40
  244. package/src/db/token-db-write-ops.ts +2 -0
  245. package/src/db/token-standing-async.ts +12 -0
  246. package/src/db/token-standing.ts +6 -9
  247. package/src/db/token-usage-retention.ts +33 -0
  248. package/src/db/token-usage-write-ops.ts +1 -1
  249. package/src/db/token-usage.ts +4 -1
  250. package/src/db/user-invites-async.ts +13 -0
  251. package/src/db/user-invites.ts +3 -3
  252. package/src/db/users.ts +14 -6
  253. package/src/db/workflow-execution.ts +3 -3
  254. package/src/db/workspaces.ts +8 -5
  255. package/src/db/write-ops.ts +31 -12
  256. package/src/db/writer-fault-seam.ts +2 -9
  257. package/src/db/writer-fault-test-ops.ts +18 -0
  258. package/src/db/writer-gateway.ts +42 -46
  259. package/src/dev.ts +12 -16
  260. package/src/event-loop-lag.ts +4 -2
  261. package/src/event-loop-yield.ts +2 -2
  262. package/src/events.ts +10 -8
  263. package/src/host-provider-store.ts +5 -4
  264. package/src/hub-metrics-report.ts +5 -1
  265. package/src/hub-metrics.ts +38 -18
  266. package/src/init.ts +299 -0
  267. package/src/injection-sweep-pacing.ts +6 -8
  268. package/src/invite-link.ts +16 -9
  269. package/src/land-gate-notifications.ts +11 -10
  270. package/src/land-gate-queue-progress.ts +3 -3
  271. package/src/land-settle-dispatch.ts +52 -92
  272. package/src/lifecycle-context-pressure.ts +11 -10
  273. package/src/lifecycle-manager.ts +104 -98
  274. package/src/maintenance/breaker.ts +18 -16
  275. package/src/maintenance/checkout-refresh.ts +18 -1
  276. package/src/maintenance/critical-job-watchdog.ts +3 -3
  277. package/src/maintenance/events.ts +3 -3
  278. package/src/maintenance/history-retention-job.ts +30 -0
  279. package/src/maintenance/jobs.ts +29 -67
  280. package/src/maintenance/long-running-work.ts +3 -1
  281. package/src/maintenance/offline-agent-prune-job.ts +28 -0
  282. package/src/maintenance/orphaned-sessions.ts +5 -4
  283. package/src/maintenance/pauses.ts +4 -10
  284. package/src/maintenance/plan-ready-notice-job.ts +71 -0
  285. package/src/maintenance/scheduler.ts +18 -13
  286. package/src/maintenance/stalled-delivery-pager.ts +4 -4
  287. package/src/maintenance/teams.ts +19 -30
  288. package/src/maintenance/workspaces.ts +17 -27
  289. package/src/managed-policy-escalation.ts +7 -7
  290. package/src/managed-policy.ts +3 -3
  291. package/src/managed-provider-gate.ts +5 -4
  292. package/src/managed-spawn-reservation.ts +5 -4
  293. package/src/mcp/index.ts +8 -8
  294. package/src/mcp/output-descriptions.ts +1 -1
  295. package/src/mcp/presentation.ts +2 -1
  296. package/src/mcp/runtime-output.ts +6 -1
  297. package/src/mcp/self-care-visibility.ts +2 -2
  298. package/src/mcp/spawn-targets-matrix.ts +10 -1
  299. package/src/mcp/tool-groups.ts +3 -2
  300. package/src/mcp/tool-roles.ts +81 -0
  301. package/src/mcp/tools-workspace.ts +1 -1
  302. package/src/mcp-blackboard-tools.ts +6 -5
  303. package/src/mcp-decision-tools.ts +7 -7
  304. package/src/mcp-egress-tools.ts +10 -9
  305. package/src/mcp-issue-activity-tools.ts +2 -2
  306. package/src/mcp-issue-association-tools.ts +4 -4
  307. package/src/mcp-issue-ref-tools.ts +3 -3
  308. package/src/mcp-merge-tools.ts +5 -5
  309. package/src/mcp-notification-subscription-tools.ts +14 -15
  310. package/src/mcp-output-levels.test-fixture.ts +1 -1
  311. package/src/mcp-profile-trust-tools.ts +1 -1
  312. package/src/mcp-project-journal-tools.ts +4 -12
  313. package/src/mcp-project-tools.ts +17 -18
  314. package/src/mcp-routing-policy-tools.ts +3 -2
  315. package/src/mcp-team-tools.ts +6 -6
  316. package/src/mcp-workflow-tools.ts +5 -3
  317. package/src/memory-area-injection.ts +13 -12
  318. package/src/memory-boundary-capture.ts +6 -6
  319. package/src/memory-injection.ts +45 -43
  320. package/src/merge-pause-maintenance.ts +5 -4
  321. package/src/notification-router.ts +44 -17
  322. package/src/notify.ts +5 -5
  323. package/src/observed-reset-refresh.ts +4 -4
  324. package/src/operator-alarm.ts +2 -5
  325. package/src/project-ingest.ts +6 -6
  326. package/src/project-instructions.ts +8 -1
  327. package/src/project-trust.ts +12 -11
  328. package/src/prompt-resolver.ts +3 -3
  329. package/src/provider-quota-async.ts +5 -7
  330. package/src/provider-timeline-event.ts +4 -7
  331. package/src/quota-band-delivery.ts +2 -2
  332. package/src/recipe-runner.ts +4 -3
  333. package/src/retention-config-store.ts +4 -3
  334. package/src/reviewer-pipeline.ts +11 -10
  335. package/src/routes/_route.ts +4 -4
  336. package/src/routes/_shared.ts +13 -12
  337. package/src/routes/agent-effort.ts +5 -5
  338. package/src/routes/agent-heartbeat-quota.ts +23 -0
  339. package/src/routes/agent-keep.ts +1 -1
  340. package/src/routes/agent-reporting.ts +1 -1
  341. package/src/routes/agent-self-effort.ts +5 -5
  342. package/src/routes/agent-sessions.ts +24 -24
  343. package/src/routes/agents-spawn.ts +1 -1
  344. package/src/routes/agents.ts +17 -119
  345. package/src/routes/auth.ts +44 -17
  346. package/src/routes/authority-audit.ts +2 -2
  347. package/src/routes/automations.ts +6 -5
  348. package/src/routes/channel-binding-delete.ts +1 -1
  349. package/src/routes/channel-output.ts +3 -3
  350. package/src/routes/claude-api-budget.ts +5 -5
  351. package/src/routes/commands-listing.ts +1 -1
  352. package/src/routes/commands.ts +29 -27
  353. package/src/routes/context-resets.ts +2 -2
  354. package/src/routes/coordinator-teams.ts +1 -1
  355. package/src/routes/decisions.ts +2 -2
  356. package/src/routes/host-providers.ts +18 -0
  357. package/src/routes/host-secret-files.ts +1 -1
  358. package/src/routes/hosts.ts +11 -11
  359. package/src/routes/inbox.ts +3 -2
  360. package/src/routes/index.ts +7 -3
  361. package/src/routes/integrations.ts +9 -7
  362. package/src/routes/issue-activity.ts +2 -2
  363. package/src/routes/issue-associations.ts +4 -4
  364. package/src/routes/issue-refs.ts +3 -3
  365. package/src/routes/kernel-timers-operator.ts +1 -1
  366. package/src/routes/memory.ts +1 -1
  367. package/src/routes/merges.ts +11 -11
  368. package/src/routes/messages.ts +23 -17
  369. package/src/routes/orchestrator-bootstrap.ts +3 -1
  370. package/src/routes/orchestrator-host-registration.ts +2 -0
  371. package/src/routes/orchestrator-host-utilization.ts +2 -2
  372. package/src/routes/orchestrator-proxy.ts +2 -2
  373. package/src/routes/orchestrator.ts +27 -18
  374. package/src/routes/pairs.ts +8 -8
  375. package/src/routes/project-profile-instructions.ts +1 -1
  376. package/src/routes/project-trust.ts +1 -1
  377. package/src/routes/projects.ts +16 -16
  378. package/src/routes/prompt-templates.ts +12 -12
  379. package/src/routes/provider-quotas.ts +10 -10
  380. package/src/routes/run-command.ts +1 -1
  381. package/src/routes/secrets-backup.ts +4 -5
  382. package/src/routes/secrets-import.ts +3 -4
  383. package/src/routes/secrets-vault.ts +12 -14
  384. package/src/routes/settings.ts +1 -1
  385. package/src/routes/shipping.ts +9 -1
  386. package/src/routes/spawn-policy.ts +8 -7
  387. package/src/routes/sse.ts +2 -2
  388. package/src/routes/team-templates.ts +7 -7
  389. package/src/routes/teams.ts +10 -10
  390. package/src/routes/tokens.ts +18 -17
  391. package/src/routes/users.ts +24 -24
  392. package/src/routes/viewer-read.ts +3 -3
  393. package/src/routes/web-tool-calls.ts +4 -4
  394. package/src/routes/workflows.ts +2 -2
  395. package/src/routes/workspaces.ts +17 -16
  396. package/src/routing-policy-push.ts +6 -6
  397. package/src/runtime-grant.ts +17 -11
  398. package/src/runtime-install.ts +30 -0
  399. package/src/runtime-tokens.ts +20 -28
  400. package/src/secrets-broker/config.ts +1 -1
  401. package/src/secrets-broker/service.ts +2 -2
  402. package/src/security.ts +3 -1
  403. package/src/self-resume-carry.ts +21 -110
  404. package/src/self-resume-supersede.ts +4 -3
  405. package/src/self-resume.ts +54 -66
  406. package/src/server-background.ts +1 -1
  407. package/src/server.ts +25 -26
  408. package/src/services/agent-action.ts +12 -31
  409. package/src/services/agent-effort.ts +7 -32
  410. package/src/services/agent-hang-watchdog-job.ts +2 -2
  411. package/src/services/agent-heartbeat.ts +166 -0
  412. package/src/services/agent-reporting.ts +1 -1
  413. package/src/services/auth-context.ts +6 -0
  414. package/src/services/browser-inventory.ts +3 -3
  415. package/src/services/browser-session-state.ts +3 -2
  416. package/src/services/browser-session.ts +21 -27
  417. package/src/services/bus-command-update.ts +9 -9
  418. package/src/services/checkout-refresh-state.ts +1 -0
  419. package/src/services/checkout-refresh.test-fixture.ts +3 -2
  420. package/src/services/command-host.ts +7 -2
  421. package/src/services/coordinator-digest.ts +3 -2
  422. package/src/services/dispatch-command.ts +12 -13
  423. package/src/services/effective-launch-driver.ts +14 -9
  424. package/src/services/host-changed-paths.test-fixture.ts +5 -6
  425. package/src/services/host-project-readiness.ts +2 -2
  426. package/src/services/host-providers.ts +1 -1
  427. package/src/services/host-utilization.ts +9 -9
  428. package/src/services/idle-agent-digest.ts +17 -12
  429. package/src/services/idle-epics.ts +4 -4
  430. package/src/services/interrupt-agent.ts +12 -9
  431. package/src/services/issue-activity.ts +3 -3
  432. package/src/services/issue-associations.ts +15 -18
  433. package/src/services/issue-lifecycle-comments.ts +3 -2
  434. package/src/services/issue-lifecycle.ts +14 -13
  435. package/src/services/issue-refs.ts +4 -5
  436. package/src/services/kernel-timers-cutover-chaos-worker.ts +1 -1
  437. package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
  438. package/src/services/kernel-timers-ingress.ts +3 -3
  439. package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
  440. package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
  441. package/src/services/kernel-timers-outbox.ts +1 -1
  442. package/src/services/kernel-timers-stage10-operator.ts +1 -1
  443. package/src/services/kernel-timers.ts +4 -3
  444. package/src/services/land-gate-placement.ts +11 -2
  445. package/src/services/land-issue-relations.ts +5 -4
  446. package/src/services/land-restart-retry.ts +7 -6
  447. package/src/services/landed-ancestry.ts +6 -5
  448. package/src/services/legacy-landing-host.ts +4 -1
  449. package/src/services/legacy-landing-recovery.ts +8 -6
  450. package/src/services/managed-running.ts +17 -17
  451. package/src/services/memory-areas.ts +3 -3
  452. package/src/services/merge-pause.ts +9 -15
  453. package/src/services/operator-decisions.ts +37 -41
  454. package/src/services/orchestrator-registration-recovery.ts +6 -2
  455. package/src/services/orchestrator-upgrade.ts +14 -12
  456. package/src/services/permission-decision.ts +4 -3
  457. package/src/services/plan-ci-notice.ts +1 -1
  458. package/src/services/plan-conformance.ts +4 -4
  459. package/src/services/plan-dispatch-policy.ts +10 -3
  460. package/src/services/plan-dispatch.ts +35 -14
  461. package/src/services/plan-graph.ts +39 -261
  462. package/src/services/plan-import.ts +1 -1
  463. package/src/services/plan-live-bindings.ts +8 -37
  464. package/src/services/plan-task-create.ts +1 -1
  465. package/src/services/plan-terminal-refs.ts +2 -12
  466. package/src/services/plan-wake-digest.ts +8 -3
  467. package/src/services/profile-trust.ts +2 -2
  468. package/src/services/project.ts +11 -10
  469. package/src/services/prompt-templates.ts +6 -5
  470. package/src/services/provider-api-key.ts +73 -0
  471. package/src/services/provider-hold-nudge.ts +9 -9
  472. package/src/services/provider-hold-record.ts +13 -12
  473. package/src/services/provider-state-audit.ts +19 -18
  474. package/src/services/provisioning-harness/driver.ts +1 -1
  475. package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
  476. package/src/services/provisioning-harness/lifecycle.ts +24 -22
  477. package/src/services/provisioning-harness/prepare.ts +16 -17
  478. package/src/services/rate-limit-resume.ts +10 -9
  479. package/src/services/red-main-auto-revert.ts +7 -5
  480. package/src/services/red-main-controller-deps.ts +20 -3
  481. package/src/services/red-main-incident.ts +3 -1
  482. package/src/services/red-main-quarantine.ts +2 -3
  483. package/src/services/register-agent.ts +22 -22
  484. package/src/services/restart-project-role.ts +1 -1
  485. package/src/services/restart-spawn.ts +17 -16
  486. package/src/services/review-publish.ts +7 -24
  487. package/src/services/review-ref-reconcile.ts +29 -38
  488. package/src/services/runtime-dependency-alert.ts +27 -0
  489. package/src/services/scheduler-command.ts +11 -9
  490. package/src/services/scheduler.ts +5 -5
  491. package/src/services/self-effort-grant.ts +5 -25
  492. package/src/services/send-message.ts +16 -33
  493. package/src/services/shutdown-agent.ts +17 -14
  494. package/src/services/spawn-agent.ts +12 -41
  495. package/src/services/spawn-chain-inspector.ts +1 -1
  496. package/src/services/spawn-cwd-placement.ts +21 -5
  497. package/src/services/spawn-issue-activity.ts +8 -6
  498. package/src/services/spawn-launch.ts +17 -1
  499. package/src/services/spawn-loss-escalation.ts +1 -1
  500. package/src/services/spawn-registration-watchdog.ts +2 -2
  501. package/src/services/spawn-repo-probe.ts +7 -5
  502. package/src/services/spawn-tree-cleanup.ts +7 -8
  503. package/src/services/steward-reaper.ts +4 -4
  504. package/src/services/task-context-hydration.ts +25 -1
  505. package/src/services/task-delivery.ts +20 -34
  506. package/src/services/task-entity.ts +40 -203
  507. package/src/services/task-issue-link.ts +13 -20
  508. package/src/services/task-issue-weave.ts +12 -11
  509. package/src/services/task-lifecycle.ts +27 -31
  510. package/src/services/task-repo-cwd.ts +37 -0
  511. package/src/services/task-review-hold.ts +4 -17
  512. package/src/services/task-semantic-events.ts +13 -11
  513. package/src/services/task-state-reconcile.ts +3 -4
  514. package/src/services/task-validation.ts +2 -2
  515. package/src/services/team-templates.ts +5 -5
  516. package/src/services/team.ts +31 -98
  517. package/src/services/terminal-provider-exit.ts +6 -5
  518. package/src/services/timer-message-fire-chaos-worker.ts +7 -3
  519. package/src/services/timer-message-fire-outbox.ts +1 -1
  520. package/src/services/transient-agent-reaper.ts +22 -19
  521. package/src/services/turn-reconcile-audit.ts +9 -9
  522. package/src/services/user-onboarding.ts +8 -6
  523. package/src/services/user-profile.ts +6 -9
  524. package/src/services/work-finality.ts +16 -4
  525. package/src/services/workflow-auto-start.ts +2 -1
  526. package/src/services/workflow-caller.ts +61 -4
  527. package/src/services/workflow-child-proof-worker.ts +1 -1
  528. package/src/services/workflow-control-proof-worker.ts +1 -1
  529. package/src/services/workflow-coordinator.ts +8 -2
  530. package/src/services/workflow-decisions.ts +5 -5
  531. package/src/services/workflow-deferred-cleanup.ts +1 -1
  532. package/src/services/workflow-effect-driver.ts +42 -19
  533. package/src/services/workflow-effects.ts +41 -27
  534. package/src/services/workflow-pins.ts +7 -4
  535. package/src/services/workflow-reconcile.ts +1 -0
  536. package/src/services/workflow-resume-pins.ts +3 -3
  537. package/src/services/workflow-routing-defaults.ts +18 -0
  538. package/src/services/workflow-run-view.ts +4 -3
  539. package/src/services/workflow-run.test-fixture.ts +1 -1
  540. package/src/services/workflow-runs.ts +34 -22
  541. package/src/services/workflow-supervisor-state.ts +21 -1
  542. package/src/services/workflow-supervisor.ts +4 -3
  543. package/src/services/workspace-recovery.ts +4 -3
  544. package/src/setup.ts +47 -8
  545. package/src/spawn-admission.ts +10 -2
  546. package/src/spawn-placement.ts +27 -9
  547. package/src/spawn-targets.ts +8 -8
  548. package/src/sse-agent-status.ts +15 -6
  549. package/src/sse.ts +49 -24
  550. package/src/startup-context-injection.ts +61 -57
  551. package/src/steward-handoff.ts +4 -3
  552. package/src/steward-policy-cleanup.ts +9 -8
  553. package/src/steward.ts +2 -2
  554. package/src/task-dispatch-live.ts +5 -2
  555. package/src/task-dispatcher.ts +2 -2
  556. package/src/token-db.ts +2 -2
  557. package/src/token-usage-async.ts +2 -4
  558. package/src/user-awaiting-reply.ts +5 -5
  559. package/src/utils.ts +7 -0
  560. package/src/workspace-actions.ts +24 -29
  561. package/src/workspace-auto-merge.ts +14 -12
  562. package/src/workspace-changed-paths-client.ts +16 -5
  563. package/src/workspace-cleanup-stale.ts +30 -7
  564. package/src/workspace-command-settle.ts +24 -16
  565. package/src/workspace-config.ts +1 -1
  566. package/src/workspace-conflict-resolver.ts +9 -7
  567. package/src/workspace-dead-owner-recovery.ts +5 -4
  568. package/src/workspace-escalation.ts +12 -11
  569. package/src/workspace-human-escalation.ts +3 -3
  570. package/src/workspace-land-gate-watchdog.ts +3 -3
  571. package/src/workspace-land-refusal.ts +20 -0
  572. package/src/workspace-land-stopped.ts +1 -0
  573. package/src/workspace-merge.ts +10 -26
  574. package/src/workspace-nothing-to-land-notice.ts +2 -2
  575. package/src/workspace-orphans.ts +18 -37
  576. package/src/workspace-pr-completion.ts +10 -8
  577. package/src/workspace-rekey.ts +3 -3
  578. package/src/workspace-steward-failure.ts +2 -2
  579. package/src/workspace-steward-wake.ts +2 -2
  580. package/public/assets/agent-liveness-CaNwK0Zf.js +0 -2
  581. package/public/assets/overview-C1DCTzzV.js +0 -2
  582. package/public/assets/provider-display-DsuWMvVL.js +0 -2
  583. package/public/assets/run-card-CpKqRbhg.js +0 -2
  584. package/public/assets/shipping-B9YtnwtG.js +0 -2
  585. package/public/assets/store-DcClXLH0.js +0 -9
  586. package/runner/src/agent-runner/http-liveness.ts +0 -85
  587. package/src/db/on-loop-write-transaction.ts +0 -34
@@ -3,5 +3,5 @@ import type { WorkspaceConfig } from "@humwick/sdk";
3
3
  // Single source for the isolated-worktree symlink default (config-store + settings registry).
4
4
  // Only the untracked rig config is linked; AGENTS.md is tracked (#3516), so a worktree gets it from git.
5
5
  export const WORKSPACE_CONFIG_DEFAULTS: WorkspaceConfig = {
6
- symlinkPaths: [".claude-rig"],
6
+ symlinkPaths: [],
7
7
  };
@@ -81,7 +81,8 @@ async function withdrawArmedLand(ws: WorkspaceRecord, reason: string): Promise<"
81
81
  export async function handBackLandConflict(ws: WorkspaceRecord, now: number, why: string): Promise<ConflictHandback> {
82
82
  const meta = ws.metadata as Record<string, unknown>;
83
83
  if (conflictHandedBackForArm(meta)) return "skipped";
84
- const instructions = handbackInstructions(ws, why);
84
+ const cause = typeof meta.mergeError === "string" ? meta.mergeError : undefined;
85
+ const instructions = handbackInstructions(ws, cause && !why.includes(cause) ? `${why}: ${cause}` : why);
85
86
  const withdrawn = await withdrawArmedLand(ws, instructions);
86
87
  // The steward's shutdown fences the row out of every other lane until it settles: the sweep
87
88
  // retries this pending hand-back (workspace-steward-watchdog.ts), never the steward path.
@@ -106,7 +107,7 @@ export async function handBackLandConflict(ws: WorkspaceRecord, now: number, why
106
107
  // One notice per recipient: it also wakes the owner, so no separate `landed-failure` (whose per-arm key
107
108
  // the land-conflict Task notice already holds). A notify failure falls through to the operator alarm.
108
109
  try {
109
- routeNotification({
110
+ await routeNotification({
110
111
  type: "workspace.stranded_escalation", forceDelivery: true, ttlMs: null,
111
112
  scope: { workspaceId: ws.id, repoRoot: ws.repoRoot, author: ws.ownerAgentId, parent: coordinator ?? undefined },
112
113
  recipients,
@@ -130,14 +131,14 @@ export async function handBackLandConflict(ws: WorkspaceRecord, now: number, why
130
131
  }
131
132
  }
132
133
 
133
- raiseOperatorAlarm({
134
+ (await raiseOperatorAlarm({
134
135
  clientId: `steward-handoff-unescalatable-${ws.id}:${strandKey}`,
135
136
  source: "workspace-steward-handoff-watchdog",
136
137
  subject: "Land conflict has no one to hand it back to",
137
138
  detail: `${branchLabel} in ${ws.repoRoot} has an unresolved land conflict and no owner, coordinator, or fallback to hand it back to (${why}). Configure AGENT_RELAY_WORKSPACE_STEWARD_FALLBACK or land/reclaim the worktree manually.`,
138
139
  view: "orchestrators",
139
140
  metadata: { maintenanceJobId: "workspace-steward-handoff-watchdog", workspaceId: ws.id, repoRoot: ws.repoRoot, branch: ws.branch, reason: why },
140
- });
141
+ }));
141
142
  await transitionWorkspaceLandStateAsync(ws.id, "merge-error", { stewardHandoffEscalatedAt: now, stewardUnavailable: true, conflictHandbackPending: undefined, ...stewardEnded });
142
143
  if (withdrawn === "none") await finishWorkspaceStewardHandoff(ws);
143
144
  await createActivityEventAsync({
@@ -167,14 +168,15 @@ export async function superviseLandConflict(ws: WorkspaceRecord, reason: string,
167
168
 
168
169
  const inFlight = new Set<Promise<unknown>>();
169
170
 
170
- /** Fire-and-forget form for settle paths that must not await the wake (#1790). */
171
- export function superviseLandConflictLater(workspaceId: string, reason: string, opts: { tip?: string } = {}): void {
171
+ /** Track the wake so deferred settle queues can drain its committed effects (#1790/#1870). */
172
+ export function superviseLandConflictLater(workspaceId: string, reason: string, opts: { tip?: string } = {}): Promise<void> {
172
173
  const ws = getWorkspace(workspaceId);
173
- if (!ws) return;
174
+ if (!ws) return Promise.resolve();
174
175
  const run = superviseLandConflict(ws, reason, opts)
175
176
  .catch((error) => console.warn(`[workspace-conflict-resolver] supervising ${workspaceId} failed; the hand-off watchdog retries: ${errMessage(error)}`))
176
177
  .finally(() => inFlight.delete(run));
177
178
  inFlight.add(run);
179
+ return run.then(() => {});
178
180
  }
179
181
 
180
182
  export async function settleConflictSupervisionForTests(): Promise<void> {
@@ -1,19 +1,20 @@
1
+ import { createCommandAsync } from "./commands-write";
1
2
  // Host-bound rescue for an unpushed dead-owner workspace. Kept separate from
2
3
  // the orphan sweep so command construction remains reusable without inflating
3
4
  // the disk⇄DB reconciler.
4
5
  import type { WorkspaceRecord } from "./types";
5
- import { createCommand } from "./commands-db";
6
+
6
7
  import { emitCommandEvent } from "./command-events";
7
8
 
8
- export function dispatchDeadOwnerRescue(orch: { agentId: string }, workspace: WorkspaceRecord): string {
9
- const command = createCommand({
9
+ export async function dispatchDeadOwnerRescue(orch: { agentId: string }, workspace: WorkspaceRecord): Promise<string> {
10
+ const command = (await createCommandAsync({
10
11
  type: "workspace.reconcile", source: "system", target: orch.agentId, correlationId: workspace.id,
11
12
  params: {
12
13
  action: "reconcile", workspaceId: workspace.id, repoRoot: workspace.repoRoot,
13
14
  worktreePath: workspace.worktreePath, branch: workspace.branch, baseRef: workspace.baseRef,
14
15
  baseSha: workspace.baseSha, autoReclaim: "dead-owner", requestedBy: "workspace-dead-owner-reaper", requestedAt: Date.now(),
15
16
  },
16
- });
17
+ }));
17
18
  emitCommandEvent(command, `command.${command.status}`);
18
19
  return command.id;
19
20
  }
@@ -1,5 +1,6 @@
1
+ import { claimWorkspaceHumanEscalationAlertAsync } from "./db/runtime-tail-async";
1
2
  import { stewardFallbackTarget } from "./config";
2
- import { claimWorkspaceHumanEscalationAlert } from "./db";
3
+
3
4
  import { routeNotification } from "./notification-router";
4
5
  import { raiseOperatorAlarm } from "./operator-alarm";
5
6
  import { resolveStewardIdentity } from "./steward-identity";
@@ -18,7 +19,7 @@ export interface WorkspaceCustodyEscalationInput {
18
19
  idempotencyKey?: string;
19
20
  }
20
21
 
21
- export function routeWorkspaceCustodyEscalation(input: WorkspaceCustodyEscalationInput): string[] {
22
+ export async function routeWorkspaceCustodyEscalation(input: WorkspaceCustodyEscalationInput): Promise<string[]> {
22
23
  const { ownerAgentId, coordinatorAgentId } = resolveStewardIdentity(input.workspace);
23
24
  const fallback = stewardFallbackTarget();
24
25
  const recipients = [...new Set([ownerAgentId, coordinatorAgentId, fallback].filter((value): value is string => Boolean(value)))];
@@ -31,7 +32,7 @@ export function routeWorkspaceCustodyEscalation(input: WorkspaceCustodyEscalatio
31
32
  // the caller's idempotencyKey (which already bakes in the condition
32
33
  // fingerprint) so an unchanged condition never re-sends, while a real change
33
34
  // (new key) still alerts.
34
- if (input.idempotencyKey && !claimWorkspaceHumanEscalationAlert(input.idempotencyKey)) {
35
+ if (input.idempotencyKey && !(await claimWorkspaceHumanEscalationAlertAsync(input.idempotencyKey))) {
35
36
  const channelId = workspaceHumanEscalationChannelId();
36
37
  return channelId ? [channelId] : [];
37
38
  }
@@ -41,18 +42,18 @@ export function routeWorkspaceCustodyEscalation(input: WorkspaceCustodyEscalatio
41
42
  ownerAgentId,
42
43
  fallbackTarget: fallback || undefined,
43
44
  };
44
- const human = notifyWorkspaceHumanEscalation({
45
+ const human = (await notifyWorkspaceHumanEscalation({
45
46
  subject: input.subject,
46
47
  body: input.body,
47
48
  payload,
48
49
  source: "workspace-custody",
49
- });
50
+ }));
50
51
  if (human.accepted && human.channelId) return [human.channelId];
51
52
  console.warn(`[workspace-escalation] zero agent recipients and no human channel for workspace ${input.workspace.id}: ${human.reason ?? "unknown reason"}`);
52
53
  return [];
53
54
  }
54
55
 
55
- routeNotification({
56
+ await routeNotification({
56
57
  type: input.type ?? "workspace.stranded_escalation",
57
58
  scope: {
58
59
  workspaceId: input.workspace.id,
@@ -84,13 +85,13 @@ export function routeWorkspaceCustodyEscalation(input: WorkspaceCustodyEscalatio
84
85
  // undefined) and most `review_requested` auto-abandons have no agent to page by default,
85
86
  // so without this the notice is swallowed and the strand loops in the dark. Returns the
86
87
  // (possibly empty) recipient list so the caller can still decide whether to stamp state.
87
- export function routeWorkspaceCustodyEscalationOrAlarm(
88
+ export async function routeWorkspaceCustodyEscalationOrAlarm(
88
89
  input: WorkspaceCustodyEscalationInput & { source: string },
89
- ): string[] {
90
+ ): Promise<string[]> {
90
91
  const { source, ...escalation } = input;
91
- const targets = routeWorkspaceCustodyEscalation(escalation);
92
+ const targets = await routeWorkspaceCustodyEscalation(escalation);
92
93
  if (!targets.length) {
93
- raiseOperatorAlarm({
94
+ (await raiseOperatorAlarm({
94
95
  clientId: `${escalation.idempotencyKey ?? `${escalation.workspace.id}:${escalation.subject}`}:no-recipients`,
95
96
  source,
96
97
  subject: escalation.subject,
@@ -101,7 +102,7 @@ export function routeWorkspaceCustodyEscalationOrAlarm(
101
102
  branch: escalation.workspace.branch,
102
103
  status: escalation.workspace.status,
103
104
  },
104
- });
105
+ }));
105
106
  }
106
107
  return targets;
107
108
  }
@@ -43,7 +43,7 @@ export function warnIfNoHumanReachableEscalationTarget(log: (message: string) =>
43
43
  return true;
44
44
  }
45
45
 
46
- export function notifyWorkspaceHumanEscalation(input: WorkspaceHumanEscalationInput): WorkspaceHumanEscalationResult {
46
+ export async function notifyWorkspaceHumanEscalation(input: WorkspaceHumanEscalationInput): Promise<WorkspaceHumanEscalationResult> {
47
47
  const channelId = workspaceHumanEscalationChannelId();
48
48
  if (!channelId) return { accepted: false, reason: "no human escalation channel configured" };
49
49
  if (!getChannel(channelId)) return { accepted: false, reason: `human escalation channel ${channelId} is not registered` };
@@ -59,9 +59,9 @@ export function notifyWorkspaceHumanEscalation(input: WorkspaceHumanEscalationIn
59
59
 
60
60
  try {
61
61
  if (channelId === DEFAULT_NTFY_CHANNEL_ID) {
62
- relayNotifyNtfy(event, input.idempotencyKey);
62
+ (await relayNotifyNtfy(event, input.idempotencyKey));
63
63
  } else {
64
- relayEgressToChannel({ channelId, event }, undefined, input.idempotencyKey);
64
+ (await relayEgressToChannel({ channelId, event }, undefined, input.idempotencyKey));
65
65
  }
66
66
  return { accepted: true, channelId };
67
67
  } catch (error) {
@@ -41,21 +41,21 @@ export async function runLandGateFailureWatchdog(opts: { now?: number; delayMs?:
41
41
  const coordinator = resolveCoordinatorAgentId(owner);
42
42
  const target = coordinator ?? stewardFallbackTarget() ?? owner;
43
43
  if (!target) {
44
- raiseOperatorAlarm({
44
+ (await raiseOperatorAlarm({
45
45
  clientId: `land-gate-failed-unescalatable:${fresh.id}:${failure.notifiedAt}`,
46
46
  source: "workspace-land-gate-watchdog",
47
47
  subject: "Land gate failure has no escalation recipient",
48
48
  detail: `${fresh.branch ?? fresh.id} remains blocked by required gate ${failure.gateName ?? "(unknown)"} with no author, coordinator, or configured fallback.`,
49
49
  view: "orchestrators",
50
50
  metadata: { workspaceId: fresh.id, repoRoot: fresh.repoRoot, branch: fresh.branch, gateName: failure.gateName },
51
- });
51
+ }));
52
52
  await patchWorkspaceMetadataAsync(fresh.id, { landGateFailureEscalatedAt: now });
53
53
  escalated.push(fresh.id);
54
54
  continue;
55
55
  }
56
56
  const targetAgent = getAgent(target);
57
57
  const enabled = notificationEnabledFor("workspace.land_gate_failed", { agentId: target, teamId: targetAgent?.teamId });
58
- routeNotification({
58
+ await routeNotification({
59
59
  type: "workspace.land_gate_failed",
60
60
  scope: { author: owner, parent: coordinator ?? undefined, repoRoot: fresh.repoRoot, workspaceId: fresh.id },
61
61
  recipients: [target],
@@ -0,0 +1,20 @@
1
+ import type { WorkspaceRecord } from "@humwick/sdk";
2
+ import { updateWorkspaceStatusAsync } from "./db";
3
+ import { notifyBranchLandFailed } from "./branch-landed";
4
+ import { deferLandSettleSideEffect } from "./land-settle-dispatch";
5
+ import { landStoppedFact, recordLandStopped } from "./workspace-land-stopped";
6
+
7
+ export class LandConfigurationError extends Error {}
8
+
9
+ /** A new delivery arms a new hand-off; base movement cannot repair a refused configuration (#3824). */
10
+ export function workspaceLandRefused(workspace: WorkspaceRecord): boolean {
11
+ const stop = landStoppedFact(workspace.metadata);
12
+ return stop?.reason === "refused" && stop.handoff === workspace.metadata.landRequestAttemptAt;
13
+ }
14
+
15
+ export async function refuseWorkspaceLand(workspace: WorkspaceRecord, reason: string, commandId?: string): Promise<void> {
16
+ if (workspaceLandRefused(workspace)) return;
17
+ const current = await updateWorkspaceStatusAsync(workspace.id, "review_requested", { mergeError: reason });
18
+ await recordLandStopped(workspace.id, "refused", reason, { final: true });
19
+ deferLandSettleSideEffect("land-refused", () => notifyBranchLandFailed({ workspace: current ?? workspace, commandId, reason }));
20
+ }
@@ -5,6 +5,7 @@ import { getWorkspace, patchWorkspaceMetadataAsync } from "./db";
5
5
  import type { WorkspaceRecord } from "./types";
6
6
 
7
7
  export type LandStopReason =
8
+ | "refused"
8
9
  | "no-progress"
9
10
  | "nothing-to-land"
10
11
  | "retry-exhausted"
@@ -1,3 +1,5 @@
1
+ import { acquireMergeLeaseAsync, releaseMergeLeaseAsync } from "./db/runtime-tail-async";
2
+ import { LandConfigurationError, refuseWorkspaceLand } from "./workspace-land-refusal";
1
3
  import { capturedDeliveryGateRefusal } from "./services/captured-delivery-gate";
2
4
  import { ValidationError } from "./db/connection";
3
5
  import { WORKSPACE_MERGE_HOLD_MESSAGE } from "./db/workspace-merge-hold";
@@ -6,19 +8,7 @@ import { resolve } from "node:path";
6
8
  import { randomUUID } from "node:crypto";
7
9
  import { errMessage, isRecord, stringValue, type LandingContainmentMode } from "@humwick/sdk";
8
10
  import { cancelPendingLegacyLandingsAsync, createLegacyLandingAsync } from "./commands-landing-async";
9
- import {
10
- acquireMergeLease,
11
- exitCertificateMatchesInstance,
12
- getActiveMergePause,
13
- getAgent,
14
- listAgents,
15
- listOrchestrators,
16
- patchWorkspaceMetadataAsync,
17
- releaseMergeLease,
18
- REVIEW_HOLD_REJECT_MESSAGE,
19
- updateWorkspaceStatusAsync,
20
- workspaceLandBarrier,
21
- } from "./db";
11
+ import { exitCertificateMatchesInstance, getActiveMergePause, getAgent, listAgents, listOrchestrators, patchWorkspaceMetadataAsync, REVIEW_HOLD_REJECT_MESSAGE, updateWorkspaceStatusAsync, workspaceLandBarrier } from "./db";
22
12
  import { ensureLegacyOpenLandingOwnershipAsync } from "./db/landing-ingress-async";
23
13
  import { OFFLINE_PRUNE_MS } from "./config";
24
14
  import { getLandingConfig } from "./config-store";
@@ -44,8 +34,6 @@ import type { LandingLaneIdentity } from "./landing-lane-key";
44
34
  import { archiveLandAttempt, CLEAR_LAST_ATTEMPT_VERDICT, CLEAR_MERGE_RETRY, heavyGateQueuePriorityForRetry } from "./workspace-merge-progress";
45
35
  import { coalesceWorkspaceMerge } from "./workspace-merge-dispatch";
46
36
 
47
- // Re-export so consumers can import the tuple from the strategy home without a
48
- // second import hop.
49
37
  export { AUTO_MERGE_POLICIES } from "./types";
50
38
 
51
39
  // One home for the land-strategy contract, shared by BOTH land surfaces — the HTTP
@@ -393,12 +381,7 @@ async function dispatchWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
393
381
  // unauthorized one is refused outright instead of being silently ignored.
394
382
  const gate = resolveWorkspaceLandGate(workspace, { level: opts.gateLevel, reason: opts.gateReason, auth: opts.gateAuth });
395
383
  if (!gate.ok) return { ok: false, status: gate.status, error: gate.error };
396
- // #638 — an active merge-pause is the operator's tourniquet for a merge loop on this
397
- // repo. The auto-merge job already honors it (workspace-auto-merge.ts), but gate the
398
- // shared dispatcher too as defense-in-depth: never let an auto-merge-originated request
399
- // acquire the lease + storm while paused, regardless of which caller dispatched it. A
400
- // manual/steward land (any other `requestedBy`) is the intended RECOVERY path during a
401
- // pause, so it's allowed through.
384
+ // #638 — auto-merge honors the repo pause here too; manual/steward lands remain a recovery path.
402
385
  if (!plainGit && opts.requestedBy === "auto-merge" && getActiveMergePause(workspace.repoRoot, workspace.baseRef ?? "main")) {
403
386
  return { ok: false, status: 409, error: `auto-merge paused for ${workspace.repoRoot}` };
404
387
  }
@@ -420,9 +403,10 @@ async function dispatchWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
420
403
  let gatePlacement: Awaited<ReturnType<typeof selectLandGateHost>>;
421
404
  try {
422
405
  gatePlacement = await selectLandGateHost(workspace, onlineOwner, laneIdentity.remoteIdentity,
423
- effectiveStrategy !== "pr" && effectiveStrategy !== "auto" && gate.gate.level !== "none" ? laneIdentity.gateRequirements : undefined);
406
+ effectiveStrategy !== "pr" && effectiveStrategy !== "auto" && gate.gate.level !== "none" ? laneIdentity.gateRequirements : undefined, laneIdentity.gateDepsStrategy);
424
407
  } catch (error) {
425
- return { ok: false, status: 409, error: errMessage(error) };
408
+ if (error instanceof LandConfigurationError) await refuseWorkspaceLand(workspace, error.message);
409
+ return { ok: false, status: error instanceof LandConfigurationError ? 422 : 409, error: errMessage(error) };
426
410
  }
427
411
  const gateHost = gatePlacement.orchestrator;
428
412
  const mergeLeaseKey = laneIdentity.remoteIdentity.startsWith("remote:") ? laneIdentity.remoteIdentity : `remote:${laneIdentity.remoteIdentity}`;
@@ -438,7 +422,7 @@ async function dispatchWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
438
422
  let leaseAcquired = false;
439
423
  let commandCreated = false;
440
424
  if (!plainGit || gatePlacement.delegated) {
441
- const lease = acquireMergeLease(mergeLeaseKey, workspace.id, opts.requestedBy);
425
+ const lease = (await acquireMergeLeaseAsync(mergeLeaseKey, workspace.id, opts.requestedBy));
442
426
  if (!lease.ok) {
443
427
  if (containmentMode === "cgroup-v2-close-v1") {
444
428
  await cleanupLegacyLandingReservationOnHost(gateHost, executionTreeHandle!).catch(() => false);
@@ -493,7 +477,7 @@ async function dispatchWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
493
477
  lastWorkspaceActionAt: armAt,
494
478
  });
495
479
  if (!updated) {
496
- if (leaseAcquired) releaseMergeLease({ repoRoot: mergeLeaseKey, workspaceId: workspace.id });
480
+ if (leaseAcquired) (await releaseMergeLeaseAsync({ repoRoot: mergeLeaseKey, workspaceId: workspace.id }));
497
481
  if (containmentMode === "cgroup-v2-close-v1") {
498
482
  await cleanupLegacyLandingReservationOnHost(gateHost, executionTreeHandle!).catch(() => false);
499
483
  }
@@ -604,7 +588,7 @@ async function dispatchWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
604
588
  } catch (e) {
605
589
  // Acquired the lease but failed before dispatch — release it or the repo
606
590
  // stays blocked until the TTL expires.
607
- if (!commandCreated && leaseAcquired) releaseMergeLease({ repoRoot: mergeLeaseKey, workspaceId: workspace.id });
591
+ if (!commandCreated && leaseAcquired) (await releaseMergeLeaseAsync({ repoRoot: mergeLeaseKey, workspaceId: workspace.id }));
608
592
  if (!commandCreated && containmentMode === "cgroup-v2-close-v1") {
609
593
  await cleanupLegacyLandingReservationOnHost(gateHost, executionTreeHandle!).catch(() => false);
610
594
  }
@@ -6,14 +6,14 @@ import { withWorkspaceTaskOwnerRoles } from "./task-owner-notices";
6
6
  import { resolveLandedTaskIds } from "./services/landed-task-attribution";
7
7
  import type { WorkspaceRecord } from "./types";
8
8
 
9
- export function notifyNothingToLand(workspace: WorkspaceRecord, sha: string, commandId: string, sourceHeadSha?: string): void {
9
+ export async function notifyNothingToLand(workspace: WorkspaceRecord, sha: string, commandId: string, sourceHeadSha?: string): Promise<void> {
10
10
  const author = workspace.ownerAgentId;
11
11
  const coordinator = resolveCoordinatorAgentId(author);
12
12
  const taskOwners = resolveLandedTaskIds({ workspace, sourceHeadSha }).map(id => resolveTaskOwnerAgentId(getTaskDetail(id)));
13
13
  const recipients = withWorkspaceTaskOwnerRoles([author, coordinator, ...taskOwners], workspace);
14
14
  if (!recipients.length) return;
15
15
  const base = workspace.baseRef ?? "base";
16
- routeNotification({
16
+ await routeNotification({
17
17
  type: "branch.landed",
18
18
  scope: { author, parent: coordinator ?? undefined, repoRoot: workspace.repoRoot, workspaceId: workspace.id },
19
19
  recipients, forceDelivery: true, ttlMs: null,
@@ -1,3 +1,6 @@
1
+ import { pruneWorkspaceOrphanAlertsAsync, pruneStaleWorkspaceHumanEscalationAlertsAsync, claimWorkspaceOrphanAlertAsync } from "./db/runtime-tail-async";
2
+ import { dispatchOrphanCleanup } from "./workspace-cleanup-stale";
3
+ import { emitCommandEvent } from "./command-events";
1
4
  // Orphaned-worktree reconciliation (#244). An isolated worktree on disk with no
2
5
  // live DB row is "orphaned" — left behind when a session ended without a clean
3
6
  // teardown (crash, killed runner, a reaped row). Symmetrically, a live row whose
@@ -20,8 +23,8 @@
20
23
 
21
24
  import { resolve } from "node:path";
22
25
  import type { WorkspaceMergePreview, WorkspaceOrphan, WorkspaceProbe, WorkspaceProbeWorktree, WorkspaceRecord, WorkspaceStatus } from "./types";
23
- import { claimWorkspaceOrphanAlert, createActivityEventAsync, getWorkspace, listOrchestrators, listWorkspaces, pruneStaleWorkspaceHumanEscalationAlerts, pruneWorkspaceOrphanAlerts, updateWorkspaceStatusAsync } from "./db";
24
- import { createCommand } from "./commands-db";
26
+ import { createActivityEventAsync, getWorkspace, listOrchestrators, listWorkspaces, updateWorkspaceStatusAsync } from "./db";
27
+
25
28
  import { isPathWithinBase } from "./utils";
26
29
  import { IN_FLIGHT_WORKSPACE_STATUSES, TERMINAL_WORKSPACE_STATUSES, worktreeReapable, type WorktreeReapState } from "./workspace-phase";
27
30
  import { isOwnerAlive, isOwnerProcessConfirmedGone, liveAgentCwds, worktreeInUseByLiveAgent } from "./workspace-merge";
@@ -33,7 +36,6 @@ import { READY_TO_LAND_ESCALATION_STATUSES, routeWorkspaceCustodyEscalationOrAla
33
36
  import { workspaceLandBlocked } from "./land-block";
34
37
  import { dispatchDeadOwnerRescue } from "./workspace-dead-owner-recovery";
35
38
  import { runWithConcurrency, sortLeastRecentlyProbed } from "./maintenance/workspaces";
36
- import { emitCommandEvent } from "./command-events";
37
39
  import {
38
40
  WORKSPACE_ORPHAN_REAPER_DEAD_OWNER_PROBE_BATCH_SIZE,
39
41
  WORKSPACE_ORPHAN_REAPER_MISSING_PROBE_BATCH_SIZE,
@@ -421,27 +423,6 @@ export async function collectWorkspaceOrphans(
421
423
  return { orphans, missingWorktrees, deadOwnerWorkspaces, ...(moreOrphanEnrichmentWork ? { moreOrphanEnrichmentWork } : {}) };
422
424
  }
423
425
 
424
- function dispatchCleanup(orch: OnlineOrchestrator, orphan: WorkspaceOrphan): string {
425
- const command = createCommand({
426
- type: "workspace.cleanup",
427
- source: "system",
428
- target: orch.agentId,
429
- params: {
430
- action: "cleanup",
431
- worktreePath: orphan.worktreePath,
432
- repoRoot: orphan.repoRoot,
433
- branch: orphan.branch,
434
- baseRef: orphan.baseRef,
435
- baseSha: orphan.baseSha,
436
- deleteBranch: true,
437
- reclaim: true,
438
- requestedBy: "workspace-orphan-reaper",
439
- requestedAt: Date.now(),
440
- },
441
- });
442
- emitCommandEvent(command, `command.${command.status}`);
443
- return command.id;
444
- }
445
426
 
446
427
  /**
447
428
  * Scheduled reaper (maintenance job). Auto-removes orphaned worktrees that are
@@ -520,7 +501,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
520
501
  if (!reapEnabled) continue; // detect-only mode
521
502
  if (nonTerminalRowsByPath.has(resolve(orphan.worktreePath))) continue; // still claimed — never reap (#278)
522
503
  if (worktreeInUseByLiveAgent(orphan.worktreePath, liveCwds)) continue; // a live agent runs in it — never reap its cwd
523
- const commandId = dispatchCleanup(orch, orphan);
504
+ const commandId = (await dispatchOrphanCleanup(orch.agentId, orphan));
524
505
  reaped.push(orphan.worktreePath);
525
506
  await createActivityEventAsync({
526
507
  clientId: `workspace-orphan-reaped-${orphan.worktreePath}-${now}`,
@@ -541,7 +522,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
541
522
  const alertKey = `disk:${resolve(orphan.worktreePath)}`;
542
523
  liveAlertKeys.add(alertKey);
543
524
  const fingerprint = orphanAlertFingerprint({ headSha: orphan.headSha, ahead: orphan.ahead, unmergedAhead: orphan.unmergedAhead, dirty: orphan.dirty, safeToReap: orphan.safeToReap });
544
- if (!claimWorkspaceOrphanAlert(alertKey, fingerprint, now)) continue;
525
+ if (!(await claimWorkspaceOrphanAlertAsync(alertKey, fingerprint, now))) continue;
545
526
  flagged.push(orphan.worktreePath);
546
527
  const detail = orphan.safeToReap === undefined
547
528
  ? "host could not be probed for land-state"
@@ -549,7 +530,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
549
530
  ? "uncommitted changes in the worktree"
550
531
  : `${orphan.unmergedAhead ?? orphan.ahead ?? "?"} un-landed commit(s)`;
551
532
  if (orphanHasWorkEvidence(orphan)) {
552
- routeWorkspaceCustodyEscalationOrAlarm({
533
+ await routeWorkspaceCustodyEscalationOrAlarm({
553
534
  source: "workspace-orphan-reaper",
554
535
  workspace: { id: `orphan:${orphan.worktreePath}`, repoRoot: orphan.repoRoot, branch: orphan.branch, status: "review_requested", ownerAgentId: undefined },
555
536
  subject: "Stranded worktree needs attention",
@@ -586,9 +567,9 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
586
567
  const inFlight = IN_FLIGHT_WORKSPACE_STATUSES.has(workspace.status);
587
568
  if (ownerAlive || inFlight) {
588
569
  liveAlertKeys.add(key);
589
- if (!claimWorkspaceOrphanAlert(key, orphanAlertFingerprint({ status: workspace.status, ownerAlive, inFlight }), now)) continue;
570
+ if (!(await claimWorkspaceOrphanAlertAsync(key, orphanAlertFingerprint({ status: workspace.status, ownerAlive, inFlight }), now))) continue;
590
571
  if (workspaceNeedsCustodyEscalation(workspace, false)) {
591
- routeWorkspaceCustodyEscalationOrAlarm({
572
+ await routeWorkspaceCustodyEscalationOrAlarm({
592
573
  source: "workspace-orphan-reaper",
593
574
  workspace,
594
575
  subject: "Workspace row has no worktree on disk",
@@ -658,7 +639,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
658
639
  if (!updated) continue;
659
640
  autoAbandoned.push(workspace.id);
660
641
  if (workspaceNeedsCustodyEscalation(workspace, previewHasWorkEvidence(probe.kind === "preview" ? probe.preview : null))) {
661
- routeWorkspaceCustodyEscalationOrAlarm({
642
+ await routeWorkspaceCustodyEscalationOrAlarm({
662
643
  source: "workspace-orphan-reaper",
663
644
  workspace,
664
645
  type: "workspace.auto_abandoned",
@@ -690,7 +671,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
690
671
 
691
672
  liveAlertKeys.add(key);
692
673
  const missingFingerprint = orphanAlertFingerprint({ status: workspace.status, probe: probe.kind, recoverableTip: probe.kind === "preview" ? probe.preview.recoverableTip : undefined, headSha: probe.kind === "preview" ? probe.preview.headSha : undefined, ahead: probe.kind === "preview" ? probe.preview.ahead : undefined, unmergedAhead: probe.kind === "preview" ? probe.preview.unmergedAhead : undefined });
693
- if (!claimWorkspaceOrphanAlert(key, missingFingerprint, now)) continue;
674
+ if (!(await claimWorkspaceOrphanAlertAsync(key, missingFingerprint, now))) continue;
694
675
  flaggedMissingWorktrees.push(workspace.id);
695
676
  const hasWorkEvidence = probe.kind === "preview" && previewHasWorkEvidence(probe.preview);
696
677
  const detail = probe.kind === "preview"
@@ -701,7 +682,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
701
682
  ? `host could not confirm whether branch ${workspace.branch} has landed`
702
683
  : "host could not confirm whether recoverable branch work remains";
703
684
  if (workspaceNeedsCustodyEscalation(workspace, hasWorkEvidence)) {
704
- routeWorkspaceCustodyEscalationOrAlarm({
685
+ await routeWorkspaceCustodyEscalationOrAlarm({
705
686
  source: "workspace-orphan-reaper",
706
687
  workspace,
707
688
  subject: "Missing-worktree workspace needs attention",
@@ -846,10 +827,10 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
846
827
  liveDeadOwnerKeys.add(flagKey);
847
828
  liveAlertKeys.add(flagKey);
848
829
  const deadOwnerFingerprint = orphanAlertFingerprint({ status: workspace.status, headSha: preview?.headSha, ahead: preview?.ahead, unmergedAhead: preview?.unmergedAhead, dirtyCount: preview?.dirtyCount, probeAvailable: Boolean(preview) });
849
- if (!claimWorkspaceOrphanAlert(flagKey, deadOwnerFingerprint, now)) continue;
830
+ if (!(await claimWorkspaceOrphanAlertAsync(flagKey, deadOwnerFingerprint, now))) continue;
850
831
  deadOwnerFlagged.push(workspace.id);
851
832
  const rescueCommandId = preview?.originCaptureChecked === true && preview.originCaptured === false && orch
852
- ? dispatchDeadOwnerRescue(orch, workspace)
833
+ ? (await dispatchDeadOwnerRescue(orch, workspace))
853
834
  : undefined;
854
835
  const detail = safeToReap === undefined
855
836
  ? "host could not be probed for land-state"
@@ -858,7 +839,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
858
839
  : `${preview?.unmergedAhead ?? preview?.ahead ?? "?"} un-landed commit(s)`;
859
840
  const hasWorkEvidence = previewHasWorkEvidence(preview);
860
841
  if (workspaceNeedsCustodyEscalation(workspace, hasWorkEvidence)) {
861
- routeWorkspaceCustodyEscalationOrAlarm({
842
+ await routeWorkspaceCustodyEscalationOrAlarm({
862
843
  source: "workspace-orphan-reaper",
863
844
  workspace,
864
845
  subject: "Dead-owner worktree needs attention",
@@ -896,8 +877,8 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
896
877
  // still waiting it out and re-fire orphan alerts already claimed for this condition.
897
878
  if (!signal?.aborted) {
898
879
  for (const key of deadOwnerTracker.keys()) if (!liveDeadOwnerKeys.has(key)) deadOwnerTracker.delete(key);
899
- pruneWorkspaceOrphanAlerts(liveAlertKeys);
900
- pruneStaleWorkspaceHumanEscalationAlerts(now, HUMAN_ESCALATION_ALERT_MAX_AGE_MS);
880
+ (await pruneWorkspaceOrphanAlertsAsync(liveAlertKeys));
881
+ (await pruneStaleWorkspaceHumanEscalationAlertsAsync(now, HUMAN_ESCALATION_ALERT_MAX_AGE_MS));
901
882
  }
902
883
 
903
884
  // #2408 — true whenever ANY of the three per-tick probe budgets left candidates un-probed this run.
@@ -1,6 +1,8 @@
1
+ import { createActivityEventAsync } from "./db/activity-async";
2
+ import { createCommandAsync } from "./commands-write";
1
3
  import { isRecord } from "@humwick/sdk";
2
- import { createCommand, getCommand } from "./commands-db";
3
- import { createActivityEvent, patchWorkspaceMetadataAsync, workspaceLandBarrier } from "./db";
4
+ import { getCommand } from "./commands-db";
5
+ import { patchWorkspaceMetadataAsync, workspaceLandBarrier } from "./db";
4
6
  import { handleReviewerPipelineScan, isAwaitingReviewerApproval } from "./reviewer-pipeline";
5
7
  import { isOwnerAlive, requestWorkspaceMerge } from "./workspace-merge";
6
8
  import type { Command, WorkspaceAutoMergePolicy, WorkspaceMergePreview, WorkspaceRecord } from "./types";
@@ -39,7 +41,7 @@ export async function reconcileLandedPr(workspace: WorkspaceRecord, preview: Wor
39
41
  },
40
42
  });
41
43
  if (recycle.ok) {
42
- createActivityEvent({
44
+ (await createActivityEventAsync({
43
45
  clientId: `workspace-pr-recycle-${workspace.id}-${Date.now()}`,
44
46
  kind: "state",
45
47
  title: "Workspace recycling after PR land",
@@ -48,7 +50,7 @@ export async function reconcileLandedPr(workspace: WorkspaceRecord, preview: Wor
48
50
  icon: "ti-git-merge",
49
51
  view: "orchestrators",
50
52
  metadata: { source: "server", maintenanceJobId: "workspace-conflict-scan", workspaceId: workspace.id, commandId: recycle.command.id, landedVia: "pr" },
51
- });
53
+ }));
52
54
  return { kind: "recycle", command: recycle.command };
53
55
  }
54
56
  // 409 = lease held by an in-flight merge — retry next sweep, don't finalize (re-strands a
@@ -199,7 +201,7 @@ async function dispatchRelayPrMergeCommand(workspace: WorkspaceRecord, preview:
199
201
  const now = Date.now();
200
202
  const prNumber = preview.prNumber ?? (typeof workspace.metadata.prNumber === "number" ? workspace.metadata.prNumber : undefined);
201
203
  const prUrl = preview.prUrl ?? text(workspace.metadata.prUrl);
202
- const command = createCommand({
204
+ const command = (await createCommandAsync({
203
205
  type: "workspace.pr-merge",
204
206
  source: "system",
205
207
  target: orchestratorAgentId,
@@ -209,7 +211,7 @@ async function dispatchRelayPrMergeCommand(workspace: WorkspaceRecord, preview:
209
211
  branch: workspace.branch, baseRef: workspace.baseRef, prNumber, prUrl, policy,
210
212
  requestedBy: "relay-pr-completion", requestedAt: now,
211
213
  },
212
- });
214
+ }));
213
215
  await patchWorkspaceMetadataAsync(workspace.id, {
214
216
  relayMerged: true, relayMergeCommandId: command.id, relayMergeDispatchedAt: now, relayMergePolicy: policy,
215
217
  relayMergeError: undefined, relayMergeFailedAt: undefined,
@@ -221,7 +223,7 @@ async function dispatchRelayPrRefreshCommand(workspace: WorkspaceRecord, preview
221
223
  const now = Date.now();
222
224
  const prNumber = preview.prNumber ?? (typeof workspace.metadata.prNumber === "number" ? workspace.metadata.prNumber : undefined);
223
225
  const prUrl = preview.prUrl ?? text(workspace.metadata.prUrl);
224
- const command = createCommand({
226
+ const command = (await createCommandAsync({
225
227
  type: "workspace.pr-refresh",
226
228
  source: "system",
227
229
  target: orchestratorAgentId,
@@ -231,7 +233,7 @@ async function dispatchRelayPrRefreshCommand(workspace: WorkspaceRecord, preview
231
233
  branch: workspace.branch, baseRef: workspace.baseRef, prNumber, prUrl, policy, refreshKey, attempts,
232
234
  requestedBy: "relay-pr-completion", requestedAt: now,
233
235
  },
234
- });
236
+ }));
235
237
  await patchWorkspaceMetadataAsync(workspace.id, {
236
238
  prRefreshCommandId: command.id, prRefreshDispatchedAt: now, prRefreshPolicy: policy, prRefreshPrNumber: prNumber,
237
239
  prRefreshKey: refreshKey, prRefreshAttempts: attempts, prRefreshError: undefined, prRefreshFailedAt: undefined,
@@ -55,7 +55,7 @@ export function fenceWorkspaceRekeyCommand(commandId: string): Promise<{ fenced:
55
55
  export async function drainStewardRekeyNotices(): Promise<void> {
56
56
  for (const row of pendingStewardRekeyNotices()) {
57
57
  try {
58
- const routed = notifyTaskCoordinatorOfRekey(row);
58
+ const routed = await notifyTaskCoordinatorOfRekey(row);
59
59
  if (routed) await getGateway().write("workspaceRekey.noticeSent", { eventId: row.id });
60
60
  } catch (error) {
61
61
  console.warn(`[steward-rekey] notice for task event ${row.id} failed; retrying later: ${error}`);
@@ -63,7 +63,7 @@ export async function drainStewardRekeyNotices(): Promise<void> {
63
63
  }
64
64
  }
65
65
 
66
- function notifyTaskCoordinatorOfRekey(row: StewardRekeyNoticeRow): boolean {
66
+ async function notifyTaskCoordinatorOfRekey(row: StewardRekeyNoticeRow): Promise<boolean> {
67
67
  const task = getTaskDetail(row.task_id);
68
68
  if (!task) return false;
69
69
  const m = parseJson<Record<string, unknown>>(row.metadata, {});
@@ -82,7 +82,7 @@ function notifyTaskCoordinatorOfRekey(row: StewardRekeyNoticeRow): boolean {
82
82
  ...(rewritten.length ? [`${rewritten.length} commit(s) changed patch identity`] : []),
83
83
  ...(merges.length ? [`${merges.length} merge commit(s) were re-resolved and cannot be verified by patch-id`] : []),
84
84
  ];
85
- const delivered = routeNotification({
85
+ const delivered = await routeNotification({
86
86
  type: "task.steward_rekey",
87
87
  scope: {
88
88
  taskId: String(task.id), transition: "steward-rekey", workspaceId,
@@ -30,13 +30,13 @@ export async function recordStewardWakeFailure(workspace: WorkspaceRecord, error
30
30
  const body = `Workspace \`${ws.id}\` (\`${ws.branch ?? ws.id}\` → \`${ws.baseRef ?? "base"}\`): ${error}. Relay will retry after ${Math.ceil(STEWARD_HANDOFF_WATCHDOG_MS / 60_000)} minutes. ${stewardRecoveryAdvice(ws.baseRef ?? "main", capExhausted)}`;
31
31
  const payload = { kind: "workspace.steward-spawn-failed", workspaceId: ws.id, branch: ws.branch, reason: error };
32
32
  if (recipients.length) {
33
- routeNotification({
33
+ await routeNotification({
34
34
  type: "workspace.stranded_escalation", forceDelivery: true, ttlMs: null,
35
35
  scope: { workspaceId: ws.id, repoRoot: ws.repoRoot, author: ownerAgentId, parent: coordinatorAgentId ?? undefined },
36
36
  recipients, message: { subject, body, payload, idempotencyKey: `steward-spawn-failed:${ws.id}:${failureId}` },
37
37
  });
38
38
  } else {
39
- raiseOperatorAlarm({ clientId: `steward-spawn-failed:${ws.id}:${failureId}`, source: "workspace-steward-failure", subject, detail: body, dedupeEvent: true, metadata: payload });
39
+ (await raiseOperatorAlarm({ clientId: `steward-spawn-failed:${ws.id}:${failureId}`, source: "workspace-steward-failure", subject, detail: body, dedupeEvent: true, metadata: payload }));
40
40
  }
41
41
  await patchWorkspaceMetadataAsync(ws.id, { stewardWakeFailureNotifiedAt: now });
42
42
  }
@@ -92,7 +92,7 @@ export async function wakeRepoSteward(ws: WorkspaceRecord, reason: string, opts:
92
92
  stewardHandoffEscalatedAt: undefined, stewardRewakeCount: undefined,
93
93
  } : {}),
94
94
  });
95
- routeNotification({
95
+ await routeNotification({
96
96
  type: "workspace.steward_task",
97
97
  scope: { workspaceId: ws.id, repoRoot: ws.repoRoot, author: ownerAgentId, parent: coordinatorAgentId ?? undefined },
98
98
  recipients: [`policy:${policyName}`],
@@ -139,7 +139,7 @@ export async function wakeRepoSteward(ws: WorkspaceRecord, reason: string, opts:
139
139
  }, attempt < STEWARD_WAKE_STAMP_ATTEMPTS ? current : undefined);
140
140
  if (!stamped) continue;
141
141
  if (current.landState === "merge-error") await transitionWorkspaceLandStateAsync(ws.id, "steward-requested");
142
- notifyStewardHandoff({ workspace: ws, stewardId: policyName, coordinatorAgentId, reason });
142
+ await notifyStewardHandoff({ workspace: ws, stewardId: policyName, coordinatorAgentId, reason });
143
143
  return { ok: true, policy: policyName };
144
144
  }
145
145
  } catch (e) {
@@ -1,2 +0,0 @@
1
- import{T as e}from"./display-BrKWFGJz.js";function t(t,n){return!!n&&n.status!==`offline`&&!e(t,n)}export{t};
2
- //# sourceMappingURL=agent-liveness-CaNwK0Zf.js.map