@humwick/server 0.130.1 → 0.130.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (811) hide show
  1. package/README.md +5 -0
  2. package/bundled/prompts/manifest.json +1 -0
  3. package/bundled/prompts/task.hydration.md +1 -1
  4. package/bundled/roles/builder.md +1 -1
  5. package/docs/guides/sub-coordinators.md +12 -5
  6. package/docs/guides/tools-administration.md +4 -0
  7. package/docs/guides/tools-coordination.md +2 -0
  8. package/docs/guides/tools-tasks.md +8 -0
  9. package/docs/guides/workflows.md +74 -0
  10. package/docs/openapi.json +486 -4
  11. package/package.json +10 -18
  12. package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-Bq9kr21N.js} +2 -2
  13. package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-Dqiroy06.js} +2 -2
  14. package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-DYU962-H.js} +2 -2
  15. package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-DhPfzioE.js} +2 -2
  16. package/public/assets/{activity-yLztXEBt.js → activity-DzCcQTee.js} +2 -2
  17. package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-SgDt9i3T.js} +2 -2
  18. package/public/assets/agent-liveness-Bq-s73jW.js +2 -0
  19. package/public/assets/{agent-name-CTZBrSD9.js → agent-name-CcY3Aijy.js} +2 -2
  20. package/public/assets/agent-profiles-cxtRBn6O.js +2 -0
  21. package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-DGYbIhaI.js} +2 -2
  22. package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-DHbftV0N.js} +2 -2
  23. package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-CY113sp-.js} +2 -2
  24. package/public/assets/{agents-BYDslkJc.js → agents-BPzY7IlQ.js} +2 -2
  25. package/public/assets/{analytics-B-XSbEMC.js → analytics-DENFPv_a.js} +2 -2
  26. package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-KRvSc7sl.js} +2 -2
  27. package/public/assets/{artifacts-DPN1q4pA.js → artifacts-C9gSmL3s.js} +2 -2
  28. package/public/assets/{artifacts-oBOqks-2.js → artifacts-DT-HkI5O.js} +2 -2
  29. package/public/assets/{automation-4KcRFXEu.js → automation-BsmjQhKD.js} +2 -2
  30. package/public/assets/{backlog-Cw9xPTCF.js → backlog-8NYH_62t.js} +2 -2
  31. package/public/assets/{busy-health-CTu32MZt.js → busy-health-D3hwvYb4.js} +2 -2
  32. package/public/assets/{channels-BiXzg1G9.js → channels-DCJ5WL7O.js} +2 -2
  33. package/public/assets/{chat-Ctk2qwvA.js → chat-DAIl357U.js} +3 -3
  34. package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-CzrZfr9U.js} +2 -2
  35. package/public/assets/{connectors-C36ax4Vw.js → connectors-xTxtlyou.js} +2 -2
  36. package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BpebFLK2.js} +2 -2
  37. package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-BHvI5wXC.js} +2 -2
  38. package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-DGT0o3wJ.js} +2 -2
  39. package/public/assets/{deploys-Bwfq146q.js → deploys-hqWOHSHE.js} +2 -2
  40. package/public/assets/{display-CfO7rTuF.js → display-CDeH4I8T.js} +2 -2
  41. package/public/assets/{files-DhhZI2Ih.js → files-BTeGVmTg.js} +2 -2
  42. package/public/assets/{fleet-B_rFEbnL.js → fleet-DgXtNgCa.js} +2 -2
  43. package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BHEt5yc_.js} +2 -2
  44. package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-MLtodyPp.js} +3 -3
  45. package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-CAe664Z8.js} +2 -2
  46. package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-mapF4Fj9.js} +2 -2
  47. package/public/assets/index-CqqgOI5R.js +15 -0
  48. package/public/assets/index-MYAIwYTX.css +2 -0
  49. package/public/assets/{insights-fH1EL-qZ.js → insights-DNyf7IzF.js} +2 -2
  50. package/public/assets/{integrations-C5Oix6ng.js → integrations-DlYOHq7T.js} +2 -2
  51. package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-CeWBNWn7.js} +2 -2
  52. package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-Cib8nqdE.js} +2 -2
  53. package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-DSn1cPm7.js} +2 -2
  54. package/public/assets/{managed-agents-egllbpij.js → managed-agents-C3CkM81m.js} +2 -2
  55. package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-W4VQQPAv.js} +3 -3
  56. package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-CMsTdhjq.js} +2 -2
  57. package/public/assets/{memory-C8WmXsyr.js → memory-BV17qtO4.js} +2 -2
  58. package/public/assets/{messages-BzQdqlO6.js → messages-Bm_1AqSA.js} +2 -2
  59. package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Dg-vfP09.js} +2 -2
  60. package/public/assets/{overview-DCUnI4Z7.js → overview-DcYCrvlr.js} +2 -2
  61. package/public/assets/{pairs-ftCd2XcD.js → pairs-8o9nuG3V.js} +2 -2
  62. package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-BsRyBMea.js} +2 -2
  63. package/public/assets/project-profile-instructions-DETKFn_E.js +2 -0
  64. package/public/assets/projects-M_m6AHws.js +2 -0
  65. package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-C_mNCgeL.js} +2 -2
  66. package/public/assets/provider-display-BEeLXC_D.js +2 -0
  67. package/public/assets/{registry-DWCU5c8q.js → registry-DDHHHE5N.js} +2 -2
  68. package/public/assets/run-card-Dt4I4jaP.js +2 -0
  69. package/public/assets/scroll-text-BKXS1ahr.js +2 -0
  70. package/public/assets/{secrets-C7GIUATz.js → secrets-BkVwxI5O.js} +2 -2
  71. package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-Crq-6a-B.js} +2 -2
  72. package/public/assets/{settings-C6sZ9eBa.js → settings-CYcavMFu.js} +2 -2
  73. package/public/assets/shipping-H6gzEeZB.js +2 -0
  74. package/public/assets/{stats-V9Z-GxUd.js → stats-BJVeWkpV.js} +2 -2
  75. package/public/assets/{status-dot-CVv0iGHL.js → status-dot-BcHyw1Vw.js} +2 -2
  76. package/public/assets/store-DKPDIZBe.js +9 -0
  77. package/public/assets/{tasks-CXU75HRF.js → tasks-qJjlQPpx.js} +2 -2
  78. package/public/assets/{teams-BPf976zb.js → teams-Cd5Sk1uX.js} +2 -2
  79. package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-CpY5_m7W.js} +3 -3
  80. package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-DI_2llFR.js} +2 -2
  81. package/public/assets/token-estimate-Co-Jdphh.js +2 -0
  82. package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-0yJA_buM.js} +2 -2
  83. package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-uJXHf34W.js} +2 -2
  84. package/public/assets/use-project-list-CpWl6eHQ.js +2 -0
  85. package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BdxBW8mL.js} +2 -2
  86. package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-3IndfpOc.js} +2 -2
  87. package/public/assets/versioned-prompt-editor-CIVg7XB1.js +8 -0
  88. package/public/assets/{work-queue-TCjJxeT-.js → work-queue-B9rnLwHZ.js} +2 -2
  89. package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-X8wxyhzC.js} +2 -2
  90. package/public/assets/{workflows-CXQX20Qj.js → workflows-o5YyMFW7.js} +2 -2
  91. package/public/assets/{workspaces-qSYzKYMA.js → workspaces-CzEGoAng.js} +2 -2
  92. package/public/cosmos.html +4 -4
  93. package/public/index.html +31 -29
  94. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  95. package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
  96. package/runner/src/adapters/claude-effort.ts +2 -4
  97. package/runner/src/adapters/claude-headless.ts +1 -1
  98. package/runner/src/adapters/claude-launch-exit.ts +26 -0
  99. package/runner/src/adapters/claude-session-probe.ts +1 -1
  100. package/runner/src/adapters/claude-tmux.ts +38 -10
  101. package/runner/src/adapters/claude.ts +28 -75
  102. package/runner/src/adapters/codex-launch-config.ts +4 -5
  103. package/runner/src/adapters/codex.ts +1 -1
  104. package/runner/src/adapters/opencode-provider.ts +7 -22
  105. package/runner/src/adapters/opencode.ts +4 -4
  106. package/runner/src/adapters/provider-quota-harvest.ts +20 -71
  107. package/runner/src/agent-runner/credentials.ts +42 -12
  108. package/runner/src/agent-runner/inbox.ts +27 -0
  109. package/runner/src/agent-runner/lifecycle-milestones.ts +2 -4
  110. package/runner/src/agent-runner/liveness-exchange.ts +104 -0
  111. package/runner/src/bin/claude.ts +4 -0
  112. package/runner/src/bin/codex.ts +4 -0
  113. package/runner/src/bin/opencode.ts +4 -0
  114. package/runner/src/claude-system-prompt.ts +49 -0
  115. package/runner/src/index.ts +5 -2
  116. package/runner/src/launch-assembly.ts +14 -10
  117. package/runner/src/profile-home.ts +1 -1
  118. package/runner/src/project-instructions.ts +2 -2
  119. package/runner/src/provider-command.ts +18 -0
  120. package/runner/src/provider-setup.ts +35 -0
  121. package/runner/src/providers.ts +2 -1
  122. package/runner/src/runner-core.ts +32 -38
  123. package/runner/src/runner-helpers.ts +0 -8
  124. package/runner/src/session-scratch.ts +6 -2
  125. package/runner/src/spawn-input.ts +2 -1
  126. package/runner/src/test-run-dedup.ts +59 -56
  127. package/runner/test-support/provisioning-context.ts +4 -2
  128. package/runner/test-support/runner-harness.ts +2 -1
  129. package/scripts/cd-config.ts +8 -0
  130. package/scripts/gate-run-lease.ts +10 -7
  131. package/scripts/gate.sh +5 -1
  132. package/scripts/steward-policy-cleanup.ts +2 -2
  133. package/src/agent-authz.ts +2 -2
  134. package/src/agent-drive-arbiter.ts +3 -8
  135. package/src/agent-exit-cleanup-async.ts +2 -2
  136. package/src/agent-exit-cleanup.ts +23 -19
  137. package/src/agent-lifecycle-events.ts +112 -85
  138. package/src/agent-ref.ts +3 -2
  139. package/src/agent-status-events.ts +43 -14
  140. package/src/auth/password.ts +4 -3
  141. package/src/auth/session-refresh.ts +1 -1
  142. package/src/auth/session.test-fixture.ts +2 -2
  143. package/src/auth/session.ts +7 -7
  144. package/src/automations/crud.ts +8 -81
  145. package/src/automations/dispatch.ts +33 -58
  146. package/src/automations/index.ts +1 -1
  147. package/src/automations/persistence.ts +65 -0
  148. package/src/automations/precheck.ts +18 -16
  149. package/src/automations/read-async.ts +11 -0
  150. package/src/automations/reconcile.ts +30 -39
  151. package/src/automations/storage.ts +33 -10
  152. package/src/automations/write-async.ts +33 -0
  153. package/src/branch-land-notice.ts +93 -0
  154. package/src/branch-landed.ts +31 -98
  155. package/src/bus.ts +40 -39
  156. package/src/cd-deploy-notify.ts +32 -4
  157. package/src/cd-host-lag-notify.ts +7 -6
  158. package/src/ci/incidents.ts +2 -2
  159. package/src/ci/monitor.ts +5 -8
  160. package/src/ci/notifications.ts +4 -4
  161. package/src/ci/root-missing.ts +4 -9
  162. package/src/ci/transition-notify.ts +12 -44
  163. package/src/claude-app/oauth-http.ts +3 -3
  164. package/src/cli/cd-pauses.ts +19 -0
  165. package/src/cli/orchestrator.ts +1 -1
  166. package/src/cli/state.ts +2 -19
  167. package/src/cli/task-edit.ts +22 -0
  168. package/src/cli/task.ts +3 -1
  169. package/src/cli/workflow.ts +19 -4
  170. package/src/commands-db.ts +7 -7
  171. package/src/commands-write.ts +8 -0
  172. package/src/compaction-watch.ts +10 -8
  173. package/src/config-store-write.ts +13 -1
  174. package/src/config-store.ts +25 -14
  175. package/src/config.ts +4 -11
  176. package/src/connectors.ts +10 -8
  177. package/src/context-advisory.ts +22 -21
  178. package/src/db/activity-async.ts +6 -1
  179. package/src/db/activity-write-ops.ts +12 -1
  180. package/src/db/activity.ts +1 -14
  181. package/src/db/agent-action-write.ts +36 -0
  182. package/src/db/agent-control-async.ts +9 -0
  183. package/src/db/agent-control-write.ts +49 -0
  184. package/src/db/agent-effort-observe.ts +22 -0
  185. package/src/db/agent-meta.ts +14 -3
  186. package/src/db/agent-search.ts +1 -15
  187. package/src/db/agents-async.ts +59 -9
  188. package/src/db/agents-write-ops.ts +12 -3
  189. package/src/db/agents.ts +95 -65
  190. package/src/db/auth-identities.ts +2 -2
  191. package/src/db/automation-read-ops.ts +11 -0
  192. package/src/db/automation-write-ops.ts +46 -0
  193. package/src/db/blackboard.ts +2 -2
  194. package/src/db/browser-session-write.ts +32 -0
  195. package/src/db/bus-outbox-write-ops.ts +3 -1
  196. package/src/db/checkout-refresh-schema.ts +47 -0
  197. package/src/db/checkout-refresh.ts +5 -5
  198. package/src/db/ci-incidents-async.ts +5 -5
  199. package/src/db/ci-incidents-write-ops.ts +2 -2
  200. package/src/db/command-agent-profile-backfill.ts +39 -0
  201. package/src/db/command-agent-profiles.ts +5 -1
  202. package/src/db/command-retention.ts +126 -0
  203. package/src/db/command-row.ts +10 -2
  204. package/src/db/commands-list-query.ts +2 -0
  205. package/src/db/commands-planner-stats.test-fixture.ts +8 -0
  206. package/src/db/commands-read-ops.ts +16 -0
  207. package/src/db/commands-spawn-read.ts +1 -1
  208. package/src/db/config-store-write-ops.ts +7 -2
  209. package/src/db/connection.ts +1 -182
  210. package/src/db/context-carry-write.ts +74 -0
  211. package/src/db/continuation-archives-async.ts +5 -0
  212. package/src/db/continuation-archives-write-ops.ts +7 -0
  213. package/src/db/continuations.ts +6 -6
  214. package/src/db/db-error-registry.ts +12 -0
  215. package/src/db/db-writer-worker.ts +8 -1
  216. package/src/db/deploy-events-async.ts +1 -0
  217. package/src/db/deploy-events-read-ops.ts +2 -1
  218. package/src/db/deploy-events.ts +35 -4
  219. package/src/db/gateway.ts +26 -133
  220. package/src/db/history-retention-ops.ts +13 -0
  221. package/src/db/hosts-registration.ts +10 -2
  222. package/src/db/hosts.ts +9 -6
  223. package/src/db/inbox-async.ts +2 -2
  224. package/src/db/inbox-read-ops.ts +1 -1
  225. package/src/db/inbox.ts +9 -17
  226. package/src/db/index.ts +2 -0
  227. package/src/db/integrations-async.ts +8 -0
  228. package/src/db/integrations-ops.ts +15 -0
  229. package/src/db/integrations.ts +15 -21
  230. package/src/db/issue-associations.ts +2 -2
  231. package/src/db/issue-lifecycle.ts +3 -4
  232. package/src/db/issue-refs-async.ts +23 -0
  233. package/src/db/issue-refs-read-ops.ts +6 -0
  234. package/src/db/issue-refs-write-ops.ts +29 -0
  235. package/src/db/issue-refs.ts +15 -16
  236. package/src/db/kernel-event-log-schema.ts +2 -0
  237. package/src/db/land-boundaries.ts +51 -5
  238. package/src/db/land-gate-attestations.ts +2 -2
  239. package/src/db/landing-receipts.ts +2 -2
  240. package/src/db/lifecycle-context-write.ts +5 -0
  241. package/src/db/lifecycle-tail-async.ts +76 -0
  242. package/src/db/lifecycle-tail-write-ops.ts +62 -0
  243. package/src/db/lifecycle-write-window.ts +2 -1
  244. package/src/db/lineage-pair-dedupe-sql.ts +3 -3
  245. package/src/db/long-running-work.ts +2 -2
  246. package/src/db/main-connection-mode.ts +11 -0
  247. package/src/db/main-connection-writes.ts +41 -2
  248. package/src/db/maintenance-job-reconcile.ts +61 -0
  249. package/src/db/maintenance-job-runs-async.ts +14 -0
  250. package/src/db/maintenance-job-write-ops.ts +9 -0
  251. package/src/db/maintenance-pauses.ts +2 -2
  252. package/src/db/mappers.ts +2 -14
  253. package/src/db/merge-lease.ts +1 -15
  254. package/src/db/message-send.ts +4 -0
  255. package/src/db/messages.ts +31 -25
  256. package/src/db/migrations.ts +25 -16
  257. package/src/db/notification-write-ops.ts +19 -0
  258. package/src/db/operator-answer-write.ts +19 -0
  259. package/src/db/orchestrators.ts +14 -76
  260. package/src/db/pairs-async.ts +22 -1
  261. package/src/db/pairs-write-ops.ts +8 -3
  262. package/src/db/pairs.ts +42 -61
  263. package/src/db/plan-dispatch-schema.ts +5 -1
  264. package/src/db/plan-ready-notices.ts +43 -0
  265. package/src/db/plan-tools-include-migration.ts +36 -0
  266. package/src/db/plans-write-ops.ts +2 -0
  267. package/src/db/presence-buffer.ts +5 -0
  268. package/src/db/presence-loop.ts +18 -23
  269. package/src/db/presence-write.ts +0 -6
  270. package/src/db/project-entries-async.ts +14 -0
  271. package/src/db/project-entries-read-ops.ts +5 -1
  272. package/src/db/project-entries-write-ops.ts +8 -0
  273. package/src/db/project-entries.ts +15 -12
  274. package/src/db/project-journal.ts +2 -2
  275. package/src/db/project-profile-instructions.ts +50 -0
  276. package/src/db/project-trust-approvals.ts +2 -2
  277. package/src/db/prompt-templates.ts +4 -4
  278. package/src/db/prompt-versions.ts +9 -2
  279. package/src/db/provider-config-history.ts +8 -3
  280. package/src/db/provider-model-seed.ts +34 -0
  281. package/src/db/read-op-marshaling-fixtures.ts +23 -0
  282. package/src/db/read-ops.ts +8 -0
  283. package/src/db/retention.ts +13 -2
  284. package/src/db/review-publish-write.ts +8 -0
  285. package/src/db/routing-policy.ts +2 -3
  286. package/src/db/runtime-admin-async.ts +19 -0
  287. package/src/db/runtime-admin-write-ops.ts +36 -0
  288. package/src/db/runtime-tail-async.ts +288 -0
  289. package/src/db/runtime-tail-write-ops.ts +97 -0
  290. package/src/db/schema.ts +13 -4
  291. package/src/db/spawn-budget.ts +5 -0
  292. package/src/db/spawn-delegation-state.ts +11 -4
  293. package/src/db/spawn-delegation.ts +1 -11
  294. package/src/db/sql-audit-indexes.ts +3 -0
  295. package/src/db/stats-async.ts +9 -6
  296. package/src/db/task-entity.ts +28 -6
  297. package/src/db/task-list.ts +3 -1
  298. package/src/db/tasks.ts +1 -17
  299. package/src/db/team-claim-policy.ts +60 -0
  300. package/src/db/teams-async.ts +4 -0
  301. package/src/db/teams-write-ops.ts +4 -0
  302. package/src/db/terminal-events.ts +15 -0
  303. package/src/db/timer-cutover-bodies.ts +292 -0
  304. package/src/db/timer-cutover-core.ts +37 -278
  305. package/src/db/timer-cutover-state.ts +40 -0
  306. package/src/db/timer-cutover-write-ops.ts +1 -40
  307. package/src/db/timer-ingress.ts +7 -1
  308. package/src/db/token-db-write-ops.ts +19 -0
  309. package/src/db/token-standing-async.ts +12 -0
  310. package/src/db/token-standing.ts +21 -20
  311. package/src/db/token-usage-retention.ts +33 -0
  312. package/src/db/token-usage-write-ops.ts +1 -1
  313. package/src/db/token-usage.ts +4 -1
  314. package/src/db/user-invites-async.ts +13 -0
  315. package/src/db/user-invites.ts +3 -3
  316. package/src/db/users.ts +14 -6
  317. package/src/db/workflow-contact.ts +1 -1
  318. package/src/db/workflow-task-read-ops.ts +30 -0
  319. package/src/db/workspaces.ts +8 -5
  320. package/src/db/write-ops.ts +37 -12
  321. package/src/db/writer-fault-seam.ts +2 -9
  322. package/src/db/writer-fault-test-ops.ts +18 -0
  323. package/src/db/writer-gateway.ts +58 -56
  324. package/src/dev.ts +8 -3
  325. package/src/dispatch-availability.ts +10 -6
  326. package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
  327. package/src/event-loop-lag.ts +4 -2
  328. package/src/event-loop-yield.ts +2 -2
  329. package/src/events.ts +10 -8
  330. package/src/host/disk-alert.ts +121 -0
  331. package/src/host-provider-store.ts +5 -4
  332. package/src/hub-metrics-report.ts +5 -1
  333. package/src/hub-metrics.ts +38 -18
  334. package/src/injection-sweep-pacing.ts +6 -8
  335. package/src/land-gate-notifications.ts +11 -10
  336. package/src/land-gate-queue-progress.ts +3 -3
  337. package/src/land-settle-dispatch.ts +52 -92
  338. package/src/lifecycle-context-pressure.ts +11 -10
  339. package/src/lifecycle-manager.ts +107 -100
  340. package/src/maintenance/breaker.ts +18 -16
  341. package/src/maintenance/cd-watcher.ts +3 -3
  342. package/src/maintenance/checkout-refresh.ts +18 -1
  343. package/src/maintenance/critical-job-watchdog.ts +19 -20
  344. package/src/maintenance/events.ts +3 -3
  345. package/src/maintenance/history-retention-job.ts +30 -0
  346. package/src/maintenance/index.ts +1 -0
  347. package/src/maintenance/jobs.ts +32 -69
  348. package/src/maintenance/long-running-work.ts +3 -1
  349. package/src/maintenance/offline-agent-prune-job.ts +28 -0
  350. package/src/maintenance/orphaned-sessions.ts +5 -4
  351. package/src/maintenance/pauses.ts +4 -10
  352. package/src/maintenance/plan-ready-notice-job.ts +71 -0
  353. package/src/maintenance/scheduler.ts +98 -137
  354. package/src/maintenance/stalled-delivery-pager.ts +10 -9
  355. package/src/maintenance/teams.ts +19 -30
  356. package/src/maintenance/workspaces.ts +18 -28
  357. package/src/managed-policy-escalation.ts +7 -7
  358. package/src/managed-policy.ts +32 -28
  359. package/src/managed-provider-gate.ts +5 -4
  360. package/src/managed-spawn-reservation.ts +5 -4
  361. package/src/mcp/index.ts +12 -9
  362. package/src/mcp/output-descriptions.ts +8 -8
  363. package/src/mcp/presentation.ts +6 -5
  364. package/src/mcp/project-profile-instructions.ts +32 -0
  365. package/src/mcp/runtime-output.ts +6 -1
  366. package/src/mcp/self-care-visibility.ts +2 -2
  367. package/src/mcp/spawn-targets-matrix.ts +10 -1
  368. package/src/mcp/tool-groups.ts +4 -3
  369. package/src/mcp/tool-roles.ts +81 -0
  370. package/src/mcp/tools-spawn.ts +4 -3
  371. package/src/mcp/tools-workspace.ts +1 -1
  372. package/src/mcp-agent-action.ts +1 -2
  373. package/src/mcp-blackboard-tools.ts +6 -5
  374. package/src/mcp-decision-tools.ts +7 -7
  375. package/src/mcp-egress-tools.ts +10 -9
  376. package/src/mcp-issue-activity-tools.ts +2 -2
  377. package/src/mcp-issue-association-tools.ts +4 -4
  378. package/src/mcp-issue-ref-tools.ts +13 -12
  379. package/src/mcp-maintenance-tools.ts +2 -2
  380. package/src/mcp-merge-tools.ts +5 -5
  381. package/src/mcp-notification-subscription-tools.ts +14 -15
  382. package/src/mcp-output-levels.test-fixture.ts +1 -1
  383. package/src/mcp-profile-trust-tools.ts +5 -5
  384. package/src/mcp-project-journal-tools.ts +4 -12
  385. package/src/mcp-project-tools.ts +17 -18
  386. package/src/mcp-provider-catalog.ts +2 -2
  387. package/src/mcp-routing-policy-tools.ts +3 -2
  388. package/src/mcp-task-tools.ts +11 -5
  389. package/src/mcp-team-template-tools.ts +3 -3
  390. package/src/mcp-team-tools.ts +6 -6
  391. package/src/mcp-workflow-tools.ts +13 -4
  392. package/src/memory-area-injection.ts +13 -12
  393. package/src/memory-boundary-capture.ts +6 -6
  394. package/src/memory-injection.ts +45 -43
  395. package/src/merge-pause-maintenance.ts +5 -4
  396. package/src/notification-router.ts +44 -17
  397. package/src/notification-types.ts +2 -1
  398. package/src/notify.ts +5 -5
  399. package/src/observed-reset-refresh.ts +4 -4
  400. package/src/operator-alarm.ts +23 -11
  401. package/src/project-ingest.ts +6 -6
  402. package/src/project-instructions.ts +12 -1
  403. package/src/project-profile-instruction-text.ts +6 -0
  404. package/src/project-profile-instructions.ts +20 -0
  405. package/src/project-trust.ts +12 -11
  406. package/src/prompt-resolver.ts +3 -3
  407. package/src/provider-catalog-store.ts +3 -49
  408. package/src/provider-config-store.ts +12 -11
  409. package/src/provider-model-seed.ts +1 -18
  410. package/src/provider-quota-async.ts +5 -7
  411. package/src/provider-quota-config-store.ts +5 -4
  412. package/src/provider-secrets.test-fixture.ts +3 -3
  413. package/src/provider-timeline-event.ts +4 -7
  414. package/src/quota-band-delivery.ts +2 -2
  415. package/src/recipe-runner.ts +6 -5
  416. package/src/repo-config-source.ts +10 -4
  417. package/src/retention-config-store.ts +4 -3
  418. package/src/reviewer-pipeline.ts +11 -10
  419. package/src/routes/_route.ts +4 -4
  420. package/src/routes/_shared.ts +13 -12
  421. package/src/routes/agent-effort.ts +5 -5
  422. package/src/routes/agent-heartbeat-quota.ts +23 -0
  423. package/src/routes/agent-keep.ts +1 -1
  424. package/src/routes/agent-profiles.ts +6 -6
  425. package/src/routes/agent-reporting.ts +1 -1
  426. package/src/routes/agent-self-effort.ts +5 -5
  427. package/src/routes/agent-sessions.ts +24 -24
  428. package/src/routes/agents-spawn.ts +2 -2
  429. package/src/routes/agents.ts +19 -121
  430. package/src/routes/auth.ts +14 -15
  431. package/src/routes/authority-audit.ts +2 -2
  432. package/src/routes/automations.ts +6 -5
  433. package/src/routes/channel-binding-delete.ts +1 -1
  434. package/src/routes/channel-output.ts +3 -3
  435. package/src/routes/claude-api-budget.ts +5 -5
  436. package/src/routes/commands-listing.ts +5 -1
  437. package/src/routes/commands.ts +31 -29
  438. package/src/routes/context-resets.ts +2 -2
  439. package/src/routes/continuation-archives.ts +2 -2
  440. package/src/routes/coordinator-teams.ts +1 -1
  441. package/src/routes/decisions.ts +2 -2
  442. package/src/routes/host-secret-files.ts +1 -1
  443. package/src/routes/hosts.ts +11 -11
  444. package/src/routes/inbox.ts +3 -2
  445. package/src/routes/index.ts +12 -2
  446. package/src/routes/integrations.ts +32 -56
  447. package/src/routes/issue-activity.ts +2 -2
  448. package/src/routes/issue-associations.ts +4 -4
  449. package/src/routes/issue-refs.ts +9 -9
  450. package/src/routes/kernel-timers-operator.ts +1 -1
  451. package/src/routes/memory.ts +1 -1
  452. package/src/routes/merges.ts +11 -11
  453. package/src/routes/messages.ts +23 -17
  454. package/src/routes/orchestrator-bootstrap.ts +2 -2
  455. package/src/routes/orchestrator-host-registration.ts +4 -2
  456. package/src/routes/orchestrator-host-utilization.ts +5 -3
  457. package/src/routes/orchestrator-proxy.ts +4 -4
  458. package/src/routes/orchestrator.ts +28 -19
  459. package/src/routes/pairs.ts +8 -8
  460. package/src/routes/project-profile-instructions.ts +27 -0
  461. package/src/routes/project-trust.ts +3 -3
  462. package/src/routes/projects.ts +16 -16
  463. package/src/routes/prompt-templates.ts +12 -12
  464. package/src/routes/provider-config.ts +6 -6
  465. package/src/routes/provider-quota-config.ts +2 -2
  466. package/src/routes/provider-quotas.ts +10 -10
  467. package/src/routes/run-command.ts +1 -1
  468. package/src/routes/secrets-backup.ts +2 -2
  469. package/src/routes/secrets-import.ts +1 -1
  470. package/src/routes/secrets-vault.ts +7 -7
  471. package/src/routes/settings.ts +6 -6
  472. package/src/routes/shipping.ts +9 -1
  473. package/src/routes/spawn-policy.ts +8 -7
  474. package/src/routes/sse.ts +2 -2
  475. package/src/routes/stats.ts +6 -6
  476. package/src/routes/task-http.ts +15 -1
  477. package/src/routes/task-issues.ts +11 -26
  478. package/src/routes/tasks.ts +22 -53
  479. package/src/routes/team-templates.ts +12 -12
  480. package/src/routes/teams-config.ts +2 -2
  481. package/src/routes/teams.ts +10 -10
  482. package/src/routes/tokens.ts +30 -22
  483. package/src/routes/users.ts +24 -24
  484. package/src/routes/viewer-read.ts +3 -3
  485. package/src/routes/web-tool-calls.ts +4 -4
  486. package/src/routes/workflows.ts +22 -7
  487. package/src/routes/workspaces.ts +17 -16
  488. package/src/routing-policy-normalize.ts +1 -2
  489. package/src/routing-policy-push.ts +6 -6
  490. package/src/routing-step-defaults.ts +0 -2
  491. package/src/runner-token-mint-limit.ts +63 -0
  492. package/src/runtime-grant.ts +21 -13
  493. package/src/runtime-tokens.ts +59 -35
  494. package/src/secrets-broker/config.ts +1 -1
  495. package/src/secrets-broker/service.ts +2 -2
  496. package/src/security.ts +16 -21
  497. package/src/self-resume-carry.ts +21 -110
  498. package/src/self-resume-supersede.ts +4 -3
  499. package/src/self-resume.ts +54 -66
  500. package/src/server-background.ts +2 -2
  501. package/src/server.ts +26 -24
  502. package/src/services/agent-action.ts +12 -31
  503. package/src/services/agent-effort.ts +7 -32
  504. package/src/services/agent-hang-watchdog-job.ts +2 -2
  505. package/src/services/agent-heartbeat.ts +166 -0
  506. package/src/services/agent-reporting.ts +1 -1
  507. package/src/services/browser-inventory.ts +3 -3
  508. package/src/services/browser-session-state.ts +3 -2
  509. package/src/services/browser-session.ts +21 -27
  510. package/src/services/bus-command-update.ts +9 -9
  511. package/src/services/checkout-refresh-state.ts +1 -0
  512. package/src/services/checkout-refresh.test-fixture.ts +3 -2
  513. package/src/services/command-host.ts +7 -2
  514. package/src/services/coordinator-digest.ts +3 -2
  515. package/src/services/dispatch-command.ts +12 -13
  516. package/src/services/effective-launch-driver.ts +14 -9
  517. package/src/services/host-changed-paths.test-fixture.ts +5 -6
  518. package/src/services/host-project-readiness.ts +2 -2
  519. package/src/services/host-providers.ts +1 -1
  520. package/src/services/host-utilization.ts +27 -4
  521. package/src/services/idle-agent-digest.ts +17 -12
  522. package/src/services/idle-epics.ts +9 -10
  523. package/src/services/interrupt-agent.ts +12 -9
  524. package/src/services/issue-activity.ts +3 -3
  525. package/src/services/issue-associations.ts +15 -18
  526. package/src/services/issue-lifecycle-comments.ts +3 -2
  527. package/src/services/issue-lifecycle.ts +69 -72
  528. package/src/services/issue-refs.ts +10 -15
  529. package/src/services/kernel-timers-cutover-chaos-worker.ts +11 -8
  530. package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
  531. package/src/services/kernel-timers-ingress.ts +4 -4
  532. package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
  533. package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
  534. package/src/services/kernel-timers-outbox.ts +1 -1
  535. package/src/services/kernel-timers-stage10-operator.ts +1 -1
  536. package/src/services/kernel-timers.ts +4 -3
  537. package/src/services/land-gate-placement.ts +11 -2
  538. package/src/services/land-issue-relations.ts +5 -4
  539. package/src/services/land-restart-retry.ts +7 -6
  540. package/src/services/landed-ancestry.ts +25 -8
  541. package/src/services/legacy-landing-host.ts +4 -1
  542. package/src/services/legacy-landing-recovery.ts +8 -6
  543. package/src/services/managed-running.ts +17 -17
  544. package/src/services/memory-areas.ts +17 -53
  545. package/src/services/merge-pause.ts +9 -15
  546. package/src/services/operator-decisions.ts +37 -41
  547. package/src/services/orchestrator-registration-recovery.ts +6 -2
  548. package/src/services/orchestrator-upgrade.ts +14 -12
  549. package/src/services/permission-decision.ts +4 -3
  550. package/src/services/plan-ci-notice.ts +57 -0
  551. package/src/services/plan-ci-recovery.ts +2 -55
  552. package/src/services/plan-conformance.ts +4 -4
  553. package/src/services/plan-dispatch-policy.ts +10 -3
  554. package/src/services/plan-dispatch.ts +35 -14
  555. package/src/services/plan-graph.ts +39 -261
  556. package/src/services/plan-import.ts +1 -1
  557. package/src/services/plan-live-bindings.ts +8 -37
  558. package/src/services/plan-task-create.ts +1 -1
  559. package/src/services/plan-terminal-refs.ts +2 -12
  560. package/src/services/plan-wake-digest.ts +9 -3
  561. package/src/services/profile-trust.ts +6 -5
  562. package/src/services/project-config-read.ts +70 -0
  563. package/src/services/project-profile-instructions.ts +54 -0
  564. package/src/services/project.ts +11 -10
  565. package/src/services/prompt-templates.ts +6 -5
  566. package/src/services/provider-hold-nudge.ts +9 -9
  567. package/src/services/provider-hold-record.ts +13 -12
  568. package/src/services/provider-state-audit.ts +19 -18
  569. package/src/services/provisioning-harness/budget-baseline.json +4 -4
  570. package/src/services/provisioning-harness/driver.ts +1 -1
  571. package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
  572. package/src/services/provisioning-harness/lifecycle.ts +24 -22
  573. package/src/services/provisioning-harness/prepare.ts +16 -17
  574. package/src/services/rate-limit-resume.ts +10 -9
  575. package/src/services/red-main-auto-revert.ts +7 -5
  576. package/src/services/red-main-controller-deps.ts +20 -3
  577. package/src/services/red-main-incident.ts +3 -1
  578. package/src/services/red-main-quarantine.ts +2 -3
  579. package/src/services/register-agent.ts +22 -22
  580. package/src/services/restart-project-role.ts +1 -1
  581. package/src/services/restart-spawn.ts +74 -61
  582. package/src/services/review-publish.ts +7 -24
  583. package/src/services/review-ref-reconcile.ts +29 -38
  584. package/src/services/runtime-dependency-alert.ts +27 -0
  585. package/src/services/scheduler-command.ts +11 -9
  586. package/src/services/scheduler.ts +5 -5
  587. package/src/services/self-care-state.ts +2 -1
  588. package/src/services/self-effort-grant.ts +5 -25
  589. package/src/services/self-effort.ts +5 -5
  590. package/src/services/send-message.ts +21 -34
  591. package/src/services/shutdown-agent.ts +17 -14
  592. package/src/services/spawn-agent.ts +25 -43
  593. package/src/services/spawn-chain-inspector.ts +7 -14
  594. package/src/services/spawn-cwd-placement.ts +21 -5
  595. package/src/services/spawn-issue-activity.ts +8 -6
  596. package/src/services/spawn-launch.ts +17 -1
  597. package/src/services/spawn-loss-escalation.ts +1 -1
  598. package/src/services/spawn-policy.ts +68 -0
  599. package/src/services/spawn-registration-watchdog.ts +2 -2
  600. package/src/services/spawn-repo-probe.ts +7 -5
  601. package/src/services/spawn-tree-cleanup.ts +8 -9
  602. package/src/services/steward-reaper.ts +4 -4
  603. package/src/services/task-context-hydration.ts +25 -1
  604. package/src/services/task-delivery.ts +20 -34
  605. package/src/services/task-dispatch.ts +3 -0
  606. package/src/services/task-entity.ts +40 -203
  607. package/src/services/task-issue-link.ts +13 -20
  608. package/src/services/task-issue-weave.ts +12 -11
  609. package/src/services/task-lifecycle.ts +27 -31
  610. package/src/services/task-repo-cwd.ts +37 -0
  611. package/src/services/task-review-hold.ts +4 -17
  612. package/src/services/task-semantic-events.ts +13 -11
  613. package/src/services/task-state-reconcile.ts +8 -17
  614. package/src/services/task-validation.ts +2 -2
  615. package/src/services/team-templates.ts +12 -11
  616. package/src/services/team.ts +31 -98
  617. package/src/services/terminal-provider-exit.ts +6 -5
  618. package/src/services/timer-message-fire-chaos-worker.ts +7 -3
  619. package/src/services/timer-message-fire-outbox.ts +1 -1
  620. package/src/services/transient-agent-reaper.ts +25 -20
  621. package/src/services/turn-reconcile-audit.ts +9 -9
  622. package/src/services/user-onboarding.ts +8 -6
  623. package/src/services/user-profile.ts +6 -9
  624. package/src/services/work-finality.ts +16 -4
  625. package/src/services/workflow-auto-start.ts +26 -13
  626. package/src/services/workflow-caller.ts +61 -4
  627. package/src/services/workflow-child-proof-worker.ts +1 -1
  628. package/src/services/workflow-ci-main.ts +1 -1
  629. package/src/services/workflow-control-proof-worker.ts +1 -1
  630. package/src/services/workflow-coordinator.ts +8 -2
  631. package/src/services/workflow-decisions.ts +5 -5
  632. package/src/services/workflow-deferred-cleanup.ts +5 -3
  633. package/src/services/workflow-effect-driver.ts +42 -17
  634. package/src/services/workflow-effects.ts +58 -37
  635. package/src/services/workflow-land-notice.ts +10 -0
  636. package/src/services/workflow-pause-text.ts +43 -0
  637. package/src/services/workflow-pins.ts +7 -4
  638. package/src/services/workflow-reconcile.ts +14 -11
  639. package/src/services/workflow-resume-pins.ts +3 -3
  640. package/src/services/workflow-routing-defaults.ts +18 -0
  641. package/src/services/workflow-run-view.ts +6 -3
  642. package/src/services/workflow-run.test-fixture.ts +1 -1
  643. package/src/services/workflow-runs.ts +61 -33
  644. package/src/services/workflow-supervisor-state.ts +26 -1
  645. package/src/services/workflow-supervisor.ts +11 -6
  646. package/src/services/workspace-recovery.ts +4 -3
  647. package/src/settings/registry.ts +1 -2
  648. package/src/spawn-admission.ts +10 -2
  649. package/src/spawn-command.ts +4 -4
  650. package/src/spawn-models.ts +10 -12
  651. package/src/spawn-placement.ts +28 -10
  652. package/src/spawn-targets.ts +9 -9
  653. package/src/sse-agent-status.ts +15 -6
  654. package/src/sse.ts +49 -24
  655. package/src/startup-context-injection.ts +62 -57
  656. package/src/state-adoption/cd-cutover.ts +53 -7
  657. package/src/state-adoption/fleet-cutover.ts +35 -0
  658. package/src/state-adoption/fleet-plan.ts +36 -0
  659. package/src/state-adoption/index.ts +2 -2
  660. package/src/state-adoption/linux-plan.ts +2 -2
  661. package/src/state-adoption/linux.ts +2 -2
  662. package/src/state-adoption/macos-plan.ts +2 -2
  663. package/src/state-adoption/macos.ts +1 -1
  664. package/src/steward-handoff.ts +4 -3
  665. package/src/steward-policy-cleanup.ts +9 -8
  666. package/src/steward.ts +9 -8
  667. package/src/task-dispatch-live.ts +6 -3
  668. package/src/task-dispatcher.ts +3 -3
  669. package/src/teams-config-store.ts +4 -3
  670. package/src/token-db-write.ts +10 -0
  671. package/src/token-db.ts +2 -2
  672. package/src/token-usage-async.ts +2 -4
  673. package/src/user-awaiting-reply.ts +5 -5
  674. package/src/workspace-actions.ts +24 -29
  675. package/src/workspace-auto-merge.ts +14 -12
  676. package/src/workspace-changed-paths-client.ts +16 -5
  677. package/src/workspace-cleanup-stale.ts +30 -7
  678. package/src/workspace-command-settle.ts +26 -17
  679. package/src/workspace-config.ts +1 -1
  680. package/src/workspace-conflict-resolver.ts +9 -7
  681. package/src/workspace-dead-owner-recovery.ts +5 -4
  682. package/src/workspace-escalation.ts +12 -11
  683. package/src/workspace-human-escalation.ts +3 -3
  684. package/src/workspace-land-gate-watchdog.ts +3 -3
  685. package/src/workspace-land-refusal.ts +20 -0
  686. package/src/workspace-land-stopped.ts +1 -0
  687. package/src/workspace-merge.ts +10 -26
  688. package/src/workspace-nothing-to-land-notice.ts +2 -2
  689. package/src/workspace-orphans.ts +18 -37
  690. package/src/workspace-pr-completion.ts +10 -8
  691. package/src/workspace-rekey.ts +3 -3
  692. package/src/workspace-steward-failure.ts +2 -2
  693. package/src/workspace-steward-wake.ts +4 -4
  694. package/node_modules/@humwick/kernel/LICENSE +0 -167
  695. package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
  696. package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
  697. package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
  698. package/node_modules/@humwick/kernel/config.ts +0 -111
  699. package/node_modules/@humwick/kernel/contract.ts +0 -572
  700. package/node_modules/@humwick/kernel/control-authz.ts +0 -281
  701. package/node_modules/@humwick/kernel/control.ts +0 -645
  702. package/node_modules/@humwick/kernel/effects.ts +0 -493
  703. package/node_modules/@humwick/kernel/event-log.ts +0 -319
  704. package/node_modules/@humwick/kernel/http-transport.ts +0 -384
  705. package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
  706. package/node_modules/@humwick/kernel/identity.ts +0 -248
  707. package/node_modules/@humwick/kernel/index.ts +0 -28
  708. package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
  709. package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
  710. package/node_modules/@humwick/kernel/landing.ts +0 -953
  711. package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
  712. package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
  713. package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
  714. package/node_modules/@humwick/kernel/message-authority.ts +0 -281
  715. package/node_modules/@humwick/kernel/module-host.ts +0 -722
  716. package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
  717. package/node_modules/@humwick/kernel/package.json +0 -39
  718. package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
  719. package/node_modules/@humwick/kernel/persistence.ts +0 -510
  720. package/node_modules/@humwick/kernel/registry.ts +0 -60
  721. package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
  722. package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
  723. package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
  724. package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
  725. package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
  726. package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
  727. package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
  728. package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
  729. package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
  730. package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
  731. package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
  732. package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
  733. package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
  734. package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
  735. package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
  736. package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
  737. package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
  738. package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
  739. package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
  740. package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
  741. package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
  742. package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
  743. package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
  744. package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
  745. package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
  746. package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
  747. package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
  748. package/node_modules/@humwick/offload/LICENSE +0 -167
  749. package/node_modules/@humwick/offload/README.md +0 -57
  750. package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
  751. package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
  752. package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
  753. package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
  754. package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
  755. package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
  756. package/node_modules/@humwick/offload/dist/envelope.js +0 -80
  757. package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
  758. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
  759. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
  760. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
  761. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
  762. package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
  763. package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
  764. package/node_modules/@humwick/offload/dist/index.js +0 -5
  765. package/node_modules/@humwick/offload/dist/index.js.map +0 -1
  766. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
  767. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
  768. package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
  769. package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
  770. package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
  771. package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
  772. package/node_modules/@humwick/offload/dist/types.js +0 -176
  773. package/node_modules/@humwick/offload/dist/types.js.map +0 -1
  774. package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
  775. package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
  776. package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
  777. package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
  778. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
  779. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
  780. package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
  781. package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
  782. package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
  783. package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
  784. package/node_modules/@humwick/offload/dist/worker.js +0 -1
  785. package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
  786. package/node_modules/@humwick/offload/package.json +0 -42
  787. package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
  788. package/node_modules/@humwick/offload/src/envelope.ts +0 -92
  789. package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
  790. package/node_modules/@humwick/offload/src/index.ts +0 -4
  791. package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
  792. package/node_modules/@humwick/offload/src/types.ts +0 -235
  793. package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
  794. package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
  795. package/node_modules/@humwick/offload/src/worker.ts +0 -5
  796. package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
  797. package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
  798. package/public/assets/index-B7ZerHLY.css +0 -2
  799. package/public/assets/index-BU3uWo2t.js +0 -15
  800. package/public/assets/projects-B_lmcqfO.js +0 -2
  801. package/public/assets/provider-display-DbLWpP3j.js +0 -2
  802. package/public/assets/run-card-CO_bguQf.js +0 -2
  803. package/public/assets/shipping-Bu8p1gEw.js +0 -2
  804. package/public/assets/store-BvtFdlGX.js +0 -9
  805. package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
  806. package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
  807. package/runner/src/agent-runner/http-liveness.ts +0 -85
  808. package/runner/src/gate-run-lease-probe.ts +0 -38
  809. package/src/db/claude-catalog-reconcile.ts +0 -27
  810. package/src/db/on-loop-write-transaction.ts +0 -34
  811. package/src/routing-model-aliases.ts +0 -21
