@humwick/server 0.130.2 → 0.130.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (570) 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 +73 -4
  8. package/package.json +8 -7
  9. package/public/assets/{MessageBubble-BWLqMGKG.js → MessageBubble-Bq9kr21N.js} +2 -2
  10. package/public/assets/{PlanGraphPanel-3TlIQpjk.js → PlanGraphPanel-Dqiroy06.js} +2 -2
  11. package/public/assets/{TraceView-Wimm0Czv.js → TraceView-DYU962-H.js} +2 -2
  12. package/public/assets/{VaultDecisionCard-Bau_vNax.js → VaultDecisionCard-DhPfzioE.js} +2 -2
  13. package/public/assets/{activity-CrSurn-r.js → activity-DzCcQTee.js} +2 -2
  14. package/public/assets/{agent-lineage-CknAJKcb.js → agent-lineage-SgDt9i3T.js} +2 -2
  15. package/public/assets/agent-liveness-Bq-s73jW.js +2 -0
  16. package/public/assets/{agent-name-DKbiIhBo.js → agent-name-CcY3Aijy.js} +2 -2
  17. package/public/assets/{agent-profiles-DwF6EQ4R.js → agent-profiles-cxtRBn6O.js} +2 -2
  18. package/public/assets/{agent-project-badge-Diz4Sjjb.js → agent-project-badge-DGYbIhaI.js} +2 -2
  19. package/public/assets/{agent-tools-CRhpRQza.js → agent-tools-DHbftV0N.js} +2 -2
  20. package/public/assets/{agent-type-icon-LrUEU3lB.js → agent-type-icon-CY113sp-.js} +2 -2
  21. package/public/assets/{agents-B-v66C-4.js → agents-BPzY7IlQ.js} +2 -2
  22. package/public/assets/{analytics-BqCb-LKi.js → analytics-DENFPv_a.js} +2 -2
  23. package/public/assets/{artifact-viewer-kf4pGuAR.js → artifact-viewer-KRvSc7sl.js} +2 -2
  24. package/public/assets/{artifacts-DJevXcvg.js → artifacts-C9gSmL3s.js} +2 -2
  25. package/public/assets/{artifacts-D32zyw4Y.js → artifacts-DT-HkI5O.js} +2 -2
  26. package/public/assets/{automation-BpRajx_5.js → automation-BsmjQhKD.js} +2 -2
  27. package/public/assets/{backlog-D_UjTdzX.js → backlog-8NYH_62t.js} +2 -2
  28. package/public/assets/{busy-health-N3VEh4ao.js → busy-health-D3hwvYb4.js} +2 -2
  29. package/public/assets/{channels-9jopungq.js → channels-DCJ5WL7O.js} +2 -2
  30. package/public/assets/{chat-CSXrTB3C.js → chat-DAIl357U.js} +3 -3
  31. package/public/assets/{code-preview-p1NnmqK0.js → code-preview-CzrZfr9U.js} +2 -2
  32. package/public/assets/{connectors-CZdqlDNL.js → connectors-xTxtlyou.js} +2 -2
  33. package/public/assets/{cosmos-BgdsE4dG.js → cosmos-BpebFLK2.js} +2 -2
  34. package/public/assets/{crate-agent-30aXTKva.js → crate-agent-BHvI5wXC.js} +2 -2
  35. package/public/assets/{dependency-graph-B_jvw2GE.js → dependency-graph-DGT0o3wJ.js} +2 -2
  36. package/public/assets/{deploys-DoN6bAb5.js → deploys-hqWOHSHE.js} +2 -2
  37. package/public/assets/{display-BrKWFGJz.js → display-CDeH4I8T.js} +2 -2
  38. package/public/assets/{files-D6XEu8Ng.js → files-BTeGVmTg.js} +2 -2
  39. package/public/assets/{fleet-C7jQWbw2.js → fleet-DgXtNgCa.js} +2 -2
  40. package/public/assets/{fleet-metrics-BiDs3MLx.js → fleet-metrics-BHEt5yc_.js} +2 -2
  41. package/public/assets/{formatted-body-CQBwc1fb.js → formatted-body-MLtodyPp.js} +3 -3
  42. package/public/assets/{formatted-body-impl-DyG0WsQS.js → formatted-body-impl-CAe664Z8.js} +2 -2
  43. package/public/assets/{host-providers-dialog-DKaW31dN.js → host-providers-dialog-mapF4Fj9.js} +2 -2
  44. package/public/assets/{index-CRHep3M9.js → index-CqqgOI5R.js} +5 -5
  45. package/public/assets/{insights-CzrtkpOE.js → insights-DNyf7IzF.js} +2 -2
  46. package/public/assets/{integrations-aVsUmigt.js → integrations-DlYOHq7T.js} +2 -2
  47. package/public/assets/{issue-ref-chip-BnSlM_95.js → issue-ref-chip-CeWBNWn7.js} +2 -2
  48. package/public/assets/{log-viewer-qe7Ee47Z.js → log-viewer-Cib8nqdE.js} +2 -2
  49. package/public/assets/{maintenance-NfjqFZAk.js → maintenance-DSn1cPm7.js} +2 -2
  50. package/public/assets/{managed-agents-BiH0HgaE.js → managed-agents-C3CkM81m.js} +2 -2
  51. package/public/assets/{markdown-preview-BixaT3Xr.js → markdown-preview-W4VQQPAv.js} +3 -3
  52. package/public/assets/{markdown-preview-impl-DNGlWIS3.js → markdown-preview-impl-CMsTdhjq.js} +2 -2
  53. package/public/assets/{memory-DNsCl6UX.js → memory-BV17qtO4.js} +2 -2
  54. package/public/assets/{messages-DopU1L1X.js → messages-Bm_1AqSA.js} +2 -2
  55. package/public/assets/{orchestrators-Cq7ckLQT.js → orchestrators-Dg-vfP09.js} +2 -2
  56. package/public/assets/{overview-C1DCTzzV.js → overview-DcYCrvlr.js} +2 -2
  57. package/public/assets/{pairs-DE_m6rrE.js → pairs-8o9nuG3V.js} +2 -2
  58. package/public/assets/{profile-icon-B3rfh77F.js → profile-icon-BsRyBMea.js} +2 -2
  59. package/public/assets/{project-profile-instructions-DQWZE0kA.js → project-profile-instructions-DETKFn_E.js} +2 -2
  60. package/public/assets/{projects-Br2Bd2h1.js → projects-M_m6AHws.js} +2 -2
  61. package/public/assets/{prompt-settings-BKvFsvGD.js → prompt-settings-C_mNCgeL.js} +2 -2
  62. package/public/assets/provider-display-BEeLXC_D.js +2 -0
  63. package/public/assets/{registry-Cw38_6gW.js → registry-DDHHHE5N.js} +2 -2
  64. package/public/assets/run-card-Dt4I4jaP.js +2 -0
  65. package/public/assets/{secrets-DxI-vzSq.js → secrets-BkVwxI5O.js} +2 -2
  66. package/public/assets/{service-access-settings-D9s_VJbd.js → service-access-settings-Crq-6a-B.js} +2 -2
  67. package/public/assets/{settings-CKZTVGIx.js → settings-CYcavMFu.js} +2 -2
  68. package/public/assets/shipping-H6gzEeZB.js +2 -0
  69. package/public/assets/{stats-DyUBKyWI.js → stats-BJVeWkpV.js} +2 -2
  70. package/public/assets/{status-dot-DYqlEUhJ.js → status-dot-BcHyw1Vw.js} +2 -2
  71. package/public/assets/store-DKPDIZBe.js +9 -0
  72. package/public/assets/{tasks-Bh7Chr4-.js → tasks-qJjlQPpx.js} +2 -2
  73. package/public/assets/{teams-bowI7qVY.js → teams-Cd5Sk1uX.js} +2 -2
  74. package/public/assets/{terminal-viewer-BgVLHdsU.js → terminal-viewer-CpY5_m7W.js} +3 -3
  75. package/public/assets/{terminal-viewer-impl-Dz22UPy6.js → terminal-viewer-impl-DI_2llFR.js} +2 -2
  76. package/public/assets/{use-agent-terminal-DSQQ-iY7.js → use-agent-terminal-0yJA_buM.js} +2 -2
  77. package/public/assets/{use-decisions-samMQhQf.js → use-decisions-uJXHf34W.js} +2 -2
  78. package/public/assets/{use-project-list-59LheVP7.js → use-project-list-CpWl6eHQ.js} +2 -2
  79. package/public/assets/{use-selectors-BZa25xEB.js → use-selectors-BdxBW8mL.js} +2 -2
  80. package/public/assets/{user-avatar-DHxlvUvV.js → user-avatar-3IndfpOc.js} +2 -2
  81. package/public/assets/{versioned-prompt-editor-BmED5DnJ.js → versioned-prompt-editor-CIVg7XB1.js} +2 -2
  82. package/public/assets/{work-queue-CSvpuNLz.js → work-queue-B9rnLwHZ.js} +2 -2
  83. package/public/assets/{workflow-marker-DAZcj5qt.js → workflow-marker-X8wxyhzC.js} +2 -2
  84. package/public/assets/{workflows-DdmxRSyg.js → workflows-o5YyMFW7.js} +2 -2
  85. package/public/assets/{workspaces-BxeKfVuF.js → workspaces-CzEGoAng.js} +2 -2
  86. package/public/cosmos.html +4 -4
  87. package/public/index.html +28 -28
  88. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  89. package/runner/src/adapters/claude-headless.ts +1 -1
  90. package/runner/src/adapters/claude-launch-exit.ts +26 -0
  91. package/runner/src/adapters/claude-session-probe.ts +1 -1
  92. package/runner/src/adapters/claude-tmux.ts +38 -10
  93. package/runner/src/adapters/claude.ts +28 -75
  94. package/runner/src/adapters/provider-quota-harvest.ts +20 -71
  95. package/runner/src/agent-runner/lifecycle-milestones.ts +2 -2
  96. package/runner/src/agent-runner/liveness-exchange.ts +104 -0
  97. package/runner/src/claude-system-prompt.ts +49 -0
  98. package/runner/src/launch-assembly.ts +14 -10
  99. package/runner/src/profile-home.ts +1 -1
  100. package/runner/src/project-instructions.ts +2 -2
  101. package/runner/src/provider-command.ts +18 -0
  102. package/runner/src/provider-setup.ts +2 -1
  103. package/runner/src/runner-core.ts +14 -15
  104. package/runner/src/runner-helpers.ts +0 -8
  105. package/runner/src/session-scratch.ts +6 -2
  106. package/runner/test-support/provisioning-context.ts +4 -2
  107. package/runner/test-support/runner-harness.ts +2 -1
  108. package/scripts/steward-policy-cleanup.ts +2 -2
  109. package/src/agent-authz.ts +2 -2
  110. package/src/agent-drive-arbiter.ts +3 -8
  111. package/src/agent-exit-cleanup-async.ts +2 -2
  112. package/src/agent-exit-cleanup.ts +23 -19
  113. package/src/agent-lifecycle-events.ts +112 -85
  114. package/src/agent-ref.ts +3 -2
  115. package/src/agent-status-events.ts +43 -14
  116. package/src/auth/password.ts +4 -3
  117. package/src/auth/session-refresh.ts +1 -1
  118. package/src/auth/session.test-fixture.ts +2 -2
  119. package/src/auth/session.ts +7 -7
  120. package/src/automations/crud.ts +8 -81
  121. package/src/automations/dispatch.ts +33 -58
  122. package/src/automations/index.ts +1 -1
  123. package/src/automations/persistence.ts +65 -0
  124. package/src/automations/precheck.ts +18 -16
  125. package/src/automations/read-async.ts +11 -0
  126. package/src/automations/reconcile.ts +30 -39
  127. package/src/automations/storage.ts +33 -10
  128. package/src/automations/write-async.ts +33 -0
  129. package/src/branch-land-notice.ts +3 -3
  130. package/src/branch-landed.ts +25 -23
  131. package/src/bus.ts +21 -19
  132. package/src/cd-deploy-notify.ts +2 -2
  133. package/src/ci/notifications.ts +4 -4
  134. package/src/ci/root-missing.ts +3 -3
  135. package/src/ci/transition-notify.ts +5 -5
  136. package/src/claude-app/oauth-http.ts +3 -3
  137. package/src/cli/workflow.ts +12 -3
  138. package/src/commands-db.ts +4 -4
  139. package/src/commands-write.ts +8 -0
  140. package/src/compaction-watch.ts +10 -8
  141. package/src/config-store-write.ts +2 -2
  142. package/src/config.ts +4 -11
  143. package/src/connectors.ts +10 -8
  144. package/src/context-advisory.ts +22 -21
  145. package/src/db/agent-action-write.ts +36 -0
  146. package/src/db/agent-control-async.ts +9 -0
  147. package/src/db/agent-control-write.ts +49 -0
  148. package/src/db/agent-effort-observe.ts +22 -0
  149. package/src/db/agent-meta.ts +14 -3
  150. package/src/db/agents-async.ts +8 -5
  151. package/src/db/agents.ts +15 -12
  152. package/src/db/auth-identities.ts +2 -2
  153. package/src/db/automation-read-ops.ts +11 -0
  154. package/src/db/automation-write-ops.ts +46 -0
  155. package/src/db/blackboard.ts +2 -2
  156. package/src/db/browser-session-write.ts +32 -0
  157. package/src/db/bus-outbox-write-ops.ts +3 -1
  158. package/src/db/checkout-refresh-schema.ts +47 -0
  159. package/src/db/checkout-refresh.ts +5 -5
  160. package/src/db/command-agent-profile-backfill.ts +39 -0
  161. package/src/db/command-agent-profiles.ts +5 -1
  162. package/src/db/command-retention.ts +126 -0
  163. package/src/db/commands-planner-stats.test-fixture.ts +8 -0
  164. package/src/db/commands-read-ops.ts +16 -0
  165. package/src/db/connection.ts +1 -182
  166. package/src/db/context-carry-write.ts +74 -0
  167. package/src/db/continuations.ts +4 -4
  168. package/src/db/db-error-registry.ts +12 -0
  169. package/src/db/gateway.ts +26 -133
  170. package/src/db/history-retention-ops.ts +13 -0
  171. package/src/db/inbox-async.ts +2 -2
  172. package/src/db/inbox-read-ops.ts +1 -1
  173. package/src/db/inbox.ts +9 -3
  174. package/src/db/issue-associations.ts +2 -2
  175. package/src/db/issue-refs-async.ts +4 -1
  176. package/src/db/issue-refs-read-ops.ts +6 -0
  177. package/src/db/issue-refs.ts +8 -8
  178. package/src/db/kernel-event-log-schema.ts +2 -0
  179. package/src/db/land-boundaries.ts +51 -5
  180. package/src/db/land-gate-attestations.ts +2 -2
  181. package/src/db/landing-receipts.ts +2 -2
  182. package/src/db/lifecycle-context-write.ts +5 -0
  183. package/src/db/lifecycle-tail-async.ts +76 -0
  184. package/src/db/lifecycle-tail-write-ops.ts +62 -0
  185. package/src/db/lifecycle-write-window.ts +2 -1
  186. package/src/db/lineage-pair-dedupe-sql.ts +3 -3
  187. package/src/db/main-connection-mode.ts +11 -0
  188. package/src/db/main-connection-writes.ts +20 -2
  189. package/src/db/maintenance-job-runs-async.ts +2 -2
  190. package/src/db/maintenance-job-write-ops.ts +1 -1
  191. package/src/db/maintenance-pauses.ts +2 -2
  192. package/src/db/message-send.ts +4 -0
  193. package/src/db/messages.ts +31 -25
  194. package/src/db/migrations.ts +18 -1
  195. package/src/db/notification-write-ops.ts +19 -0
  196. package/src/db/operator-answer-write.ts +19 -0
  197. package/src/db/orchestrators.ts +10 -4
  198. package/src/db/pairs-async.ts +22 -1
  199. package/src/db/pairs-write-ops.ts +8 -3
  200. package/src/db/pairs.ts +41 -48
  201. package/src/db/plan-dispatch-schema.ts +5 -1
  202. package/src/db/plan-ready-notices.ts +43 -0
  203. package/src/db/plan-tools-include-migration.ts +36 -0
  204. package/src/db/plans-write-ops.ts +2 -0
  205. package/src/db/presence-buffer.ts +5 -0
  206. package/src/db/presence-loop.ts +18 -23
  207. package/src/db/presence-write.ts +0 -6
  208. package/src/db/project-entries-async.ts +14 -0
  209. package/src/db/project-entries-read-ops.ts +5 -1
  210. package/src/db/project-entries-write-ops.ts +8 -0
  211. package/src/db/project-entries.ts +15 -12
  212. package/src/db/project-journal.ts +2 -2
  213. package/src/db/project-trust-approvals.ts +2 -2
  214. package/src/db/prompt-templates.ts +4 -4
  215. package/src/db/read-op-marshaling-fixtures.ts +18 -0
  216. package/src/db/read-ops.ts +4 -0
  217. package/src/db/retention.ts +13 -2
  218. package/src/db/review-publish-write.ts +8 -0
  219. package/src/db/runtime-admin-async.ts +19 -0
  220. package/src/db/runtime-admin-write-ops.ts +36 -0
  221. package/src/db/runtime-tail-async.ts +288 -0
  222. package/src/db/runtime-tail-write-ops.ts +97 -0
  223. package/src/db/schema.ts +4 -1
  224. package/src/db/spawn-budget.ts +5 -0
  225. package/src/db/spawn-delegation.ts +1 -11
  226. package/src/db/sql-audit-indexes.ts +3 -0
  227. package/src/db/stats-async.ts +5 -3
  228. package/src/db/task-entity.ts +5 -4
  229. package/src/db/team-claim-policy.ts +60 -0
  230. package/src/db/teams-async.ts +4 -0
  231. package/src/db/teams-write-ops.ts +4 -0
  232. package/src/db/terminal-events.ts +15 -0
  233. package/src/db/timer-cutover-bodies.ts +292 -0
  234. package/src/db/timer-cutover-core.ts +37 -278
  235. package/src/db/timer-cutover-state.ts +40 -0
  236. package/src/db/timer-cutover-write-ops.ts +1 -40
  237. package/src/db/token-db-write-ops.ts +2 -0
  238. package/src/db/token-standing-async.ts +12 -0
  239. package/src/db/token-standing.ts +6 -9
  240. package/src/db/token-usage-retention.ts +33 -0
  241. package/src/db/token-usage-write-ops.ts +1 -1
  242. package/src/db/token-usage.ts +4 -1
  243. package/src/db/user-invites-async.ts +13 -0
  244. package/src/db/user-invites.ts +3 -3
  245. package/src/db/users.ts +14 -6
  246. package/src/db/workspaces.ts +8 -5
  247. package/src/db/write-ops.ts +31 -12
  248. package/src/db/writer-fault-seam.ts +2 -9
  249. package/src/db/writer-fault-test-ops.ts +18 -0
  250. package/src/db/writer-gateway.ts +42 -46
  251. package/src/dev.ts +8 -3
  252. package/src/event-loop-lag.ts +4 -2
  253. package/src/event-loop-yield.ts +2 -2
  254. package/src/events.ts +10 -8
  255. package/src/host-provider-store.ts +5 -4
  256. package/src/hub-metrics-report.ts +5 -1
  257. package/src/hub-metrics.ts +38 -18
  258. package/src/injection-sweep-pacing.ts +6 -8
  259. package/src/land-gate-notifications.ts +11 -10
  260. package/src/land-gate-queue-progress.ts +3 -3
  261. package/src/land-settle-dispatch.ts +52 -92
  262. package/src/lifecycle-context-pressure.ts +11 -10
  263. package/src/lifecycle-manager.ts +104 -98
  264. package/src/maintenance/breaker.ts +18 -16
  265. package/src/maintenance/checkout-refresh.ts +18 -1
  266. package/src/maintenance/critical-job-watchdog.ts +3 -3
  267. package/src/maintenance/events.ts +3 -3
  268. package/src/maintenance/history-retention-job.ts +30 -0
  269. package/src/maintenance/jobs.ts +29 -67
  270. package/src/maintenance/long-running-work.ts +3 -1
  271. package/src/maintenance/offline-agent-prune-job.ts +28 -0
  272. package/src/maintenance/orphaned-sessions.ts +5 -4
  273. package/src/maintenance/pauses.ts +4 -10
  274. package/src/maintenance/plan-ready-notice-job.ts +71 -0
  275. package/src/maintenance/scheduler.ts +18 -13
  276. package/src/maintenance/stalled-delivery-pager.ts +4 -4
  277. package/src/maintenance/teams.ts +19 -30
  278. package/src/maintenance/workspaces.ts +17 -27
  279. package/src/managed-policy-escalation.ts +7 -7
  280. package/src/managed-policy.ts +3 -3
  281. package/src/managed-provider-gate.ts +5 -4
  282. package/src/managed-spawn-reservation.ts +5 -4
  283. package/src/mcp/index.ts +8 -8
  284. package/src/mcp/output-descriptions.ts +1 -1
  285. package/src/mcp/presentation.ts +2 -1
  286. package/src/mcp/runtime-output.ts +6 -1
  287. package/src/mcp/self-care-visibility.ts +2 -2
  288. package/src/mcp/spawn-targets-matrix.ts +10 -1
  289. package/src/mcp/tool-groups.ts +3 -2
  290. package/src/mcp/tool-roles.ts +81 -0
  291. package/src/mcp/tools-workspace.ts +1 -1
  292. package/src/mcp-blackboard-tools.ts +6 -5
  293. package/src/mcp-decision-tools.ts +7 -7
  294. package/src/mcp-egress-tools.ts +10 -9
  295. package/src/mcp-issue-activity-tools.ts +2 -2
  296. package/src/mcp-issue-association-tools.ts +4 -4
  297. package/src/mcp-issue-ref-tools.ts +3 -3
  298. package/src/mcp-merge-tools.ts +5 -5
  299. package/src/mcp-notification-subscription-tools.ts +14 -15
  300. package/src/mcp-output-levels.test-fixture.ts +1 -1
  301. package/src/mcp-profile-trust-tools.ts +1 -1
  302. package/src/mcp-project-journal-tools.ts +4 -12
  303. package/src/mcp-project-tools.ts +17 -18
  304. package/src/mcp-routing-policy-tools.ts +3 -2
  305. package/src/mcp-team-tools.ts +6 -6
  306. package/src/mcp-workflow-tools.ts +5 -3
  307. package/src/memory-area-injection.ts +13 -12
  308. package/src/memory-boundary-capture.ts +6 -6
  309. package/src/memory-injection.ts +45 -43
  310. package/src/merge-pause-maintenance.ts +5 -4
  311. package/src/notification-router.ts +44 -17
  312. package/src/notify.ts +5 -5
  313. package/src/observed-reset-refresh.ts +4 -4
  314. package/src/operator-alarm.ts +2 -5
  315. package/src/project-ingest.ts +6 -6
  316. package/src/project-instructions.ts +8 -1
  317. package/src/project-trust.ts +12 -11
  318. package/src/prompt-resolver.ts +3 -3
  319. package/src/provider-quota-async.ts +5 -7
  320. package/src/provider-timeline-event.ts +4 -7
  321. package/src/quota-band-delivery.ts +2 -2
  322. package/src/recipe-runner.ts +4 -3
  323. package/src/retention-config-store.ts +4 -3
  324. package/src/reviewer-pipeline.ts +11 -10
  325. package/src/routes/_route.ts +4 -4
  326. package/src/routes/_shared.ts +13 -12
  327. package/src/routes/agent-effort.ts +5 -5
  328. package/src/routes/agent-heartbeat-quota.ts +23 -0
  329. package/src/routes/agent-keep.ts +1 -1
  330. package/src/routes/agent-reporting.ts +1 -1
  331. package/src/routes/agent-self-effort.ts +5 -5
  332. package/src/routes/agent-sessions.ts +24 -24
  333. package/src/routes/agents-spawn.ts +1 -1
  334. package/src/routes/agents.ts +17 -119
  335. package/src/routes/auth.ts +14 -15
  336. package/src/routes/authority-audit.ts +2 -2
  337. package/src/routes/automations.ts +6 -5
  338. package/src/routes/channel-binding-delete.ts +1 -1
  339. package/src/routes/channel-output.ts +3 -3
  340. package/src/routes/claude-api-budget.ts +5 -5
  341. package/src/routes/commands-listing.ts +1 -1
  342. package/src/routes/commands.ts +29 -27
  343. package/src/routes/context-resets.ts +2 -2
  344. package/src/routes/coordinator-teams.ts +1 -1
  345. package/src/routes/decisions.ts +2 -2
  346. package/src/routes/host-secret-files.ts +1 -1
  347. package/src/routes/hosts.ts +11 -11
  348. package/src/routes/inbox.ts +3 -2
  349. package/src/routes/index.ts +2 -1
  350. package/src/routes/integrations.ts +9 -7
  351. package/src/routes/issue-activity.ts +2 -2
  352. package/src/routes/issue-associations.ts +4 -4
  353. package/src/routes/issue-refs.ts +3 -3
  354. package/src/routes/kernel-timers-operator.ts +1 -1
  355. package/src/routes/memory.ts +1 -1
  356. package/src/routes/merges.ts +11 -11
  357. package/src/routes/messages.ts +23 -17
  358. package/src/routes/orchestrator-bootstrap.ts +1 -1
  359. package/src/routes/orchestrator-host-registration.ts +2 -0
  360. package/src/routes/orchestrator-host-utilization.ts +2 -2
  361. package/src/routes/orchestrator-proxy.ts +2 -2
  362. package/src/routes/orchestrator.ts +27 -18
  363. package/src/routes/pairs.ts +8 -8
  364. package/src/routes/project-profile-instructions.ts +1 -1
  365. package/src/routes/project-trust.ts +1 -1
  366. package/src/routes/projects.ts +16 -16
  367. package/src/routes/prompt-templates.ts +12 -12
  368. package/src/routes/provider-quotas.ts +10 -10
  369. package/src/routes/run-command.ts +1 -1
  370. package/src/routes/secrets-backup.ts +2 -2
  371. package/src/routes/secrets-import.ts +1 -1
  372. package/src/routes/secrets-vault.ts +7 -7
  373. package/src/routes/settings.ts +1 -1
  374. package/src/routes/shipping.ts +9 -1
  375. package/src/routes/spawn-policy.ts +8 -7
  376. package/src/routes/sse.ts +2 -2
  377. package/src/routes/team-templates.ts +7 -7
  378. package/src/routes/teams.ts +10 -10
  379. package/src/routes/tokens.ts +18 -17
  380. package/src/routes/users.ts +24 -24
  381. package/src/routes/viewer-read.ts +3 -3
  382. package/src/routes/web-tool-calls.ts +4 -4
  383. package/src/routes/workflows.ts +2 -2
  384. package/src/routes/workspaces.ts +17 -16
  385. package/src/routing-policy-push.ts +6 -6
  386. package/src/runtime-grant.ts +17 -11
  387. package/src/runtime-tokens.ts +20 -28
  388. package/src/secrets-broker/config.ts +1 -1
  389. package/src/secrets-broker/service.ts +2 -2
  390. package/src/security.ts +3 -1
  391. package/src/self-resume-carry.ts +21 -110
  392. package/src/self-resume-supersede.ts +4 -3
  393. package/src/self-resume.ts +54 -66
  394. package/src/server-background.ts +1 -1
  395. package/src/server.ts +21 -22
  396. package/src/services/agent-action.ts +12 -31
  397. package/src/services/agent-effort.ts +7 -32
  398. package/src/services/agent-hang-watchdog-job.ts +2 -2
  399. package/src/services/agent-heartbeat.ts +166 -0
  400. package/src/services/agent-reporting.ts +1 -1
  401. package/src/services/browser-inventory.ts +3 -3
  402. package/src/services/browser-session-state.ts +3 -2
  403. package/src/services/browser-session.ts +21 -27
  404. package/src/services/bus-command-update.ts +9 -9
  405. package/src/services/checkout-refresh-state.ts +1 -0
  406. package/src/services/checkout-refresh.test-fixture.ts +3 -2
  407. package/src/services/command-host.ts +7 -2
  408. package/src/services/coordinator-digest.ts +3 -2
  409. package/src/services/dispatch-command.ts +12 -13
  410. package/src/services/effective-launch-driver.ts +14 -9
  411. package/src/services/host-changed-paths.test-fixture.ts +5 -6
  412. package/src/services/host-project-readiness.ts +2 -2
  413. package/src/services/host-providers.ts +1 -1
  414. package/src/services/host-utilization.ts +9 -9
  415. package/src/services/idle-agent-digest.ts +17 -12
  416. package/src/services/idle-epics.ts +4 -4
  417. package/src/services/interrupt-agent.ts +12 -9
  418. package/src/services/issue-activity.ts +3 -3
  419. package/src/services/issue-associations.ts +15 -18
  420. package/src/services/issue-lifecycle-comments.ts +3 -2
  421. package/src/services/issue-lifecycle.ts +14 -13
  422. package/src/services/issue-refs.ts +4 -5
  423. package/src/services/kernel-timers-cutover-chaos-worker.ts +1 -1
  424. package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
  425. package/src/services/kernel-timers-ingress.ts +3 -3
  426. package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
  427. package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
  428. package/src/services/kernel-timers-outbox.ts +1 -1
  429. package/src/services/kernel-timers-stage10-operator.ts +1 -1
  430. package/src/services/kernel-timers.ts +4 -3
  431. package/src/services/land-gate-placement.ts +11 -2
  432. package/src/services/land-issue-relations.ts +5 -4
  433. package/src/services/land-restart-retry.ts +7 -6
  434. package/src/services/landed-ancestry.ts +6 -5
  435. package/src/services/legacy-landing-host.ts +4 -1
  436. package/src/services/legacy-landing-recovery.ts +8 -6
  437. package/src/services/managed-running.ts +17 -17
  438. package/src/services/memory-areas.ts +3 -3
  439. package/src/services/merge-pause.ts +9 -15
  440. package/src/services/operator-decisions.ts +37 -41
  441. package/src/services/orchestrator-registration-recovery.ts +6 -2
  442. package/src/services/orchestrator-upgrade.ts +14 -12
  443. package/src/services/permission-decision.ts +4 -3
  444. package/src/services/plan-ci-notice.ts +1 -1
  445. package/src/services/plan-conformance.ts +4 -4
  446. package/src/services/plan-dispatch-policy.ts +10 -3
  447. package/src/services/plan-dispatch.ts +35 -14
  448. package/src/services/plan-graph.ts +39 -261
  449. package/src/services/plan-import.ts +1 -1
  450. package/src/services/plan-live-bindings.ts +8 -37
  451. package/src/services/plan-task-create.ts +1 -1
  452. package/src/services/plan-terminal-refs.ts +2 -12
  453. package/src/services/plan-wake-digest.ts +8 -3
  454. package/src/services/profile-trust.ts +2 -2
  455. package/src/services/project.ts +11 -10
  456. package/src/services/prompt-templates.ts +6 -5
  457. package/src/services/provider-hold-nudge.ts +9 -9
  458. package/src/services/provider-hold-record.ts +13 -12
  459. package/src/services/provider-state-audit.ts +19 -18
  460. package/src/services/provisioning-harness/driver.ts +1 -1
  461. package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
  462. package/src/services/provisioning-harness/lifecycle.ts +24 -22
  463. package/src/services/provisioning-harness/prepare.ts +16 -17
  464. package/src/services/rate-limit-resume.ts +10 -9
  465. package/src/services/red-main-auto-revert.ts +7 -5
  466. package/src/services/red-main-controller-deps.ts +20 -3
  467. package/src/services/red-main-incident.ts +3 -1
  468. package/src/services/red-main-quarantine.ts +2 -3
  469. package/src/services/register-agent.ts +22 -22
  470. package/src/services/restart-project-role.ts +1 -1
  471. package/src/services/restart-spawn.ts +17 -16
  472. package/src/services/review-publish.ts +7 -24
  473. package/src/services/review-ref-reconcile.ts +29 -38
  474. package/src/services/runtime-dependency-alert.ts +27 -0
  475. package/src/services/scheduler-command.ts +11 -9
  476. package/src/services/scheduler.ts +5 -5
  477. package/src/services/self-effort-grant.ts +5 -25
  478. package/src/services/send-message.ts +16 -33
  479. package/src/services/shutdown-agent.ts +17 -14
  480. package/src/services/spawn-agent.ts +12 -41
  481. package/src/services/spawn-chain-inspector.ts +1 -1
  482. package/src/services/spawn-cwd-placement.ts +21 -5
  483. package/src/services/spawn-issue-activity.ts +8 -6
  484. package/src/services/spawn-launch.ts +17 -1
  485. package/src/services/spawn-loss-escalation.ts +1 -1
  486. package/src/services/spawn-registration-watchdog.ts +2 -2
  487. package/src/services/spawn-repo-probe.ts +7 -5
  488. package/src/services/spawn-tree-cleanup.ts +7 -8
  489. package/src/services/steward-reaper.ts +4 -4
  490. package/src/services/task-context-hydration.ts +25 -1
  491. package/src/services/task-delivery.ts +20 -34
  492. package/src/services/task-entity.ts +40 -203
  493. package/src/services/task-issue-link.ts +13 -20
  494. package/src/services/task-issue-weave.ts +12 -11
  495. package/src/services/task-lifecycle.ts +27 -31
  496. package/src/services/task-repo-cwd.ts +37 -0
  497. package/src/services/task-review-hold.ts +4 -17
  498. package/src/services/task-semantic-events.ts +13 -11
  499. package/src/services/task-state-reconcile.ts +3 -4
  500. package/src/services/task-validation.ts +2 -2
  501. package/src/services/team-templates.ts +5 -5
  502. package/src/services/team.ts +31 -98
  503. package/src/services/terminal-provider-exit.ts +6 -5
  504. package/src/services/timer-message-fire-chaos-worker.ts +7 -3
  505. package/src/services/timer-message-fire-outbox.ts +1 -1
  506. package/src/services/transient-agent-reaper.ts +22 -19
  507. package/src/services/turn-reconcile-audit.ts +9 -9
  508. package/src/services/user-onboarding.ts +8 -6
  509. package/src/services/user-profile.ts +6 -9
  510. package/src/services/work-finality.ts +16 -4
  511. package/src/services/workflow-auto-start.ts +2 -1
  512. package/src/services/workflow-caller.ts +61 -4
  513. package/src/services/workflow-child-proof-worker.ts +1 -1
  514. package/src/services/workflow-control-proof-worker.ts +1 -1
  515. package/src/services/workflow-coordinator.ts +8 -2
  516. package/src/services/workflow-decisions.ts +5 -5
  517. package/src/services/workflow-deferred-cleanup.ts +1 -1
  518. package/src/services/workflow-effect-driver.ts +42 -19
  519. package/src/services/workflow-effects.ts +41 -27
  520. package/src/services/workflow-pins.ts +7 -4
  521. package/src/services/workflow-reconcile.ts +1 -0
  522. package/src/services/workflow-resume-pins.ts +3 -3
  523. package/src/services/workflow-routing-defaults.ts +18 -0
  524. package/src/services/workflow-run-view.ts +4 -3
  525. package/src/services/workflow-run.test-fixture.ts +1 -1
  526. package/src/services/workflow-runs.ts +34 -22
  527. package/src/services/workflow-supervisor-state.ts +21 -1
  528. package/src/services/workflow-supervisor.ts +4 -3
  529. package/src/services/workspace-recovery.ts +4 -3
  530. package/src/spawn-admission.ts +10 -2
  531. package/src/spawn-placement.ts +27 -9
  532. package/src/spawn-targets.ts +8 -8
  533. package/src/sse-agent-status.ts +15 -6
  534. package/src/sse.ts +49 -24
  535. package/src/startup-context-injection.ts +61 -57
  536. package/src/steward-handoff.ts +4 -3
  537. package/src/steward-policy-cleanup.ts +9 -8
  538. package/src/steward.ts +2 -2
  539. package/src/task-dispatch-live.ts +5 -2
  540. package/src/task-dispatcher.ts +2 -2
  541. package/src/token-db.ts +2 -2
  542. package/src/token-usage-async.ts +2 -4
  543. package/src/user-awaiting-reply.ts +5 -5
  544. package/src/workspace-actions.ts +24 -29
  545. package/src/workspace-auto-merge.ts +14 -12
  546. package/src/workspace-changed-paths-client.ts +16 -5
  547. package/src/workspace-cleanup-stale.ts +30 -7
  548. package/src/workspace-command-settle.ts +24 -16
  549. package/src/workspace-config.ts +1 -1
  550. package/src/workspace-conflict-resolver.ts +9 -7
  551. package/src/workspace-dead-owner-recovery.ts +5 -4
  552. package/src/workspace-escalation.ts +12 -11
  553. package/src/workspace-human-escalation.ts +3 -3
  554. package/src/workspace-land-gate-watchdog.ts +3 -3
  555. package/src/workspace-land-refusal.ts +20 -0
  556. package/src/workspace-land-stopped.ts +1 -0
  557. package/src/workspace-merge.ts +10 -26
  558. package/src/workspace-nothing-to-land-notice.ts +2 -2
  559. package/src/workspace-orphans.ts +18 -37
  560. package/src/workspace-pr-completion.ts +10 -8
  561. package/src/workspace-rekey.ts +3 -3
  562. package/src/workspace-steward-failure.ts +2 -2
  563. package/src/workspace-steward-wake.ts +2 -2
  564. package/public/assets/agent-liveness-CaNwK0Zf.js +0 -2
  565. package/public/assets/provider-display-DsuWMvVL.js +0 -2
  566. package/public/assets/run-card-CpKqRbhg.js +0 -2
  567. package/public/assets/shipping-B9YtnwtG.js +0 -2
  568. package/public/assets/store-DcClXLH0.js +0 -9
  569. package/runner/src/agent-runner/http-liveness.ts +0 -85
  570. package/src/db/on-loop-write-transaction.ts +0 -34
