@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,11 +1,14 @@
1
+ import { resolveIssueRefFromStringAsync } from "../db/issue-refs-async";
2
+ import { removeAssociationAsync, associateIssueAsync } from "../db/runtime-tail-async";
3
+ import { deletePlanAsync, createPlanRowAsync } from "../db/plans-async";
1
4
  import { hasScope, isRecord } from "@humwick/sdk";
2
- import { addTaskDependency, createPlanRow, deletePlan, getAgent, getEntry, getPlan, getPlanAsync, getPlanByTeam, getPlanByThread, getTaskDetail, listPlansWithBoundOwner, planThreadExists, removeTaskDependency, replacePlanNodeScoped, sendMessage, sendMessageWithResultAsync, setPlanArchivedAsync, ValidationError } from "../db";
5
+ import { sendMessageAsync, addTaskDependency, getAgent, getEntry, getPlan, getPlanAsync, getPlanByTeam, getPlanByThread, getTaskDetail, listPlansWithBoundOwner, planThreadExists, removeTaskDependency, replacePlanNodeScoped, sendMessageWithResultAsync, setPlanArchivedAsync, ValidationError } from "../db";
3
6
  // The shared #2520 patch-time source derivation lives beside the writer op body it mirrors;
4
7
  // plan-graph op bodies are imported directly (the barrel only re-exports plan-graph-async).
5
8
  import { applyPatchStatusSourceDerivation, bindPlanNodeBody } from "../db/plan-graph";
6
9
  import { writeTransaction } from "../db/connection";
7
- import { associateIssue, planNodeIssueEntityId, removeAssociation } from "../db/issue-associations";
8
- import { resolveIssueRefFromString } from "../db/issue-refs";
10
+ import { planNodeIssueEntityId } from "../db/issue-associations";
11
+
9
12
  import { emitRelayEvent } from "../events";
10
13
  import { cleanString, cleanStringArray, optionalEnum } from "../validation";
11
14
  import { resolveActorIssueRepo } from "../agent-issue-repo";
@@ -84,67 +87,6 @@ function cleanOwnerRef(value: unknown): PlanOwnerRef | undefined {
84
87
  return Object.keys(out).length ? out : undefined;
85
88
  }
86
89
 