@@ -1,7 +1,10 @@
1
+ import { getGateway } from "../db/gateway";
2
+ import type { observeEffortBody } from "../db/agent-effort-observe";
3
+ import { sendMessageAsync } from "../db/message-send";
1
4
  import type { AgentEffortState } from "@humwick/sdk";
2
5
  import { getCommand } from "../commands-db";
3
6
  import { emitCommandEvent } from "../command-events";
4
- import { findMessageByIdempotencyKey, sendMessage, validateAgentSession, writeTransaction } from "../db";
7
+ import { findMessageByIdempotencyKey, validateAgentSession, writeTransaction } from "../db";
5
8
  import { EffortReportRejected, recordEffortObservedInternal, type EffortObservation } from "../db/agent-effort-state";
6
9
  import { emitRelayEvent } from "../events";
7
10
  import { emitNewMessage } from "../sse";
@@ -9,47 +12,19 @@ import type { Command, Message } from "../types";
9
12
 
10
13
  export { EffortReportRejected };
11
14
 
12
- /** #2984 — the prompt that resumes an agent once its own effort change applied. */
13
- export function selfEffortContinuation(effort: string): string {
14
- return `Effort is now ${effort}. Continue your work.`;
15
- }
16
-
17
15
  /** Dashboard + runner notice: the agent's desired/observed effort changed. */
