@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
@@ -1,10 +1,14 @@
1
1
  #!/usr/bin/env bun
2
+ import { setConfigAsync, setAgentProfileAsync } from "../config-store-write";
3
+ import { upsertOrchestratorAsync } from "../db/orchestrators-async";
4
+ import { allowLocalLandingHost } from "./spawn-placement.test-fixture";
5
+ import { upsertAgentAsync } from "../db/agents-async";
2
6
  import { relayEnv, writeChildEnv } from "@humwick/sdk/env";
3
7
  import { appendFileSync, closeSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeSync } from "node:fs";
4
8
  import { createHash } from "node:crypto";
5
9
  import { hostname } from "node:os";
6
10
  import { dirname, join } from "node:path";
7
- import { getAgent, getOrchestrator, initDb, upsertAgent, upsertOrchestrator } from "../db";
11
+ import { getAgent, getOrchestrator, initDb } from "../db";
8
12
  import { assemblePreparedSpawnChain, prepareCommandChain, prepareSpawnChain, type PreparedSpawnChain } from "./spawn-chain-inspector";
9
13
  import { ClaudeApiAdapter } from "../../runner/src/adapters/claude-api";
10
14
  import type { ApiBudgetAccounting } from "../../runner/src/api-budget-accounting";
@@ -27,7 +31,7 @@ import { listCommands } from "../commands-db";
27
31
  import { restartSpawnParamsForAgent, restartSpawnParamsForAgentAsync } from "./restart-spawn";
28
32
  import { landOnOrigin } from "./project-role.test-fixture";
29
33
  import { prepareServiceAccessConfig } from "../../runner/src/adapters/service-access";
30
- import { deleteAgentProfile, setAgentProfile, setConfig } from "../config-store";
34
+ import { deleteAgentProfile } from "../config-store";
31
35
  import { setRoutingPolicy } from "../routing-policy-store";
32
36
 
33
37
  const SPAWN_AGENT_ORCHESTRATOR_ID = "effective-launch";