87
- // #220: a bare `#NNN` issueId ref needs a default repo to resolve against — issue-refs.ts
88
- // throws without one, contrary to its own error text advertising the bare form as accepted.
89
- // Resolve it the same way #533 resolves chat `#NNN` linkify: the CALLING agent's own project
90
- // (cwd → project → issueRepo), falling back to the single global env default. This scopes the
91
- // default to the actor's actual repo rather than guessing from teamId — agents have no
92
- // team→project FK; cwd is the only durable link (see agent-issue-repo.ts).
93
- // Shared with the Task issue-link path (#2214) via resolveActorIssueRepo.
94
- function cleanRefs(value: unknown, actor: string): PlanNode["refs"] | undefined {
95
- if (value === undefined || value === null) return undefined;
96
- const ref = cleanRecordRef(value, "refs");
97
- if (!ref) return undefined;
98
- const out: PlanNode["refs"] = {};
99
- const issueId = cleanString(ref.issueId, "refs.issueId", { max: 1000 });
100
- if (issueId) {
101
- out.issueId = resolveIssueRefFromString({ ref: issueId, defaultRepo: resolveActorIssueRepo(actor) }).id;
102
- }
103
- // #836: refs.taskId is the live binding seam to a durable Task. Validate it resolves to a
104
- // deliverable Task; store the canonical numeric id as a string. Once bound, the node's
105
- // label/scopeBlurb/status PROJECT from the Task (see projectPlanOverTasks) — no double-keeping.
106
- const taskIdRaw = ref.taskId;
107
- const taskIdStr = typeof taskIdRaw === "number" ? String(taskIdRaw) : cleanString(taskIdRaw, "refs.taskId", { max: 240 });
108
- if (taskIdStr) {
109
- const taskId = parseTaskId(taskIdStr);
110
- if (taskId === undefined) throw new ValidationError("refs.taskId must be a positive task id");
111
- if (!getTaskDetail(taskId)) throw new ValidationError(`refs.taskId ${taskId} is not a deliverable task`);
112
- out.taskId = String(taskId);
113
- }
114
- // agentId/landingRef remain populated by live binding in later slices (#838); reject here.
115
- const unsupported = ["agentId", "landingRef"].filter((key) => cleanString(ref[key], `refs.${key}`, { max: 240 }));
116
- if (unsupported.length > 0) throw new ValidationError("agentId/landingRef refs are populated by live binding in a later slice");
117
- return Object.keys(out).length ? out : undefined;
118
- }
119
-
120
- function syncPlanNodeIssueAssociation(planId: string, node: PlanNode): void {
121
- if (!node.refs?.issueId) return;
122
- associateIssue(node.refs.issueId, "plan-node", planNodeIssueEntityId(planId, node.id));
123
- }
124
-
125
- function removePlanNodeIssueAssociation(planId: string, node: PlanNode): void {
126
- if (!node.refs?.issueId) return;
127
- removeAssociation(node.refs.issueId, "plan-node", planNodeIssueEntityId(planId, node.id));
128
- }
129
-
130
- function syncChangedPlanNodeIssueAssociation(planId: string, before: PlanNode | undefined, after: PlanNode): void {
131
- if (before?.refs?.issueId && before.refs.issueId !== after.refs?.issueId) {
132
- removeAssociation(before.refs.issueId, "plan-node", planNodeIssueEntityId(planId, before.id));
133
- }
134
- if (after.refs?.issueId) syncPlanNodeIssueAssociation(planId, after);
135
- }
136
-
137
- function cleanBlackboardRefs(value: unknown, planTeamId?: string): string[] | undefined {
138
- const refs = cleanStringArray(value, "node.blackboardRefs", { itemMax: 120, maxItems: 100 });
139
- if (!refs?.length) return refs;
140
- if (!planTeamId) throw new ValidationError("plan has no team; cannot reference blackboard entries");
141
- for (const ref of refs) {
142
- const entry = getEntry(ref);
143
- if (!entry || entry.teamId !== planTeamId) throw new ValidationError(`blackboard entry not found for plan team: ${ref}`);
144
- }
145
- return refs;
146
- }
147
-
148
90
  function cleanStatusSource(value: unknown): PlanNode["statusSource"] {
149
91
  const statusSource = optionalEnum(value, "statusSource", ["manual", "bound"] as const, "manual");
150
92
  return statusSource;
@@ -181,27 +123,6 @@ function applyBoundStatus(node: PlanNode): PlanNode {
181
123
  return { ...node, status: boundStatusForAgent(getAgent(agentId)) ?? "pending" };
182
124
  }
183
125
 
184
- function cleanNode(input: PlanNodeInput, actor: string, planTeamId?: string): PlanNode {
185
- if (!isRecord(input)) throw new ValidationError("node must be an object");
186
- const scopeBlurb = cleanString(input.scopeBlurb, "node.scopeBlurb", { max: 2000 });
187
- const ownerRef = cleanOwnerRef(input.ownerRef);
188
- const lane = cleanString(input.lane, "node.lane", { max: 120 });
189
- const refs = cleanRefs(input.refs, actor);
190
- const blackboardRefs = cleanBlackboardRefs(input.blackboardRefs, planTeamId);
191
- const statusSource = deriveStatusSource(input.statusSource, input.status, Boolean(refs?.taskId || refs?.issueId));
192
- return applyBoundStatus({
193
- id: cleanString(input.id, "node.id", { required: true, max: 120 })!,
194
- label: cleanString(input.label, "node.label", { required: true, max: PLAN_NODE_LABEL_MAX })!,
195
- ...(scopeBlurb ? { scopeBlurb } : {}),
196
- ...(ownerRef ? { ownerRef } : {}),
197
- ...(lane ? { lane } : {}),
198
- status: optionalEnum(input.status, "node.status", PLAN_STATUSES, "pending") as PlanStatus,
199
- statusSource,
200
- ...(refs ? { refs } : {}),
201
- ...(blackboardRefs ? { blackboardRefs } : {}),
202
- });
203
- }
204
-
205
126
  // The aggregate writer owns persisted validation (issue/task/blackboard existence and bound
206
127
  // presence). This companion only validates shape, producing clone-safe command data.
207
128
  function cleanNodeForAggregate(input: PlanNodeInput): PlanNode {
@@ -247,14 +168,6 @@ function cleanPatchForAggregate(patch: PlanNodePatch): Partial<PlanNode> {
247
168
  return out;
248
169
  }
249
170
 
250
- function cleanNodes(value: unknown, actor: string, planTeamId?: string): PlanNode[] {
251
- if (value === undefined || value === null) return [];
252
- if (!Array.isArray(value)) throw new ValidationError("nodes must be an array");
253
- const nodes = value.map((item) => cleanNode(item as PlanNodeInput, actor, planTeamId));
254
- assertUnique(nodes.map((node) => node.id), "node id");
255
- return nodes;
256
- }
257
-
258
171
  function cleanEdge(input: unknown): PlanEdge {
259
172
  if (!isRecord(input)) throw new ValidationError("edge must be an object");
260
173
  return {
@@ -340,19 +253,19 @@ export function emitPlan(type: "plan.created" | "plan.changed" | "plan.deleted",
340
253
 
341
254
  // #1035: a plan anchors to a messages.thread_id, but a fresh coordinator has no thread yet —
342
255
  // forcing it to send a throwaway message just to mint one. When no threadId is supplied, mint the
343
- // thread server-side by self-threading a lightweight system message (the same sendMessage path the
256
+ // thread server-side by self-threading a lightweight system message (the same sendMessageAsync path the
344
257
  // caller would have used). Sent AS the actor when that agent is registered, else the reserved
345
258
  // `system` sink, so the mint always passes the sender-registration gate.
346
- function mintPlanThread(ctx: AuthContext, channel: string | undefined): number {
259
+ async function mintPlanThread(ctx: AuthContext, channel: string | undefined): Promise<number> {
347
260
  ensureCanMintThread(ctx);
348
261
  const actor = actorId(ctx);
349
262
  const sender = getAgent(actor) ? actor : "system";
350
- const root = sendMessage({
263
+ const root = (await sendMessageAsync({
351
264
  from: sender,
352
265
  to: "system",
353
266
  body: "Plan thread root",
354
267
  ...(channel ? { channel } : {}),
355
- });
268
+ }));
356
269
  return root.threadId ?? root.id;
357
270
  }
358
271
 
@@ -364,7 +277,7 @@ async function mintPlanThreadAsync(ctx: AuthContext, channel: string | undefined
364
277
  return root.threadId ?? root.id;
365
278
  }
366
279
 
367
- // #1043: the mint inserts a real message row through the db `sendMessage` path, which normally
280
+ // #1043: the mint inserts a real message row through the db `sendMessageAsync` path, which normally
368
281
  // lives behind the `message:send` scope. `plans:write` alone must not be a side-door around it, so
369
282
  // gate the mint on `message:send`. Internal `system` principals (empty-scope trusted callers) and
370
283
  // full-reach `*` tokens pass through untouched — `hasScope` short-circuits `*`.
@@ -375,78 +288,16 @@ function ensureCanMintThread(ctx: AuthContext): void {
375
288
  }
376
289
  }
377
290
 
378
- export function createPlan(input: PlanCreateInput, ctx: AuthContext): Plan {
379
- const channel = cleanString(input.channel, "channel", { max: 120 });
380
- const actor = actorId(ctx);
381
- const explicitTeamId = cleanString(input.teamId, "teamId", { max: 120 });
382
- const teamId = explicitTeamId ?? (input.teamId === undefined || input.teamId === null ? getAgent(actor)?.teamId : undefined);
383
- const nodes = cleanNodes(input.nodes, actor, teamId);
384
- const edges = cleanEdges(input.edges);
385
- validateEdges(nodes, edges);
386
- const title = cleanString(input.title, "title", { max: 240 });
387
- const objective = cleanString(input.objective, "objective", { max: 4000 });
388
- const acceptance = cleanPlanAcceptance(input.acceptance);
389
- // Resolve the thread only AFTER the payload validates (#1043): auto-minting first left an orphan
390
- // 'Plan thread root' row behind on every rejected create.
391
- const threadId = input.threadId === undefined || input.threadId === null
392
- ? mintPlanThread(ctx, channel)
393
- : cleanThreadId(input.threadId);
394
- if (!planThreadExists(threadId)) throw new ValidationError(`thread ${threadId} not found`);
395
- const plan = createPlanRow({
396
- threadId,
397
- teamId,
398
- channel,
399
- title,
400
- objective,
401
- nodes,
402
- edges,
403
- acceptance,
404
- createdBy: actor,
405
- });
406
- for (const node of plan.nodes) syncPlanNodeIssueAssociation(plan.id, node);
407
- emitPlan("plan.created", plan, actor);
408
- return plan;
291
+ export async function createPlan(input: PlanCreateInput, ctx: AuthContext): Promise<Plan> {
292
+ return createPlanAsync(input, ctx);
409
293
  }
410
294
 
411
- export function addPlanNode(planId: string, nodeInput: PlanNodeInput, ctx: AuthContext): Plan {
412
- const actor = actorId(ctx);
413
- // S6 #2079: fence behind the version-CAS; re-derive the node on the freshest snapshot each attempt.
414
- let node!: PlanNode;
415
- const updated = replacePlanNodeScoped(planId, (plan) => {
416
- node = cleanNode(nodeInput, actor, plan.teamId);
417
- if (plan.nodes.some((item) => item.id === node.id)) throw new ValidationError(`node ${node.id} already exists`);
418
- return { ...plan, nodes: [...plan.nodes, node] };
419
- }, actor);
420
- syncPlanNodeIssueAssociation(updated.id, node); emitPlan("plan.changed", updated, actor);
421
- return updated;
422
- }
423
-
424
- export function updatePlanNode(planId: string, nodeId: string, patch: PlanNodePatch, ctx: AuthContext): Plan {
425
- const actor = actorId(ctx);
426
- // S6 #2079: re-apply the patch onto the latest node map (by nodeId); a distinct-node edit survives.
427
- let existing!: PlanNode; let next!: PlanNode;
428
- const updated = replacePlanNodeScoped(planId, (plan) => {
429
- const current = plan.nodes.find((node) => node.id === nodeId);
430
- if (!current) throw new ValidationError(`node ${nodeId} not found`); existing = current;
431
- const statusSource = patch.statusSource !== undefined ? cleanStatusSource(patch.statusSource) : current.statusSource;
432
- const base: PlanNode = {
433
- ...current,
434
- ...(patch.label !== undefined ? { label: cleanString(patch.label, "label", { required: true, max: PLAN_NODE_LABEL_MAX })! } : {}),
435
- ...(patch.scopeBlurb !== undefined ? optionalProp("scopeBlurb", cleanString(patch.scopeBlurb, "scopeBlurb", { max: 2000 })) : {}),
436
- ...(patch.ownerRef !== undefined ? optionalProp("ownerRef", cleanOwnerRef(patch.ownerRef)) : {}),
437
- ...(patch.lane !== undefined ? optionalProp("lane", cleanString(patch.lane, "lane", { max: 120 })) : {}),
438
- ...(patch.status !== undefined ? { status: optionalEnum(patch.status, "status", PLAN_STATUSES) as PlanStatus } : {}),
439
- ...(patch.refs !== undefined ? optionalProp("refs", cleanRefs(patch.refs, actor)) : {}),
440
- ...(patch.blackboardRefs !== undefined ? optionalProp("blackboardRefs", cleanBlackboardRefs(patch.blackboardRefs, plan.teamId)) : {}),
441
- statusSource,
442
- };
443
- // #2520 RESOLUTION — the ONE shared patch-time source derivation (lives beside the writer op
444
- // body it mirrors; see applyPatchStatusSourceDerivation in db/plan-graph.ts).
445
- next = applyBoundStatus(applyPatchStatusSourceDerivation(patch, current, base));
446
- return { ...plan, nodes: plan.nodes.map((node) => node.id === nodeId ? next : node) };
447
- }, actor);
448
- syncChangedPlanNodeIssueAssociation(updated.id, existing, next); emitPlan("plan.changed", updated, actor);
449
- return updated;
295
+ export async function addPlanNode(planId: string, nodeInput: PlanNodeInput, ctx: AuthContext): Promise<Plan> {
296
+ return addPlanNodeAsync(planId, nodeInput, ctx);
297
+ }
298
+
299
+ export async function updatePlanNode(planId: string, nodeId: string, patch: PlanNodePatch, ctx: AuthContext): Promise<Plan> {
300
+ return updatePlanNodeAsync(planId, nodeId, patch, ctx);
450
301
  }
451
302
 
452
303
  function optionalProp<K extends keyof PlanNode>(key: K, value: PlanNode[K] | undefined): Partial<PlanNode> {
@@ -470,72 +321,20 @@ function assertEdgeKeepsAcyclic(plan: Plan, edge: PlanEdge): void {
470
321
  validateEdges(projected.nodes, dedupeEdges([...projected.edges, edge]));
471
322
  }
472
323
 
473
- export function addPlanEdge(planId: string, edgeInput: unknown, ctx: AuthContext): Plan {
474
- const plan = existingPlan(planId);
475
- const edge = cleanEdge(edgeInput);
476
- assertEdgeKeepsAcyclic(plan, edge);
477
- // #836: when BOTH endpoints are Task-bound, the canonical edge store is task_dependencies,
478
- // not the plan JSON. Plan edge {from,to} means `to` depends on `from`. The combined-graph
479
- // pre-check above already rejected cross-store cycles; the edge surfaces back via projection.
480
- const fromTask = boundTaskId(plan, edge.from);
481
- const toTask = boundTaskId(plan, edge.to);
482
- if (fromTask !== undefined && toTask !== undefined) {
483
- addTaskDependency(toTask, fromTask, actorId(ctx));
484
- const projected = projectPlanOverTasks(existingPlan(planId));
485
- emitPlan("plan.changed", projected, actorId(ctx));
486
- return projected;
487
- }
488
- // S6 #2079: fence behind the version-CAS; re-append + re-check acyclicity on the fresh snapshot.
489
- const updated = replacePlanNodeScoped(planId, (fresh) => {
490
- assertEdgeKeepsAcyclic(fresh, edge);
491
- return { ...fresh, edges: dedupeEdges([...fresh.edges, edge]) };
492
- }, actorId(ctx));
493
- emitPlan("plan.changed", updated, actorId(ctx)); return updated;
324
+ export async function addPlanEdge(planId: string, edgeInput: unknown, ctx: AuthContext): Promise<Plan> {
325
+ return addPlanEdgeAsync(planId, edgeInput, ctx);
494
326
  }
495
327
 
496
- export function removePlanNode(planId: string, nodeId: string, ctx: AuthContext): Plan {
497
- const actor = actorId(ctx);
498
- // S6 #2079: fence the removal behind the version-CAS; re-resolve the node on the fresh snapshot.
499
- let removed!: PlanNode;
500
- const updated = replacePlanNodeScoped(planId, (plan) => {
501
- const current = plan.nodes.find((node) => node.id === nodeId);
502
- if (!current) throw new ValidationError(`node ${nodeId} not found`); removed = current;
503
- return {
504
- ...plan,
505
- nodes: plan.nodes.filter((node) => node.id !== nodeId),
506
- edges: plan.edges.filter((edge) => edge.from !== nodeId && edge.to !== nodeId),
507
- };
508
- }, actor);
509
- removePlanNodeIssueAssociation(updated.id, removed); emitPlan("plan.changed", updated, actor);
510
- return updated;
511
- }
512
-
513
- export function removePlanEdge(planId: string, edgeInput: unknown, ctx: AuthContext): Plan {
514
- const plan = existingPlan(planId);
515
- const edge = cleanEdge(edgeInput);
516
- // A bound-pair edge can live in BOTH task_dependencies and the plan JSON, and projection unions
517
- // them: clear both stores or the edge reappears (#2877).
518
- const fromTask = boundTaskId(plan, edge.from);
519
- const toTask = boundTaskId(plan, edge.to);
520
- const depRemoved = fromTask !== undefined && toTask !== undefined && removeTaskDependency(toTask, fromTask, actorId(ctx));
521
- // S6 #2079: fence behind the version-CAS; re-resolve the edge (and its not-found check) on fresh.
522
- const updated = replacePlanNodeScoped(planId, (fresh) => {
523
- const edges = fresh.edges.filter((item) => item.from !== edge.from || item.to !== edge.to);
524
- if (!depRemoved && edges.length === fresh.edges.length) throw new ValidationError(`edge ${edge.from}->${edge.to} not found`);
525
- return { ...fresh, edges };
526
- }, actorId(ctx));
527
- const projected = projectPlanOverTasks(updated);
528
- emitPlan("plan.changed", projected, actorId(ctx));
529
- return projected;
530
- }
531
-
532
- export function deletePlanGraph(planId: string, ctx: AuthContext): { id: string; deleted: true } {
533
- const plan = existingPlan(planId);
534
- const actor = actorId(ctx);
535
- deletePlan(plan.id, actor);
536
- for (const node of plan.nodes) removePlanNodeIssueAssociation(plan.id, node);
537
- emitPlan("plan.deleted", plan, actor);
538
- return { id: plan.id, deleted: true };
328
+ export async function removePlanNode(planId: string, nodeId: string, ctx: AuthContext): Promise<Plan> {
329
+ return (await removePlanNodeAsync(planId, nodeId, ctx)).plan;
330
+ }
331
+
332
+ export async function removePlanEdge(planId: string, edgeInput: unknown, ctx: AuthContext): Promise<Plan> {
333
+ return removePlanEdgeAsync(planId, edgeInput, ctx);
334
+ }
335
+
336
+ export async function deletePlanGraph(planId: string, ctx: AuthContext): Promise<{ id: string; deleted: true }> {
337
+ return deletePlanGraphAsync(planId, ctx);
539
338
  }
540
339
 
541
340
  export async function archivePlanGraphAsync(planId: string, archived: boolean, ctx: AuthContext): Promise<Plan> {
@@ -547,29 +346,12 @@ export async function archivePlanGraphAsync(planId: string, archived: boolean, c
547
346
 
548
347
  // In-process (legacy/unit-test) sibling of the gateway-backed applyBoundOwnersAsync path (production
549
348
  // never takes this branch). S6 #2079: fence each write behind the version-CAS; re-derive on fresh.
550
- export function updateBoundPlanNodesForAgent(agentId: string, status: PlanStatus, actor = "server"): Plan[] {
551
- const boundFlip = (node: PlanNode): boolean =>
552
- node.statusSource === "bound" && node.ownerRef?.agentId === agentId && node.status !== "landed" && node.status !== status;
553
- const updated: Plan[] = [];
554
- for (const plan of listPlansWithBoundOwner(agentId)) {
555
- // Skip-no-op on the initial snapshot: don't even fence a write when there's nothing to flip.
556
- if (!plan.nodes.some(boundFlip)) continue;
557
- // Preserve that contract THROUGH a CAS-conflict retry: if a re-read snapshot no longer needs a
558
- // flip (a concurrent writer already applied it), return null so no version bump / event fires.
559
- let wrote = false;
560
- const next = replacePlanNodeScoped(plan.id, (fresh) => {
561
- wrote = fresh.nodes.some(boundFlip);
562
- return wrote ? { ...fresh, nodes: fresh.nodes.map((node) => (boundFlip(node) ? { ...node, status } : node)) } : null;
563
- }, actor);
564
- if (!wrote) continue; // the retry resolved to a no-op — nothing was written, so don't emit/collect
565
- emitPlan("plan.changed", next, actor); updated.push(next);
566
- }
567
- return updated;
349
+ export async function updateBoundPlanNodesForAgent(agentId: string, status: PlanStatus, actor = "server"): Promise<Plan[]> {
350
+ return updateBoundPlanNodesForAgentAsync(agentId, status, actor);
568
351
  }
569
352
 
570
- export function updateBoundPlanNodesFromAgent(agentId: string, actor = "server"): Plan[] {
571
- const status = boundStatusForAgent(getAgent(agentId));
572
- return status ? updateBoundPlanNodesForAgent(agentId, status, actor) : [];
353
+ export async function updateBoundPlanNodesFromAgent(agentId: string, actor = "server"): Promise<Plan[]> {
354
+ return updateBoundPlanNodesFromAgentAsync(agentId, boundStatusForAgent(getAgent(agentId)), actor);
573
355
  }
574
356
 
575
357
  /** Gateway-only live-binding path. The read precheck avoids submitting a no-op writer job. */
@@ -581,7 +363,7 @@ export async function updateBoundPlanNodesForAgentAsync(agentId: string, status:
581
363
  }
582
364
 
583
365
  export async function updateBoundPlanNodesFromAgentAsync(agentId: string, status: PlanStatus | undefined, actor = "server"): Promise<Plan[]> {
584
- return status ? updateBoundPlanNodesForAgentAsync(agentId, status, actor) : [];
366
+ return status ? (await updateBoundPlanNodesForAgentAsync(agentId, status, actor)) : [];
585
367
  }
586
368
 
587
369
  // #836: `view: "tasks"` returns the pure task-backed DAG synthesized from a team's deliverable
@@ -623,12 +405,8 @@ export interface BindPlanNodeInput {
623
405
  taskId?: number;
624
406
  }
625
407
 
626
- export function bindPlanNodeToTask(planId: string, nodeId: string, input: BindPlanNodeInput, ctx: AuthContext): { plan: Plan; taskId: number } {
627
- const actor = actorId(ctx);
628
- const result = writeTransaction(() => bindPlanNodeBody({ planId, nodeId, taskId: input.taskId, actor }, Date.now()));
629
- emitPlan("plan.changed", result.plan, actor);
630
- emitPlanTaskEvents(result.taskEvents);
631
- return { plan: result.plan, taskId: result.taskId! };
408
+ export async function bindPlanNodeToTask(planId: string, nodeId: string, input: BindPlanNodeInput, ctx: AuthContext): Promise<{ plan: Plan; taskId: number }> {
409
+ return bindPlanNodeToTaskAsync(planId, nodeId, input, ctx);
632
410
  }
633
411
 
634
412
  // HTTP and MCP can await. Keep the synchronous entry points above for the event reducers and
@@ -698,6 +476,6 @@ export async function bindPlanNodeToTaskAsync(planId: string, nodeId: string, in
698
476
  // The aggregate ack is after COMMIT. Emit every consumer-facing task intent only here,
699
477
  // never from the worker, so failed aggregate writes are observably silent.
700
478
  emitPlan("plan.changed", result.plan, actor);
701
- emitPlanTaskEvents(result.taskEvents);
479
+ await emitPlanTaskEvents(result.taskEvents);
702
480
  return { plan: result.plan, taskId: result.taskId! };
703
481
  }
@@ -60,7 +60,7 @@ export async function importPlan(input: Record<string, unknown>, ctx: AuthContex
60
60
  const { dryRun, ...args } = preparePlanImport(input, ctx);
61
61
  if (dryRun) return await getGateway().read("planGraph.import.preview", args) as unknown as PlanImportResult;
62
62
  const result = await getGateway().write("planGraph.import", args) as unknown as PlanImportWriteResult;
63
- emitPlanTaskEvents(result.taskEvents);
63
+ await emitPlanTaskEvents(result.taskEvents);
64
64
  if (result.plan) emitPlan(args.expectedVersion === 0 ? "plan.created" : "plan.changed", result.plan, args.actor);
65
65
  return result.receipt;
66
66
  }
@@ -1,8 +1,9 @@
1
- import { getTeam, getTeamAsync } from "../db";
2
- import { getGateway } from "../db/gateway";
1
+ import { updateBoundPlanNodesFromAgentAsync, updateBoundPlanNodesForAgentAsync } from "./plan-graph";
2
+ import { getTeamAsync } from "../db";
3
+ import { trackRelayEvent } from "../relay-event-drain";
3
4
  import { subscribeRelayEvents, type RelayEvent } from "../events";
4
5
  import { routeNotification } from "../notification-router";
5
- import { updateBoundPlanNodesForAgent, updateBoundPlanNodesForAgentAsync, updateBoundPlanNodesFromAgent, updateBoundPlanNodesFromAgentAsync } from "./plan-graph";
6
+
6
7
 
7
8
  let unsubscribe: (() => void) | undefined;
8
9
 
@@ -48,7 +49,7 @@ async function notifyBoundExit(event: RelayEvent, updatedPlans: Awaited<ReturnTy
48
49
  const target = team?.coordinatorId ?? `team:${plan.teamId}`;
49
50
  const blockedNodes = plan.nodes.filter((node) => node.statusSource === "bound" && node.ownerRef?.agentId === agentId && node.status === "blocked");
50
51
  if (blockedNodes.length === 0) continue;
51
- routeNotification({
52
+ await routeNotification({
52
53
  type: "plan.bound_agent_exited",
53
54
  scope: { agentId, planId: plan.id, teamId: plan.teamId },
54
55
  recipients: [target],
@@ -92,39 +93,9 @@ async function handlePlanBindingEventAsync(event: RelayEvent): Promise<void> {
92
93
  }
93
94
 
94
95
  function handlePlanBindingEvent(event: RelayEvent): void {
95
- // The in-process backend exists only for legacy/unit tests. Keep its old synchronous reducer
96
- // contract so these tests do not accidentally test scheduling; worker-backed production never
97
- // takes this branch and has no event-loop SQLite access.
98
- if (getGateway().stats.backend === "in-process") {
99
- if (event.type === "agent.status") {
100
- const agentId = agentIdFromEvent(event);
101
- if (agentId) updateBoundPlanNodesFromAgent(agentId, event.source || "server");
102
- return;
103
- }
104
- if (event.type === "branch.landed") {
105
- const agentId = stringField(event.data.author);
106
- if (agentId) updateBoundPlanNodesForAgent(agentId, "landed", event.source || "server");
107
- return;
108
- }
109
- if (event.type === "agent.exited") {
110
- const agentId = agentIdFromEvent(event);
111
- if (!agentId || isGracefulExitReason(stringField(event.data.reason))) return;
112
- const updated = updateBoundPlanNodesForAgent(agentId, "blocked", event.source || "server");
113
- const reason = stringField(event.data.reason);
114
- for (const plan of updated) {
115
- if (!plan.teamId) continue;
116
- const team = getTeam(plan.teamId);
117
- const nodes = plan.nodes.filter((node) => node.statusSource === "bound" && node.ownerRef?.agentId === agentId && node.status === "blocked");
118
- if (nodes.length) routeNotification({ type: "plan.bound_agent_exited", scope: { agentId, planId: plan.id, teamId: plan.teamId }, recipients: [team?.coordinatorId ?? `team:${plan.teamId}`], message: { subject: "Bound plan node blocked", body: `Agent \`${agentId}\` exited${reason ? ` (${reason})` : ""}; blocked plan node(s) ${nodes.map((node) => `\`${node.id}\``).join(", ")} in \`${plan.id}\`.`, payload: { kind: "plan.bound_agent_exited", planId: plan.id, agentId, nodeIds: nodes.map((node) => node.id), reason }, replyExpected: false } });
119
- }
120
- return;
121
- }
122
- }
123
- // Event listeners are synchronous. Serialize the asynchronous aggregate submissions so an
124
- // agent's rapid status sequence reaches the FIFO writer in event order.
125
- pending = pending.then(() => handlePlanBindingEventAsync(event)).catch((error) => {
126
- console.error("plan live binding update failed", error);
127
- });
96
+ const run = pending.then(() => handlePlanBindingEventAsync(event));
97
+ pending = run.catch(() => {});
98
+ trackRelayEvent(run, "plan.live-binding");
128
99
  }
129
100
 
130
101
  export function startPlanLiveBindings(): void {
@@ -72,7 +72,7 @@ export async function createPlanTaskAsync(input: CreateTaskEntityInput, extras:
72
72
  };
73
73
  // The caller's key makes a retry return the first result instead of a second Task or node.
74
74
  const result = await getGateway().write("planGraph.task.create", args, { idempotencyKey: options.idempotencyKey ?? randomUUID() }) as unknown as CreatePlanTaskResult;
75
- emitPlanTaskEvents(result.taskEvents);
75
+ await emitPlanTaskEvents(result.taskEvents);
76
76
  if (result.plan) emitPlan("plan.changed", result.plan, createdBy);
77
77
  // A replay returns the first write's result; the receipt reads the Task as it is now.
78
78
  const task = await getTaskDetailAsync(result.task.id) ?? result.task;
@@ -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) {
@@ -70,6 +75,7 @@ export function renderPlanWakeDigest(agentId: string, now = Date.now()): string
70
75
  do {
71
76
  const page = listPlansByTeam(teamId, { limit: 8, cursor });
72
77
  for (const summary of page.plans) {
78
+ if (!summary.nodeCount) continue;
73
79
  const plan = getPlan(summary.id);
74
80
  if (!plan) continue;
75
81
  const line = planLine(plan, now);
@@ -1,7 +1,8 @@
1
1
  // #3636 — project trust edits without the dashboard: set a profile's review mode, acknowledge its
2
2
  // project hooks/MCP, approve an observed value. One seam for the HTTP routes and the MCP tool.
3
3
  import { ValidationError, type AgentProfile, type ProfileProjectReviewMode } from "@humwick/sdk";
4
- import { getAgentProfile, setAgentProfile, validateAgentProfile } from "../config-store";
4
+ import { getAgentProfile, validateAgentProfile } from "../config-store";
5
+ import { setAgentProfileAsync } from "../config-store-write";
5
6
  import type { ConfigEntry } from "../types";
6
7
  import type { ProjectTrustApproval, ProjectTrustCapability } from "../db/project-trust-approvals";
7
8
  import { approveProjectCapabilityReview, projectCellsHash } from "../project-trust";
@@ -38,17 +39,17 @@ export function withProjectTrust(profile: AgentProfile, update: ProjectTrustUpda
38
39
  return validated;
39
40
  }
40
41
 
41
- export function updateProfileProjectTrust(name: string, update: ProjectTrustUpdate, by: string): ConfigEntry<AgentProfile> {
42
+ export async function updateProfileProjectTrustAsync(name: string, update: ProjectTrustUpdate, by: string): Promise<ConfigEntry<AgentProfile>> {
42
43
  if (!update.review && !update.ack?.length) throw new ValidationError("nothing to update: pass review and/or ack");
43
- const saved = setAgentProfile(withProjectTrust(existingProfile(name).value, update, by), by, { overrideBuiltIn: true });
44
+ const saved = await setAgentProfileAsync(withProjectTrust(existingProfile(name).value, update, by), by, { overrideBuiltIn: true });
44
45
  emitConfigChanged(saved.namespace, saved.key, saved.version);
45
46
  return saved;
46
47
  }
47
48
 
48
49
  /** Approve an observed `sha256:…` (fingerprint) or `commit:…` value; the mode follows the prefix. */
49
- 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> {
50
51
  const profileName = existingProfile(input.name).value.name;
51
52
  const mode = input.value.startsWith("commit:") ? "commit" : input.value.startsWith("sha256:") ? "fingerprint" : undefined;
52
53
  if (!mode) throw new ValidationError(`approved value must start with "sha256:" or "commit:", as shown in the refusal`);
53
- 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 }));
54
55
  }
@@ -0,0 +1,70 @@
1
+ // #3635/#3736 — one reader for `.agent-relay/*.json` project config (areas.json, spawn-policy.json): the
2
+ // file at the checkout's default branch (origin/<default>, fetched first), read on the checkout's host
3
+ // through the #3043 project-files reader. Never a working tree and never cached, so a stale checkout or
4
+ // an old negative answer cannot hide a file that landed.
5
+ import { readProjectFiles } from "@humwick/sdk";
6
+ import type { ConfigAtCommit } from "@humwick/sdk/repo-config-file";
7
+ import { errMessage } from "@humwick/sdk";
8
+ import { rootsForProject } from "../db";
9
+ import { localProjectGit, readHostProjectFiles } from "../project-roles";
10
+ import { hostIsRelayHost } from "../relay-host-locality";
11
+ import { resolveProjectFilesHost } from "./spawn-project-role";
12
+
13
+ /** A checkout to read from: a cwd on a host (a hostname or a registered orchestrator). */
14
+ export interface ProjectCheckout {
15
+ cwd: string;
16
+ host?: string;
17
+ orchestratorId?: string;
18
+ }
19
+
20
+ export type ConfigLookup<T> = ConfigAtCommit<T> | { status: "unreadable"; error: string };
21
+
22
+ type Snapshot = { ref: string; sha: string; files: Record<string, string | null> };
23
+
24
+ const warned = new Set<string>();
25
+
26
+ /** One warning per distinct problem, so a broken file does not flood the log on every read. */
27
+ export function warnConfigOnce(key: string, message: string): void {
28
+ if (warned.has(key)) return;
29
+ if (warned.size >= 1000) warned.clear();
30
+ warned.add(key);
31
+ console.warn(message);
32
+ }
33
+
34
+ /** `file` at the checkout's default branch; a read failure is `unreadable`, never a throw. Invalid and
35
+ * unreadable outcomes warn once, naming `file`, the checkout and why, with `consequence` appended. */
36
+ export async function readProjectConfig<T>(checkout: ProjectCheckout, file: string, parse: (snapshot: Snapshot) => ConfigAtCommit<T>, consequence: string): Promise<ConfigLookup<T>> {
37
+ const where = `${checkout.orchestratorId ?? checkout.host ?? "local"}:${checkout.cwd}`;
38
+ try {
39
+ const snapshot = !checkout.orchestratorId && hostIsRelayHost(checkout.host)
40
+ ? await readProjectFiles({ paths: [file] }, localProjectGit(checkout.cwd))
41
+ : await readHostProjectFiles(
42
+ resolveProjectFilesHost({ subject: file, cwd: checkout.cwd, orchestratorId: checkout.orchestratorId, preferHost: checkout.host }),
43
+ checkout.cwd, { paths: [file] }, file,
44
+ );
45
+ const lookup = parse(snapshot);
46
+ if (lookup.status === "invalid") warnConfigOnce(`${file}@${where}@${lookup.sha}`, `[project-config] ${file} for ${where} at ${lookup.sha.slice(0, 12)} is invalid: ${lookup.error}; ${consequence}`);
47
+ return lookup;
48
+ } catch (err) {
49
+ const error = errMessage(err);
50
+ warnConfigOnce(`${file}@${where}`, `[project-config] ${file} for ${where}: unreadable: ${error}; ${consequence}`);
51
+ return { status: "unreadable", error };
52
+ }
53
+ }
54
+
55
+ /** The first checkout that can be read answers: the preferred ones, then each registered root of the project. */
56
+ export async function readProjectConfigFirst<T>(
57
+ projectId: string | undefined, preferred: readonly ProjectCheckout[], file: string, parse: (snapshot: Snapshot) => ConfigAtCommit<T>, consequence: string,
58
+ ): Promise<{ lookup?: ConfigAtCommit<T>; failures: string[] }> {
59
+ const checkouts: ProjectCheckout[] = [
60
+ ...preferred,
61
+ ...(projectId ? rootsForProject(projectId).map((root) => ({ cwd: root.rootPath, ...(root.orchestratorId ? { orchestratorId: root.orchestratorId } : {}) })) : []),
62
+ ];
63
+ const failures: string[] = [];
64
+ for (const checkout of checkouts) {
65
+ const lookup = await readProjectConfig(checkout, file, parse, consequence);
66
+ if (lookup.status !== "unreadable") return { lookup, failures };
67
+ failures.push(lookup.error);
68
+ }
69
+ return { failures };
70
+ }