18
16
  export function emitEffortState(state: AgentEffortState): void {
19
17
  emitRelayEvent({ type: "agent.effort", source: "server", subject: state.agentId, data: state as unknown as Record<string, unknown> });
20
18
  }
21
19
 
22
- /** One continuation per owed resume (keyed by the self request's version): a repeated report finds the first. */
23
- function enqueueSelfContinuation(agentId: string, version: number, effort: string): Message | undefined {
24
- const idempotencyKey = `effort-continuation:${agentId}:${version}`;
25
- if (findMessageByIdempotencyKey("system", idempotencyKey)) return undefined;
26
- return sendMessage({
27
- from: "system",
28
- to: agentId,
29
- kind: "system",
30
- subject: "Effort changed",
31
- body: selfEffortContinuation(effort),
32
- replyExpected: false,
33
- idempotencyKey,
34
- payload: { kind: "agent.effort_continuation", agentId, effortVersion: version, effort },
35
- });
36
- }
37
-
38
20
  export interface EffortReport { instanceId: string; version: number; effort: string; previousEffort: string | null }
39
21
 
40
- export class EffortReportFenced extends Error {}
22
+ export { EffortReportFenced, selfEffortContinuation } from "../db/agent-effort-observe";
41
23
 
42
24
  /** A runner applied (or verified) a desired version. Fenced to the agent's current incarnation; the
43
25
  * observation and the resume it settles are one transaction. */
