@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
@@ -11,8 +11,16 @@
11
11
 
12
12
  import { agentSessionGuardResult } from "./agent-predicates.ts";
13
13
  import {
14
+ agentLifecycleWriteArgs,
15
+ bufferOrBypassHeartbeat,
14
16
  getAgent,
17
+ prepareAgentLifecycleUpdate,
15
18
  runBeforeAgentStatusTransitionHandlers,
19
+ type AgentLifecycleUpdate,
20
+ type AgentLifecycleUpdateResult,
21
+ type HeartbeatInput,
22
+ type OrphanedTokenPage,
23
+ type OrphanedTokenRevocation,
16
24
  validateAgentSession,
17
25
  type UpsertAgentTxResult,
18
26
  type UpsertAgentOptions,
@@ -123,7 +131,7 @@ export async function setStatusAsync(id: string, status: AgentCard["status"], gu
123
131
  const before = await getAgentAsync(id);
124
132
  if (!agentSessionGuardResult(before, guard).ok) return false;
125
133
  if (!before) return false;
126
- if (before.status !== status) runBeforeAgentStatusTransitionHandlers(before, status);
134
+ if (before.status !== status) await runBeforeAgentStatusTransitionHandlers(before, status);
127
135
  if (status === "offline" || status === "stale") evictPendingPresence(id);
128
136
  const now = Date.now();
129
137
  // #2111 — buffered into the short lifecycle window and submitted with its peers as ONE batch job.
@@ -209,6 +217,32 @@ export async function recordAgentExitDiagnosticsAsync(
209
217
  return getAgentAsync(id);
210
218
  }
211
219
 
220
+ /** `applyAgentLifecycleUpdate` with the write on the writer thread (#1870 S7). The guard, the `before` read
221
+ * and the transition handlers stay on the main thread ahead of submission; the op CAS-fences on
222
+ * `before.epoch`, so a takeover that lands in the hop turns this into a no-op instead of a clobber. */
223
+ export async function applyAgentLifecycleUpdateAsync(
224
+ id: string,
225
+ update: AgentLifecycleUpdate,
226
+ guard?: AgentSessionGuard,
227
+ now: number = Date.now(),
228
+ ): Promise<AgentLifecycleUpdateResult> {
229
+ // Allocated first, per the ordinal-timing rule at the top of setStatusAsync.
230
+ const seq = nextLifecycleSeq();
231
+ const before = prepareAgentLifecycleUpdate(id, update, guard, false);
232
+ if (!before) return { ok: false, changed: false, metaWriteBytes: 0, before: null, after: null };
233
+ if (update.status !== undefined && update.status !== before.status) await runBeforeAgentStatusTransitionHandlers(before, update.status);
234
+ const result = (await getGateway().write("agents.applyLifecycleUpdate", agentLifecycleWriteArgs(before, update, seq, now))) as unknown as Omit<AgentLifecycleUpdateResult, "ok" | "before">;
235
+ return { ok: true, before, ...result };
236
+ }
237
+
238
+ /** `recordHeartbeat` for the transports: a steady-state beat is buffered at once; a presence-critical one
239
+ * writes on the writer thread (#1870 S7). */
240
+ export async function recordHeartbeatAsync(id: string, opts: HeartbeatInput = {}): Promise<boolean> {
241
+ const beat = bufferOrBypassHeartbeat(id, opts);
242
+ if (typeof beat === "boolean") return beat;
243
+ return (await applyAgentLifecycleUpdateAsync(id, beat, opts.guard, opts.now ?? Date.now())).changed;
244
+ }
245
+
212
246
  export async function heartbeatAsync(
213
247
  id: string,
214
248
  guard?: AgentSessionGuard,
@@ -263,7 +297,7 @@ export async function reapStaleAgentsAsync(ttlMs: number = STALE_TTL_MS, lagGrac
263
297
  */
264
298
  export async function pruneOfflineAgentsAsync(
265
299
  maxOfflineMs: number = DAY_MS,
266
- options: { onFinality?: (result: WorkFinalFlushResult) => void } = {},
300
+ options: { onFinality?: (result: WorkFinalFlushResult) => void; onArchivePurgeFailure?: () => void } = {},
267
301
  ): Promise<string[]> {
268
302
  const cutoff = Date.now() - maxOfflineMs;
269
303
  const candidates = (await getGateway().read("agents.offlinePruneCandidates", {
@@ -271,7 +305,7 @@ export async function pruneOfflineAgentsAsync(
271
305
  })) as unknown as AgentCard[];
272
306
  const candidateIds = candidates.map((candidate) => candidate.id);
273
307
  if (candidateIds.length === 0) return [];
274
- await purgeArchivesBeforeDelete(candidateIds, cutoff);
308
+ if (!await purgeArchivesBeforeDelete(candidateIds, cutoff)) options.onArchivePurgeFailure?.();
275
309
 
276
310
  const finalityQueues = takeDeferredLineageReports(candidateIds);
277
311
  const refreshFinalityCandidates = candidates
@@ -301,11 +335,13 @@ export async function pruneOfflineAgentsAsync(
301
335
  }
302
336
 
303
337
  /** #3012 — best effort: whatever the off-loop purge leaves, the delete's own FK cascade still removes. */
304
- async function purgeArchivesBeforeDelete(agentIds: string[], offlineBefore?: number): Promise<void> {
338
+ async function purgeArchivesBeforeDelete(agentIds: string[], offlineBefore?: number): Promise<boolean> {
305
339
  try {
306
340
  await purgeContinuationArchivesAsync({ agentIds, offlineBefore });
341
+ return true;
307
342
  } catch (error) {
308
343
  console.warn("[agents] continuation archive purge before delete failed; the cascade will remove them:", error);
344
+ return false;
309
345
  }
310
346
  }
311
347
 
@@ -319,14 +355,28 @@ export async function deleteAgentAsync(id: string): Promise<{ ok: boolean; error
319
355
  return deleted ? { ok: true } : { ok: false, error: "agent not found" };
320
356
  }
321
357
 
358
+ // #3776 — the sweep is one short writer op per page of agents (each agent's lineage revoke stays atomic), so
359
+ // other writes interleave between pages. It stops when aborted or past its budget; the next run starts over.
360
+ const ORPHAN_SWEEP_PAGE_SIZE = 8;
361
+ const ORPHAN_SWEEP_BUDGET_MS = 30_000;
362
+
322
363
  export async function revokeOrphanedRuntimeTokensAsync(
323
364
  graceMs: number = STALE_TTL_MS,
324
365
  lagGraceMs = 0,
325
- ): Promise<Array<{ agentId: string; jtis: string[] }>> {
326
- return (await getGateway().write("agents.revokeOrphanedTokens", { graceMs, lagGraceMs })) as unknown as Array<{
327
- agentId: string;
328
- jtis: string[];
329
- }>;
366
+ options: { signal?: AbortSignal; budgetMs?: number; pageSize?: number } = {},
367
+ ): Promise<{ revoked: OrphanedTokenRevocation[]; complete: boolean }> {
368
+ const { signal, budgetMs = ORPHAN_SWEEP_BUDGET_MS, pageSize = ORPHAN_SWEEP_PAGE_SIZE } = options;
369
+ const deadline = Date.now() + budgetMs;
370
+ const revoked: OrphanedTokenRevocation[] = [];
371
+ let afterId: string | undefined;
372
+ do {
373
+ if (signal?.aborted) return { revoked, complete: false };
374
+ const page = (await getGateway().write("agents.revokeOrphanedTokens", { graceMs, lagGraceMs, afterId, limit: pageSize })) as unknown as OrphanedTokenPage;
375
+ revoked.push(...page.revoked);
376
+ if (page.nextAfterId === null) return { revoked, complete: true };
377
+ afterId = page.nextAfterId;
378
+ } while (Date.now() < deadline);
379
+ return { revoked, complete: false };
330
380
  }
331
381
 
332
382
  export async function revokeRuntimeTokensForAgentAsync(
@@ -19,6 +19,8 @@ import { applyIdleSelfCare } from "./idle-self-care";
19
19
  // write (none of these are) would need `idempotent: false` plus a caller-supplied key.
20
20
 
21
21
  import {
22
+ applyAgentLifecycleUpdateInternal,
23
+ type AgentLifecycleWriteArgs,
22
24
  clearAgentMetaKeys,
23
25
  deleteAgentInternal,
24
26
  heartbeat,
@@ -41,6 +43,7 @@ import {
41
43
  import { pruneOfflineAgentsWithFinality, type AgentsPruneOfflineOpArgs } from "./agents-prune-write-op.ts";
42
44
  import { setAgentKeepState } from "./agent-keep.ts";
43
45
  import type { AgentCard, AgentKeep, AgentSessionGuard, ContextState, ManagedSessionExitDiagnostics, ProviderCapabilities, QuotaState, RegisterAgentInput } from "../types";
46
+ import type { OrphanedTokenPage } from "./agents.ts";
44
47
  import type { LineageRevokeReason } from "./token-standing.ts";
45
48
  import type { LifecycleWriteOutcome } from "./lifecycle-seq.ts";
46
49
  import type { WriterOpContext, WriterOpSpec } from "./write-ops.ts";
@@ -69,7 +72,7 @@ export interface AgentsHeartbeatOpArgs {
69
72
  export interface AgentsRecordContextSnapshotOpArgs { agentId: string; context: ContextState }
70
73
  export interface AgentsReapStaleOpArgs { ttlMs: number; lagGraceMs: number; protectedIds?: string[]; seq: number }
71
74
  export interface AgentsDeleteOpArgs { id: string }
72
- export interface AgentsRevokeOrphanedTokensOpArgs { graceMs: number; lagGraceMs: number }
75
+ export interface AgentsRevokeOrphanedTokensOpArgs { graceMs: number; lagGraceMs: number; afterId?: string; limit?: number }
73
76
  export interface AgentsRevokeTokensForAgentOpArgs { agentId: string; reason?: LineageRevokeReason }
74
77
 
75
78
  export const AGENTS_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = Object.freeze({
@@ -107,6 +110,12 @@ export const AGENTS_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = Object.f
107
110
  // coalescing window buffered them) and return a tri-state: `superseded` means a later-submitted
108
111
  // lifecycle write already landed, which is a SUCCESS for the caller and must not be mistaken for a
109
112
  // missing agent. See lifecycle-seq.ts.
113
+ "agents.applyLifecycleUpdate": {
114
+ // #1870 S7: bus status frame and heartbeat bypass; a replay of the same `seq` is a no-op on the fenced columns.
115
+ offLoop: true,
116
+ idempotent: true,
117
+ fn: (args: AgentLifecycleWriteArgs) => applyAgentLifecycleUpdateInternal(args),
118
+ },
110
119
  "agents.setStatus": {
111
120
  offLoop: true,
112
121
  idempotent: true,
@@ -176,8 +185,8 @@ export const AGENTS_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = Object.f
176
185
  "agents.revokeOrphanedTokens": {
177
186
  offLoop: true,
178
187
  idempotent: true,
179
- fn: (args: AgentsRevokeOrphanedTokensOpArgs, ctx: WriterOpContext): Array<{ agentId: string; jtis: string[] }> =>
180
- revokeOrphanedRuntimeTokens(args.graceMs, args.lagGraceMs, ctx.now),
188
+ fn: (args: AgentsRevokeOrphanedTokensOpArgs, ctx: WriterOpContext): OrphanedTokenPage =>
189
+ revokeOrphanedRuntimeTokens(args.graceMs, args.lagGraceMs, ctx.now, { afterId: args.afterId, limit: args.limit }),
181
190
  },
182
191
  "agents.revokeTokensForAgent": {
183
192
  offLoop: true,
package/src/db/agents.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { trackRelayEvent } from "../relay-event-drain";
1
2
  import { mainThreadRegistry } from "./main-thread-state";
2
3
  import { spawnTreeParentIds } from "./spawn-tree";
3
4
  import { recordSpawnProcessExit } from "./spawn-process-evidence";
@@ -8,6 +9,7 @@ import { STALE_TTL_MS, DAY_MS } from "../config";
8
9
  import { withoutAuthzMetaKeys } from "../authz-meta-keys";
9
10
  import {
10
11
  jsonBytes,
12
+ serializeProfileProjection,
11
13
  splitAgentMetaForStorage,
12
14
  splitAgentMetaPatchForStorage,
13
15
  topLevelJsonPath,
@@ -48,10 +50,10 @@ import type {
48
50
  QuotaState,
49
51
  } from "../types";
50
52
 
51
- type BeforeAgentStatusTransition = (agent: AgentCard, nextStatus: AgentCard["status"]) => void;
53
+ type BeforeAgentStatusTransition = (agent: AgentCard, nextStatus: AgentCard["status"]) => unknown;
52
54
  const beforeAgentStatusTransitionHandlers = mainThreadRegistry("agents.ts:beforeAgentStatusTransitionHandlers", new Set<BeforeAgentStatusTransition>());
53
55
 
54
- /** Register synchronous work that must finish before a status transition is persisted. */
56
+ /** Register work that must finish before a status transition is persisted. */
55
57
  export function onBeforeAgentStatusTransition(handler: BeforeAgentStatusTransition): () => void {
56
58
  beforeAgentStatusTransitionHandlers.add(handler);
57
59
  return () => beforeAgentStatusTransitionHandlers.delete(handler);
@@ -62,8 +64,9 @@ export function onBeforeAgentStatusTransition(handler: BeforeAgentStatusTransiti
62
64
  * a writer-worker's own instance), so this must only ever be invoked main-thread-side: from
63
65
  * `setStatus` directly, or from `setStatusAsync`'s pre-write orchestration. Never from the
64
66
  * `agents.setStatus` op body. */
65
- export function runBeforeAgentStatusTransitionHandlers(before: AgentCard, next: AgentCard["status"]): void {
66
- for (const handler of beforeAgentStatusTransitionHandlers) handler(before, next);
67
+ export function runBeforeAgentStatusTransitionHandlers(before: AgentCard, next: AgentCard["status"]): Promise<void> {
68
+ const pending = [...beforeAgentStatusTransitionHandlers].map(handler => handler(before, next));
69
+ return trackRelayEvent(Promise.all(pending).then(() => {}), "agent.before-status");
67
70
  }
68
71
 
69
72
  const CONTEXT_SNAPSHOT_DEBOUNCE_MS = 60_000;
@@ -161,7 +164,7 @@ export function upsertAgentInternal(
161
164
  const contextState = mergeRelayContextMarkers(input.id, input.context);
162
165
  const storedMeta = splitAgentMetaForStorage(withCanonicalSpawnRequestId(input.meta));
163
166
  const metaJson = JSON.stringify(storedMeta.meta);
164
- const profileProjectionJson = storedMeta.profileProjection == null ? null : JSON.stringify(storedMeta.profileProjection);
167
+ const profileProjectionJson = storedMeta.profileProjectionProvided ? serializeProfileProjection(input.id, storedMeta.profileProjection) : null;
165
168
  warnIfAgentMetaOversized(input.id, metaJson, "stored meta");
166
169
  const stmt = getDb().query(`
167
170
  INSERT INTO agents (id, name, kind, label, tags, system_tags, machine, rig, capabilities, ready, status, instance_id, epoch, provider_capabilities, context_state, quota_state, profile_projection, meta, lifecycle, spawned_by, team_id, status_seq, ready_seq, last_seen, created_at)
@@ -479,28 +482,51 @@ export function applyAgentLifecycleUpdate(
479
482
  guard?: AgentSessionGuard,
480
483
  now: number = Date.now(),
481
484
  ): AgentLifecycleUpdateResult {
482
- const miss: AgentLifecycleUpdateResult = { ok: false, changed: false, metaWriteBytes: 0, before: null, after: null };
483
- const before = getPersistedAgentRuntimeCard(id);
484
- if (!before) return miss;
485
- if (!agentSessionGuardResult(before, guard).ok) return miss;
485
+ const seq = nextLifecycleSeq();
486
+ const before = prepareAgentLifecycleUpdate(id, update, guard);
487
+ if (!before) return { ok: false, changed: false, metaWriteBytes: 0, before: null, after: null };
488
+ return { ok: true, before, ...inWriteTransaction(() => applyAgentLifecycleUpdateInternal(agentLifecycleWriteArgs(before, update, seq, now))) };
489
+ }
486
490
 
491
+ /** The writer-op args for one lifecycle delta (#1870 S7). `seq` is taken at the caller's entry (lifecycle-seq.ts
492
+ * rule 1); `expectedEpoch` fences the write to the instance `before` was read from across the writer hop. */
493
+ export interface AgentLifecycleWriteArgs {
494
+ id: string;
495
+ update: AgentLifecycleUpdate;
496
+ seq: number;
497
+ now: number;
498
+ expectedEpoch: number;
499
+ before: { instanceId?: string; spawnRequestId: string; terminalProviderExit?: unknown };
500
+ }
501
+
502
+ export function agentLifecycleWriteArgs(before: AgentCard, update: AgentLifecycleUpdate, seq: number, now: number): AgentLifecycleWriteArgs {
503
+ return { id: before.id, update, seq, now, expectedEpoch: before.epoch, before: { instanceId: before.instanceId, spawnRequestId: String(before.meta?.spawnRequestId ?? ""), terminalProviderExit: before.meta?.terminalProviderExit } };
504
+ }
505
+
506
+ /** The main-thread half of a lifecycle delta: guard, `before` snapshot, transition handlers and presence
507
+ * eviction (main-thread state), all before the write is submitted. Null when the guard rejects. */
508
+ export function prepareAgentLifecycleUpdate(id: string, update: AgentLifecycleUpdate, guard?: AgentSessionGuard, runHandlers = true): AgentCard | null {
509
+ const before = getPersistedAgentRuntimeCard(id);
510
+ if (!before || !agentSessionGuardResult(before, guard).ok) return null;
487
511
  const nextStatus = update.status;
488
- // Pre-transition handlers are main-thread-only state (see runBeforeAgentStatusTransitionHandlers)
489
- // and must run BEFORE the write lands, exactly as `setStatus` does.
490
- if (nextStatus !== undefined && nextStatus !== before.status) runBeforeAgentStatusTransitionHandlers(before, nextStatus);
512
+ // Pre-transition handlers must run BEFORE the write lands, exactly as `setStatus` does.
513
+ if (runHandlers && nextStatus !== undefined && nextStatus !== before.status) runBeforeAgentStatusTransitionHandlers(before, nextStatus);
491
514
  // #1468 — a terminal transition evicts any buffered beat so a coalesced advance cannot later
492
515
  // resurrect a gone agent at flush.
493
516
  if (nextStatus === "offline" || nextStatus === "stale") evictPendingPresence(id);
517
+ return before;
518
+ }
494
519
 
495
- // #2111 review BLOCKER 1 — raise each written column's ordinal so a lifecycle write the coalescing
496
- // window deferred cannot commit afterwards and undo it. This path only ever WINS its own races (it
497
- // commits synchronously, and any submission carrying a higher ordinal has not been allocated yet),
498
- // but it is fenced anyway so every writer of these columns obeys one rule.
499
- const seq = nextLifecycleSeq();
520
+ /** Op body (`agents.applyLifecycleUpdate`): the fenced UPDATE, its effects, and the offline post-commit, in the
521
+ * caller's transaction. #2111 review BLOCKER 1 — each written column's ordinal is raised, so a lifecycle write
522
+ * the coalescing window deferred cannot commit afterwards and undo it. */
523
+ export function applyAgentLifecycleUpdateInternal(args: AgentLifecycleWriteArgs): Omit<AgentLifecycleUpdateResult, "ok" | "before"> {
524
+ const { id, update, seq, now, before } = args;
525
+ const nextStatus = update.status;
500
526
  // Named params throughout: the fenced-column fragments repeat `$seq`, which positional `?` could
501
527
  // only express by counting placeholders across a dynamically-built SET list.
502
528
  const sets: string[] = ["last_seen = $now"];
503
- const params: Record<string, unknown> = { $now: now, $seq: seq, $id: id };
529
+ const params: Record<string, unknown> = { $now: now, $seq: seq, $id: id, $epoch: args.expectedEpoch };
504
530
  let metaWriteBytes = 0;
505
531
  if (nextStatus !== undefined) {
506
532
  sets.push(fencedColumnSql("status", "$status", "$seq"));
@@ -543,7 +569,7 @@ export function applyAgentLifecycleUpdate(
543
569
  }
544
570
  if (patch.profileProjectionProvided) {
545
571
  sets.push("profile_projection = $profileProjection");
546
- params.$profileProjection = patch.profileProjection == null ? null : JSON.stringify(patch.profileProjection);
572
+ params.$profileProjection = serializeProfileProjection(id, patch.profileProjection);
547
573
  }
548
574
  }
549
575
  const runtime = update.runtime;
@@ -558,16 +584,10 @@ export function applyAgentLifecycleUpdate(
558
584
  params.$qs = runtime?.quota ? JSON.stringify(runtime.quota) : null;
559
585
  }
560
586
 
561
- // BEGIN IMMEDIATE (#1428/#1431) so busy_timeout governs contention, joining an ambient writer-op
562
- // transaction rather than nesting when this body is reached through the gateway.
563
- const changed = inWriteTransaction(() => {
564
- const applied = getDb().query(`UPDATE agents SET ${sets.join(", ")} WHERE id = $id`).run(params as never).changes > 0;
565
- const terminalLaunch = terminalProviderLaunchId(update.meta?.terminalProviderExit ?? before.meta?.terminalProviderExit);
566
- if (applied && nextStatus === "offline" && terminalLaunch) revokeVaultTokens(id, now, "provider_terminal_exit", before.instanceId, String(before.meta?.spawnRequestId ?? ""), terminalLaunch);
567
- if (applied && contextState) recordContextSnapshot(id, contextState, now);
568
- return applied;
569
- });
570
-
587
+ const changed = getDb().query(`UPDATE agents SET ${sets.join(", ")} WHERE id = $id AND epoch = $epoch`).run(params as never).changes > 0;
588
+ const terminalLaunch = terminalProviderLaunchId(update.meta?.terminalProviderExit ?? before.terminalProviderExit);
589
+ if (changed && nextStatus === "offline" && terminalLaunch) revokeVaultTokens(id, now, "provider_terminal_exit", before.instanceId, before.spawnRequestId, terminalLaunch);
590
+ if (changed && contextState) recordContextSnapshot(id, contextState, now);
571
591
  // NOTE (from setStatus): `offline` is a LIVENESS observation, not a confirmed death — it re-elects
572
592
  // stewards and closes pairs but must NOT release a steward's workspace claim (#1789 part 2, F2).
573
593
  // Gated on the requested status, not on a status CHANGE, matching setStatus's own condition.
@@ -575,7 +595,7 @@ export function applyAgentLifecycleUpdate(
575
595
  closeOpenPairsForAgent(id, now);
576
596
  electWorkspaceStewards();
577
597
  }
578
- return { ok: true, changed, metaWriteBytes, before, after: getPersistedAgentRuntimeCard(id) };
598
+ return { changed, metaWriteBytes, after: getPersistedAgentRuntimeCard(id) };
579
599
  }
580
600
 
581
601
  export function mergeAgentMeta(id: string, meta: Record<string, unknown>, guard?: AgentSessionGuard, now: number = Date.now()): boolean {
@@ -598,7 +618,7 @@ export function mergeAgentMeta(id: string, meta: Record<string, unknown>, guard?
598
618
  warnIfAgentMetaOversized(id, metaJson, "stored meta");
599
619
  const result = getDb()
600
620
  .query("UPDATE agents SET meta = ?, profile_projection = ?, last_seen = ? WHERE id = ?")
601
- .run(metaJson, stored.profileProjection == null ? null : JSON.stringify(stored.profileProjection), now, id);
621
+ .run(metaJson, serializeProfileProjection(id, stored.profileProjection), now, id);
602
622
  return result.changes > 0;
603
623
  }
604
624
 
@@ -614,7 +634,7 @@ export function markAgentReadyNotified(id: string, at: number = Date.now()): boo
614
634
  const merged = { ...(agent.meta ?? {}), readyNotifiedAt: at };
615
635
  const stored = splitAgentMetaForStorage(merged);
616
636
  return getDb().query("UPDATE agents SET meta = ?, profile_projection = ? WHERE id = ?")
617
- .run(JSON.stringify(stored.meta), stored.profileProjection == null ? null : JSON.stringify(stored.profileProjection), id).changes > 0;
637
+ .run(JSON.stringify(stored.meta), serializeProfileProjection(id, stored.profileProjection), id).changes > 0;
618
638
  }
619
639
 
620
640
  /** Delete specific keys from an agent's meta blob. Returns true if anything changed. Used to clear
@@ -633,7 +653,7 @@ export function clearAgentMetaKeys(id: string, keys: string[]): boolean {
633
653
  if (!changed) return false;
634
654
  const stored = splitAgentMetaForStorage(meta);
635
655
  return getDb().query("UPDATE agents SET meta = ?, profile_projection = ? WHERE id = ?")
636
- .run(JSON.stringify(stored.meta), stored.profileProjection == null ? null : JSON.stringify(stored.profileProjection), id).changes > 0;
656
+ .run(JSON.stringify(stored.meta), serializeProfileProjection(id, stored.profileProjection), id).changes > 0;
637
657
  }
638
658
 
639
659
  /**
@@ -724,7 +744,7 @@ export function recordAgentExitDiagnosticsInternal(
724
744
  .run({
725
745
  $seq: lifecycleSeq,
726
746
  $meta: JSON.stringify(stored.meta),
727
- $profileProjection: stored.profileProjection == null ? null : JSON.stringify(stored.profileProjection),
747
+ $profileProjection: serializeProfileProjection(id, stored.profileProjection),
728
748
  $id: id,
729
749
  } as never);
730
750
  return result.changes > 0 ? agent.epoch : null;
@@ -828,21 +848,27 @@ export function heartbeat(
828
848
  // withBufferedPresence / bufferedLiveAgentIds) live in the leaf module ./presence-buffer.ts so every
829
849
  // liveness reader can fold in the buffer without an import cycle (agents.ts imports channels.ts).
830
850
 
851
+ /** Heartbeat: buffers the steady-state liveness advance (flushed by `flushPresence`), writes presence-critical
852
+ * transitions at once. False if the session guard rejects or the agent is gone. Sync twin for tests; the
853
+ * transports use `recordHeartbeatAsync`, which writes the bypass on the writer thread (#1870 S7). */
854
+ export function recordHeartbeat(id: string, opts: HeartbeatInput = {}): boolean {
855
+ const beat = bufferOrBypassHeartbeat(id, opts);
856
+ return typeof beat === "boolean" ? beat : applyAgentLifecycleUpdate(id, beat, opts.guard, opts.now ?? Date.now()).changed;
857
+ }
858
+
859
+ export interface HeartbeatInput {
860
+ guard?: AgentSessionGuard;
861
+ /** Semantic status reported by the beat (bus path); undefined for the runtime-less API path. */
862
+ status?: AgentCard["status"];
863
+ runtime?: { providerCapabilities?: ProviderCapabilities; context?: ContextState; quota?: QuotaState };
864
+ now?: number;
865
+ }
866
+
831
867
  /**
832
- * Hot-path heartbeat entry point for the bus/API transports. Coalesces the steady-state liveness
833
- * advance into the in-memory buffer (flushed by `flushPresence`), but writes synchronously for
834
- * presence-critical transitions. Returns false if the session guard rejects or the agent is gone.
868
+ * The shared decision of `recordHeartbeat` and `recordHeartbeatAsync`: buffer a steady-state beat (returns
869
+ * the result) or hand back the lifecycle delta a presence-critical beat must write now.
835
870
  */
836
- export function recordHeartbeat(
837
- id: string,
838
- opts: {
839
- guard?: AgentSessionGuard;
840
- /** Semantic status reported by the beat (bus path); undefined for the runtime-less API path. */
841
- status?: AgentCard["status"];
842
- runtime?: { providerCapabilities?: ProviderCapabilities; context?: ContextState; quota?: QuotaState };
843
- now?: number;
844
- } = {},
845
- ): boolean {
871
+ export function bufferOrBypassHeartbeat(id: string, opts: HeartbeatInput): boolean | AgentLifecycleUpdate {
846
872
  if (!validateAgentSession(id, opts.guard).ok) return false;
847
873
  const current = getAgent(id);
848
874
  if (!current) return false;
@@ -861,9 +887,9 @@ export function recordHeartbeat(
861
887
  opts.runtime.context.lifecycleState !== current.context?.lifecycleState;
862
888
  const prev = pendingPresence.get(id);
863
889
  if (resurrection || statusChanged || lifecycleTransition) {
864
- // Merge any buffered-but-unflushed runtime cols into this synchronous write so the bypass never
865
- // DISCARDS a coalesced advance (a beat that carried context but was buffered, then a status
866
- // change arrives carrying none). Per column: this beat wins, else the pending value.
890
+ // Merge any buffered-but-unflushed runtime cols into this write so the bypass never DISCARDS a
891
+ // coalesced advance (a beat that carried context but was buffered, then a status change arrives
892
+ // carrying none). Per column: this beat wins, else the pending value.
867
893
  const runtime = prev
868
894
  ? {
869
895
  providerCapabilities: opts.runtime?.providerCapabilities ?? prev.providerCapabilities,
@@ -871,16 +897,10 @@ export function recordHeartbeat(
871
897
  quota: opts.runtime?.quota ?? prev.quota,
872
898
  }
873
899
  : opts.runtime;
874
- pendingPresence.delete(id); // this synchronous write supersedes any buffered advance
875
- // #2111 — was `heartbeat()` (one UPDATE) followed by `setStatus()` (a second UPDATE of the SAME
876
- // row inside its own BEGIN IMMEDIATE). One consolidated update now carries both; the explicit
877
- // status overrides the resurrection CASE exactly as the second write used to.
878
- return applyAgentLifecycleUpdate(
879
- id,
880
- { status: statusChanged ? opts.status : undefined, resurrectOnBeat: true, runtime },
881
- opts.guard,
882
- now,
883
- ).changed;
900
+ pendingPresence.delete(id); // this write supersedes any buffered advance
901
+ // #2111 — one consolidated update carries both the beat and the explicit status, which overrides
902
+ // the resurrection CASE.
903
+ return { status: statusChanged ? opts.status : undefined, resurrectOnBeat: true, runtime };
884
904
  }
885
905
 
886
906
  // Steady state: buffer. Merge context advisory markers now (matches heartbeat()'s per-beat merge),
@@ -1192,6 +1212,10 @@ export function deleteAgent(id: string): { ok: boolean; error?: string } {
1192
1212
  return deleted ? { ok: true } : { ok: false, error: "agent not found" };
1193
1213
  }
1194
1214
 
1215
+ export type OrphanedTokenRevocation = { agentId: string; jtis: string[] };
1216
+ /** One page of the orphan sweep: agents after `afterId` in id order, up to `limit` (#3776: one short write each). */
1217
+ export type OrphanedTokenPage = { revoked: OrphanedTokenRevocation[]; nextAfterId: string | null };
1218
+
1195
1219
  // #1057(1) — close the orphan-token window #1051 left open. A dead runner with no replacement
1196
1220
  // used to keep its token valid until the 24h offline prune (~720× the pre-#1051 ~2min horizon).
1197
1221
  // This sweep revokes ("stale", re-mintable — #484) the runtime tokens of agents whose process the
@@ -1204,12 +1228,18 @@ export function deleteAgent(id: string): { ok: boolean; error?: string } {
1204
1228
  // `lagGraceMs` mirrors the stale reaper's #1048/#1055 discipline: while the relay's own event
1205
1229
  // loop was stalled, a live claimant's heartbeats may not have been processed yet, so the window
1206
1230
  // widens by the observed lag rather than misreading the backlog as post-mortem silence.
1207
- export function revokeOrphanedRuntimeTokens(graceMs: number = STALE_TTL_MS, lagGraceMs = 0, now = Date.now()): Array<{ agentId: string; jtis: string[] }> {
1231
+ export function revokeOrphanedRuntimeTokens(
1232
+ graceMs: number = STALE_TTL_MS,
1233
+ lagGraceMs = 0,
1234
+ now = Date.now(),
1235
+ page: { afterId?: string; limit?: number } = {},
1236
+ ): OrphanedTokenPage {
1208
1237
  const cutoff = now - graceMs - Math.max(0, lagGraceMs);
1238
+ const limit = page.limit ?? -1;
1209
1239
  const rows = getDb()
1210
- .query(`SELECT id, meta, last_seen FROM agents WHERE status = 'offline' AND meta LIKE '%lastExitReceivedAt%' AND NOT ${reservedAgentIdSql()}`)
1211
- .all() as Array<{ id: string; meta: string | null; last_seen: number }>;
1212
- const revoked: Array<{ agentId: string; jtis: string[] }> = [];
1240
+ .query(`SELECT id, meta, last_seen FROM agents WHERE status = 'offline' AND meta LIKE '%lastExitReceivedAt%' AND NOT ${reservedAgentIdSql()} AND id > ? ORDER BY id LIMIT ?`)
1241
+ .all(page.afterId ?? "", limit) as Array<{ id: string; meta: string | null; last_seen: number }>;
1242
+ const revoked: OrphanedTokenRevocation[] = [];
1213
1243
  for (const row of rows) {
1214
1244
  const meta = parseJson<Record<string, unknown>>(row.meta ?? "{}", {});
1215
1245
  const receivedAt = typeof meta.lastExitReceivedAt === "number" ? meta.lastExitReceivedAt : undefined;
@@ -1218,7 +1248,7 @@ export function revokeOrphanedRuntimeTokens(graceMs: number = STALE_TTL_MS, lagG
1218
1248
  const jtis = revokeProviderRuntimeTokensByJti(runtimeTokenJtisFromMeta(meta), "stale", now);
1219
1249
  if (jtis.length > 0) revoked.push({ agentId: row.id, jtis });
1220
1250
  }
1221
- return revoked;
1251
+ return { revoked, nextAfterId: limit > 0 && rows.length === limit ? rows[rows.length - 1]!.id : null };
1222
1252
  }
1223
1253
 
1224
1254
  // #484: `reason` is stamped on each revocation so a stale-on-restart revocation
@@ -93,9 +93,9 @@ export function createAuthIdentity(input: {
93
93
  providerSubject: string;
94
94
  secretHash?: string | null;
95
95
  metadata?: Record<string, unknown>;
96
- }): AuthIdentity {
96
+ }, submittedAt: number = Date.now()): AuthIdentity {
97
97
  const id = randomUUID();
98
- const now = Date.now();
98
+ const now = submittedAt;
99
99
  getDb()
100
100
  .query(
101
101
  `INSERT INTO auth_identities (id, user_id, provider, provider_subject, secret_hash, metadata, created_at)
@@ -0,0 +1,11 @@
1
+ // #3799 — automation scans (run listing, reconcile/precheck/dispatch ticks) on the reader pool.
2
+ // A cold scan of automation_runs once blocked the hub loop for seconds on swap-bound I/O.
3
+ import { listAutomationRuns, listDispatchableQueuedRuns, listDueAutomations, listPendingPrecheckRuns, listReconcilableRuns } from "../automations/storage.ts";
4
+
5
+ export const AUTOMATION_READ_OPS = {
6
+ "automations.listRuns": (args: { automationId?: string; status?: string; limit?: number }) => listAutomationRuns(args),
7
+ "automations.pendingPrecheckRuns": () => listPendingPrecheckRuns(),
8
+ "automations.reconcilableRuns": () => listReconcilableRuns(),
9
+ "automations.dispatchableQueuedRuns": () => listDispatchableQueuedRuns(),
10
+ "automations.dueAutomations": (args: { now: number }) => listDueAutomations(args.now),
11
+ };
@@ -0,0 +1,46 @@
1
+ import { ValidationError } from "@humwick/sdk";
2
+ import { insertAutomation, updateAutomationNormalized, deleteAutomation } from "../automations/persistence";
3
+ import { nextScheduledAt } from "../automations/cron";
4
+ import { getAutomation, getAutomationRun, hasActiveRun, insertRun, enqueueAutomationRun, updateRun, cancelActiveRuns, rescheduleAutomation } from "../automations/storage";
5
+ import type { Automation } from "../types";
6
+ import type { WriterOpSpec } from "./write-ops";
7
+
8
+ function admitRun(input: { automationId: string; now: number; manual?: boolean; queuedRunId?: string }) {
9
+ const automation = getAutomation(input.automationId);
10
+ if (!automation) return null;
11
+ const active = hasActiveRun(automation.id);
12
+ if (input.queuedRunId) {
13
+ const run = getAutomationRun(input.queuedRunId);
14
+ if (!run || run.automationId !== automation.id || run.status !== "scheduled" || active) return null;
15
+ updateRun(run.id, { status: "dispatching" }, input.now);
16
+ return { automation, run: getAutomationRun(run.id)! };
17
+ }
18
+ if (input.manual) {
19
+ if (active) throw new ValidationError("automation already has an active run");
20
+ } else {
21
+ if (!automation.enabled || automation.nextRunAt === undefined || automation.nextRunAt > input.now) return null;
22
+ if (active && automation.concurrencyPolicy === "replace") cancelActiveRuns(automation.id, input.now, "Replaced by newer scheduled run");
23
+ else if (active && automation.concurrencyPolicy === "queue") enqueueAutomationRun(automation, automation.nextRunAt, input.now);
24
+ const next = automation.enabled ? nextScheduledAt(automation.schedule, automation.timezone, input.now) : undefined;
25
+ rescheduleAutomation(automation, next, input.now);
26
+ if (active && automation.concurrencyPolicy !== "replace") return null;
27
+ }
28
+ const run = insertRun(automation, input.manual ? input.now : automation.nextRunAt ?? input.now, input.now);
29
+ return { automation: getAutomation(automation.id)!, run };
30
+ }
31
+
32
+ export const AUTOMATION_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = Object.freeze({
33
+ "automations.create": { offLoop: true, idempotent: false, fn: (a: { normalized: Parameters<typeof insertAutomation>[0]; now: number }) => insertAutomation(a.normalized, a.now) },
34
+ "automations.update": { offLoop: true, idempotent: false, fn: (a: { id: string; normalized: Parameters<typeof updateAutomationNormalized>[1]; expected: Automation; now: number }) => {
35
+ const current = getAutomation(a.id);
36
+ if (!current || JSON.stringify(current) !== JSON.stringify(a.expected)) throw new ValidationError("automation changed or was deleted during catalog validation");
37
+ return updateAutomationNormalized(a.id, a.normalized, a.now);
38
+ } },
39
+ "automations.delete": { offLoop: true, idempotent: true, fn: (a: { id: string }) => deleteAutomation(a.id) },
40
+ "automations.admitRun": { offLoop: true, idempotent: false, fn: admitRun },
41
+ "automations.insertRun": { offLoop: true, idempotent: false, fn: (a: Parameters<typeof insertRun>) => insertRun(...a) },
42
+ "automations.enqueueRun": { offLoop: true, idempotent: false, fn: (a: Parameters<typeof enqueueAutomationRun>) => enqueueAutomationRun(...a) },
43
+ "automations.updateRun": { offLoop: true, idempotent: false, fn: (a: Parameters<typeof updateRun>) => updateRun(...a) ?? null },
44
+ "automations.cancelRuns": { offLoop: true, idempotent: false, fn: (a: Parameters<typeof cancelActiveRuns>) => cancelActiveRuns(...a) ?? null },
45
+ "automations.reschedule": { offLoop: true, idempotent: false, fn: (a: Parameters<typeof rescheduleAutomation>) => rescheduleAutomation(...a) ?? null },
46
+ });
@@ -161,11 +161,11 @@ export function searchEntries(
161
161
  return rows.map(rowToEntry);
162
162
  }
163
163
 
164
- export function retractEntry(id: string): BlackboardEntry | null {
164
+ export function retractEntry(id: string, submittedAt: number = Date.now()): BlackboardEntry | null {
165
165
  const existing = getEntry(id);
166
166
  if (!existing) return null;
167
167
  assertStatus("retracted");
168
168
  getDb().query("UPDATE blackboard_entries SET status = 'retracted', updated_at = ? WHERE id = ?")
169
- .run(Date.now(), id);
169
+ .run(submittedAt, id);
170
170
  return getEntry(id);
171
171
  }
@@ -0,0 +1,32 @@
1
+ import { getAgent } from "./agents";
2
+ import { createCommandInternal } from "../commands-db";
3
+ import { countActiveBrowserSessions, getBrowserSessionRow, insertBrowserSession, transitionBrowserSession } from "./browser-sessions";
4
+ import { getOrchestrator } from "./orchestrators";
5
+ import type { BrowserLimits } from "@humwick/sdk";
6
+
7
+ export interface StartBrowserWrite {
8
+ id: string; commandId: string; agentId: string; instanceId?: string; epoch?: number;
9
+ orchestratorId: string; limits: BrowserLimits;
10
+ }
11
+ export function startBrowserBody(input: StartBrowserWrite, now: number) {
12
+ const agent = getAgent(input.agentId);
13
+ if (!agent || agent.status === "offline" || agent.instanceId !== input.instanceId || agent.epoch !== input.epoch) return { conflict: "agent" as const };
14
+ const host = getOrchestrator(input.orchestratorId);
15
+ if (!host || host.status !== "online") return { conflict: "host" as const };
16
+ if (countActiveBrowserSessions({ agentId: input.agentId }) >= input.limits.perAgent) return { conflict: "agentLimit" as const };
17
+ if (countActiveBrowserSessions({ orchestratorId: host.id }) >= input.limits.perHost) return { conflict: "hostLimit" as const };
18
+ const command = createCommandInternal({ id: input.commandId, input: { type: "browser.start", source: input.agentId, target: host.agentId, correlationId: input.id,
19
+ params: { sessionId: input.id, agentId: input.agentId, orchestratorId: host.id, idleTimeoutMs: input.limits.idleTimeoutMinutes * 60_000, hostSessionLimit: input.limits.perHost } } }, now);
20
+ const row = insertBrowserSession({ id: input.id, agentId: input.agentId, orchestratorId: host.id, startCommandId: command.id, now });
21
+ return { row, command };
22
+ }
23
+
24
+ export function stopBrowserBody(input: { id: string; reason: string; commandId: string }, now: number) {
25
+ const row = getBrowserSessionRow(input.id);
26
+ if (!row || (row.status !== "starting" && row.status !== "running")) return { row };
27
+ const host = getOrchestrator(row.orchestratorId);
28
+ if (!host) return { row: transitionBrowserSession(row.id, ["starting", "running"], { status: "stopped", stoppedAt: now, error: "orchestrator no longer registered" }, now) };
29
+ const command = createCommandInternal({ id: input.commandId, input: { type: "browser.stop", source: "system", target: host.agentId, correlationId: row.id,
30
+ params: { sessionId: row.id, agentId: row.agentId, orchestratorId: host.id, reason: input.reason } } }, now);
31
+ return { row: transitionBrowserSession(row.id, ["starting", "running"], { status: "stopping", stopCommandId: command.id }, now), command };
32
+ }
@@ -31,8 +31,10 @@ export const BUS_OUTBOX_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = Obje
31
31
  "bus.append": {
32
32
  offLoop: true,
33
33
  // Appending assigns a new sequence row; retries reconcile by idempotency key rather than
34
- // inserting a second durable event after a phantom acknowledgement.
34
+ // inserting a second durable event after a phantom acknowledgement. A plain emit never retries,
35
+ // so it goes keyless and writes no ledger row (#3614).
35
36
  idempotent: false,
37
+ atMostOnce: true,
36
38
  fn: (args: BusAppendOpArgs, ctx: WriterOpContext) => ({
37
39
  ...appendRelayEventInternal(args.type, args.source, args.data, args.subject, ctx.now)!, replayed: false,
38
40
  }),