@@ -36,16 +40,17 @@ const SPAWN_AGENT_ORCHESTRATOR_ID = "effective-launch";
36
40
  async function spawnAgentCommandParams(request: EffectiveLaunchRequest): Promise<Record<string, unknown>> {
37
41
  // This host's own orchestrator: the spawn reads repo content locally, as on the relay host.
38
42
  const auto = request.autoRouting;
39
- upsertOrchestrator({ id: SPAWN_AGENT_ORCHESTRATOR_ID, hostname: hostname(), providers: auto?.providers ?? [request.provider], baseDir: request.cwd });
43
+ (await upsertOrchestratorAsync({ id: SPAWN_AGENT_ORCHESTRATOR_ID, hostname: hostname(), providers: auto?.providers ?? [request.provider], baseDir: request.cwd }));
44
+ allowLocalLandingHost(SPAWN_AGENT_ORCHESTRATOR_ID);
40
45
  if (auto) {
41
46
  setRoutingPolicy(auto.policy, { updatedBy: "effective-launch" });
42
- for (const provider of auto.providers) setConfig("provider-enablement", provider, { enabled: !auto.disabled?.includes(provider) }, "effective-launch");
47
+ for (const provider of auto.providers) (await setConfigAsync("provider-enablement", provider, { enabled: !auto.disabled?.includes(provider) }, "effective-launch"));
43
48
  const result = await spawnAgent({ provider: "auto", dispatch: auto.dispatch, orchestratorId: SPAWN_AGENT_ORCHESTRATOR_ID, cwd: request.cwd,
44
49
  taskless: true, workflow: false, approvalMode: "open", waitForRegistrationMs: 0, requestedVia: "effective-launch", requestedBy: "effective-launch" } as SpawnAgentInput, authContextFromSystem());
45
50
  return result.command.params;
46
51
  }
47
52
  if (request.dispatchTask && request.role !== undefined) {
48
- const task = createTaskEntity({ title: "Dispatch a role", intent: "Dispatch a role", dispatch: request.dispatchTask.dispatch, createdBy: "effective-launch" });
53
+ const task = await createTaskEntity({ title: "Dispatch a role", intent: "Dispatch a role", dispatch: request.dispatchTask.dispatch, createdBy: "effective-launch" });
49
54
  const dispatched = await relayDispatchTool({ kind: "server", actor: "effective-launch" }, "relay_task_dispatch", {
50
55
  taskId: task.id, role: request.role, cwd: request.cwd, orchestratorId: SPAWN_AGENT_ORCHESTRATOR_ID, pin: { provider: request.provider }, createReview: false, workflow: false,
51
56
  });
@@ -77,7 +82,7 @@ async function spawnAgentCommandParams(request: EffectiveLaunchRequest): Promise
77
82
  async function restartCommandParams(spawned: Record<string, unknown>, request: EffectiveLaunchRequest & { role: string; restart: { land: Record<string, string> } }): Promise<Record<string, unknown>> {
78
83
  const agentId = spawned.agentId as string;
79
84
  const meta = { provider: request.provider, cwd: request.cwd, spawnRequestId: spawned.spawnRequestId, profile: spawned.profile, model: spawned.model, effort: spawned.effort, approvalMode: spawned.approvalMode, workspaceMode: spawned.workspaceMode };
80
- upsertAgent({ id: agentId, name: agentId, kind: "provider", status: "online", ready: true, machine: SPAWN_AGENT_ORCHESTRATOR_ID, meta });
85
+ (await upsertAgentAsync({ id: agentId, name: agentId, kind: "provider", status: "online", ready: true, machine: SPAWN_AGENT_ORCHESTRATOR_ID, meta }));
81
86
  landOnOrigin(request.cwd, request.restart.land, "role edit after the spawn", { fetch: true });
82
87
  const params = await restartSpawnParamsForAgentAsync(getAgent(agentId)!, getOrchestrator(SPAWN_AGENT_ORCHESTRATOR_ID), undefined, spawned.spawnRequestId as string);
83
88
  if (!params) throw new Error(`restarting ${agentId} built no successor spawn`);
@@ -86,7 +91,7 @@ async function restartCommandParams(spawned: Record<string, unknown>, request: E
86
91
 
87
92
  async function restartWithoutProfileParams(spawned: Record<string, unknown>, request: EffectiveLaunchRequest & { profile: string; restart: { deleteProfile: true; mode: "sync" | "async" } }): Promise<Record<string, unknown>> {
88
93
  const id = spawned.agentId as string;
89
- registerAgent({ id, name: id, kind: "provider", status: "idle", ready: true, instanceId: "before-profile-deletion",
94
+ await registerAgent({ id, name: id, kind: "provider", status: "idle", ready: true, instanceId: "before-profile-deletion",
90
95
  meta: { provider: request.provider, cwd: request.cwd, profile: request.profile, spawnRequestId: spawned.spawnRequestId,
91
96
  harnessSubagents: request.spawn?.harnessSubagents, approvalMode: spawned.approvalMode } }, authContextFromSystem());
92
97
  if (!deleteAgentProfile(request.profile)) throw new Error(`profile not deleted: ${request.profile}`);
@@ -147,7 +152,7 @@ export async function main(): Promise<void> {
147
152
  mkdirSync(process.env.CLAUDE_CONFIG_DIR, { recursive: true, mode: 0o700 });
148
153
  mkdirSync(process.env.CODEX_HOME, { recursive: true, mode: 0o700 });
149
154
  initDb(":memory:");
150
- if (request.profileDefinition) setAgentProfile(request.profileDefinition);
155
+ if (request.profileDefinition) (await setAgentProfileAsync(request.profileDefinition));
151
156
 
152
157
  if (relayEnv(process.env, "AGENT_RELAY_EFFECTIVE_LAUNCH_FAULT") === "enable-runner-managed-tool-deferral") {
153
158
  const manifest = getManifest(request.provider)?.mcpToolManifest;
@@ -179,7 +184,7 @@ export async function main(): Promise<void> {
179
184
  prepared = request.commandParams
180
185
  ? prepareCommandChain(request.commandParams, { ...chainRequest, spawn: { headless: true } }, observe)
181
186
  : request.managedPolicy
182
- ? prepareCommandChain(buildManagedSpawnParams(request.managedPolicy, "sp_effective_managed", { createdBy: "effective-launch", authority: SYSTEM_LAUNCH }), chainRequest, observe)
187
+ ? prepareCommandChain((await buildManagedSpawnParams(request.managedPolicy, "sp_effective_managed", { createdBy: "effective-launch", authority: SYSTEM_LAUNCH })), chainRequest, observe)
183
188
  : prepareSpawnChain(chainRequest, observe);
184
189
  }
185
190
  trace("adapter-assembly", "start");
@@ -1,13 +1,14 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import { existsSync } from "node:fs";
3
3
  import { join } from "node:path";
4
- import { changedPathsSinceMergeBase, readProjectFiles, type ProjectDirExtension } from "@humwick/sdk";
4
+ import { readProjectFiles, type ProjectDirExtension } from "@humwick/sdk";
5
+ import { workspaceChangedPaths } from "../../orchestrator/src/workspace-probe/changed-paths";
5
6
 
6
7
  /**
7
8
  * In-process stand-in for an OWNING orchestrator host (#2535 cross-host test coverage). The
8
9
  * delivery diff gate routes through the owner's `GET /api/workspace/changed-paths`; these
9
10
  * helpers let a test's `globalThis.fetch` stub ANSWER that route the way a real host does —
10
- * by computing the changed paths with the REAL shared SDK baseline against the simulated
11
+ * by running the REAL host probe (`workspaceChangedPaths`) against the simulated
11
12
  * host's own disk view, which can differ from what the server process can see:
12
13
  *
13
14
  * - `mapHostRepo(serverVisiblePath, hostRepoDir)` — the host resolves `serverVisiblePath` to
@@ -95,10 +96,8 @@ export async function changedPathsResponse(url: URL): Promise<Response | undefin
95
96
  if (failure === "truncated") return Response.json({ ok: false, reason: "git diff unavailable (probe output truncated on the owning host)" });
96
97
  const dir = hostDir(serverVisiblePath);
97
98
  if (!existsSync(dir)) return Response.json({ ok: false, reason: "worktree unavailable", missing: true });
98
- const result = await changedPathsSinceMergeBase(async (_worktreePath, args) => {
99
- const r = spawnSync("git", ["-C", dir, ...args], { encoding: "utf8", maxBuffer: 16 * 1024 * 1024, stdio: ["ignore", "pipe", "pipe"] });
100
- return { ok: r.status === 0, out: r.stdout ?? "", err: r.stderr ?? "" };
101
- }, {
99
+ // The REAL owning-host probe (base fetch + shared SDK baseline) against the host's disk view.
100
+ const result = await workspaceChangedPaths({
102
101
  worktreePath: dir,
103
102
  baseRef: url.searchParams.get("baseRef") ?? undefined,
104
103
  baseSha: url.searchParams.get("baseSha") ?? undefined,
@@ -5,10 +5,10 @@ import { checkoutRefreshEnabled } from "../config";
5
5
  import { cleanHostProjectToolchainStatus } from "../project-toolchain";
6
6
  import { probeHostRepo } from "./spawn-repo-probe";
7
7
 
8
- /** A refresh receipt whose dependency hook failed: the checkout's dependencies do not match its head. Behind or in-progress refreshes carry no reason, so they stay ready. */
8
+ /** A refresh receipt whose dependency hook failed: the checkout's dependencies do not match its head. Skipped or in-progress refreshes stay ready; their reason is not a hook failure. */
9
9
  function failedDependencyHook(row: CheckoutRefreshStatus): string | undefined {
10
10
  const result = row.result;
11
- return result?.enabled && result.dependency?.status === "pending" && result.reason ? result.reason : undefined;
11
+ return result?.enabled && result.status === "error" && result.dependency?.status === "pending" && result.reason ? result.reason : undefined;
12
12
  }
13
13
 
14
14
  /**
@@ -44,7 +44,7 @@ function cleanToggle(body: unknown): HostProviderWrite {
44
44
  /** Env-migration seed through the same per-host chain as operator writes, with audit. */
45
45
  export async function seedHostProviders(hostId: string, envProviders: readonly string[], switchableCatalog: readonly SpawnProvider[]) {
46
46
  return serializeHostWrite(hostId, async () => {
47
- const seeded = seedHostProvidersFromEnv(hostId, envProviders, switchableCatalog);
47
+ const seeded = (await seedHostProvidersFromEnv(hostId, envProviders, switchableCatalog));
48
48
  if (!seeded) return null;
49
49
  const disabled = Object.entries(seeded.providers).filter(([, t]) => !t.enabled).map(([p]) => p);
50
50
  await auditEvent({
@@ -55,16 +55,16 @@ export async function recordHostUtilization(input: RecordHostUtilizationInput):
55
55
  return false;
56
56
  }
57
57
  recordHostUtilizationSample(input.hostId, input.machine, input.now ?? Date.now());
58
- if (recorded?.gateAlert) notifyGateCapacity(input.hostId, recorded.hostLabel ?? input.hostId, recorded.gateAlert, input.now ?? Date.now());
59
- if (recorded?.diskAlert) notifyDisk(input.hostId, recorded.hostLabel ?? input.hostId, recorded.diskAlert);
58
+ if (recorded?.gateAlert) (await notifyGateCapacity(input.hostId, recorded.hostLabel ?? input.hostId, recorded.gateAlert, input.now ?? Date.now()));
59
+ if (recorded?.diskAlert) (await notifyDisk(input.hostId, recorded.hostLabel ?? input.hostId, recorded.diskAlert));
60
60
  return true;
61
61
  }
62
62
 
63
63
  /** Operator ntfy plus the steward/coordinator target — the same two recipients as the critical-job watchdog. */
64
- function notifyDisk(hostId: string, label: string, alert: DiskAlert): void {
64
+ async function notifyDisk(hostId: string, label: string, alert: DiskAlert): Promise<void> {
65
65
  const notice = composeDiskNotice(hostId, label, alert);
66
66
  const payload = { ...alert, kind: `host-disk.${alert.kind}`, hostId };
67
- const human = notifyWorkspaceHumanEscalation({
67
+ const human = (await notifyWorkspaceHumanEscalation({
68
68
  subject: notice.subject,
69
69
  body: notice.body,
70
70
  priority: notice.priority,
@@ -72,15 +72,15 @@ function notifyDisk(hostId: string, label: string, alert: DiskAlert): void {
72
72
  source: "host-disk",
73
73
  payload,
74
74
  idempotencyKey: notice.idempotencyKey,
75
- });
75
+ }));
76
76
  const target = stewardFallbackTarget();
77
- const routed = target ? notifyTarget("maintenance.degraded", {}, target, notice.subject, notice.body, payload, notice.idempotencyKey) : null;
77
+ const routed = target ? await notifyTarget("maintenance.degraded", {}, target, notice.subject, notice.body, payload, notice.idempotencyKey) : null;
78
78
  console.warn(`[relay] ${notice.subject}${human.accepted || routed ? "" : " — nobody was notified (no ntfy channel or steward target)"}`);
79
79
  }
80
80
 
81
- function notifyGateCapacity(hostId: string, label: string, alert: GateCapacityAlert, now: number): void {
81
+ async function notifyGateCapacity(hostId: string, label: string, alert: GateCapacityAlert, now: number): Promise<void> {
82
82
  const notice = composeGateCapacityNotice(hostId, label, alert, now);
83
- const result = notifyWorkspaceHumanEscalation({
83
+ const result = (await notifyWorkspaceHumanEscalation({
84
84
  subject: notice.subject,
85
85
  body: notice.body,
86
86
  priority: notice.priority,
@@ -88,6 +88,6 @@ function notifyGateCapacity(hostId: string, label: string, alert: GateCapacityAl
88
88
  source: "gate-capacity",
89
89
  payload: { ...alert, kind: `gate-capacity.${alert.kind}`, hostId },
90
90
  idempotencyKey: notice.idempotencyKey,
91
- });
91
+ }));
92
92
  console.warn(`[relay] ${notice.subject}${result.accepted ? "" : ` — operator NOT paged: ${result.reason}`}`);
93
93
  }
@@ -1,3 +1,4 @@
1
+ import { updateIdleDigestScanAsync, startIdleDigestWindowAsync, finishIdleDigestScanAsync } from "../db/runtime-tail-async";
1
2
  // #3428 — the one idle-children classifier and the coordinator digest built on it. Each team's
2
3
  // coordinator gets at most one digest per window, and only when something qualifies. Provably safe
3
4
  // children can be stopped automatically; the digest reports them only once termination is confirmed.
@@ -13,7 +14,7 @@ import {
13
14
  listWorkspaces,
14
15
  workflowRunIdOf,
15
16
  } from "../db";
16
- import { finishIdleDigestScan, getIdleDigestWindow, startIdleDigestWindow, updateIdleDigestScan } from "../db/idle-digest";
17
+ import { getIdleDigestWindow } from "../db/idle-digest";
17
18
  import { workflowOwnsAgent } from "../db/workflow-task-read-ops";
18
19
  import { getIdleDigestConfig, idleDigestMayRun, teamIdleDigestSettings } from "../idle-digest-config";
19
20
  import { providerIdleAnchor } from "../idle-self-care";
@@ -45,7 +46,7 @@ export interface IdleChildRow {
45
46
  action: string;
46
47
  }
47
48
 
48
- interface SafeCandidate { row: IdleChildRow; instanceId?: string; epoch: number; idleAt: number }
49
+ export interface SafeCandidate { row: IdleChildRow; instanceId?: string; epoch: number; idleAt: number }
49
50
 
50
51
  export interface IdleDigestStop {
51
52
  agentId: string;
@@ -164,7 +165,7 @@ export async function classifyIdleChildren(children: AgentCard[], now: number):
164
165
 
165
166
  /** Why a safe candidate may no longer be stopped, read from the fresh card. Runs before the stop and
166
167
  * again inside shutdownAgent at command admission, after its host probe and audit, in one write transaction. */
167
- function stopRefusal(candidate: SafeCandidate, current: AgentCard, now: number): { reason: string; openTasks: OwnedTask[] } | undefined {
168
+ export function stopRefusal(candidate: SafeCandidate, current: AgentCard, now: number): { reason: string; openTasks: OwnedTask[] } | undefined {
168
169
  if (current.instanceId !== candidate.instanceId || current.epoch !== candidate.epoch) return { reason: "incarnation-changed", openTasks: [] };
169
170
  const eligibility = childEligibility(current, now);
170
171
  if (eligibility.excluded) return { reason: eligibility.excluded, openTasks: [] };
@@ -189,12 +190,16 @@ async function stopSafeChild(candidate: SafeCandidate, now: number, teamId: stri
189
190
  try {
190
191
  // requestedBy names the parent, so the child's exit does not also wake it: this digest reports it.
191
192
  const { command } = await shutdownAgent({
192
- agentId: agent.id, requestedVia: "maintenance", reason: IDLE_DIGEST_REAP_REASON, admit,
193
+ agentId: agent.id, requestedVia: "maintenance", reason: IDLE_DIGEST_REAP_REASON, idleCandidate: candidate,
193
194
  requestedBy: agent.spawnedBy ?? "idle-digest", auditMetadata: { idleDigest: true, teamId },
194
195
  }, authContextFromSystem());
195
196
  return { stop: { ...base, commandId: command.id, outcome: "pending" } };
196
197
  } catch (error) {
197
- if (error instanceof AutomaticShutdownRefused) return asRefused();
198
+ if (error instanceof AutomaticShutdownRefused) {
199
+ const current = getAgent(agent.id);
200
+ if (current) refusal = stopRefusal(candidate, current, now);
201
+ return asRefused();
202
+ }
198
203
  // The guard's fresh probe found unique work or could not verify the branch: a check row, not a failed stop.
199
204
  if (error instanceof UnlandedWorkRefusal || error instanceof UnverifiedWorkRefusal) {
200
205
  const { verdict } = error;
@@ -251,18 +256,18 @@ function idleDigestSubject(scan: IdleDigestScan): string {
251
256
  }
252
257
 
253
258
  /** Deliver once every stop has resolved, or the settle window lapsed; an empty window sends nothing. */
254
- function settleScan(teamId: string, coordinatorId: string, scan: IdleDigestScan, now: number): "waiting" | "sent" | "empty" {
259
+ async function settleScan(teamId: string, coordinatorId: string, scan: IdleDigestScan, now: number): Promise<"waiting" | "sent" | "empty"> {
255
260
  const resolved = { ...scan, stops: scan.stops.map(resolveStop) };
256
261
  if (resolved.stops.some((stop) => stop.outcome === "pending") && now - scan.at < STOP_SETTLE_MS) {
257
- updateIdleDigestScan(teamId, resolved);
262
+ (await updateIdleDigestScanAsync(teamId, resolved));
258
263
  return "waiting";
259
264
  }
260
265
  const body = renderIdleDigest(resolved);
261
266
  if (!body) {
262
- finishIdleDigestScan(teamId);
267
+ (await finishIdleDigestScanAsync(teamId));
263
268
  return "empty";
264
269
  }
265
- const [message] = routeNotification({
270
+ const [message] = await routeNotification({
266
271
  type: "agent.idle_digest",
267
272
  scope: { agentId: coordinatorId },
268
273
  recipients: [coordinatorId],
@@ -274,7 +279,7 @@ function settleScan(teamId: string, coordinatorId: string, scan: IdleDigestScan,
274
279
  replyExpected: false,
275
280
  },
276
281
  });
277
- finishIdleDigestScan(teamId, message ? { at: now, messageId: message.id } : undefined);
282
+ (await finishIdleDigestScanAsync(teamId, message ? { at: now, messageId: message.id } : undefined));
278
283
  return "sent";
279
284
  }
280
285
 
@@ -306,11 +311,11 @@ export async function runIdleAgentDigest(context: { signal?: AbortSignal; now?:
306
311
  }
307
312
  }
308
313
  scan = { at: now, check: classes.check, safe: settings.autoReapSafe ? [] : classes.safe.map((c) => c.row), stops };
309
- startIdleDigestWindow(team.id, now, scan);
314
+ (await startIdleDigestWindowAsync(team.id, now, scan));
310
315
  result.scanned.push(team.id);
311
316
  result.stopsRequested += stops.filter((stop) => stop.commandId).length;
312
317
  }
313
- const outcome = settleScan(team.id, team.coordinatorId, scan, now);
318
+ const outcome = await settleScan(team.id, team.coordinatorId, scan, now);
314
319
  if (outcome === "waiting") result.waiting.push(team.id);
315
320
  if (outcome === "sent") result.sent.push(team.id);
316
321
  }
@@ -16,8 +16,8 @@ function inFlight(task: Task): boolean {
16
16
  && (task.status !== "open" || !!task.ownerAgentId);
17
17
  }
18
18
 
19
- function reportUnresolvable(teamId: string, issue: IssueRef): void {
20
- routeNotification({
19
+ async function reportUnresolvable(teamId: string, issue: IssueRef): Promise<void> {
20
+ await routeNotification({
21
21
  type: "team.idle", scope: { teamId }, recipients: [`coordinator:${teamId}`],
22
22
  message: { kind: "system", from: "system", subject: "Tracker reference unresolvable",
23
23
  body: `${issue.repo}#${issue.externalKey} was not found on two tracker refreshes. Automatic refresh stopped; correct or remove the reference.`,
@@ -32,7 +32,7 @@ export async function refreshTeamEpicHierarchy(teamId: string, signal?: AbortSig
32
32
  for (const issue of teamEpicWork(teamId).issues) {
33
33
  if (signal?.aborted) break;
34
34
  if (issueTrackerNotFoundCount(issue.id) >= 2) {
35
- reportUnresolvable(teamId, issue);
35
+ await reportUnresolvable(teamId, issue);
36
36
  continue;
37
37
  }
38
38
  let statusLoaded = false;
@@ -48,7 +48,7 @@ export async function refreshTeamEpicHierarchy(teamId: string, signal?: AbortSig
48
48
  } catch (error) {
49
49
  if (!statusLoaded && error instanceof GitHubApiError && error.statusCode === 404
50
50
  && await recordIssueTrackerNotFoundAsync(issue.id) >= 2) {
51
- reportUnresolvable(teamId, issue);
51
+ await reportUnresolvable(teamId, issue);
52
52
  continue;
53
53
  }
54
54
  const failure = `Tracker refresh failed for ${issue.repo}#${issue.externalKey}: ${errMessage(error)}; retained prior snapshot.`;
@@ -1,8 +1,10 @@
1
+ import { deleteMessageAsync } from "../db/message-reads-async";
2
+ import { sendMessageAsync } from "../db/message-send";
1
3
  import { isHumanAgentId } from "@humwick/sdk";
2
4
  import { randomUUID } from "node:crypto";
3
- import { createCommandInternal } from "../commands-db";
5
+ import { createAgentControlAsync } from "../db/agent-control-async";
4
6
  import { emitCommandEvent } from "../command-events";
5
- import { ValidationError, createActivityEventAsync, deleteMessage, getAgent, getMessage, sendMessage } from "../db";
7
+ import { ValidationError, createActivityEventAsync, getAgent, getMessage } from "../db";
6
8
  import { emitActivityEvent, emitMessageDeleted, emitNewMessage } from "../sse";
7
9
  import type { ActivityEventInput, AgentCard, Command, CreateCommandInput } from "../types";
8
10
  import type { AuthContext } from "./auth-context";
@@ -41,11 +43,11 @@ function assertInterruptSupported(agent: AgentCard, mode: InterruptMode): void {
41
43
  }
42
44
  }
43
45
 
44
- function sessionMessageForRedirect(agentId: string, ctx: AuthContext, body: string, commandId: string) {
46
+ async function sessionMessageForRedirect(agentId: string, ctx: AuthContext, body: string, commandId: string) {
45
47
  const from = ctx.callerAgentId && getAgent(ctx.callerAgentId) ? ctx.callerAgentId : "system";
46
48
  // This ownership marker is created only by this server-side redirect flow. Terminal settlement
47
49
  // must never trust activity rows: activity:write callers may write arbitrary observability metadata.
48
- return sendMessage({ from, to: agentId, kind: "session", body, meta: { createdByCommandId: commandId } });
50
+ return (await sendMessageAsync({ from, to: agentId, kind: "session", body, meta: { createdByCommandId: commandId } }));
49
51
  }
50
52
 
51
53
  function revalidateAgentInstance(snapshot: AgentCard): AgentCard {
@@ -56,7 +58,7 @@ function revalidateAgentInstance(snapshot: AgentCard): AgentCard {
56
58
  return current;
57
59
  }
58
60
 
59
- export function settleInterruptRedirectMessage(command: Command): boolean {
61
+ export async function settleInterruptRedirectMessage(command: Command): Promise<boolean> {
60
62
  if (command.type !== "agent.interrupt" || !["failed", "timed_out", "rejected", "canceled"].includes(command.status)) return false;
61
63
  if (command.params.action !== "interrupt" || command.params.agentId !== command.target) return false;
62
64
  const redirect = command.params.redirect;
@@ -69,7 +71,7 @@ export function settleInterruptRedirectMessage(command: Command): boolean {
69
71
  // Exact primary-key lookup plus the server-stamped message owner is the authorization link. The
70
72
  // activity row is observability only and cannot authorize this destructive deletion.
71
73
  if (message.meta?.createdByCommandId !== command.id) return false;
72
- if (!deleteMessage(message.id)) return false;
74
+ if (!(await deleteMessageAsync(message.id))) return false;
73
75
  emitMessageDeleted(message.id);
74
76
  return true;
75
77
  }
@@ -81,7 +83,7 @@ export function settleInterruptRedirectMessage(command: Command): boolean {
81
83
  export async function dispatchInterrupt(input: InterruptAgentInput, ctx: AuthContext): Promise<InterruptAgentResult> {
82
84
  const agent = getAgent(input.agentId);
83
85
  if (!agent) throw new ShutdownTargetError(`agent ${input.agentId} not found`);
84
- authorizeShutdown(ctx, { agentId: input.agentId, requestedVia: input.requestedVia });
86
+ (await authorizeShutdown(ctx, { agentId: input.agentId, requestedVia: input.requestedVia }));
85
87
  assertInterruptSupported(agent, input.mode);
86
88
 
87
89
  if (input.mode === "stop" && agent.status !== "busy") {
@@ -134,11 +136,12 @@ export async function dispatchInterrupt(input: InterruptAgentInput, ctx: AuthCon
134
136
  // the await is rejected rather than receiving predecessor-bound interrupt state.
135
137
  const event = await createActivityEventAsync(activityInput);
136
138
  const current = revalidateAgentInstance(agent);
137
- const sessionMessage = body ? sessionMessageForRedirect(current.id, ctx, body, commandId) : undefined;
139
+ const sessionMessage = body ? (await sessionMessageForRedirect(current.id, ctx, body, commandId)) : undefined;
138
140
  if (sessionMessage && commandInput.params.redirect && typeof commandInput.params.redirect === "object") {
139
141
  (commandInput.params.redirect as Record<string, unknown>).messageId = sessionMessage.id;
140
142
  }
141
- const command = createCommandInternal({ input: commandInput, id: commandId });
143
+ const { command: admitted } = await createAgentControlAsync({ agent, commandInput, commandId });
144
+ const command = admitted!;
142
145
  if (sessionMessage) emitNewMessage(sessionMessage);
143
146
  emitCommandEvent(command, "command.requested");
144
147
  emitActivityEvent(event);
@@ -4,7 +4,7 @@ import {
4
4
  type IssueActivityAction,
5
5
  type RecordIssueActivityInput,
6
6
  } from "../db/activity";
7
- import { listAgentIssueActivityAsync, listIssueActivityAgentsAsync } from "../db/activity-async";
7
+ import { recordIssueActivityAsync, listAgentIssueActivityAsync, listIssueActivityAgentsAsync } from "../db/activity-async";
8
8
  import { emitActivityEvent } from "../sse";
9
9
 
10
10
  export {
@@ -16,8 +16,8 @@ export {
16
16
  type RecordIssueActivityInput,
17
17
  };
18
18
 
19
- export function recordAndEmitIssueActivity(input: RecordIssueActivityInput) {
20
- const event = recordIssueActivity(input);
19
+ export async function recordAndEmitIssueActivity(input: RecordIssueActivityInput) {
20
+ const event = await recordIssueActivityAsync(input);
21
21
  emitActivityEvent(event);
22
22
  return event;
23
23
  }
@@ -1,10 +1,7 @@
1
- import {
2
- associateIssue,
3
- listEntitiesForIssue,
4
- listIssuesForEntity,
5
- removeAssociation,
6
- } from "../db/issue-associations";
7
- import { getIssueRef, resolveIssueRefByExternalKey, resolveIssueRefFromString } from "../db/issue-refs";
1
+ import { resolveIssueRefFromStringAsync, resolveIssueRefByExternalKeyAsync } from "../db/issue-refs-async";
2
+ import { removeAssociationAsync, associateIssueAsync } from "../db/runtime-tail-async";
3
+ import { listEntitiesForIssue, listIssuesForEntity } from "../db/issue-associations";
4
+ import { getIssueRef } from "../db/issue-refs";
8
5
  import type { IssueAssociationEntityType, IssueAssociationIssue, IssueProvider } from "../types";
9
6
  import { ValidationError } from "../db/connection";
10
7
 
@@ -24,36 +21,36 @@ interface AssociateIssueInput extends ResolveAssociationIssueInput {
24
21
  entityId: string;
25
22
  }
26
23
 
27
- export function resolveAssociationIssueRef(input: ResolveAssociationIssueInput) {
24
+ export async function resolveAssociationIssueRef(input: ResolveAssociationIssueInput) {
28
25
  if (input.issueRefId) {
29
26
  const issueRef = getIssueRef(input.issueRefId);
30
27
  if (!issueRef) throw new ValidationError(`issue ref ${input.issueRefId} not found`);
31
28
  return issueRef;
32
29
  }
33
30
  if (input.ref) {
34
- return resolveIssueRefFromString({
31
+ return (await resolveIssueRefFromStringAsync({
35
32
  ref: input.ref,
36
33
  defaultRepo: input.defaultRepo ?? input.repo,
37
34
  provider: input.provider,
38
35
  title: input.title,
39
- });
36
+ }));
40
37
  }
41
38
  if (input.provider && input.repo && input.externalKey) {
42
- return resolveIssueRefByExternalKey({
39
+ return (await resolveIssueRefByExternalKeyAsync({
43
40
  provider: input.provider,
44
41
  repo: input.repo,
45
42
  externalKey: input.externalKey,
46
43
  url: input.url,
47
44
  title: input.title,
48
- });
45
+ }));
49
46
  }
50
47
  throw new ValidationError("issueRefId, ref, or provider/repo/externalKey required");
51
48
  }
52
49
 
53
- export function associateIssueRef(input: AssociateIssueInput) {
54
- const issueRef = resolveAssociationIssueRef(input);
50
+ export async function associateIssueRef(input: AssociateIssueInput) {
51
+ const issueRef = (await resolveAssociationIssueRef(input));
55
52
  return {
56
- association: associateIssue(issueRef.id, input.entityType, input.entityId),
53
+ association: (await associateIssueAsync(issueRef.id, input.entityType, input.entityId)),
57
54
  issueRef,
58
55
  };
59
56
  }
@@ -66,7 +63,7 @@ export function listIssueEntities(issueRefId: string) {
66
63
  return listEntitiesForIssue(issueRefId);
67
64
  }
68
65
 
69
- export function removeIssueAssociation(input: AssociateIssueInput): { deleted: boolean } {
70
- const issueRef = resolveAssociationIssueRef(input);
71
- return { deleted: removeAssociation(issueRef.id, input.entityType, input.entityId) };
66
+ export async function removeIssueAssociation(input: AssociateIssueInput): Promise<{ deleted: boolean }> {
67
+ const issueRef = (await resolveAssociationIssueRef(input));
68
+ return { deleted: (await removeAssociationAsync(issueRef.id, input.entityType, input.entityId)) };
72
69
  }
@@ -1,5 +1,6 @@
1
+ import { recordIssueLifecycleCommentAsync } from "../db/runtime-tail-async";
1
2
  import { createHash } from "node:crypto";
2
- import { hasIssueLifecycleComment, recordIssueLifecycleComment } from "../db/long-running-work";
3
+ import { hasIssueLifecycleComment } from "../db/long-running-work";
3
4
  import type { IssueTrackerAdapter } from "../issue-tracker";
4
5
  import type { IssueRef } from "../types";
5
6
 
@@ -8,5 +9,5 @@ export async function commentIssueLifecycleOnce(adapter: IssueTrackerAdapter, re
8
9
  const commentKey = createHash("sha256").update(body).digest("hex");
9
10
  if (hasIssueLifecycleComment(ref.id, landKey, commentKey)) return;
10
11
  await adapter.comment(ref, body);
11
- recordIssueLifecycleComment(ref.id, landKey, commentKey);
12
+ (await recordIssueLifecycleCommentAsync(ref.id, landKey, commentKey));
12
13
  }
@@ -1,9 +1,10 @@
1
+ import { associateIssueAsync, insertTaskEventAsync } from "../db/runtime-tail-async";
1
2
  import { commentIssueLifecycleOnce } from "./issue-lifecycle-comments";
2
3
  import { deferIssueClose, pendingDoneWhenTasks } from "./issue-completion";
3
4
  import { canCloseBacklink, landTaskIssueLinks, recordReferencesOnlyLand } from "./land-issue-relations";
4
5
  import { errMessage } from "@humwick/sdk";
5
6
  import { resolveLandedTaskIds, type LandedTaskAttributionInput } from "./landed-task-attribution";
6
- import { getTaskDetail, insertTaskEvent, listTaskEvents } from "../db";
7
+ import { getTaskDetail, listTaskEvents } from "../db";
7
8
  import { listEntitiesForIssue, listIssuesForEntity } from "../db/issue-associations";
8
9
  import {
9
10
  getSuccessfulIssueLifecycleAction,
@@ -11,7 +12,7 @@ import {
11
12
  } from "../db/issue-lifecycle";
12
13
  import { getIssueRef } from "../db/issue-refs";
13
14
  import { resolveIssueRefByExternalKeyAsync, resolveIssueRefFromStringAsync, updateIssueRefAsync, upsertIssueLifecycleActionAsync } from "../db/issue-refs-async";
14
- import { associateIssue } from "../db/issue-associations";
15
+
15
16
  import { resolveIssueTrackerAdapter } from "../issue-tracker";
16
17
  import { defaultIssueRepo } from "../config";
17
18
  // `repoFromGitRemote` / `parseOwnerRepoFromRemote` live in the shared ./git-remote module
@@ -226,18 +227,18 @@ function taskIssueLinkMismatches(taskIds: number[], declared: IssueRef[] | undef
226
227
  });
227
228
  }
228
229
 
229
- function recordIssueLinkMismatch(taskId: number, mismatch: IssueLinkMismatch, input: LandedIssueLifecycleInput): void {
230
+ async function recordIssueLinkMismatch(taskId: number, mismatch: IssueLinkMismatch, input: LandedIssueLifecycleInput): Promise<void> {
230
231
  const key = landKey(input);
231
232
  if (listTaskEvents(taskId).some((event) => event.type === "issue-link-mismatch" && event.metadata.landKey === key)) return;
232
233
  const body = `Landed commit declared issue(s) ${mismatch.declared.map((key) => `#${key}`).join(", ")}, while Task T${taskId} remains linked to ${mismatch.associated.map((key) => `#${key}`).join(", ")}. Used the commit declaration for issue lifecycle; Task links were not changed.`;
233
- insertTaskEvent(taskId, {
234
+ (await insertTaskEventAsync(taskId, {
234
235
  source: "issue-lifecycle",
235
236
  type: "issue-link-mismatch",
236
237
  severity: "warning",
237
238
  title: "Commit issue declaration differs from Task link",
238
239
  body,
239
240
  metadata: { landKey: key, declared: mismatch.declared, associated: mismatch.associated, source: "commit-declaration" },
240
- }, Date.now());
241
+ }, Date.now()));
241
242
  const task = getTaskDetail(taskId);
242
243
  if (task) emitTaskChanged(task, "task.issue-link-mismatch");
243
244
  }
@@ -479,7 +480,7 @@ export async function closeIssueRefForLand(
479
480
  status: "succeeded",
480
481
  });
481
482
  if (input.workspace.ownerAgentId) {
482
- recordAndEmitIssueActivity({
483
+ (await recordAndEmitIssueActivity({
483
484
  agentId: input.workspace.ownerAgentId,
484
485
  action: "done",
485
486
  issueRefId: latest.id,
@@ -487,7 +488,7 @@ export async function closeIssueRefForLand(
487
488
  title: "Issue closed on land",
488
489
  body: comment,
489
490
  metadata: { workspaceId: input.workspace.id, branch: input.workspace.branch, commitSha: input.mergedSha, source },
490
- });
491
+ }));
491
492
  }
492
493
  // #2520 — relay's own completed close is a terminal trigger for the plan nodes bound to
493
494
  // this ref. Awaited post-commit effect: the close is already durable, and the plan update
@@ -546,9 +547,9 @@ export async function handleLandedIssueLifecycle(input: LandedIssueLifecycleInpu
546
547
  const taskIds = resolveLandedTaskIds(input);
547
548
  const links = landTaskIssueLinks(taskIds);
548
549
  const resolved = await resolveIssueRefsForLand(input, links);
549
- recordReferencesOnlyLand(links, resolved.refs, landKey(input));
550
+ (await recordReferencesOnlyLand(links, resolved.refs, landKey(input)));
550
551
  const mismatches = taskIssueLinkMismatches(taskIds, resolved.declared);
551
- for (const mismatch of mismatches) recordIssueLinkMismatch(mismatch.taskId, mismatch, input);
552
+ for (const mismatch of mismatches) (await recordIssueLinkMismatch(mismatch.taskId, mismatch, input));
552
553
  if (resolved.refs.length === 0 && taskIds.length > 0 && taskIds.every((id) => listIssuesForEntity("task", String(id)).length === 0)) {
553
554
  logFailure(opts, `issue lifecycle found landed task(s) without linked issue refs: tasks=${taskIds.join(",")} workspace=${input.workspace.id} branch=${input.workspace.branch ?? "unknown"}`);
554
555
  }
@@ -566,15 +567,15 @@ async function resolveReopenRef(input: ReopenIssueLifecycleInput): Promise<Issue
566
567
  if (!issueRef) throw new Error(`issue ref ${input.issueRefId} not found`);
567
568
  return issueRef;
568
569
  }
569
- if (input.ref) return resolveIssueRefFromStringAsync({ ref: input.ref, defaultRepo: input.defaultRepo ?? input.repo, provider: input.provider, title: input.title });
570
+ if (input.ref) return (await resolveIssueRefFromStringAsync({ ref: input.ref, defaultRepo: input.defaultRepo ?? input.repo, provider: input.provider, title: input.title }));
570
571
  if (input.provider && input.repo && input.externalKey) {
571
- return resolveIssueRefByExternalKeyAsync({
572
+ return (await resolveIssueRefByExternalKeyAsync({
572
573
  provider: input.provider,
573
574
  repo: input.repo,
574
575
  externalKey: input.externalKey,
575
576
  url: input.url,
576
577
  title: input.title,
577
- });
578
+ }));
578
579
  }
579
580
  throw new Error("issueRefId, ref, or provider/repo/externalKey required");
580
581
  }
@@ -596,7 +597,7 @@ export async function reopenIssueLifecycle(input: ReopenIssueLifecycleInput, opt
596
597
  status: "succeeded",
597
598
  source: "explicit",
598
599
  });
599
- if (input.entityType && input.entityId) associateIssue(issueRef.id, input.entityType, input.entityId);
600
+ if (input.entityType && input.entityId) (await associateIssueAsync(issueRef.id, input.entityType, input.entityId));
600
601
  return { issueRef: opened, action: "reopened", landKey: key };
601
602
  } catch (error) {
602
603
  const message = errMessage(error);
@@ -1,7 +1,6 @@
1
- import { deleteIssueRefAsync, resolveIssueRefByExternalKeyAsync, resolveIssueRefFromStringAsync, updateIssueRefAsync, upsertIssueRefAsync } from "../db/issue-refs-async";
1
+ import { deleteIssueRefAsync, listIssueRefsAsync, resolveIssueRefByExternalKeyAsync, resolveIssueRefFromStringAsync, updateIssueRefAsync, upsertIssueRefAsync } from "../db/issue-refs-async";
2
2
  import {
3
3
  getIssueRef,
4
- listIssueRefs,
5
4
  type ListIssueRefsOptions,
6
5
  type ResolveIssueRefByExternalKeyInput,
7
6
  type ResolveIssueRefFromStringInput,
@@ -9,14 +8,14 @@ import {
9
8
  type UpsertIssueRefInput,
10
9
  } from "../db/issue-refs";
11
10
 
12
- export { getIssueRef, listIssueRefs, type ListIssueRefsOptions };
11
+ export { getIssueRef, listIssueRefsAsync, type ListIssueRefsOptions };
13
12
 
14
13
  export function upsertIssueRefMappingAsync(input: UpsertIssueRefInput) {
15
14
  return upsertIssueRefAsync(input);
16
15
  }
17
16
 
18
- export function resolveIssueRefMappingAsync(input: ResolveIssueRefByExternalKeyInput | ResolveIssueRefFromStringInput) {
19
- return "ref" in input ? resolveIssueRefFromStringAsync(input) : resolveIssueRefByExternalKeyAsync(input);
17
+ export async function resolveIssueRefMappingAsync(input: ResolveIssueRefByExternalKeyInput | ResolveIssueRefFromStringInput) {
18
+ return "ref" in input ? (await resolveIssueRefFromStringAsync(input)) : (await resolveIssueRefByExternalKeyAsync(input));
20
19
  }
21
20
 
22
21
  export function patchIssueRefMappingAsync(id: string, input: UpdateIssueRefInput) {
@@ -102,7 +102,7 @@ async function main(): Promise<void> {
102
102
  await c.tick();
103
103
  await c.tick();
104
104
  if (boundary === "before-release") {
105
- c.requestAbort("chaos release");
105
+ await c.requestAbort("chaos release");
106
106
  await c.tick();
107
107
  await c.tick();
108
108
  }