44
- export function reportEffortObserved(agentId: string, report: EffortReport, now = Date.now()): EffortObservation {
45
- let continuation: Message | undefined;
46
- const observed = writeTransaction(() => {
47
- const session = validateAgentSession(agentId, { instanceId: report.instanceId });
48
- if (!session.ok) throw new EffortReportFenced(session.error ?? "stale agent instance");
49
- const result = recordEffortObservedInternal({ agentId, ...report, now });
50
- if (result.outcome !== "stale" && result.resumeVersion !== undefined) continuation = enqueueSelfContinuation(agentId, result.resumeVersion, report.effort);
51
- return result;
52
- });
26
+ export async function reportEffortObserved(agentId: string, report: EffortReport, now = Date.now()): Promise<EffortObservation> {
27
+ const { observed, continuation } = await getGateway().write("agents.observeEffort", { agentId, ...report, now }) as unknown as ReturnType<typeof observeEffortBody>;
53
28
  if (observed.outcome === "applied") {
54
29
  const command: Command | null = observed.commandId ? getCommand(observed.commandId) : null;
55
30
  if (command) emitCommandEvent(command, "command.succeeded");
@@ -386,7 +386,7 @@ async function deliverSelfCheck(agent: AgentCard, decision: AgentHangDecision, c
386
386
  },
387
387
  });
388
388
 
389
- const messages = routeNotification({
389
+ const messages = await routeNotification({
390
390
  type: "agent.self_check",
391
391
  scope: { agentId: agent.id, parent: agent.spawnedBy, teamId: agent.teamId },
392
392
  // Explicit, though the registered `subject-agent` rule resolves the same single recipient: the
@@ -457,7 +457,7 @@ async function escalate(
457
457
 
458
458
  // Reuse the `agent.stuck_busy` notice shape (type, spawn-parent audience, `payload.kind`) so every
459
459
  // existing coordinator-side consumer renders it with no new case to handle.
460
- const messages = routeNotification({
460
+ const messages = await routeNotification({
461
461
  type: "agent.stuck_busy",
462
462
  scope: { agentId: agent.id, parent: agent.spawnedBy, teamId: agent.teamId },
463
463
  message: {
@@ -0,0 +1,166 @@
1
+ // The agent liveness exchange (#3606/#3608/#3618): one service behind POST /api/agents/:id/heartbeat
2
+ // and the bus `agent.heartbeat` command frame, so both transports apply status, readiness, the
3
+ // unread inbox and the quota piggyback identically. Transports parse and authorize at their edge.
4
+ import { isRecord, type HeartbeatResult, type ProviderQuotaUpdateInput } from "@humwick/sdk";
5
+ import { ValidationError, getAgent, markReadyAsync, recordHeartbeatAsync, setStatusAsync, validateAgentSession } from "../db";
6
+ import { isAgentUnavailable } from "../db/agent-predicates";
7
+ import type { ViewerScope } from "../db/viewer-scope";
8
+ import { emitAgentStatus } from "../agent-status-events";
9
+ import { VALID_AGENT_STATUSES, agentSessionStatus, auditEvent } from "../routes/_shared";
10
+ import { pollAgentMessages } from "../routes/messages";
11
+ import { cleanProviderQuotaUpdate } from "../routes/provider-quotas";
12
+ import { publishHeartbeatQuota } from "../routes/agent-heartbeat-quota";
13
+ import { announceSpawnedAgentReady } from "./register-agent";
14
+ import { flushQueuedDirectMessages } from "./managed-running";
15
+ import { acquireTeamOnReady } from "./team";
16
+ import { isComponentAuthorizedFor } from "../security";
17
+ import type { AgentCard, AgentSessionGuard, ComponentToken } from "../types";
18
+
19
+ type AgentStatusValue = (typeof VALID_AGENT_STATUSES)[number];
20
+
21
+ export interface AgentHeartbeatReport {
22
+ status?: AgentStatusValue;
23
+ ready?: boolean;
24
+ unread?: boolean;
25
+ providerQuota?: ProviderQuotaUpdateInput;
26
+ quotaLeaseToken?: string;
27
+ }
28
+
29
+ export type AgentHeartbeatOutcome = { ok: true; result: HeartbeatResult } | { ok: false; error: string; status: number };
30
+
31
+ type AgentActivityState = {
32
+ key: "available" | "busy" | "not-ready" | "offline";
33
+ title: string;
34
+ icon: string;
35
+ };
36
+
37
+ function agentActivityState(agent?: Pick<AgentCard, "ready" | "status"> | null): AgentActivityState | null {
38
+ if (!agent) return null;
39
+ if (agent.status === "offline") return { key: "offline", title: "Agent offline", icon: "ti-plug-off" };
40
+ if (!agent.ready) return { key: "not-ready", title: "Agent not ready", icon: "ti-loader" };
41
+ if (agent.status === "busy") return { key: "busy", title: "Agent busy", icon: "ti-activity" };
42
+ return { key: "available", title: "Agent available", icon: "ti-circle-check" };
43
+ }
44
+
45
+ async function auditAgentStateTransition(agentId: string, before: AgentCard | null | undefined, after: AgentCard | null | undefined): Promise<void> {
46
+ const previous = agentActivityState(before);
47
+ const next = agentActivityState(after);
48
+ if (!next || previous?.key === next.key) return;
49
+ await auditEvent({
50
+ clientId: "server-agent-" + agentId + "-state-" + next.key + "-" + Date.now(),
51
+ kind: "state",
52
+ title: next.title,
53
+ meta: agentId,
54
+ icon: next.icon,
55
+ view: "agents",
56
+ agentId,
57
+ });
58
+ }
59
+
60
+ export function cleanAgentStatus(value: unknown): AgentStatusValue {
61
+ if (!VALID_AGENT_STATUSES.includes(value as AgentStatusValue)) throw new ValidationError(`status must be one of: ${VALID_AGENT_STATUSES.join(", ")}`);
62
+ return value as AgentStatusValue;
63
+ }
64
+
65
+ /** Validates a wire heartbeat body; throws ValidationError. `sourceAgentId` is always the reporting agent. */
66
+ export function cleanHeartbeatReport(agentId: string, body: unknown): AgentHeartbeatReport {
67
+ const raw = isRecord(body) ? body : {};
68
+ if (raw.ready !== undefined && typeof raw.ready !== "boolean") throw new ValidationError("ready must be a boolean");
69
+ if (raw.unread !== undefined && typeof raw.unread !== "boolean") throw new ValidationError("unread must be a boolean");
70
+ const quota = raw.providerQuota === undefined ? undefined : cleanProviderQuotaUpdate(raw.providerQuota);
71
+ if (typeof quota === "string") throw new ValidationError(quota);
72
+ if (quota) quota.sourceAgentId = agentId;
73
+ return {
74
+ ...(raw.status === undefined ? {} : { status: cleanAgentStatus(raw.status) }),
75
+ ...(raw.ready === undefined ? {} : { ready: raw.ready }),
76
+ ...(raw.unread ? { unread: true } : {}),
77
+ ...(quota ? { providerQuota: quota } : {}),
78
+ ...(typeof raw.quotaLeaseToken === "string" ? { quotaLeaseToken: raw.quotaLeaseToken } : {}),
79
+ };
80
+ }
81
+
82
+ // #3606 — a reported status/readiness equal to the live card is a liveness tick, not a transition: no
83
+ // row write, no agent.status event. Presence still advances through the coalescing heartbeat buffer,
84
+ // except for a terminal row, which a beat would resurrect.
85
+ export async function noteUnchangedLifecycle(agentId: string, current: AgentCard, guard: AgentSessionGuard | undefined): Promise<void> {
86
+ if (current.status !== "offline" && current.status !== "stale") await recordHeartbeatAsync(agentId, { guard });
87
+ }
88
+
89
+ export async function applyAgentStatus(agentId: string, status: AgentStatusValue, guard: AgentSessionGuard | undefined, before: AgentCard | null): Promise<boolean> {
90
+ // #1895 (S3.2 L10, review finding 3) — routed through the async gateway facade.
91
+ if (!(await setStatusAsync(agentId, status, guard))) return false;
92
+ await auditAgentStateTransition(agentId, before, getAgent(agentId));
93
+ await emitAgentStatus(agentId);
94
+ return true;
95
+ }
96
+
97
+ export async function applyAgentReady(agentId: string, ready: boolean, guard: AgentSessionGuard | undefined, before: AgentCard | null): Promise<boolean> {
98
+ // #1895 (S3.2 L10, review finding 3) — routed through the async gateway facade.
99
+ if (!(await markReadyAsync(agentId, ready, guard))) return false;
100
+ await auditAgentStateTransition(agentId, before, getAgent(agentId));
101
+ // #308/#2432 — a spawned child's false→true ready wakes its parent (announceSpawnedAgentReady dedups).
102
+ // #1927 — the awaited audit lets a same-instance PATCH flip ready back first, so re-read the live
103
+ // card and session guard before firing, never the pre-audit snapshot.
104
+ if (ready && !before?.ready) {
105
+ const live = getAgent(agentId);
106
+ const stillCurrentInstance = validateAgentSession(agentId, guard).ok;
107
+ if (live?.ready === true && stillCurrentInstance) {
108
+ await announceSpawnedAgentReady(agentId, "agent-ready");
109
+ (await acquireTeamOnReady(agentId)); // #3107 — before the flush, so seat mail reaches a new holder
110
+ // #416 — also flush queued direct messages: a not-ready agent that becomes ready
111
+ // may have queued messages waiting (e.g. starting up, clearing context).
112
+ (await flushQueuedDirectMessages(agentId));
113
+ }
114
+ }
115
+ await emitAgentStatus(agentId);
116
+ return true;
117
+ }
118
+
119
+ /** One liveness tick. Only a value that differs from the live card takes the transition path; the rest is a coalesced beat. */
120
+ export async function applyAgentHeartbeat(agentId: string, report: AgentHeartbeatReport, guard: AgentSessionGuard | undefined, viewer: ViewerScope | null): Promise<AgentHeartbeatOutcome> {
121
+ const session = validateAgentSession(agentId, guard);
122
+ if (!session.ok) return { ok: false, error: session.error!, status: agentSessionStatus(session.error) };
123
+ // #416 — capture unavailability before heartbeat to detect the transition.
124
+ const beforeHeartbeat = getAgent(agentId);
125
+ if (beforeHeartbeat?.kind === "channel" && !beforeHeartbeat.ready) return { ok: false, error: "channel agent not ready; re-register required", status: 409 };
126
+ const notFound = { ok: false, error: "agent not found", status: 404 } as const;
127
+ const wasUnavailable = beforeHeartbeat ? isAgentUnavailable(beforeHeartbeat) : false;
128
+ let current = beforeHeartbeat;
129
+ const { status, ready } = report;
130
+ if (status !== undefined && status !== current?.status) {
131
+ if (!(await applyAgentStatus(agentId, status, guard, current))) return notFound;
132
+ current = getAgent(agentId);
133
+ }
134
+ if (ready !== undefined && ready !== current?.ready) {
135
+ if (!(await applyAgentReady(agentId, ready, guard, current))) return notFound;
136
+ }
137
+ // A reported terminal status must not be undone by the beat's offline/stale resurrection.
138
+ if (status !== "offline" && status !== "stale") {
139
+ // #1468 — route the API heartbeat through the same coalescing buffer as the bus path.
140
+ if (!(await recordHeartbeatAsync(agentId, { guard }))) return notFound;
141
+ }
142
+ if (wasUnavailable) {
143
+ const after = getAgent(agentId);
144
+ if (after && !isAgentUnavailable(after)) (await flushQueuedDirectMessages(agentId));
145
+ }
146
+ const result: HeartbeatResult = { ok: true };
147
+ if (report.unread) result.messages = await pollAgentMessages(viewer, { for: agentId, unread: true, limit: 100, turnDelivery: true });
148
+ if (report.providerQuota) {
149
+ try { result.providerQuota = await publishHeartbeatQuota(report.providerQuota, report.quotaLeaseToken); }
150
+ catch (error) { console.warn(`heartbeat quota publish failed for ${agentId}:`, error); }
151
+ }
152
+ return { ok: true, result };
153
+ }
154
+
155
+ /** #3618 — the bus `agent.heartbeat` frame. A socket reports only for the agent it registered as,
156
+ * under that registration's session guard and the scopes its upgrade credential carries. */
157
+ export async function heartbeatFromBus(conn: { agentId?: string; instanceId: string; epoch: number; componentAuth?: ComponentToken }, target: string, params: Record<string, unknown>): Promise<{ status: "succeeded" | "failed" | "rejected"; result?: Record<string, unknown>; error?: string }> {
158
+ if (!conn.agentId || target !== conn.agentId) return { status: "rejected", error: "agent.heartbeat reports only for the registered agent" };
159
+ let report: AgentHeartbeatReport;
160
+ try { report = cleanHeartbeatReport(conn.agentId, params); }
161
+ catch (error) { if (error instanceof ValidationError) return { status: "failed", error: error.message }; throw error; }
162
+ const denied = (scope: string) => conn.componentAuth && !isComponentAuthorizedFor(conn.componentAuth, { scope, resource: { agentId: conn.agentId, target: conn.agentId } });
163
+ if ((report.unread && denied("message:read")) || (report.providerQuota && denied("quota:write"))) return { status: "rejected", error: "component token lacks heartbeat scope" };
164
+ const outcome = await applyAgentHeartbeat(conn.agentId, report, { instanceId: conn.instanceId, epoch: conn.epoch }, null);
165
+ return outcome.ok ? { status: "succeeded", result: outcome.result as unknown as Record<string, unknown> } : { status: "failed", error: outcome.error };
166
+ }
@@ -10,7 +10,7 @@ export async function setAgentReportVerbosity(input: {
10
10
  requestedVia: "http" | "mcp";
11
11
  reason?: string;
12
12
  }, ctx: AuthContext): Promise<{ action: "reportVerbosity"; reportVerbosity: ReportVerbosity }> {
13
- authorizeShutdown(ctx, { agentId: input.agentId, requestedVia: input.requestedVia });
13
+ (await authorizeShutdown(ctx, { agentId: input.agentId, requestedVia: input.requestedVia }));
14
14
  const agent = getAgent(input.agentId);
15
15
  if (!agent) throw new ShutdownTargetError("agent not found");
16
16
  if (!isReportVerbosity(input.reportVerbosity)) throw new ValidationError("reportVerbosity must be off, quiet, normal or verbose");
@@ -34,7 +34,7 @@ export async function reconcileBrowserInventory(orchestratorId: string, inventor
34
34
  const live = new Set(inventory.liveSessionIds);
35
35
  const closed = new Set(inventory.closedSessionIds);
36
36
  for (const row of listBrowserSessionRows({ orchestratorId, activeOnly: true, limit: 1000 })) {
37
- if (getAgent(row.agentId)?.status === "offline") reapAgentBrowserSessions(row.agentId);
37
+ if (getAgent(row.agentId)?.status === "offline") (await reapAgentBrowserSessions(row.agentId));
38
38
  const idleMs = inventory.idleMs?.[row.id];
39
39
  if (idleMs !== undefined) noteBrowserActivity(row, idleMs, Date.now());
40
40
  if (live.has(row.id) || (!registration && !closed.has(row.id))) continue;
@@ -44,9 +44,9 @@ export async function reconcileBrowserInventory(orchestratorId: string, inventor
44
44
  if (command?.status === "pending") continue;
45
45
  }
46
46
  const now = Date.now();
47
- transitionAndEmit(row.id, [row.status], {
47
+ (await transitionAndEmit(row.id, [row.status], {
48
48
  status: row.status === "stopping" || closed.has(row.id) ? "stopped" : "failed", stoppedAt: now,
49
49
  error: registration ? "browser absent from orchestrator registration" : "browser process ended on host",
50
- }, now);
50
+ }, now));
51
51
  }
52
52
  }
@@ -1,3 +1,4 @@
1
+ import { getGateway } from "../db/gateway";
1
2
  // #3489 H4 — the one write path for browser session rows after insert: every change is pushed as
2
3
  // `browser.session.<status>`, so the dashboard follows starts, stops, idle expiry and crashes without polling.
3
4
  import type { BrowserSession, BrowserSessionStatus } from "@humwick/sdk";
@@ -26,8 +27,8 @@ export function emitBrowserSession(row: BrowserSessionRow): void {
26
27
  }
27
28
 
28
29
  /** Applies a guarded transition and announces it; undefined when the row already left `from`. */
29
- export function transitionAndEmit(id: string, from: readonly BrowserSessionStatus[], patch: BrowserSessionPatch, now: number): BrowserSessionRow | undefined {
30
- const row = transitionBrowserSession(id, from, patch, now);
30
+ export async function transitionAndEmit(id: string, from: readonly BrowserSessionStatus[], patch: BrowserSessionPatch, now: number): Promise<BrowserSessionRow | undefined> {
31
+ const row = await getGateway().write("browser.transition", [id, from, patch, now]) as unknown as BrowserSessionRow | undefined;
31
32
  if (!row) return undefined;
32
33
  if (row.status === "running") lastActivity.set(row.id, lastActivity.get(row.id) ?? now);
33
34
  else if (row.status === "stopped" || row.status === "failed") lastActivity.delete(row.id);
@@ -1,3 +1,5 @@
1
+ import { getGateway } from "../db/gateway";
2
+ import type { startBrowserBody, stopBrowserBody } from "../db/browser-session-write";
1
3
  // #3489 — Relay-managed browser sessions. The server owns identity, limits and lifecycle state; the agent's own
2
4
  // orchestrator owns the Chromium process and executes `browser.start` / `browser.stop` from the command bus.
3
5
  // Command results are folded into the row as they arrive (and again on read, which also settles a missed event).
@@ -6,14 +8,14 @@ import { isRecord, stringValue, type BrowserLimits, type BrowserSession } from "
6
8
  import { getBrowserLimits } from "../browser-config";
7
9
  import { canAccessBrowserSession, type BrowserCaller } from "../browser-authz";
8
10
  import { emitCommandEvent } from "../command-events";
9
- import { createCommandInternal } from "../commands-db";
11
+
10
12
  import { subscribeRelayEvents } from "../events";
11
13
  import type { Command } from "../types";
12
14
  import { getCommandAsync } from "../commands-write";
13
15
  import { getAgentProfile } from "../config-store";
14
16
  import { getAgent, getOrchestrator } from "../db";
15
17
  import {
16
- countActiveBrowserSessions, getBrowserSessionRow, insertBrowserSession, listBrowserSessionRows, type BrowserSessionRow,
18
+ getBrowserSessionRow, listBrowserSessionRows, type BrowserSessionRow,
17
19
  } from "../db/browser-sessions";
18
20
  import { getLaunchFact } from "../db/launch-facts";
19
21
  import { generationLaunchParams } from "../db/generation-launch";
@@ -67,17 +69,13 @@ export async function startBrowserSession(caller: BrowserCaller, input: { agentI
67
69
  const limits = getBrowserLimits();
68
70
  // Settle finished stops first, so a reaped session stops counting against the limits.
69
71
  for (const row of [...listBrowserSessionRows({ agentId, activeOnly: true, limit: 100 }), ...listBrowserSessionRows({ orchestratorId: host.id, activeOnly: true, limit: 100 })]) await reconcile(row);
70
- // Count and insert run in one synchronous stretch, so two concurrent starts cannot both pass the cap.
71
- if (countActiveBrowserSessions({ agentId }) >= limits.perAgent) {
72
- throw new BrowserSessionError(`agent ${agentId} already has ${limits.perAgent} browser session(s) (limit from settings browser/default)`, 409);
73
- }
74
- if (countActiveBrowserSessions({ orchestratorId: host.id }) >= limits.perHost) {
75
- throw new BrowserSessionError(`host ${host.id} already runs ${limits.perHost} browser session(s) (limit from settings browser/default)`, 409);
76
- }
77
72
  const id = randomUUID();
78
- const command = createCommandInternal({ id: randomUUID(), input: { type: "browser.start", source: agentId, target: host.agentId, correlationId: id,
79
- params: { sessionId: id, agentId, orchestratorId: host.id, idleTimeoutMs: limits.idleTimeoutMinutes * 60_000, hostSessionLimit: limits.perHost } } });
80
- emitBrowserSession(insertBrowserSession({ id, agentId, orchestratorId: host.id, startCommandId: command.id, now: Date.now() }));
73
+ const result = await getGateway().write("browser.start", { id, commandId: randomUUID(), agentId, instanceId: agent.instanceId, epoch: agent.epoch, orchestratorId: host.id, limits }, { idempotencyKey: id }) as unknown as ReturnType<typeof startBrowserBody>;
74
+ if (result.conflict === "agentLimit") throw new BrowserSessionError(`agent ${agentId} already has ${limits.perAgent} browser session(s) (limit from settings browser/default)`, 409);
75
+ if (result.conflict === "hostLimit") throw new BrowserSessionError(`host ${host.id} already runs ${limits.perHost} browser session(s) (limit from settings browser/default)`, 409);
76
+ if (result.conflict) throw new BrowserSessionError("browser session target changed during admission", 409);
77
+ const { command, row } = result;
78
+ emitBrowserSession(row);
81
79
  emitCommandEvent(command, "command.requested");
82
80
  return { session: publicView(await settle(id, signal)), limits };
83
81
  }
@@ -92,16 +90,16 @@ async function reconcile(row: BrowserSessionRow): Promise<BrowserSessionRow> {
92
90
  const patch = command.status === "succeeded"
93
91
  ? { status: "running" as const, cdpUrl: stringValue(result.cdpUrl), pid: typeof result.pid === "number" ? result.pid : undefined, profileDir: stringValue(result.profileDir) }
94
92
  : { status: "failed" as const, error: command.error ?? `browser.start ${command.status}`, stoppedAt: now };
95
- return transitionAndEmit(row.id, ["starting"], patch, now) ?? getBrowserSessionRow(row.id)!;
93
+ return (await transitionAndEmit(row.id, ["starting"], patch, now)) ?? getBrowserSessionRow(row.id)!;
96
94
  }
97
95
  if (row.status === "stopping" && row.stopCommandId) {
98
96
  const command = await getCommandAsync(row.stopCommandId);
99
97
  if (!command || !isTerminalCommandStatus(command.status)) {
100
98
  if (now - row.updatedAt < SETTLE_TIMEOUT_MS) return row;
101
- return transitionAndEmit(row.id, ["stopping"], { status: "failed", stoppedAt: now, error: "browser stop did not settle" }, now) ?? row;
99
+ return (await transitionAndEmit(row.id, ["stopping"], { status: "failed", stoppedAt: now, error: "browser stop did not settle" }, now)) ?? row;
102
100
  }
103
101
  const error = command.status === "succeeded" ? undefined : command.error ?? `browser.stop ${command.status}`;
104
- return transitionAndEmit(row.id, ["stopping"], { status: "stopped", stoppedAt: now, ...(error ? { error } : {}) }, now) ?? getBrowserSessionRow(row.id)!;
102
+ return (await transitionAndEmit(row.id, ["stopping"], { status: "stopped", stoppedAt: now, ...(error ? { error } : {}) }, now)) ?? getBrowserSessionRow(row.id)!;
105
103
  }
106
104
  return row;
107
105
  }
@@ -133,27 +131,23 @@ export async function listBrowserSessions(caller: BrowserCaller, filter: { agent
133
131
  }
134
132
 
135
133
  /** Issue `browser.stop`; idempotent for a session that is already stopping or over. */
136
- function requestStop(row: BrowserSessionRow, reason: string): BrowserSessionRow {
134
+ async function requestStop(row: BrowserSessionRow, reason: string): Promise<BrowserSessionRow> {
137
135
  if (row.status !== "starting" && row.status !== "running") return row;
138
- const host = getOrchestrator(row.orchestratorId);
139
- const now = Date.now();
140
- if (!host) return transitionAndEmit(row.id, ["starting", "running"], { status: "stopped", stoppedAt: now, error: "orchestrator no longer registered" }, now) ?? row;
141
- const command = createCommandInternal({ id: randomUUID(), input: { type: "browser.stop", source: "system", target: host.agentId, correlationId: row.id,
142
- params: { sessionId: row.id, agentId: row.agentId, orchestratorId: host.id, reason } } });
143
- const stopping = transitionAndEmit(row.id, ["starting", "running"], { status: "stopping", stopCommandId: command.id }, now);
144
- emitCommandEvent(command, "command.requested");
145
- return stopping ?? getBrowserSessionRow(row.id)!;
136
+ const result = await getGateway().write("browser.stop", { id: row.id, reason, commandId: randomUUID() }, { idempotencyKey: row.id }) as unknown as ReturnType<typeof stopBrowserBody>;
137
+ if (result.row) emitBrowserSession(result.row);
138
+ if (result.command) emitCommandEvent(result.command, "command.requested");
139
+ return result.row ?? row;
146
140
  }
147
141
 
148
142
  export async function stopBrowserSession(caller: BrowserCaller, id: string, signal?: AbortSignal): Promise<BrowserSession> {
149
- const row = requestStop(await reconcile(accessible(caller, id)), "requested");
143
+ const row = await requestStop(await reconcile(accessible(caller, id)), "requested");
150
144
  return publicView(row.status === "stopping" ? await settle(id, signal) : row);
151
145
  }
152
146
 
153
147
  /** Agent exit: every live session of the agent is stopped with it. Synchronous; the commands settle later. */
154
- export function reapAgentBrowserSessions(agentId: string): number {
148
+ export async function reapAgentBrowserSessions(agentId: string): Promise<number> {
155
149
  const live = listBrowserSessionRows({ agentId, activeOnly: true, limit: 100 }).filter((row) => row.status !== "stopping");
156
- for (const row of live) requestStop(row, "agent-exit");
150
+ for (const row of live) await requestStop(row, "agent-exit");
157
151
  return live.length;
158
152
  }
159
153
 
@@ -51,23 +51,23 @@ export async function updateCommandFromBus(input: {
51
51
  await settleScheduledCommandTimer(updated);
52
52
  }
53
53
  emitCommandEvent(updated, `command.${updated.status}`);
54
- settleSelfResumeContinuationIngestion(updated);
54
+ (await settleSelfResumeContinuationIngestion(updated));
55
55
  noteCompactionCommandCompleted(updated);
56
56
  // #2095 — durable "clear committed vs no-op" signal, fired on terminal compact/clear commands.
57
57
  noteCompactionResult(updated);
58
- enqueueContinuationInjectionAfterSelfResume(updated);
59
- enqueueLifecycleIdentityInjectionAfterContextCommand(updated);
60
- notifySelfResumeNoOp(updated);
61
- settleContextResetCarry(updated);
62
- settleSelfRestartManagedState(updated);
63
- settleInterruptRedirectMessage(updated);
58
+ (await enqueueContinuationInjectionAfterSelfResume(updated));
59
+ (await enqueueLifecycleIdentityInjectionAfterContextCommand(updated));
60
+ await notifySelfResumeNoOp(updated);
61
+ (await settleContextResetCarry(updated));
62
+ (await settleSelfRestartManagedState(updated));
63
+ (await settleInterruptRedirectMessage(updated));
64
64
  // #1565 P4b — memory rides BESIDE the continuation as its own payload (§7), delta-gated on
65
65
  // compact. Ordered LAST and contained (#1565 F8) — see the same call in routes/commands.ts.
66
- settleMemoryInjectionAfterContextCommand(updated);
66
+ (await settleMemoryInjectionAfterContextCommand(updated));
67
67
  // #1951 — the startup context (validation commands, report-up, profile charter, caller context)
68
68
  // rides beside them too, recomposed from the DB and delta-gated on compact. Contained the same
69
69
  // way: a compose throw here must not abort the settle chain.
70
- settleStartupContextInjectionAfterContextCommand(updated);
70
+ (await settleStartupContextInjectionAfterContextCommand(updated));
71
71
  }
72
72
  return { status: "succeeded", result: updated ? { command: updated } : undefined };
73
73
  }
@@ -6,6 +6,7 @@ export function checkoutRefreshHealth(row: CheckoutRefreshStatus, now = Date.now
6
6
  if (!row.result?.enabled) return undefined;
7
7
  if (["pending", "accepted", "running"].includes(row.status) && row.result.status === "waiting") return "waiting";
8
8
  if (row.result.reason) return "blocked";
9
+ if (row.status === "succeeded" && ["current", "refreshed"].includes(row.result.status)) return "healthy";
9
10
  return !row.result.successAt || now - row.result.successAt > 180_000 ? "stale" : "healthy";
10
11
  }
11
12
 
@@ -1,12 +1,13 @@
1
1
  import { createCommand, updateCommand } from "../commands-db";
2
2
 
3
3
  /** Record a host checkout's latest refresh receipt, as the executor reports a finished attempt. */
4
- export function recordRefreshReceipt(projectId: string, orchestratorId: string, rootPath: string, outcome: "hook-failed" | "current" | "behind" | "refreshing"): void {
4
+ export function recordRefreshReceipt(projectId: string, orchestratorId: string, rootPath: string, outcome: "hook-failed" | "current" | "behind" | "refreshing" | "busy"): void {
5
5
  const command = createCommand({ type: "project.checkout.refresh", source: "system", target: `orchestrator-${orchestratorId}`,
6
6
  params: { projectId, rootPath, orchestratorId, remoteUrl: "https://example.invalid/repo.git", enabled: true } });
7
- const dependency = { fingerprint: "inputs", attemptId: "attempt", status: outcome === "hook-failed" || outcome === "refreshing" ? "pending" : "current" };
7
+ const dependency = { fingerprint: "inputs", attemptId: "attempt", status: outcome === "hook-failed" || outcome === "refreshing" || outcome === "busy" ? "pending" : "current" };
8
8
  updateCommand(command.id, { status: outcome === "refreshing" ? "running" : "succeeded", result: { rootPath, enabled: true, attemptedAt: Date.now(), backups: [], headSha: "head", dependency,
9
9
  ...(outcome === "hook-failed" ? { status: "error", reason: "dependency hook failed: npm ci exited 1" }
10
+ : outcome === "busy" ? { status: "skipped", reason: "host gate admission busy; retry next refresh cycle" }
10
11
  : outcome === "behind" ? { status: "skipped", behind: 3, reason: "fetch failed" }
11
12
  : outcome === "refreshing" ? { status: "refreshing" } : { status: "current", successAt: Date.now() }) } });
12
13
  }
@@ -2,11 +2,14 @@ import { stringValue } from "@humwick/sdk";
2
2
  import type { Orchestrator } from "@humwick/sdk";
3
3
  import { getAgent, listOrchestrators, ValidationError } from "../db";
4
4
  import type { AuthContext } from "./auth-context";
5
+ import { listManagedOrchestratorsForAgent } from "../orchestrator-lookup";
5
6
  import { isPathWithinBase, sameHostIdentity } from "../utils";
6
7
 
7
8
  /** The orchestrator the caller agent is registered on, online or not: its stamped
8
- * `meta.orchestratorId`, else its `machine` matched by host identity (the runner's raw os.hostname()
9
- * differs in case/separators). */
9
+ * `meta.orchestratorId`, else the one host whose managed-agent roster runs it, else its `machine`
10
+ * matched by host identity (the runner's raw os.hostname() differs in case/separators). The roster
11
+ * covers unpinned system launches (stewards, managed policies) on a host whose OS hostname is not
12
+ * its orchestrator name, e.g. WSL "XPS15" on xps15-wsl (#3822). */
10
13
  function callerHost(ctx: AuthContext, hosts: Orchestrator[]): Orchestrator | undefined {
11
14
  const agent = ctx.callerAgentId ? getAgent(ctx.callerAgentId) : undefined;
12
15
  if (!agent) return undefined;
@@ -15,6 +18,8 @@ function callerHost(ctx: AuthContext, hosts: Orchestrator[]): Orchestrator | und
15
18
  const byId = hosts.find((item) => item.id === stamped);
16
19
  if (byId) return byId;
17
20
  }
21
+ const rostered = listManagedOrchestratorsForAgent({ agentId: agent.id });
22
+ if (rostered.length === 1) return rostered[0];
18
23
  if (!agent.machine) return undefined;
19
24
  return hosts.find((item) => sameHostIdentity(item.hostname, agent.machine) || sameHostIdentity(item.id, agent.machine));
20
25
  }
@@ -1,3 +1,4 @@
1
+ import { framed } from "../hub-metrics";
1
2
  import { errMessage } from "@humwick/sdk";
2
3
  import { flushCoordinatorDigestsAsync } from "../db/coordinator-digest-async";
3
4
  import { emitNewMessages } from "../sse";
@@ -18,11 +19,11 @@ export function startCoordinatorDigestLoop(): () => Promise<void> {
18
19
  let stopped = false;
19
20
  let timer: ReturnType<typeof setTimeout> | undefined;
20
21
  let pending: Promise<void>;
21
- const tick = async () => {
22
+ const tick = framed("timer coordinator-digest", async () => {
22
23
  try { await flushCoordinatorDigests(); }
23
24
  catch (error) { console.error(`coordinator digest flush failed: ${errMessage(error)}`); }
24
25
  finally { if (!stopped) timer = setTimeout(() => { pending = tick(); }, 1000).unref(); }
25
- };
26
+ });
26
27
  pending = tick();
27
28
  const stop = () => { stopped = true; clearTimeout(timer); removeShutdownHook(); return pending; };
28
29
  const removeShutdownHook = onShutdown("coordinator-digest", stop);
@@ -1,6 +1,7 @@
1
+ import { createCommandAsync, createKernelCommandIfAbsentAsync } from "../commands-write";
1
2
  import { writeChildEnv } from "@humwick/sdk/env";
2
3
  import { rejectCallerSealedEnv } from "../spawn-env";
3
- import { commandSecretMaskValues } from "../command-secrets";
4
+ import { commandSecretMaskValues, omitCommandFenceSecrets, redactCommandSecrets, revealCommandSecrets } from "../command-secrets";
4
5
  import { spawnDelegationState } from "../db/spawn-delegation-state";
5
6
  import { authorizeShutdown } from "./shutdown-agent";
6
7
  import { stewardGenerationCanceled } from "../db/workspace-steward-fence";
@@ -17,11 +18,9 @@ import { stewardGenerationCanceled } from "../db/workspace-steward-fence";
17
18
  // owned by the spawn (#349) / shutdown (#347) slices — they are NOT generic dispatch and stay
18
19
  // out of this service.
19
20
  import { isRecord, stringValue, ValidationError } from "@humwick/sdk";
20
- import { createCommand } from "../commands-db";
21
- import { createCommandAsync, createKernelCommandIfAbsentAsync } from "../commands-write";
21
+
22
22
  import { emitCommandEvent } from "../command-events";
23
23
  import { componentConstraintsAllow, hasComponentScope, isComponentAuthorizedFor, isOpenApprovalConstraints } from "../security";
24
- import { omitCommandFenceSecrets, redactCommandSecrets, revealCommandSecrets } from "../command-secrets";
25
24
  import { listOrchestrators } from "../db";
26
25
  import { ServiceAuthError } from "./errors";
27
26
  import type { AuthContext } from "./auth-context";
@@ -211,10 +210,10 @@ function assertPathAxesWithinConstraint(input: CreateCommandInput, component: Co
211
210
  * scope gate at the transport edge — HTTP middleware `isScopedRequestAuthorized`, bus
212
211
  * `withRegistered`). HTTP `authorizeRoute` and bus `busCommandAuthorized` both reduce to this:
213
212
  * "no component token ⇒ allow; else `isComponentAuthorizedFor(command:write, resource)`". */
214
- function assertCommandAuthorized(ctx: AuthContext, input: CreateCommandInput, schedulerFire = false): void {
213
+ async function assertCommandAuthorized(ctx: AuthContext, input: CreateCommandInput, schedulerFire = false): Promise<void> {
215
214
  if (ctx.callerAgentId && spawnDelegationState(ctx.callerAgentId).participating) {
216
215
  if (input.type === "agent.spawn") throw new ValidationError("agent.spawn requires the spawn service to preserve delegated lineage");
217
- if (input.type === "agent.shutdown") authorizeShutdown(ctx, { agentId: stringValue(input.params?.agentId), spawnRequestId: stringValue(input.params?.spawnRequestId), requestedVia: "bus" });
216
+ if (input.type === "agent.shutdown") (await authorizeShutdown(ctx, { agentId: stringValue(input.params?.agentId), spawnRequestId: stringValue(input.params?.spawnRequestId), requestedVia: "bus" }));
218
217
  }
219
218
  if (ctx.callerAgentId && stewardGenerationCanceled(ctx.callerAgentId, ctx.constraints?.spawnRequestIds?.[0])) {
220
219
  throw new ServiceAuthError("steward job canceled by land withdrawal; host mutations are fenced");
@@ -304,9 +303,9 @@ export function serializeCommandForRead(command: Command, ctx: AuthContext): Com
304
303
  }
305
304
 
306
305
  /** Dispatch options. `allowReservedCorrelation` threads the R2 (#1409) kernel-correlation opt-in to
307
- * `createCommand` — set ONLY by the kernel command bridge, whose `correlation_id` is a legitimately
306
+ * `createCommandAsync` — set ONLY by the kernel command bridge, whose `correlation_id` is a legitimately
308
307
  * `kcmd:`-namespaced dedup key. Every other (external) `dispatchCommand` caller omits it, so the
309
- * reservation stays enforced at the `createCommand` choke point. */
308
+ * reservation stays enforced at the `createCommandAsync` choke point. */
310
309
  export interface DispatchCommandOptions {
311
310
  readonly allowReservedCorrelation?: boolean;
312
311
  /** #2392 — INTERNAL ONLY. Set exclusively by the two scheduler FIRE paths
@@ -340,10 +339,10 @@ function withServerCommandProvenance(input: CreateCommandInput, options: Dispatc
340
339
  };
341
340
  }
342
341
 
343
- export function dispatchCommand(input: CreateCommandInput, ctx: AuthContext, options: DispatchCommandOptions = {}): Command {
342
+ export async function dispatchCommand(input: CreateCommandInput, ctx: AuthContext, options: DispatchCommandOptions = {}): Promise<Command> {
344
343
  const sanitizedInput = withServerCommandProvenance(input, options);
345
- assertCommandAuthorized(ctx, sanitizedInput, options.schedulerFire === true);
346
- const command = createCommand(sanitizedInput, { allowReservedCorrelation: options.allowReservedCorrelation === true });
344
+ (await assertCommandAuthorized(ctx, sanitizedInput, options.schedulerFire === true));
345
+ const command = (await createCommandAsync(sanitizedInput, { allowReservedCorrelation: options.allowReservedCorrelation === true }));
347
346
  // A freshly created command is always `pending`; emit the literal "command.requested"
348
347
  // (the relay auto-fans-out the follow-up "command.dispatched"). HTTP used the status-derived
349
348
  // `emitCommand`, bus used `emitCommandEvent(_, "command.requested")` — identical for pending.
@@ -359,7 +358,7 @@ export async function dispatchCommandAsync(
359
358
  options: DispatchCommandOptions = {},
360
359
  ): Promise<Command> {
361
360
  const sanitizedInput = withServerCommandProvenance(input, options);
362
- assertCommandAuthorized(ctx, sanitizedInput, options.schedulerFire === true);
361
+ (await assertCommandAuthorized(ctx, sanitizedInput, options.schedulerFire === true));
363
362
  const command = await createCommandAsync(sanitizedInput, {
364
363
  allowReservedCorrelation: options.allowReservedCorrelation === true,
365
364
  }, ctx.callerAgentId ?? ctx.actor.id, ctx.constraints?.projectId);
@@ -381,7 +380,7 @@ export async function dispatchKernelCommandAsync(
381
380
  options: Pick<DispatchCommandOptions, "schedulerFire" | "schedulerRequestedVia"> = {},
382
381
  ): Promise<Command> {
383
382
  const sanitizedInput = withServerCommandProvenance(input, options);
384
- assertCommandAuthorized(ctx, sanitizedInput, options.schedulerFire === true);
383
+ (await assertCommandAuthorized(ctx, sanitizedInput, options.schedulerFire === true));
385
384
  const { command, created } = await createKernelCommandIfAbsentAsync(sanitizedInput, ctx.callerAgentId ?? ctx.actor.id, ctx.constraints?.projectId);
386
385
  if (created) emitCommandEvent(command, "command.requested");
387
386
  return command;