@@ -68,16 +68,6 @@ export async function advanceTerminalPlanRefsAsync(trigger: TerminalRefTrigger):
68
68
  * (replacePlanNodeScoped), and a residual failure degrades to warn-and-continue exactly like the
69
69
  * async twin — a propagation failure must never fail the durable status/stage write.
70
70
  */
71
- export function advanceTerminalPlanRefs(trigger: TerminalRefTrigger): Plan[] {
72
- const { taskIds, issueRefIds, actor } = normalize(trigger);
73
- if (taskIds.length === 0 && issueRefIds.length === 0) return [];
74
- try {
75
- const results = applyTerminalPlanRefsBody({ taskIds, issueRefIds, actor }, Date.now());
76
- const plans = results.map((result) => result.plan);
77
- emitChanged(plans, actor);
78
- return plans;
79
- } catch (error) {
80
- console.warn(`plan-terminal-refs propagation failed (${trigger.taskId !== undefined ? `task ${trigger.taskId}` : trigger.issueRefId !== undefined ? `issue ${trigger.issueRefId}` : "trigger"}): ${errMessage(error)}`);
81
- return [];
82
- }
71
+ export async function advanceTerminalPlanRefs(trigger: TerminalRefTrigger): Promise<Plan[]> {
72
+ return advanceTerminalPlanRefsAsync(trigger);
83
73
  }
@@ -11,7 +11,7 @@ export const PLAN_WAKE_DIGEST_MAX_BYTES = 1024;
11
11
  const INTRO = "Open team Plans: keep plans current and drive acceptance; relay_decision only when really blocked. In-progress age = plan update age.";
12
12
  const MORE = "More plans/nodes: relay_plan_list; relay_plan_get mode=resume.";
13
13
 
14
- function compactText(value: string, maxBytes: number): string {
14
+ export function compactText(value: string, maxBytes: number): string {
15
15
  const text = value.slice(0, maxBytes).replace(/\s+/g, " ").trim();
16
16
  if (Buffer.byteLength(value) <= maxBytes) return text;
17
17
  let result = "";
@@ -42,9 +42,14 @@ function refsDone(node: PlanNode): boolean {
42
42
  return true;
43
43
  }
44
44
 
45
- function planLine(stored: Plan, now: number): string {
45
+ /** The one node classification both the wake digest and the ready-node notice read (#3660). */
46
+ export function liveFrontier(stored: Plan) {
46
47
  const plan = projectPlanOverTasks(stored);
47
- const frontier = planResumeFrontier(plan);
48
+ return { plan, frontier: planResumeFrontier(plan) };
49
+ }
50
+
51
+ function planLine(stored: Plan, now: number): string {
52
+ const { plan, frontier } = liveFrontier(stored);
48
53
  const parts: string[] = [];
49
54
  if (frontier.ready.length) parts.push(`ready: ${nodeList(frontier.ready)}`);
50
55
  if (frontier.inProgress.length) {
@@ -47,9 +47,9 @@ export async function updateProfileProjectTrustAsync(name: string, update: Proje
47
47
  }
48
48
 
49
49
  /** Approve an observed `sha256:…` (fingerprint) or `commit:…` value; the mode follows the prefix. */
50
- export function approveProfileProjectTrust(input: { name: string; capability: ProjectTrustCapability; repoKey: string; value: string; by: string }): ProjectTrustApproval {
50
+ export async function approveProfileProjectTrust(input: { name: string; capability: ProjectTrustCapability; repoKey: string; value: string; by: string }): Promise<ProjectTrustApproval> {
51
51
  const profileName = existingProfile(input.name).value.name;
52
52
  const mode = input.value.startsWith("commit:") ? "commit" : input.value.startsWith("sha256:") ? "fingerprint" : undefined;
53
53
  if (!mode) throw new ValidationError(`approved value must start with "sha256:" or "commit:", as shown in the refusal`);
54
- return approveProjectCapabilityReview({ profileName, repoKey: input.repoKey, capability: input.capability, mode, approvedValue: input.value, approvedBy: input.by });
54
+ return (await approveProjectCapabilityReview({ profileName, repoKey: input.repoKey, capability: input.capability, mode, approvedValue: input.value, approvedBy: input.by }));
55
55
  }
@@ -1,5 +1,6 @@
1
+ import { setProjectIssueRepoAsync, ensureProjectAsync, addProjectRootAsync } from "../db/projects-async";
1
2
  import { basename } from "node:path";
2
- import { getProjectBySlug, getProjectBySlugAsync, addProjectRoot, addProjectRootAsync, ensureProject, ensureProjectAsync, projectByRemoteUrl, projectByRemoteUrlAsync, resolveProjectForCwd, resolveProjectForCwdAsync, rootsForProject, rootsForProjectAsync, setProjectIssueRepo, setProjectIssueRepoAsync, workspaceRepoRootForCwd } from "../db";
3
+ import { getProjectBySlug, getProjectBySlugAsync, projectByRemoteUrl, projectByRemoteUrlAsync, resolveProjectForCwd, resolveProjectForCwdAsync, rootsForProject, rootsForProjectAsync, workspaceRepoRootForCwd } from "../db";
3
4
  import { ingestClaudeMd } from "../project-ingest";
4
5
  import { resolveProjectForCanonicalCwd, type CanonicalCwdMatch } from "./project-cwd";
5
6
  import { canonicalRoot, canonicalRootAsync, findGitRepoRoot, findGitRepoRootAsync } from "./canonical-root";
@@ -42,23 +43,23 @@ interface AutoSeedProjectResult {
42
43
  * project-entry mutations are intentionally outside this projects-root migration. New
43
44
  * async-capable callers must use {@link ensureProjectRootAsync}.
44
45
  */
45
- export function ensureProjectRoot(input: EnsureProjectRootInput): EnsureProjectRootResult {
46
- const project = ensureProject({
46
+ export async function ensureProjectRoot(input: EnsureProjectRootInput): Promise<EnsureProjectRootResult> {
47
+ const project = (await ensureProjectAsync({
47
48
  slug: input.slug,
48
49
  matchingRemoteUrl: input.matchingRemoteUrl,
49
50
  ...(input.title !== undefined ? { title: input.title } : {}),
50
51
  ...(input.description !== undefined ? { description: input.description } : {}),
51
52
  ...(input.tenantId !== undefined ? { tenantId: input.tenantId } : {}),
52
53
  ...(input.issueRepo !== undefined ? { issueRepo: input.issueRepo } : {}),
53
- });
54
+ }));
54
55
  const remoteUrl = input.remoteUrl ?? remoteUrlFromGitRemote(input.rootPath);
55
- const roots = addProjectRoot(project.id, input.rootPath, { remoteUrl, ref: input.ref, orchestratorId: input.orchestratorId });
56
+ const roots = (await addProjectRootAsync(project.id, input.rootPath, { remoteUrl, ref: input.ref, orchestratorId: input.orchestratorId }));
56
57
  // Auto-derive issueRepo from the root's git remote (#533) when not explicitly provided.
57
58
  // `onlyIfNull` ensures an explicit override (or earlier derivation) is never clobbered.
58
59
  if (input.issueRepo === undefined && !project.issueRepo) {
59
60
  const derived = repoFromGitRemote(input.rootPath);
60
61
  if (derived) {
61
- const updated = setProjectIssueRepo(project.id, derived, { onlyIfNull: true });
62
+ const updated = (await setProjectIssueRepoAsync(project.id, derived, { onlyIfNull: true }));
62
63
  if (updated) return { project: updated, roots };
63
64
  }
64
65
  }
@@ -117,17 +118,17 @@ async function resolveProjectForWorkspaceCwdAsync(cwd: string): Promise<Canonica
117
118
  * Synchronous compatibility seam for legacy callers. New async-capable registration/spawn
118
119
  * paths use {@link autoSeedProjectForCwdAsync} so root writes reach the writer gateway.
119
120
  */
120
- export function autoSeedProjectForCwd(cwd: string, authorId: string): AutoSeedProjectResult | null {
121
+ export async function autoSeedProjectForCwd(cwd: string, authorId: string): Promise<AutoSeedProjectResult | null> {
121
122
  const match = resolveProjectForCanonicalCwd(cwd);
122
123
  if (match.project) {
123
124
  const repoRoot = match.repoRoot ?? cwd;
124
125
  // A remote-URL match owns no root containing this checkout yet — register it so every
125
126
  // later resolve is plain containment again, and never re-derives the remote.
126
- if (match.matchedByRemote) addProjectRoot(match.project.id, repoRoot, { remoteUrl: remoteUrlFromGitRemote(repoRoot) });
127
+ if (match.matchedByRemote) (await addProjectRootAsync(match.project.id, repoRoot, { remoteUrl: remoteUrlFromGitRemote(repoRoot) }));
127
128
  let project = match.project;
128
129
  if (!project.issueRepo) {
129
130
  const derived = repoFromGitRemote(repoRoot);
130
- const updated = derived ? setProjectIssueRepo(project.id, derived, { onlyIfNull: true }) : null;
131
+ const updated = derived ? (await setProjectIssueRepoAsync(project.id, derived, { onlyIfNull: true })) : null;
131
132
  if (updated) project = updated;
132
133
  }
133
134
  return { project, repoRoot, roots: rootsForProject(project.id) };
@@ -139,7 +140,7 @@ export function autoSeedProjectForCwd(cwd: string, authorId: string): AutoSeedPr
139
140
  if (!slug) return null;
140
141
 
141
142
  if (getProjectBySlug(slug)?.status === "archived" || resolveProjectForCwd(repoRoot, { includeArchived: true })?.status === "archived" || projectByRemoteUrl(remoteUrlFromGitRemote(repoRoot), { includeArchived: true })?.status === "archived") return null;
142
- const { project, roots } = ensureProjectRoot({ slug, rootPath: repoRoot });
143
+ const { project, roots } = (await ensureProjectRoot({ slug, rootPath: repoRoot }));
143
144
  try {
144
145
  // Legacy synchronous callers cannot await filesystem ingestion. Their async
145
146
  // counterparts below perform it without blocking the server loop.
@@ -1,25 +1,26 @@
1
+ import { upsertTemplateAsync, resetTemplateAsync } from "../db/runtime-tail-async";
1
2
  import { getGateway } from "../db/gateway";
2
3
  import { promptTemplateFallback } from "../prompt-template-fallback";
3
4
  import { defaultPromptTemplates } from "../prompt-resolver";
4
5
  import { memoryRetirementMessage } from "../memory-retirement";
5
6
  import { ValidationError } from "../db/connection";
6
- import { getTemplate, listTemplates, resetTemplate, upsertTemplate, type PromptTemplateRecord } from "../db";
7
+ import { getTemplate, listTemplates, type PromptTemplateRecord } from "../db";
7
8
 
8
9
  export function listPromptTemplates(category?: string): PromptTemplateRecord[] {
9
10
  return listTemplates(category).filter((entry) => !memoryRetirementMessage(entry.slug));
10
11
  }
11
12
 
12
- export function updatePromptTemplate(slug: string, template: string): PromptTemplateRecord | null {
13
+ export async function updatePromptTemplate(slug: string, template: string): Promise<PromptTemplateRecord | null> {
13
14
  const retirement = memoryRetirementMessage(slug);
14
15
  if (retirement) throw new ValidationError(retirement);
15
- upsertTemplate(slug, template);
16
+ (await upsertTemplateAsync(slug, template));
16
17
  return getTemplate(slug);
17
18
  }
18
19
 
19
- export function resetPromptTemplate(slug: string): PromptTemplateRecord | null {
20
+ export async function resetPromptTemplate(slug: string): Promise<PromptTemplateRecord | null> {
20
21
  const retirement = memoryRetirementMessage(slug);
21
22
  if (retirement) throw new ValidationError(retirement);
22
- resetTemplate(slug);
23
+ (await resetTemplateAsync(slug));
23
24
  return getTemplate(slug);
24
25
  }
25
26
 
@@ -97,7 +97,7 @@ export async function sendStillHeldNudges(nowMs: number = Date.now(), signal?: A
97
97
  ) {
98
98
  if (await providerHoldCloseWasAggregated(agent.id, pendingClose.kind, pendingClose.seq)) {
99
99
  const { pendingCloseAt: _pendingClose, ...closed } = pendingClose;
100
- persistProviderHold(agent.id, closed);
100
+ (await persistProviderHold(agent.id, closed));
101
101
  } else {
102
102
  await notifyProviderHoldClosed(agent, pendingClose, nowMs);
103
103
  }
@@ -105,20 +105,20 @@ export async function sendStillHeldNudges(nowMs: number = Date.now(), signal?: A
105
105
 
106
106
  if (!agent.spawnedBy) {
107
107
  if (blocked && agent.kind === "provider" && agent.status !== "offline" && agentProviderState(agent)) {
108
- const hold = openProviderHold(agent.id, agentProviderState(agent), nowMs, { continuing: true });
108
+ const hold = (await openProviderHold(agent.id, agentProviderState(agent), nowMs, { continuing: true }));
109
109
  if (hold.humanPagedAt === undefined && nowMs - hold.startedAt >= TOP_LEVEL_PAGE_THRESHOLD_MS()) {
110
110
  const holdMs = Math.max(0, nowMs - hold.startedAt);
111
111
  const state = agentProviderState(agent)!;
112
112
  const label = state.label ?? state.reason ?? hold.kind;
113
- const result = notifyWorkspaceHumanEscalation({
113
+ const result = (await notifyWorkspaceHumanEscalation({
114
114
  subject: `Agent blocked: ${agent.label ?? agent.name ?? agent.id}`,
115
115
  body: `${agent.label ?? agent.name ?? agent.id} on ${agent.machine ?? "unknown host"} has been blocked for ${formatHoldDuration(holdMs)}: ${label} (${hold.kind}).`,
116
116
  payload: { kind: "agent.provider_blocked", agentId: agent.id, holdId: hold.holdId, holdMs, providerState: state },
117
117
  source: "provider-state-audit",
118
118
  tags: ["agent-relay", "provider"],
119
119
  idempotencyKey: `provider-human-blocked:${agent.id}:${hold.holdId}`,
120
- });
121
- if (result.accepted) persistProviderHold(agent.id, { ...hold, humanPagedAt: nowMs });
120
+ }));
121
+ if (result.accepted) (await persistProviderHold(agent.id, { ...hold, humanPagedAt: nowMs }));
122
122
  }
123
123
  }
124
124
  continue;
@@ -142,7 +142,7 @@ export async function sendStillHeldNudges(nowMs: number = Date.now(), signal?: A
142
142
  const quietFlaps = await quietProviderFlapsForAgents(flapCandidates.map((agent) => agent.id), nowMs);
143
143
  for (const agent of flapCandidates) {
144
144
  if (signal?.aborted) break;
145
- for (const flap of quietFlaps.get(agent.id) ?? []) notifyProviderFlap(agent, flap, isProviderBlocked(agent));
145
+ for (const flap of quietFlaps.get(agent.id) ?? []) await notifyProviderFlap(agent, flap, isProviderBlocked(agent));
146
146
  }
147
147
 
148
148
  for (const agent of nudgeCandidates) {
@@ -153,7 +153,7 @@ export async function sendStillHeldNudges(nowMs: number = Date.now(), signal?: A
153
153
  // `continuing: true` — the sweep only ever sees an already-blocked agent. Self-healing: a
154
154
  // hold whose block edge the relay missed (restart mid-hold, pre-#1615 record) is adopted here
155
155
  // rather than going unwatched.
156
- const hold = openProviderHold(agent.id, state, nowMs, { continuing: true });
156
+ const hold = (await openProviderHold(agent.id, state, nowMs, { continuing: true }));
157
157
  const sinceLastSignal = nowMs - (hold.lastNudgeAt ?? hold.startedAt);
158
158
  if (sinceLastSignal < nextNudgeIntervalMs(hold.nudgeCount)) continue;
159
159
 
@@ -162,7 +162,7 @@ export async function sendStillHeldNudges(nowMs: number = Date.now(), signal?: A
162
162
  const resetSuffix = typeof state.resetAt === "number" ? ` · resets ${formatClockUtc(state.resetAt)}` : "";
163
163
  const label = agent.label ?? agent.name ?? agent.id;
164
164
 
165
- routeNotification({
165
+ await routeNotification({
166
166
  type: "agent.provider_still_held",
167
167
  scope: { agentId: agent.id, parent: agent.spawnedBy },
168
168
  recipients: [agent.spawnedBy],
@@ -183,7 +183,7 @@ export async function sendStillHeldNudges(nowMs: number = Date.now(), signal?: A
183
183
  },
184
184
  });
185
185
 
186
- persistProviderHold(agent.id, { ...hold, nudgeCount: hold.nudgeCount + 1, lastNudgeAt: nowMs });
186
+ (await persistProviderHold(agent.id, { ...hold, nudgeCount: hold.nudgeCount + 1, lastNudgeAt: nowMs }));
187
187
  notified.push(agent.id);
188
188
  }
189
189
 
@@ -1,3 +1,4 @@
1
+ import { mergeAgentMetaAsync } from "../db/agents-async";
1
2
  // #1615 — durable identity + delivery bookkeeping for a provider hold.
2
3
  //
3
4
  // The #1610 sweep derived both from values that are neither stable nor durable: the unblock
@@ -10,14 +11,14 @@
10
11
  //
11
12
  // This module gives a hold ONE identity, minted server-side on the edge the relay actually
12
13
  // observes and persisted in the agent's SQLite meta (`meta.providerHold`). The runner never
13
- // sends that key, and `mergeAgentMeta` is a shallow merge, so a status frame can't clobber it.
14
+ // sends that key, and `mergeAgentMetaAsync` is a shallow merge, so a status frame can't clobber it.
14
15
  // Every notification for a hold — block, still-held nudges, unblock — keys on that id, so:
15
16
  // * permanent idempotency now bounds messages PER HOLD instead of per agent-lifetime;
16
17
  // * a restart mid-hold resumes the same key sequence instead of replaying it;
17
18
  // * `startedAt` is read from the provider ONCE, when the episode opens, and frozen — an
18
19
  // adapter that re-stamps `enteredAt` on every poll can no longer stall the nudge clock.
19
20
  import { isRecord } from "@humwick/sdk";
20
- import { getAgent, mergeAgentMeta } from "../db";
21
+ import { getAgent } from "../db";
21
22
  import type { ProviderState } from "../provider-state";
22
23
 
23
24
  /**
@@ -85,8 +86,8 @@ export function readProviderHold(agent: HasMeta | null | undefined): ProviderHol
85
86
  }
86
87
 
87
88
  /** Persist the record. Shallow-merged, so it survives every runner status frame. */
88
- export function persistProviderHold(agentId: string, record: ProviderHoldRecord): ProviderHoldRecord {
89
- mergeAgentMeta(agentId, { providerHold: record });
89
+ export async function persistProviderHold(agentId: string, record: ProviderHoldRecord): Promise<ProviderHoldRecord> {
90
+ (await mergeAgentMetaAsync(agentId, { providerHold: record }));
90
91
  return record;
91
92
  }
92
93
 
@@ -96,10 +97,10 @@ function seedStartedAt(state: ProviderState | null | undefined, nowMs: number):
96
97
  return typeof entered === "number" && Number.isFinite(entered) ? Math.min(entered, nowMs) : nowMs;
97
98
  }
98
99
 
99
- function mintProviderHold(agentId: string, prior: ProviderHoldRecord | null, state: ProviderState | null | undefined, nowMs: number): ProviderHoldRecord {
100
+ async function mintProviderHold(agentId: string, prior: ProviderHoldRecord | null, state: ProviderState | null | undefined, nowMs: number): Promise<ProviderHoldRecord> {
100
101
  const seq = (prior?.seq ?? 0) + 1;
101
102
  const startedAt = seedStartedAt(state, nowMs);
102
- return persistProviderHold(agentId, { holdId: `h${seq}-${startedAt}`, seq, startedAt, kind: providerHoldKind(state), nudgeCount: 0 });
103
+ return (await persistProviderHold(agentId, { holdId: `h${seq}-${startedAt}`, seq, startedAt, kind: providerHoldKind(state), nudgeCount: 0 }));
103
104
  }
104
105
 
105
106
  /**
@@ -110,15 +111,15 @@ function mintProviderHold(agentId: string, prior: ProviderHoldRecord | null, sta
110
111
  * that finds an un-cleared record means the relay missed the clear, so that record is abandoned
111
112
  * rather than resurrected with an hours-stale `startedAt`.
112
113
  */
113
- export function openProviderHold(agentId: string, state: ProviderState | null | undefined, nowMs: number, opts: { continuing: boolean }): ProviderHoldRecord {
114
+ export async function openProviderHold(agentId: string, state: ProviderState | null | undefined, nowMs: number, opts: { continuing: boolean }): Promise<ProviderHoldRecord> {
114
115
  const prior = readProviderHold(getAgent(agentId));
115
116
  const open = prior !== null && prior.clearedAt === undefined;
116
117
  if (prior && open && opts.continuing) return prior;
117
118
  if (prior && !open && prior.kind === providerHoldKind(state) && nowMs - prior.clearedAt! <= HOLD_COALESCE_MS) {
118
119
  const { clearedAt: _cleared, pendingCloseAt: _pendingClose, ...reopened } = prior;
119
- return persistProviderHold(agentId, reopened);
120
+ return (await persistProviderHold(agentId, reopened));
120
121
  }
121
- return mintProviderHold(agentId, prior, state, nowMs);
122
+ return (await mintProviderHold(agentId, prior, state, nowMs));
122
123
  }
123
124
 
124
125
  /**
@@ -129,9 +130,9 @@ export function openProviderHold(agentId: string, state: ProviderState | null |
129
130
  * fallback start so the reported duration stays honest. The maintenance sweep sends the closing
130
131
  * notice only after `pendingCloseAt` has survived the coalescing window.
131
132
  */
132
- export function closeProviderHold(agentId: string, previous: ProviderState | null | undefined, clearedAt: number): ProviderHoldRecord | null {
133
+ export async function closeProviderHold(agentId: string, previous: ProviderState | null | undefined, clearedAt: number): Promise<ProviderHoldRecord | null> {
133
134
  const prior = readProviderHold(getAgent(agentId));
134
135
  if (prior && prior.clearedAt !== undefined) return prior;
135
- const record = prior ?? mintProviderHold(agentId, null, previous, clearedAt);
136
- return persistProviderHold(agentId, { ...record, clearedAt, pendingCloseAt: clearedAt });
136
+ const record = prior ?? (await mintProviderHold(agentId, null, previous, clearedAt));
137
+ return (await persistProviderHold(agentId, { ...record, clearedAt, pendingCloseAt: clearedAt }));
137
138
  }
@@ -1,4 +1,5 @@
1
- import { createActivityEvent } from "../db";
1
+ import { createActivityEventAsync } from "../db/activity-async";
2
+
2
3
  import { routeNotification } from "../notification-router";
3
4
  import { agentProviderState, formatHoldDuration, type ProviderState } from "../provider-state";
4
5
  import { redactSecrets } from "../../runner/src/adapters/tool-summary";
@@ -30,7 +31,7 @@ export async function auditProviderStateTransition(agentId: string, before: Agen
30
31
  try {
31
32
  // #1912 §4 retained: bus status-frame ingress invokes this synchronously immediately after
32
33
  // accepting the card mutation. A detached async audit would lose that ordering boundary.
33
- createActivityEvent({
34
+ (await createActivityEventAsync({
34
35
  clientId: `server-agent-${agentId}-provider-state-${nextKey ?? "cleared"}-${Date.now()}`,
35
36
  kind: "state",
36
37
  title: blocked ? `Agent blocked: ${label}` : "Agent provider unblocked",
@@ -43,35 +44,35 @@ export async function auditProviderStateTransition(agentId: string, before: Agen
43
44
  previousProviderState: previous ?? null,
44
45
  providerState: next ?? null,
45
46
  },
46
- });
47
+ }));
47
48
  if (!after) return;
48
49
  if (!after.spawnedBy) {
49
50
  if (blocked) {
50
- openProviderHold(agentId, next, nowMs, { continuing: previous?.state === "blocked" });
51
+ (await openProviderHold(agentId, next, nowMs, { continuing: previous?.state === "blocked" }));
51
52
  } else if (previous?.state === "blocked") {
52
53
  const clearedAt = typeof next?.enteredAt === "number" ? next.enteredAt : nowMs;
53
- closeProviderHold(agentId, previous, clearedAt);
54
+ (await closeProviderHold(agentId, previous, clearedAt));
54
55
  }
55
56
  return;
56
57
  }
57
58
  if (blocked) {
58
59
  // A prior flap that has been quiet for a full window is conclusively settled before this
59
60
  // fresh edge is evaluated. The `currentlyHeld` value is the state we observe NOW.
60
- for (const flap of await quietProviderFlaps(agentId, nowMs)) notifyProviderFlap(after, flap, true);
61
+ for (const flap of await quietProviderFlaps(agentId, nowMs)) await notifyProviderFlap(after, flap, true);
61
62
  // A blocked→blocked reason change continues the SAME episode (the hold never lifted), so it
62
63
  // must not re-announce; `continuing` also stops a fresh block edge from resurrecting a record
63
64
  // left open by a clear the relay missed.
64
- const hold = openProviderHold(agentId, next, nowMs, { continuing: previous?.state === "blocked" });
65
+ const hold = (await openProviderHold(agentId, next, nowMs, { continuing: previous?.state === "blocked" }));
65
66
  if (hold.blockNotifiedAt !== undefined) return;
66
67
  const announcement = await providerHoldAnnouncement(agentId, hold.kind, hold.seq, nowMs);
67
68
  if (announcement.kind === "summary") {
68
- notifyProviderFlap(after, announcement.flap, true);
69
+ await notifyProviderFlap(after, announcement.flap, true);
69
70
  return;
70
71
  }
71
72
  if (announcement.kind === "suppressed") {
72
73
  return;
73
74
  }
74
- routeNotification({
75
+ await routeNotification({
75
76
  type: "agent.provider_blocked",
76
77
  scope: { agentId, parent: after.spawnedBy },
77
78
  recipients: [after.spawnedBy],
@@ -83,7 +84,7 @@ export async function auditProviderStateTransition(agentId: string, before: Agen
83
84
  idempotencyKey: `provider-blocked:${agentId}:${hold.holdId}`,
84
85
  },
85
86
  });
86
- persistProviderHold(agentId, { ...hold, blockNotifiedAt: nowMs });
87
+ (await persistProviderHold(agentId, { ...hold, blockNotifiedAt: nowMs }));
87
88
  return;
88
89
  }
89
90
  // The closing bracket on a block: only fires when the transition actually came FROM blocked
@@ -92,7 +93,7 @@ export async function auditProviderStateTransition(agentId: string, before: Agen
92
93
  // The runner stamps `enteredAt` on every state, so `next.enteredAt` is when the hold actually
93
94
  // cleared — preferred over `nowMs` so the duration is exact even if this audit runs late.
94
95
  const clearedAt = typeof next?.enteredAt === "number" ? next.enteredAt : nowMs;
95
- closeProviderHold(agentId, previous, clearedAt);
96
+ (await closeProviderHold(agentId, previous, clearedAt));
96
97
  } catch {
97
98
  // Audit trail writes must never block bus status updates.
98
99
  }
@@ -108,17 +109,17 @@ export async function notifyProviderHoldClosed(agent: AgentCard, hold: ProviderH
108
109
  if (!agent.spawnedBy) {
109
110
  if (hold.humanPagedAt === undefined) return;
110
111
  const holdMs = Math.max(0, (hold.clearedAt ?? nowMs) - hold.startedAt);
111
- const result = notifyWorkspaceHumanEscalation({
112
+ const result = (await notifyWorkspaceHumanEscalation({
112
113
  subject: `Agent unblocked: ${agent.label ?? agent.name ?? agent.id}`,
113
114
  body: `${agent.label ?? agent.name ?? agent.id} on ${agent.machine ?? "unknown host"} unblocked after ${formatHoldDuration(holdMs)} (${hold.kind}).`,
114
115
  payload: { kind: "agent.provider_unblocked", agentId: agent.id, holdId: hold.holdId, holdMs },
115
116
  source: "provider-state-audit",
116
117
  tags: ["agent-relay", "provider"],
117
118
  idempotencyKey: `provider-human-unblocked:${agent.id}:${hold.holdId}`,
118
- });
119
+ }));
119
120
  if (result.accepted) {
120
121
  const { pendingCloseAt: _pendingClose, ...closed } = hold;
121
- persistProviderHold(agent.id, { ...closed, unblockNotifiedAt: nowMs });
122
+ (await persistProviderHold(agent.id, { ...closed, unblockNotifiedAt: nowMs }));
122
123
  }
123
124
  return;
124
125
  }
@@ -127,7 +128,7 @@ export async function notifyProviderHoldClosed(agent: AgentCard, hold: ProviderH
127
128
  const label = typeof state?.label === "string" ? state.label : "provider blocked";
128
129
  const holdMs = Math.max(0, (hold.clearedAt ?? nowMs) - hold.startedAt);
129
130
  const holdSuffix = ` (held ${formatHoldDuration(holdMs)}${hold.kind ? `, ${hold.kind}` : ""})`;
130
- routeNotification({
131
+ await routeNotification({
131
132
  type: "agent.provider_unblocked",
132
133
  scope: { agentId: agent.id, parent: agent.spawnedBy },
133
134
  recipients: [agent.spawnedBy],
@@ -147,15 +148,15 @@ export async function notifyProviderHoldClosed(agent: AgentCard, hold: ProviderH
147
148
  },
148
149
  });
149
150
  const { pendingCloseAt: _pendingClose, ...closed } = hold;
150
- persistProviderHold(agent.id, { ...closed, unblockNotifiedAt: nowMs });
151
+ (await persistProviderHold(agent.id, { ...closed, unblockNotifiedAt: nowMs }));
151
152
  }
152
153
 
153
154
  /** Route one uniquely-keyed flap summary or its terminal settle correction. */
154
- export function notifyProviderFlap(agent: AgentCard, flap: ProviderFlap, currentlyHeld: boolean): void {
155
+ export async function notifyProviderFlap(agent: AgentCard, flap: ProviderFlap, currentlyHeld: boolean): Promise<void> {
155
156
  if (!agent.spawnedBy) return;
156
157
  const terminal = flap.settledAt !== undefined;
157
158
  const durationMs = Math.max(0, (flap.settledAt ?? flap.lastEpisodeAt) - flap.flapStartedAt);
158
- routeNotification({
159
+ await routeNotification({
159
160
  type: "agent.provider_flapping",
160
161
  scope: { agentId: agent.id, parent: agent.spawnedBy },
161
162
  recipients: [agent.spawnedBy],
@@ -95,7 +95,7 @@ export async function main(): Promise<void> {
95
95
  trace("record", "complete", launch.processes);
96
96
 
97
97
  trace("lifecycle", "start");
98
- const lifecycle = captureLifecycleBoundaries(prepared, request, context.systemPromptAppend);
98
+ const lifecycle = (await captureLifecycleBoundaries(prepared, request, context.systemPromptAppend));
99
99
  lifecycle.boundaries.spawn.launch = { command: launch.command, argv: launch.argv, cwd: launch.cwd };
100
100
  trace("lifecycle", "complete", lifecycle.boundaries);
101
101
 
@@ -22,11 +22,11 @@ export async function fixtureStartupMatrix(): Promise<ContextInventory[]> {
22
22
  cpSync(join(import.meta.dir, "fixtures/project"), cwd, { recursive: true });
23
23
  mkdirSync(join(cwd, ".git"));
24
24
  initDb(":memory:");
25
- seedHarnessHost(cwd);
26
- seedMemory(cwd, { scenario: { id: "startup-inventory", cwd, profile: "worker", provider: "codex", now: 1_700_000_000_000, boundaries: [], fixtures: { memory: [
25
+ (await seedHarnessHost(cwd));
26
+ (await seedMemory(cwd, { scenario: { id: "startup-inventory", cwd, profile: "worker", provider: "codex", now: 1_700_000_000_000, boundaries: [], fixtures: { memory: [
27
27
  { id: "manual", cell: "project", title: "Harness project manual", body: "HARNESS_PROJECT_MANUAL_RULE", inject: "pinned" },
28
28
  { id: "indexed", cell: "project", title: "Harness indexed rule", body: "HARNESS_INDEXED_BODY_IS_NOT_RESIDENT", inject: "indexed" },
29
- ] } }, options: { mcp: "fixture-only" } });
29
+ ] } }, options: { mcp: "fixture-only" } }));
30
30
  return await startupContextInventory(cwd);
31
31
  } finally {
32
32
  await flushRelayEvents();
@@ -1,6 +1,8 @@
1
- import { createCommand, listCommands, updateCommand } from "../../commands-db";
1
+ import { updateCommandAsync, createCommandAsync } from "../../commands-write";
2
+ import { upsertAgentAsync } from "../../db/agents-async";
3
+ import { listCommands } from "../../commands-db";
2
4
  import { getManifest } from "@humwick/providers";
3
- import { upsertAgent } from "../../db";
5
+
4
6
  import { enqueueMemoryInjectionAfterContextCommand, sweepMissedMemoryInjections } from "../../memory-injection";
5
7
  import { parseMemorySeam } from "../../memory-seam";
6
8
  import { enqueueStartupContextInjectionAfterContextCommand } from "../../startup-context-injection";
@@ -32,9 +34,9 @@ function capabilities(provider: "claude" | "codex"): ProviderCapabilities {
32
34
  lastUpdatedAt: 1,
33
35
  };
34
36
  }
35
- function registerCapturedAgent(prepared: PreparedProvisioningSpawn, request: ProvisioningDriverRequest): AgentCard {
37
+ async function registerCapturedAgent(prepared: PreparedProvisioningSpawn, request: ProvisioningDriverRequest): Promise<AgentCard> {
36
38
  const params = prepared.command.params;
37
- return upsertAgent({
39
+ return (await upsertAgentAsync({
38
40
  id: String(params.agentId),
39
41
  name: `Harness ${request.scenario.profile}`,
40
42
  kind: "provider",
@@ -49,7 +51,7 @@ function registerCapturedAgent(prepared: PreparedProvisioningSpawn, request: Pro
49
51
  spawnRequestId: String(params.spawnRequestId),
50
52
  approvalMode: "open",
51
53
  },
52
- });
54
+ }));
53
55
  }
54
56
 
55
57
  function injectionRows(command: Command): Array<{ reason: string; content: string }> {
@@ -71,18 +73,18 @@ const BOUNDARY_SETTLE_ERROR: Record<Exclude<BoundarySettleStatus, "succeeded">,
71
73
  timed_out: "command timed out",
72
74
  };
73
75
 
74
- function contextBoundary(
76
+ async function contextBoundary(
75
77
  type: "agent.clearContext" | "agent.compact",
76
78
  agent: AgentCard,
77
79
  request: ProvisioningDriverRequest,
78
- ): { capture: BoundaryCapture; commands: Command[] } {
80
+ ): Promise<{ capture: BoundaryCapture; commands: Command[] }> {
79
81
  const boundary: SettleableBoundary = type === "agent.clearContext" ? "clear" : "compact";
80
82
  const continuation = [
81
83
  `You have been resumed by Agent Relay — provisioning harness ${boundary}.`,
82
84
  `Objective: ${request.scenario.fixtures?.continuation?.objective ?? "validate effective provisioning"}.`,
83
85
  `Working state: ${request.scenario.fixtures?.continuation?.workingState ?? "capture boundary parity"}.`,
84
86
  ].join("\n\n");
85
- const command = createCommand({
87
+ const command = (await createCommandAsync({
86
88
  type,
87
89
  source: "system",
88
90
  target: agent.id,
@@ -95,16 +97,16 @@ function contextBoundary(
95
97
  },
96
98
  ...(boundary === "compact" ? { instructions: continuation } : {}),
97
99
  },
98
- });
100
+ }));
99
101
  // #2291 — the status the runner reported, NOT an assumed success. This line read
100
102
  // `{ status: "succeeded" }` unconditionally, which is the single status under which every
101
103
  // boundary re-delivery seam fires: the harness could not express the failure mode that dropped
102
104
  // memory on 14 of one coordinator's 17 boundaries, so it never caught it.
103
105
  const status = request.scenario.boundaryStatus?.[boundary] ?? "succeeded";
104
- const settled = updateCommand(command.id, {
106
+ const settled = (await updateCommandAsync(command.id, {
105
107
  status,
106
108
  ...(status === "succeeded" ? {} : { error: BOUNDARY_SETTLE_ERROR[status] }),
107
- })!;
109
+ }))!;
108
110
  // #2293 — WHEN the reactive settle chain runs, modelled as the field runs it.
109
111
  //
110
112
  // `timed_out` is not a status any runner reports: the ONLY producer on a clear/compact is the DB
@@ -115,16 +117,16 @@ function contextBoundary(
115
117
  // crash scenario (#1023 window 2: the relay died between persisting the status and enqueuing).
116
118
  const crashed = request.scenario.boundarySettleCrash?.includes(boundary) === true;
117
119
  if (!crashed && status !== "timed_out") {
118
- enqueueContinuationInjectionAfterSelfResume(settled);
119
- enqueueLifecycleIdentityInjectionAfterContextCommand(settled);
120
- enqueueMemoryInjectionAfterContextCommand(settled, request.scenario.now);
121
- enqueueStartupContextInjectionAfterContextCommand(settled, request.scenario.now);
120
+ (await enqueueContinuationInjectionAfterSelfResume(settled));
121
+ (await enqueueLifecycleIdentityInjectionAfterContextCommand(settled));
122
+ (await enqueueMemoryInjectionAfterContextCommand(settled, request.scenario.now));
123
+ (await enqueueStartupContextInjectionAfterContextCommand(settled, request.scenario.now));
122
124
  }
123
125
  // …and then the periodic backstops, which in the field run every REAP_INTERVAL_MS regardless.
124
126
  // Running them on EVERY capture (not only the crashed ones) is deliberate: on the reactive
125
127
  // captures they prove the sweeps do not double-inject against a settle that already ran.
126
- sweepMissedContinuationInjections(request.scenario.now);
127
- sweepMissedMemoryInjections(request.scenario.now);
128
+ (await sweepMissedContinuationInjections(request.scenario.now));
129
+ (await sweepMissedMemoryInjections(request.scenario.now));
128
130
  const injections = injectionRows(settled);
129
131
  const commands = [settled, ...listCommands({ target: agent.id, type: "agent.injectContext", limit: 100 }).filter((item) => item.correlationId === settled.id)];
130
132
  return {
@@ -147,12 +149,12 @@ function preparedSeam(agent: AgentCard): BoundaryCapture["memorySeam"] {
147
149
  return seam as BoundaryCapture["memorySeam"];
148
150
  }
149
151
 
150
- export function captureLifecycleBoundaries(
152
+ export async function captureLifecycleBoundaries(
151
153
  prepared: PreparedProvisioningSpawn,
152
154
  request: ProvisioningDriverRequest,
153
155
  spawnSystemPromptAppend: string,
154
- ): { boundaries: Record<ContextBoundary, BoundaryCapture>; lifecycleCommands: Command[] } {
155
- const agent = registerCapturedAgent(prepared, request);
156
+ ): Promise<{ boundaries: Record<ContextBoundary, BoundaryCapture>; lifecycleCommands: Command[] }> {
157
+ const agent = (await registerCapturedAgent(prepared, request));
156
158
  const restartParams = restartInstructionParamsForAgent(agent, {
157
159
  spawnRequestId: String(agent.meta?.spawnRequestId),
158
160
  cwd: request.scenario.cwd,
@@ -168,8 +170,8 @@ export function captureLifecycleBoundaries(
168
170
  });
169
171
  const restartArgs = assemblePreparedSpawnChain(restartPrepared);
170
172
  const restartAppend = systemPromptAppendFromSpawnArgs(request.scenario.provider, restartArgs, restartPrepared.runnerConfig);
171
- const clear = contextBoundary("agent.clearContext", agent, request);
172
- const compact = contextBoundary("agent.compact", agent, request);
173
+ const clear = (await contextBoundary("agent.clearContext", agent, request));
174
+ const compact = (await contextBoundary("agent.compact", agent, request));
173
175
  return {
174
176
  boundaries: {
175
177
  spawn: {