@humwick/server 0.130.2 → 0.130.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/bundled/prompts/manifest.json +1 -0
  2. package/bundled/prompts/task.hydration.md +1 -1
  3. package/bundled/roles/builder.md +1 -1
  4. package/docs/guides/sub-coordinators.md +12 -5
  5. package/docs/guides/tools-coordination.md +1 -0
  6. package/docs/guides/workflows.md +16 -0
  7. package/docs/openapi.json +175 -4
  8. package/package.json +8 -7
  9. package/public/assets/{MessageBubble-BWLqMGKG.js → MessageBubble-BOkmEvgZ.js} +2 -2
  10. package/public/assets/{PlanGraphPanel-3TlIQpjk.js → PlanGraphPanel-BkaDJp0r.js} +2 -2
  11. package/public/assets/{TraceView-Wimm0Czv.js → TraceView-B99Uu2yT.js} +2 -2
  12. package/public/assets/{VaultDecisionCard-Bau_vNax.js → VaultDecisionCard-DUIfTTFF.js} +2 -2
  13. package/public/assets/{activity-CrSurn-r.js → activity-ZIX0N1El.js} +2 -2
  14. package/public/assets/{agent-lineage-CknAJKcb.js → agent-lineage-kq9TPYFw.js} +2 -2
  15. package/public/assets/agent-liveness-DSQY1Aa_.js +2 -0
  16. package/public/assets/{agent-name-DKbiIhBo.js → agent-name-C_7F4DFR.js} +2 -2
  17. package/public/assets/{agent-profiles-DwF6EQ4R.js → agent-profiles-BNOcrGcY.js} +2 -2
  18. package/public/assets/{agent-project-badge-Diz4Sjjb.js → agent-project-badge-B6yAh70a.js} +2 -2
  19. package/public/assets/{agent-tools-CRhpRQza.js → agent-tools-CcrhmOzF.js} +2 -2
  20. package/public/assets/{agent-type-icon-LrUEU3lB.js → agent-type-icon-CXSLrKiq.js} +2 -2
  21. package/public/assets/{agents-B-v66C-4.js → agents-DIZG97_X.js} +2 -2
  22. package/public/assets/{analytics-BqCb-LKi.js → analytics-rasmoPjR.js} +2 -2
  23. package/public/assets/{artifact-viewer-kf4pGuAR.js → artifact-viewer-tBpTrEPb.js} +2 -2
  24. package/public/assets/{artifacts-DJevXcvg.js → artifacts-BNkrynP1.js} +2 -2
  25. package/public/assets/{artifacts-D32zyw4Y.js → artifacts-Bjq-ZyBA.js} +2 -2
  26. package/public/assets/{automation-BpRajx_5.js → automation-Cx422L3L.js} +2 -2
  27. package/public/assets/{backlog-D_UjTdzX.js → backlog-RuFQ8PUu.js} +2 -2
  28. package/public/assets/{busy-health-N3VEh4ao.js → busy-health-BvNQ9g5x.js} +2 -2
  29. package/public/assets/{channels-9jopungq.js → channels-DNbKAS0I.js} +2 -2
  30. package/public/assets/{chat-CSXrTB3C.js → chat-Bp3Fx73h.js} +3 -3
  31. package/public/assets/{code-preview-p1NnmqK0.js → code-preview-KIRZA6cz.js} +2 -2
  32. package/public/assets/{connectors-CZdqlDNL.js → connectors-k7vO4vvc.js} +2 -2
  33. package/public/assets/{cosmos-BgdsE4dG.js → cosmos-BuVoq1aw.js} +2 -2
  34. package/public/assets/{crate-agent-30aXTKva.js → crate-agent-irqlt4NH.js} +2 -2
  35. package/public/assets/{dependency-graph-B_jvw2GE.js → dependency-graph-D_rurNBz.js} +2 -2
  36. package/public/assets/{deploys-DoN6bAb5.js → deploys-yzZqIpxE.js} +2 -2
  37. package/public/assets/{display-BrKWFGJz.js → display-BemJG1f_.js} +2 -2
  38. package/public/assets/{files-D6XEu8Ng.js → files-DXWcrxOz.js} +2 -2
  39. package/public/assets/{fleet-C7jQWbw2.js → fleet-TEuOCZXE.js} +2 -2
  40. package/public/assets/{fleet-metrics-BiDs3MLx.js → fleet-metrics-BGoDAFI-.js} +2 -2
  41. package/public/assets/{formatted-body-impl-DyG0WsQS.js → formatted-body-impl-BB9eq9nN.js} +2 -2
  42. package/public/assets/{formatted-body-CQBwc1fb.js → formatted-body-qy2nTD_1.js} +3 -3
  43. package/public/assets/{host-providers-dialog-DKaW31dN.js → host-providers-dialog-BGPHxuwT.js} +2 -2
  44. package/public/assets/{index-CRHep3M9.js → index-BC5XZc0z.js} +5 -5
  45. package/public/assets/{index-MYAIwYTX.css → index-D8Rp9pz2.css} +1 -1
  46. package/public/assets/{insights-CzrtkpOE.js → insights-C-KQG0h-.js} +2 -2
  47. package/public/assets/{integrations-aVsUmigt.js → integrations-ClPRPyKU.js} +2 -2
  48. package/public/assets/{issue-ref-chip-BnSlM_95.js → issue-ref-chip-DbH8J9Ak.js} +2 -2
  49. package/public/assets/{log-viewer-qe7Ee47Z.js → log-viewer-PH4zVn24.js} +2 -2
  50. package/public/assets/{maintenance-NfjqFZAk.js → maintenance-5lV43uTL.js} +2 -2
  51. package/public/assets/{managed-agents-BiH0HgaE.js → managed-agents-BdgU35aX.js} +2 -2
  52. package/public/assets/{markdown-preview-BixaT3Xr.js → markdown-preview-DNT4OUwQ.js} +3 -3
  53. package/public/assets/{markdown-preview-impl-DNGlWIS3.js → markdown-preview-impl-CnCcPy0A.js} +2 -2
  54. package/public/assets/{memory-DNsCl6UX.js → memory--GgWH1gH.js} +2 -2
  55. package/public/assets/{messages-DopU1L1X.js → messages-CzFl_97O.js} +2 -2
  56. package/public/assets/{orchestrators-Cq7ckLQT.js → orchestrators-CVvJVkzv.js} +2 -2
  57. package/public/assets/overview-DsrZvE86.js +2 -0
  58. package/public/assets/{pairs-DE_m6rrE.js → pairs-D2d0d2py.js} +2 -2
  59. package/public/assets/{profile-icon-B3rfh77F.js → profile-icon-_SMuSbYF.js} +2 -2
  60. package/public/assets/{project-profile-instructions-DQWZE0kA.js → project-profile-instructions-Apn15y43.js} +2 -2
  61. package/public/assets/{projects-Br2Bd2h1.js → projects-D3B6kto5.js} +2 -2
  62. package/public/assets/{prompt-settings-BKvFsvGD.js → prompt-settings-DnPB6Ez6.js} +2 -2
  63. package/public/assets/provider-display-bWwiuedV.js +2 -0
  64. package/public/assets/{registry-Cw38_6gW.js → registry-D790cIhN.js} +2 -2
  65. package/public/assets/run-card-BCro-Odj.js +2 -0
  66. package/public/assets/{secrets-DxI-vzSq.js → secrets-CVXvfvbU.js} +2 -2
  67. package/public/assets/{service-access-settings-D9s_VJbd.js → service-access-settings-D3Xxqb9w.js} +2 -2
  68. package/public/assets/{settings-CKZTVGIx.js → settings-CoUC7Jci.js} +2 -2
  69. package/public/assets/shipping-D_Lp9n_J.js +2 -0
  70. package/public/assets/{stats-DyUBKyWI.js → stats-CXiNjB9S.js} +2 -2
  71. package/public/assets/{status-dot-DYqlEUhJ.js → status-dot-C703YIy1.js} +2 -2
  72. package/public/assets/store-BgDALGIX.js +9 -0
  73. package/public/assets/{tasks-Bh7Chr4-.js → tasks-DO0WpJCx.js} +2 -2
  74. package/public/assets/{teams-bowI7qVY.js → teams-FGkdi_tL.js} +2 -2
  75. package/public/assets/{terminal-viewer-BgVLHdsU.js → terminal-viewer-Dh8dSC7e.js} +3 -3
  76. package/public/assets/{terminal-viewer-impl-Dz22UPy6.js → terminal-viewer-impl-B5Zriip3.js} +2 -2
  77. package/public/assets/{use-agent-terminal-DSQQ-iY7.js → use-agent-terminal-CRUVDvLC.js} +2 -2
  78. package/public/assets/{use-decisions-samMQhQf.js → use-decisions-CoaqRh4l.js} +2 -2
  79. package/public/assets/{use-project-list-59LheVP7.js → use-project-list-X-BgT53X.js} +2 -2
  80. package/public/assets/{use-selectors-BZa25xEB.js → use-selectors-0X_UZkk-.js} +2 -2
  81. package/public/assets/{user-avatar-DHxlvUvV.js → user-avatar-CkLhVBGu.js} +2 -2
  82. package/public/assets/{versioned-prompt-editor-BmED5DnJ.js → versioned-prompt-editor-BkTi7eim.js} +2 -2
  83. package/public/assets/{work-queue-CSvpuNLz.js → work-queue-DDOLEyKo.js} +2 -2
  84. package/public/assets/{workflow-marker-DAZcj5qt.js → workflow-marker-CzOsB8BM.js} +2 -2
  85. package/public/assets/{workflows-DdmxRSyg.js → workflows-DJilvmRM.js} +2 -2
  86. package/public/assets/{workspaces-BxeKfVuF.js → workspaces-CHcfbLR3.js} +2 -2
  87. package/public/cosmos.html +4 -4
  88. package/public/index.html +29 -29
  89. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  90. package/runner/src/adapters/claude-api.ts +1 -1
  91. package/runner/src/adapters/claude-headless.ts +1 -1
  92. package/runner/src/adapters/claude-launch-exit.ts +26 -0
  93. package/runner/src/adapters/claude-session-probe.ts +1 -1
  94. package/runner/src/adapters/claude-tmux.ts +38 -10
  95. package/runner/src/adapters/claude.ts +28 -75
  96. package/runner/src/adapters/provider-quota-harvest.ts +20 -71
  97. package/runner/src/agent-runner/lifecycle-milestones.ts +2 -2
  98. package/runner/src/agent-runner/liveness-exchange.ts +104 -0
  99. package/runner/src/claude-system-prompt.ts +49 -0
  100. package/runner/src/launch-assembly.ts +14 -10
  101. package/runner/src/profile-home.ts +1 -1
  102. package/runner/src/project-instructions.ts +2 -2
  103. package/runner/src/provider-command.ts +18 -0
  104. package/runner/src/provider-setup.ts +3 -2
  105. package/runner/src/runner-core.ts +14 -15
  106. package/runner/src/runner-helpers.ts +0 -8
  107. package/runner/src/session-scratch.ts +6 -2
  108. package/runner/test-support/provisioning-context.ts +4 -2
  109. package/runner/test-support/runner-harness.ts +2 -1
  110. package/scripts/steward-policy-cleanup.ts +2 -2
  111. package/src/agent-authz.ts +2 -2
  112. package/src/agent-drive-arbiter.ts +3 -8
  113. package/src/agent-exit-cleanup-async.ts +2 -2
  114. package/src/agent-exit-cleanup.ts +23 -19
  115. package/src/agent-lifecycle-events.ts +112 -85
  116. package/src/agent-ref.ts +3 -2
  117. package/src/agent-status-events.ts +43 -14
  118. package/src/auth/login-link.ts +35 -0
  119. package/src/auth/password.ts +4 -3
  120. package/src/auth/session-refresh.ts +1 -1
  121. package/src/auth/session.test-fixture.ts +2 -2
  122. package/src/auth/session.ts +7 -7
  123. package/src/automations/crud.ts +8 -81
  124. package/src/automations/dispatch.ts +33 -58
  125. package/src/automations/index.ts +1 -1
  126. package/src/automations/persistence.ts +65 -0
  127. package/src/automations/precheck.ts +18 -16
  128. package/src/automations/read-async.ts +11 -0
  129. package/src/automations/reconcile.ts +30 -39
  130. package/src/automations/storage.ts +33 -10
  131. package/src/automations/write-async.ts +33 -0
  132. package/src/branch-land-notice.ts +3 -3
  133. package/src/branch-landed.ts +25 -23
  134. package/src/bus.ts +21 -19
  135. package/src/cd-deploy-notify.ts +2 -2
  136. package/src/ci/notifications.ts +4 -4
  137. package/src/ci/root-missing.ts +3 -3
  138. package/src/ci/transition-notify.ts +5 -5
  139. package/src/claude-app/oauth-http.ts +3 -3
  140. package/src/cli/index.ts +7 -1
  141. package/src/cli/init.ts +53 -0
  142. package/src/cli/orchestrator.ts +1 -7
  143. package/src/cli/setup.ts +6 -4
  144. package/src/cli/workflow.ts +12 -3
  145. package/src/commands-db.ts +4 -4
  146. package/src/commands-write.ts +8 -0
  147. package/src/compaction-watch.ts +10 -8
  148. package/src/config-store-write.ts +2 -2
  149. package/src/config.ts +4 -11
  150. package/src/connectors.ts +10 -8
  151. package/src/context-advisory.ts +22 -21
  152. package/src/db/agent-action-write.ts +36 -0
  153. package/src/db/agent-control-async.ts +9 -0
  154. package/src/db/agent-control-write.ts +49 -0
  155. package/src/db/agent-effort-observe.ts +22 -0
  156. package/src/db/agent-meta.ts +14 -3
  157. package/src/db/agents-async.ts +8 -5
  158. package/src/db/agents.ts +15 -12
  159. package/src/db/auth-identities.ts +2 -2
  160. package/src/db/automation-read-ops.ts +11 -0
  161. package/src/db/automation-write-ops.ts +46 -0
  162. package/src/db/blackboard.ts +2 -2
  163. package/src/db/browser-session-write.ts +32 -0
  164. package/src/db/bus-outbox-write-ops.ts +3 -1
  165. package/src/db/checkout-refresh-schema.ts +47 -0
  166. package/src/db/checkout-refresh.ts +5 -5
  167. package/src/db/command-agent-profile-backfill.ts +39 -0
  168. package/src/db/command-agent-profiles.ts +5 -1
  169. package/src/db/command-retention.ts +126 -0
  170. package/src/db/commands-planner-stats.test-fixture.ts +8 -0
  171. package/src/db/commands-read-ops.ts +16 -0
  172. package/src/db/connection.ts +1 -182
  173. package/src/db/context-carry-write.ts +74 -0
  174. package/src/db/continuations.ts +4 -4
  175. package/src/db/db-error-registry.ts +12 -0
  176. package/src/db/gateway.ts +26 -133
  177. package/src/db/history-retention-ops.ts +13 -0
  178. package/src/db/inbox-async.ts +2 -2
  179. package/src/db/inbox-read-ops.ts +1 -1
  180. package/src/db/inbox.ts +9 -3
  181. package/src/db/issue-associations.ts +2 -2
  182. package/src/db/issue-refs-async.ts +4 -1
  183. package/src/db/issue-refs-read-ops.ts +6 -0
  184. package/src/db/issue-refs.ts +8 -8
  185. package/src/db/kernel-event-log-schema.ts +2 -0
  186. package/src/db/land-boundaries.ts +51 -5
  187. package/src/db/land-gate-attestations.ts +2 -2
  188. package/src/db/landing-receipts.ts +2 -2
  189. package/src/db/lifecycle-context-write.ts +5 -0
  190. package/src/db/lifecycle-tail-async.ts +76 -0
  191. package/src/db/lifecycle-tail-write-ops.ts +62 -0
  192. package/src/db/lifecycle-write-window.ts +2 -1
  193. package/src/db/lineage-pair-dedupe-sql.ts +3 -3
  194. package/src/db/main-connection-mode.ts +11 -0
  195. package/src/db/main-connection-writes.ts +20 -2
  196. package/src/db/maintenance-job-runs-async.ts +2 -2
  197. package/src/db/maintenance-job-write-ops.ts +1 -1
  198. package/src/db/maintenance-pauses.ts +2 -2
  199. package/src/db/message-send.ts +4 -0
  200. package/src/db/messages.ts +31 -25
  201. package/src/db/migrations.ts +18 -1
  202. package/src/db/notification-write-ops.ts +19 -0
  203. package/src/db/operator-answer-write.ts +19 -0
  204. package/src/db/orchestrators.ts +10 -4
  205. package/src/db/pairs-async.ts +22 -1
  206. package/src/db/pairs-write-ops.ts +8 -3
  207. package/src/db/pairs.ts +41 -48
  208. package/src/db/plan-dispatch-schema.ts +5 -1
  209. package/src/db/plan-ready-notices.ts +43 -0
  210. package/src/db/plan-tools-include-migration.ts +36 -0
  211. package/src/db/plans-write-ops.ts +2 -0
  212. package/src/db/presence-buffer.ts +5 -0
  213. package/src/db/presence-loop.ts +18 -23
  214. package/src/db/presence-write.ts +0 -6
  215. package/src/db/project-entries-async.ts +14 -0
  216. package/src/db/project-entries-read-ops.ts +5 -1
  217. package/src/db/project-entries-write-ops.ts +8 -0
  218. package/src/db/project-entries.ts +15 -12
  219. package/src/db/project-journal.ts +2 -2
  220. package/src/db/project-trust-approvals.ts +2 -2
  221. package/src/db/prompt-templates.ts +4 -4
  222. package/src/db/read-op-marshaling-fixtures.ts +18 -0
  223. package/src/db/read-ops.ts +4 -0
  224. package/src/db/retention.ts +13 -2
  225. package/src/db/review-publish-write.ts +8 -0
  226. package/src/db/runtime-admin-async.ts +19 -0
  227. package/src/db/runtime-admin-write-ops.ts +36 -0
  228. package/src/db/runtime-tail-async.ts +288 -0
  229. package/src/db/runtime-tail-write-ops.ts +97 -0
  230. package/src/db/schema.ts +4 -1
  231. package/src/db/spawn-budget.ts +5 -0
  232. package/src/db/spawn-delegation.ts +3 -12
  233. package/src/db/sql-audit-indexes.ts +3 -0
  234. package/src/db/stats-async.ts +5 -3
  235. package/src/db/task-entity.ts +5 -4
  236. package/src/db/team-claim-policy.ts +60 -0
  237. package/src/db/teams-async.ts +4 -0
  238. package/src/db/teams-write-ops.ts +4 -0
  239. package/src/db/terminal-events.ts +15 -0
  240. package/src/db/timer-cutover-bodies.ts +292 -0
  241. package/src/db/timer-cutover-core.ts +37 -278
  242. package/src/db/timer-cutover-state.ts +40 -0
  243. package/src/db/timer-cutover-write-ops.ts +1 -40
  244. package/src/db/token-db-write-ops.ts +2 -0
  245. package/src/db/token-standing-async.ts +12 -0
  246. package/src/db/token-standing.ts +6 -9
  247. package/src/db/token-usage-retention.ts +33 -0
  248. package/src/db/token-usage-write-ops.ts +1 -1
  249. package/src/db/token-usage.ts +4 -1
  250. package/src/db/user-invites-async.ts +13 -0
  251. package/src/db/user-invites.ts +3 -3
  252. package/src/db/users.ts +14 -6
  253. package/src/db/workflow-execution.ts +3 -3
  254. package/src/db/workspaces.ts +8 -5
  255. package/src/db/write-ops.ts +31 -12
  256. package/src/db/writer-fault-seam.ts +2 -9
  257. package/src/db/writer-fault-test-ops.ts +18 -0
  258. package/src/db/writer-gateway.ts +42 -46
  259. package/src/dev.ts +12 -16
  260. package/src/event-loop-lag.ts +4 -2
  261. package/src/event-loop-yield.ts +2 -2
  262. package/src/events.ts +10 -8
  263. package/src/host-provider-store.ts +5 -4
  264. package/src/hub-metrics-report.ts +5 -1
  265. package/src/hub-metrics.ts +38 -18
  266. package/src/init.ts +299 -0
  267. package/src/injection-sweep-pacing.ts +6 -8
  268. package/src/invite-link.ts +16 -9
  269. package/src/land-gate-notifications.ts +11 -10
  270. package/src/land-gate-queue-progress.ts +3 -3
  271. package/src/land-settle-dispatch.ts +52 -92
  272. package/src/lifecycle-context-pressure.ts +11 -10
  273. package/src/lifecycle-manager.ts +104 -98
  274. package/src/maintenance/breaker.ts +18 -16
  275. package/src/maintenance/checkout-refresh.ts +18 -1
  276. package/src/maintenance/critical-job-watchdog.ts +3 -3
  277. package/src/maintenance/events.ts +3 -3
  278. package/src/maintenance/history-retention-job.ts +30 -0
  279. package/src/maintenance/jobs.ts +29 -67
  280. package/src/maintenance/long-running-work.ts +3 -1
  281. package/src/maintenance/offline-agent-prune-job.ts +28 -0
  282. package/src/maintenance/orphaned-sessions.ts +5 -4
  283. package/src/maintenance/pauses.ts +4 -10
  284. package/src/maintenance/plan-ready-notice-job.ts +71 -0
  285. package/src/maintenance/scheduler.ts +18 -13
  286. package/src/maintenance/stalled-delivery-pager.ts +4 -4
  287. package/src/maintenance/teams.ts +19 -30
  288. package/src/maintenance/workspaces.ts +17 -27
  289. package/src/managed-policy-escalation.ts +7 -7
  290. package/src/managed-policy.ts +3 -3
  291. package/src/managed-provider-gate.ts +5 -4
  292. package/src/managed-spawn-reservation.ts +5 -4
  293. package/src/mcp/index.ts +8 -8
  294. package/src/mcp/output-descriptions.ts +1 -1
  295. package/src/mcp/presentation.ts +2 -1
  296. package/src/mcp/runtime-output.ts +6 -1
  297. package/src/mcp/self-care-visibility.ts +2 -2
  298. package/src/mcp/spawn-targets-matrix.ts +10 -1
  299. package/src/mcp/tool-groups.ts +3 -2
  300. package/src/mcp/tool-roles.ts +81 -0
  301. package/src/mcp/tools-workspace.ts +1 -1
  302. package/src/mcp-blackboard-tools.ts +6 -5
  303. package/src/mcp-decision-tools.ts +7 -7
  304. package/src/mcp-egress-tools.ts +10 -9
  305. package/src/mcp-issue-activity-tools.ts +2 -2
  306. package/src/mcp-issue-association-tools.ts +4 -4
  307. package/src/mcp-issue-ref-tools.ts +3 -3
  308. package/src/mcp-merge-tools.ts +5 -5
  309. package/src/mcp-notification-subscription-tools.ts +14 -15
  310. package/src/mcp-output-levels.test-fixture.ts +1 -1
  311. package/src/mcp-profile-trust-tools.ts +1 -1
  312. package/src/mcp-project-journal-tools.ts +4 -12
  313. package/src/mcp-project-tools.ts +17 -18
  314. package/src/mcp-routing-policy-tools.ts +3 -2
  315. package/src/mcp-team-tools.ts +6 -6
  316. package/src/mcp-workflow-tools.ts +5 -3
  317. package/src/memory-area-injection.ts +13 -12
  318. package/src/memory-boundary-capture.ts +6 -6
  319. package/src/memory-injection.ts +45 -43
  320. package/src/merge-pause-maintenance.ts +5 -4
  321. package/src/notification-router.ts +44 -17
  322. package/src/notify.ts +5 -5
  323. package/src/observed-reset-refresh.ts +4 -4
  324. package/src/operator-alarm.ts +2 -5
  325. package/src/project-ingest.ts +6 -6
  326. package/src/project-instructions.ts +8 -1
  327. package/src/project-trust.ts +12 -11
  328. package/src/prompt-resolver.ts +3 -3
  329. package/src/provider-quota-async.ts +5 -7
  330. package/src/provider-timeline-event.ts +4 -7
  331. package/src/quota-band-delivery.ts +2 -2
  332. package/src/recipe-runner.ts +4 -3
  333. package/src/retention-config-store.ts +4 -3
  334. package/src/reviewer-pipeline.ts +11 -10
  335. package/src/routes/_route.ts +4 -4
  336. package/src/routes/_shared.ts +13 -12
  337. package/src/routes/agent-effort.ts +5 -5
  338. package/src/routes/agent-heartbeat-quota.ts +23 -0
  339. package/src/routes/agent-keep.ts +1 -1
  340. package/src/routes/agent-reporting.ts +1 -1
  341. package/src/routes/agent-self-effort.ts +5 -5
  342. package/src/routes/agent-sessions.ts +24 -24
  343. package/src/routes/agents-spawn.ts +1 -1
  344. package/src/routes/agents.ts +17 -119
  345. package/src/routes/auth.ts +44 -17
  346. package/src/routes/authority-audit.ts +2 -2
  347. package/src/routes/automations.ts +6 -5
  348. package/src/routes/channel-binding-delete.ts +1 -1
  349. package/src/routes/channel-output.ts +3 -3
  350. package/src/routes/claude-api-budget.ts +5 -5
  351. package/src/routes/commands-listing.ts +1 -1
  352. package/src/routes/commands.ts +29 -27
  353. package/src/routes/context-resets.ts +2 -2
  354. package/src/routes/coordinator-teams.ts +1 -1
  355. package/src/routes/decisions.ts +2 -2
  356. package/src/routes/host-providers.ts +18 -0
  357. package/src/routes/host-secret-files.ts +1 -1
  358. package/src/routes/hosts.ts +11 -11
  359. package/src/routes/inbox.ts +3 -2
  360. package/src/routes/index.ts +7 -3
  361. package/src/routes/integrations.ts +9 -7
  362. package/src/routes/issue-activity.ts +2 -2
  363. package/src/routes/issue-associations.ts +4 -4
  364. package/src/routes/issue-refs.ts +3 -3
  365. package/src/routes/kernel-timers-operator.ts +1 -1
  366. package/src/routes/memory.ts +1 -1
  367. package/src/routes/merges.ts +11 -11
  368. package/src/routes/messages.ts +23 -17
  369. package/src/routes/orchestrator-bootstrap.ts +3 -1
  370. package/src/routes/orchestrator-host-registration.ts +2 -0
  371. package/src/routes/orchestrator-host-utilization.ts +2 -2
  372. package/src/routes/orchestrator-proxy.ts +2 -2
  373. package/src/routes/orchestrator.ts +27 -18
  374. package/src/routes/pairs.ts +8 -8
  375. package/src/routes/project-profile-instructions.ts +1 -1
  376. package/src/routes/project-trust.ts +1 -1
  377. package/src/routes/projects.ts +16 -16
  378. package/src/routes/prompt-templates.ts +12 -12
  379. package/src/routes/provider-quotas.ts +10 -10
  380. package/src/routes/run-command.ts +1 -1
  381. package/src/routes/secrets-backup.ts +4 -5
  382. package/src/routes/secrets-import.ts +3 -4
  383. package/src/routes/secrets-vault.ts +12 -14
  384. package/src/routes/settings.ts +1 -1
  385. package/src/routes/shipping.ts +9 -1
  386. package/src/routes/spawn-policy.ts +8 -7
  387. package/src/routes/sse.ts +2 -2
  388. package/src/routes/team-templates.ts +7 -7
  389. package/src/routes/teams.ts +10 -10
  390. package/src/routes/tokens.ts +18 -17
  391. package/src/routes/users.ts +24 -24
  392. package/src/routes/viewer-read.ts +3 -3
  393. package/src/routes/web-tool-calls.ts +4 -4
  394. package/src/routes/workflows.ts +2 -2
  395. package/src/routes/workspaces.ts +17 -16
  396. package/src/routing-policy-push.ts +6 -6
  397. package/src/runtime-grant.ts +17 -11
  398. package/src/runtime-install.ts +30 -0
  399. package/src/runtime-tokens.ts +20 -28
  400. package/src/secrets-broker/config.ts +1 -1
  401. package/src/secrets-broker/service.ts +2 -2
  402. package/src/security.ts +3 -1
  403. package/src/self-resume-carry.ts +21 -110
  404. package/src/self-resume-supersede.ts +4 -3
  405. package/src/self-resume.ts +54 -66
  406. package/src/server-background.ts +1 -1
  407. package/src/server.ts +25 -26
  408. package/src/services/agent-action.ts +12 -31
  409. package/src/services/agent-effort.ts +7 -32
  410. package/src/services/agent-hang-watchdog-job.ts +2 -2
  411. package/src/services/agent-heartbeat.ts +166 -0
  412. package/src/services/agent-reporting.ts +1 -1
  413. package/src/services/auth-context.ts +6 -0
  414. package/src/services/browser-inventory.ts +3 -3
  415. package/src/services/browser-session-state.ts +3 -2
  416. package/src/services/browser-session.ts +21 -27
  417. package/src/services/bus-command-update.ts +9 -9
  418. package/src/services/checkout-refresh-state.ts +1 -0
  419. package/src/services/checkout-refresh.test-fixture.ts +3 -2
  420. package/src/services/command-host.ts +7 -2
  421. package/src/services/coordinator-digest.ts +3 -2
  422. package/src/services/dispatch-command.ts +12 -13
  423. package/src/services/effective-launch-driver.ts +14 -9
  424. package/src/services/host-changed-paths.test-fixture.ts +5 -6
  425. package/src/services/host-project-readiness.ts +2 -2
  426. package/src/services/host-providers.ts +1 -1
  427. package/src/services/host-utilization.ts +9 -9
  428. package/src/services/idle-agent-digest.ts +17 -12
  429. package/src/services/idle-epics.ts +4 -4
  430. package/src/services/interrupt-agent.ts +12 -9
  431. package/src/services/issue-activity.ts +3 -3
  432. package/src/services/issue-associations.ts +15 -18
  433. package/src/services/issue-lifecycle-comments.ts +3 -2
  434. package/src/services/issue-lifecycle.ts +14 -13
  435. package/src/services/issue-refs.ts +4 -5
  436. package/src/services/kernel-timers-cutover-chaos-worker.ts +1 -1
  437. package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
  438. package/src/services/kernel-timers-ingress.ts +3 -3
  439. package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
  440. package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
  441. package/src/services/kernel-timers-outbox.ts +1 -1
  442. package/src/services/kernel-timers-stage10-operator.ts +1 -1
  443. package/src/services/kernel-timers.ts +4 -3
  444. package/src/services/land-gate-placement.ts +11 -2
  445. package/src/services/land-issue-relations.ts +5 -4
  446. package/src/services/land-restart-retry.ts +7 -6
  447. package/src/services/landed-ancestry.ts +6 -5
  448. package/src/services/legacy-landing-host.ts +4 -1
  449. package/src/services/legacy-landing-recovery.ts +8 -6
  450. package/src/services/managed-running.ts +17 -17
  451. package/src/services/memory-areas.ts +3 -3
  452. package/src/services/merge-pause.ts +9 -15
  453. package/src/services/operator-decisions.ts +37 -41
  454. package/src/services/orchestrator-registration-recovery.ts +6 -2
  455. package/src/services/orchestrator-upgrade.ts +14 -12
  456. package/src/services/permission-decision.ts +4 -3
  457. package/src/services/plan-ci-notice.ts +1 -1
  458. package/src/services/plan-conformance.ts +4 -4
  459. package/src/services/plan-dispatch-policy.ts +10 -3
  460. package/src/services/plan-dispatch.ts +35 -14
  461. package/src/services/plan-graph.ts +39 -261
  462. package/src/services/plan-import.ts +1 -1
  463. package/src/services/plan-live-bindings.ts +8 -37
  464. package/src/services/plan-task-create.ts +1 -1
  465. package/src/services/plan-terminal-refs.ts +2 -12
  466. package/src/services/plan-wake-digest.ts +8 -3
  467. package/src/services/profile-trust.ts +2 -2
  468. package/src/services/project.ts +11 -10
  469. package/src/services/prompt-templates.ts +6 -5
  470. package/src/services/provider-api-key.ts +73 -0
  471. package/src/services/provider-hold-nudge.ts +9 -9
  472. package/src/services/provider-hold-record.ts +13 -12
  473. package/src/services/provider-state-audit.ts +19 -18
  474. package/src/services/provisioning-harness/driver.ts +1 -1
  475. package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
  476. package/src/services/provisioning-harness/lifecycle.ts +24 -22
  477. package/src/services/provisioning-harness/prepare.ts +16 -17
  478. package/src/services/rate-limit-resume.ts +10 -9
  479. package/src/services/red-main-auto-revert.ts +7 -5
  480. package/src/services/red-main-controller-deps.ts +20 -3
  481. package/src/services/red-main-incident.ts +3 -1
  482. package/src/services/red-main-quarantine.ts +2 -3
  483. package/src/services/register-agent.ts +22 -22
  484. package/src/services/restart-project-role.ts +1 -1
  485. package/src/services/restart-spawn.ts +17 -16
  486. package/src/services/review-publish.ts +7 -24
  487. package/src/services/review-ref-reconcile.ts +29 -38
  488. package/src/services/runtime-dependency-alert.ts +27 -0
  489. package/src/services/scheduler-command.ts +11 -9
  490. package/src/services/scheduler.ts +5 -5
  491. package/src/services/self-effort-grant.ts +5 -25
  492. package/src/services/send-message.ts +16 -33
  493. package/src/services/shutdown-agent.ts +17 -14
  494. package/src/services/spawn-agent.ts +12 -41
  495. package/src/services/spawn-chain-inspector.ts +1 -1
  496. package/src/services/spawn-cwd-placement.ts +21 -5
  497. package/src/services/spawn-issue-activity.ts +8 -6
  498. package/src/services/spawn-launch.ts +17 -1
  499. package/src/services/spawn-loss-escalation.ts +1 -1
  500. package/src/services/spawn-registration-watchdog.ts +2 -2
  501. package/src/services/spawn-repo-probe.ts +7 -5
  502. package/src/services/spawn-tree-cleanup.ts +7 -8
  503. package/src/services/steward-reaper.ts +4 -4
  504. package/src/services/task-context-hydration.ts +25 -1
  505. package/src/services/task-delivery.ts +20 -34
  506. package/src/services/task-entity.ts +40 -203
  507. package/src/services/task-issue-link.ts +13 -20
  508. package/src/services/task-issue-weave.ts +12 -11
  509. package/src/services/task-lifecycle.ts +27 -31
  510. package/src/services/task-repo-cwd.ts +37 -0
  511. package/src/services/task-review-hold.ts +4 -17
  512. package/src/services/task-semantic-events.ts +13 -11
  513. package/src/services/task-state-reconcile.ts +3 -4
  514. package/src/services/task-validation.ts +2 -2
  515. package/src/services/team-templates.ts +5 -5
  516. package/src/services/team.ts +31 -98
  517. package/src/services/terminal-provider-exit.ts +6 -5
  518. package/src/services/timer-message-fire-chaos-worker.ts +7 -3
  519. package/src/services/timer-message-fire-outbox.ts +1 -1
  520. package/src/services/transient-agent-reaper.ts +22 -19
  521. package/src/services/turn-reconcile-audit.ts +9 -9
  522. package/src/services/user-onboarding.ts +8 -6
  523. package/src/services/user-profile.ts +6 -9
  524. package/src/services/work-finality.ts +16 -4
  525. package/src/services/workflow-auto-start.ts +2 -1
  526. package/src/services/workflow-caller.ts +61 -4
  527. package/src/services/workflow-child-proof-worker.ts +1 -1
  528. package/src/services/workflow-control-proof-worker.ts +1 -1
  529. package/src/services/workflow-coordinator.ts +8 -2
  530. package/src/services/workflow-decisions.ts +5 -5
  531. package/src/services/workflow-deferred-cleanup.ts +1 -1
  532. package/src/services/workflow-effect-driver.ts +42 -19
  533. package/src/services/workflow-effects.ts +41 -27
  534. package/src/services/workflow-pins.ts +7 -4
  535. package/src/services/workflow-reconcile.ts +1 -0
  536. package/src/services/workflow-resume-pins.ts +3 -3
  537. package/src/services/workflow-routing-defaults.ts +18 -0
  538. package/src/services/workflow-run-view.ts +4 -3
  539. package/src/services/workflow-run.test-fixture.ts +1 -1
  540. package/src/services/workflow-runs.ts +34 -22
  541. package/src/services/workflow-supervisor-state.ts +21 -1
  542. package/src/services/workflow-supervisor.ts +4 -3
  543. package/src/services/workspace-recovery.ts +4 -3
  544. package/src/setup.ts +47 -8
  545. package/src/spawn-admission.ts +10 -2
  546. package/src/spawn-placement.ts +27 -9
  547. package/src/spawn-targets.ts +8 -8
  548. package/src/sse-agent-status.ts +15 -6
  549. package/src/sse.ts +49 -24
  550. package/src/startup-context-injection.ts +61 -57
  551. package/src/steward-handoff.ts +4 -3
  552. package/src/steward-policy-cleanup.ts +9 -8
  553. package/src/steward.ts +2 -2
  554. package/src/task-dispatch-live.ts +5 -2
  555. package/src/task-dispatcher.ts +2 -2
  556. package/src/token-db.ts +2 -2
  557. package/src/token-usage-async.ts +2 -4
  558. package/src/user-awaiting-reply.ts +5 -5
  559. package/src/utils.ts +7 -0
  560. package/src/workspace-actions.ts +24 -29
  561. package/src/workspace-auto-merge.ts +14 -12
  562. package/src/workspace-changed-paths-client.ts +16 -5
  563. package/src/workspace-cleanup-stale.ts +30 -7
  564. package/src/workspace-command-settle.ts +24 -16
  565. package/src/workspace-config.ts +1 -1
  566. package/src/workspace-conflict-resolver.ts +9 -7
  567. package/src/workspace-dead-owner-recovery.ts +5 -4
  568. package/src/workspace-escalation.ts +12 -11
  569. package/src/workspace-human-escalation.ts +3 -3
  570. package/src/workspace-land-gate-watchdog.ts +3 -3
  571. package/src/workspace-land-refusal.ts +20 -0
  572. package/src/workspace-land-stopped.ts +1 -0
  573. package/src/workspace-merge.ts +10 -26
  574. package/src/workspace-nothing-to-land-notice.ts +2 -2
  575. package/src/workspace-orphans.ts +18 -37
  576. package/src/workspace-pr-completion.ts +10 -8
  577. package/src/workspace-rekey.ts +3 -3
  578. package/src/workspace-steward-failure.ts +2 -2
  579. package/src/workspace-steward-wake.ts +2 -2
  580. package/public/assets/agent-liveness-CaNwK0Zf.js +0 -2
  581. package/public/assets/overview-C1DCTzzV.js +0 -2
  582. package/public/assets/provider-display-DsuWMvVL.js +0 -2
  583. package/public/assets/run-card-CpKqRbhg.js +0 -2
  584. package/public/assets/shipping-B9YtnwtG.js +0 -2
  585. package/public/assets/store-DcClXLH0.js +0 -9
  586. package/runner/src/agent-runner/http-liveness.ts +0 -85
  587. package/src/db/on-loop-write-transaction.ts +0 -34
@@ -21,21 +21,21 @@ function routeError(err: unknown): Response {
21
21
  return error(err instanceof Error ? err.message : "prompt template route failed");
22
22
  }
23
23
 
24
- function authorizePromptRead(req: Request): Response | null {
24
+ async function authorizePromptRead(req: Request): Promise<Response | null> {
25
25
  const auth = getComponentAuth(req);
26
26
  if (auth && (hasComponentScope(auth, "system:admin") || hasComponentScope(auth, "agent:read"))) return null;
27
- return authorizeRoute(req, { scope: "system:admin" });
27
+ return (await authorizeRoute(req, { scope: "system:admin" }));
28
28
  }
29
29
 
30
30
  export const getPromptTemplatesRoute: Handler = async (req) => {
31
- const denied = authorizePromptRead(req);
31
+ const denied = (await authorizePromptRead(req));
32
32
  if (denied) return denied;
33
33
  const category = cleanString(new URL(req.url).searchParams.get("category"), "category", { max: 120 }) ?? undefined;
34
34
  return json({ templates: (await readPromptTemplates(category)).filter(entry => !memoryRetirementMessage(entry.slug)) });
35
35
  };
36
36
 
37
37
  export const getPromptTemplateRoute: Handler = async (req, params) => {
38
- const denied = authorizePromptRead(req);
38
+ const denied = (await authorizePromptRead(req));
39
39
  if (denied) return denied;
40
40
  const slug = slugParam(params);
41
41
  const retirement = memoryRetirementMessage(slug);
@@ -45,7 +45,7 @@ export const getPromptTemplateRoute: Handler = async (req, params) => {
45
45
  };
46
46
 
47
47
  export const putPromptTemplateRoute: Handler = async (req, params) => {
48
- const denied = authorizeRoute(req, { scope: versionedPromptsEnabled() ? "agent:write" : "system:admin" });
48
+ const denied = (await authorizeRoute(req, { scope: versionedPromptsEnabled() ? "agent:write" : "system:admin" }));
49
49
  if (denied) return denied;
50
50
  const parsed = await parseBody<Record<string, unknown>>(req);
51
51
  if (!parsed.ok) return error(parsed.error, parsed.status);
@@ -55,31 +55,31 @@ export const putPromptTemplateRoute: Handler = async (req, params) => {
55
55
  await mutatePrompt(authContextFromRequest(req), slug, parsed.body);
56
56
  return json(await readPromptTemplate(slug));
57
57
  }
58
- const legacyDenied = authorizeRoute(req, { scope: "system:admin" });
58
+ const legacyDenied = (await authorizeRoute(req, { scope: "system:admin" }));
59
59
  if (legacyDenied) return legacyDenied;
60
60
  const template = cleanString(parsed.body?.template, "template", { required: true, max: 200_000 })!;
61
- return json(updatePromptTemplate(slug, template));
61
+ return json((await updatePromptTemplate(slug, template)));
62
62
  } catch (err) {
63
63
  return routeError(err);
64
64
  }
65
65
  };
66
66
 
67
67
  export const postPromptTemplateResetRoute: Handler = async (req, params) => {
68
- const denied = authorizeRoute(req, { scope: versionedPromptsEnabled() ? "agent:write" : "system:admin" });
68
+ const denied = (await authorizeRoute(req, { scope: versionedPromptsEnabled() ? "agent:write" : "system:admin" }));
69
69
  if (denied) return denied;
70
70
  try {
71
71
  const slug = slugParam(params);
72
72
  if (versionedPromptsEnabled() && (await readPromptTemplate(slug))?.version !== undefined) return mutateRevision(req, slug, "adopt");
73
- const legacyDenied = authorizeRoute(req, { scope: "system:admin" });
73
+ const legacyDenied = (await authorizeRoute(req, { scope: "system:admin" }));
74
74
  if (legacyDenied) return legacyDenied;
75
- return json(resetPromptTemplate(slug));
75
+ return json((await resetPromptTemplate(slug)));
76
76
  } catch (err) {
77
77
  return routeError(err);
78
78
  }
79
79
  };
80
80
 
81
81
  export const getPromptHistoryRoute: Handler = async (req, params) => {
82
- const denied = authorizePromptRead(req);
82
+ const denied = (await authorizePromptRead(req));
83
83
  if (denied) return denied;
84
84
  const slug = slugParam(params);
85
85
  if (!versionedPromptsEnabled() || (await readPromptTemplate(slug))?.version === undefined) return error("versioned prompt not found", 404);
@@ -100,7 +100,7 @@ async function mutateRevision(req: Request, slug: string, action: "adopt" | "res
100
100
  }
101
101
 
102
102
  export const postPromptRevisionRoute: Handler = async (req, params) => {
103
- const denied = authorizeRoute(req, { scope: "agent:write" });
103
+ const denied = (await authorizeRoute(req, { scope: "agent:write" }));
104
104
  if (denied) return denied;
105
105
  return mutateRevision(req, slugParam(params), new URL(req.url).pathname.endsWith("/restore") ? "restore" : "adopt");
106
106
  };
@@ -45,7 +45,7 @@ function cleanUnavailableWindows(value: unknown): ProviderQuotaWindowIdentity[]
45
45
  return windows;
46
46
  }
47
47
 
48
- function cleanProviderQuotaUpdate(body: unknown): ProviderQuotaUpdateInput | string {
48
+ export function cleanProviderQuotaUpdate(body: unknown): ProviderQuotaUpdateInput | string {
49
49
  if (!isRecord(body)) return "JSON object body required";
50
50
  const provider = cleanString(body.provider, "provider", { required: true, max: 80 })!;
51
51
  const accountKey = cleanString(body.accountKey, "accountKey", { required: true, max: 240 })!;
@@ -122,7 +122,7 @@ export const postProviderQuotaRoute: Handler = async (req) => {
122
122
  if (!parsed.ok) return error(parsed.error, parsed.status);
123
123
  const input = cleanProviderQuotaUpdate(parsed.body);
124
124
  if (typeof input === "string") return error(input);
125
- const providerWriteGate = authorizeProviderQuotaWrite(req, input);
125
+ const providerWriteGate = (await authorizeProviderQuotaWrite(req, input));
126
126
  if (providerWriteGate) return providerWriteGate;
127
127
  if ((VALID_QUOTA_CONFIG_PROVIDERS as readonly string[]).includes(input.provider) && getProviderQuotaConfig(input.provider).enabled === false) return json({ skipped: true, reason: "provider quota collection disabled" }, 202);
128
128
  const providerContext = authContextFromRequest(req);
@@ -218,19 +218,19 @@ function cleanPublisherLeaseBody(body: unknown): {
218
218
 
219
219
  const runnerLeaseHolderId = (sourceAgentId: string) => `runner:${sourceAgentId}`;
220
220
 
221
- function authorizeProviderQuotaSourceAgent(req: Request, sourceAgentId: string): Response | null {
221
+ async function authorizeProviderQuotaSourceAgent(req: Request, sourceAgentId: string): Promise<Response | null> {
222
222
  const ctx = authContextFromRequest(req);
223
223
  if (ctx.component?.role !== "provider") return null;
224
- const denied = authorizeRoute(req, { scope: "quota:write" });
224
+ const denied = (await authorizeRoute(req, { scope: "quota:write" }));
225
225
  if (denied) return denied;
226
226
  return ctx.callerAgentId === sourceAgentId ? null : error("forbidden", 403);
227
227
  }
228
228
 
229
- function authorizeProviderQuotaWrite(req: Request, input: ProviderQuotaUpdateInput): Response | null {
229
+ export async function authorizeProviderQuotaWrite(req: Request, input: ProviderQuotaUpdateInput): Promise<Response | null> {
230
230
  const ctx = authContextFromRequest(req);
231
231
  if (ctx.component?.role !== "provider") return null;
232
232
  if (!input.sourceAgentId) return error("sourceAgentId required for provider quota writer", 403);
233
- const denied = authorizeProviderQuotaSourceAgent(req, input.sourceAgentId);
233
+ const denied = (await authorizeProviderQuotaSourceAgent(req, input.sourceAgentId));
234
234
  if (denied) return denied;
235
235
  // The authority fence is deliberately folded into providerQuotas.upsert. A pre-read here would
236
236
  // race lease transfer while the async writer is queued.
@@ -242,7 +242,7 @@ export const postProviderQuotaPublisherLeaseAcquireRoute: Handler = async (req)
242
242
  if (!parsed.ok) return error(parsed.error, parsed.status);
243
243
  const input = cleanPublisherLeaseBody(parsed.body);
244
244
  if (typeof input === "string") return error(input);
245
- const denied = authorizeProviderQuotaSourceAgent(req, input.sourceAgentId);
245
+ const denied = (await authorizeProviderQuotaSourceAgent(req, input.sourceAgentId));
246
246
  if (denied) return denied;
247
247
  return json(await acquireProviderQuotaLeaseAsync({
248
248
  provider: input.provider,
@@ -260,7 +260,7 @@ export const postProviderQuotaPublisherLeaseReleaseRoute: Handler = async (req)
260
260
  const input = cleanPublisherLeaseBody(parsed.body);
261
261
  if (typeof input === "string") return error(input);
262
262
  if (!input.leaseToken) return error("leaseToken required");
263
- const denied = authorizeProviderQuotaSourceAgent(req, input.sourceAgentId);
263
+ const denied = (await authorizeProviderQuotaSourceAgent(req, input.sourceAgentId));
264
264
  if (denied) return denied;
265
265
  return json({
266
266
  released: await releaseProviderQuotaLeaseAsync({
@@ -275,7 +275,7 @@ export const postProviderQuotaPublisherLeaseReleaseRoute: Handler = async (req)
275
275
  export const postProviderQuotaLeaseAcquireRoute: Handler = async (req, params) => {
276
276
  const orch = getOrchestrator(params.id!);
277
277
  if (!orch) return error("orchestrator not found", 404);
278
- const denied = authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } });
278
+ const denied = (await authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } }));
279
279
  if (denied) return denied;
280
280
  const parsed = await parseBody<unknown>(req);
281
281
  if (!parsed.ok) return error(parsed.error, parsed.status);
@@ -294,7 +294,7 @@ export const postProviderQuotaLeaseAcquireRoute: Handler = async (req, params) =
294
294
  export const postProviderQuotaLeaseReleaseRoute: Handler = async (req, params) => {
295
295
  const orch = getOrchestrator(params.id!);
296
296
  if (!orch) return error("orchestrator not found", 404);
297
- const denied = authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } });
297
+ const denied = (await authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } }));
298
298
  if (denied) return denied;
299
299
  const parsed = await parseBody<unknown>(req);
300
300
  if (!parsed.ok) return error(parsed.error, parsed.status);
@@ -10,7 +10,7 @@ import { authorizeRoute, error, json, parseBody, type Handler } from "./_shared"
10
10
  export const postRunCommand: Handler = async (req) => {
11
11
  // Require authentication even when the server permits credential-less development requests.
12
12
  if (!hasPresentedCredential(req) || !isAuthorized(req)) return error("authentication required", 401);
13
- const denied = authorizeRoute(req, { scope: "command:write" });
13
+ const denied = (await authorizeRoute(req, { scope: "command:write" }));
14
14
  if (denied) return denied;
15
15
  const parsed = await parseBody<unknown>(req);
16
16
  if (!parsed.ok) return error(parsed.error, parsed.status);
@@ -2,7 +2,7 @@ import { isRecord } from "@humwick/sdk";
2
2
  import { ValidationError } from "../db/connection";
3
3
  import { readBodyBytes } from "../http-body";
4
4
  import { getComponentAuth } from "../security";
5
- import { authContextFromRequest } from "../services/auth-context";
5
+ import { vaultActorOf } from "../services/auth-context";
6
6
  import { exportVaultBackup, vaultBackupStatus, writeVaultBackup } from "../secrets-vault/backup";
7
7
  import { VaultError } from "../secrets-vault/keys";
8
8
  import { restoreVaultBackup } from "../secrets-vault/restore";
@@ -20,7 +20,7 @@ function backupError(cause: unknown): Response {
20
20
  /** Backup and restore move every secret at once: the operator only, never a secrets-scoped agent. */
21
21
  function operatorRoute(handle: (body: Record<string, unknown>, actor: string) => Promise<Response>): Handler {
22
22
  return async req => {
23
- const denied = authorizeRoute(req, { scope: "secrets:write" });
23
+ const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
24
24
  if (denied) return denied;
25
25
  if (!isRootCredentialRequest(req) && getComponentAuth(req)?.role !== "dashboard") return error("operator token required for vault backup and restore", 403);
26
26
  let body: unknown = {};
@@ -30,14 +30,13 @@ function operatorRoute(handle: (body: Record<string, unknown>, actor: string) =>
30
30
  try { body = read.bytes.byteLength ? JSON.parse(new TextDecoder().decode(read.bytes)) : {}; } catch { return error("invalid JSON body", 400); }
31
31
  }
32
32
  if (!isRecord(body)) return error("body must be an object", 400);
33
- const ctx = authContextFromRequest(req);
34
- try { return await handle(body, ctx.actor.kind === "system" ? "operator" : ctx.actor.id); }
33
+ try { return await handle(body, vaultActorOf(req)); }
35
34
  catch (cause) { return backupError(cause); }
36
35
  };
37
36
  }
38
37
 
39
38
  export const getVaultBackupRoute: Handler = async req => {
40
- const denied = authorizeRoute(req, { scope: "secrets:write" });
39
+ const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
41
40
  if (denied) return denied;
42
41
  try { return json(await vaultBackupStatus()); } catch (cause) { return backupError(cause); }
43
42
  };
@@ -1,7 +1,7 @@
1
1
  import { ValidationError } from "../db/connection";
2
2
  import { isRecord } from "@humwick/sdk";
3
3
  import { getComponentAuth } from "../security";
4
- import { authContextFromRequest } from "../services/auth-context";
4
+ import { vaultActorOf } from "../services/auth-context";
5
5
  import { importVaultSecrets, previewVaultImport } from "../secrets-vault/import";
6
6
  import { VaultError } from "../secrets-vault/keys";
7
7
  import { SecretsBrokerError } from "../secrets-broker/error";
@@ -9,16 +9,15 @@ import { authorizeRoute, error, isRootCredentialRequest, json, parseBody, type H
9
9
 
10
10
  function importRoute(preview: boolean): Handler {
11
11
  return async req => {
12
- const denied = authorizeRoute(req, { scope: "secrets:write" });
12
+ const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
13
13
  if (denied) return denied;
14
14
  // Import is the operator's batch approval; a secrets-scoped agent may not approve its own migration.
15
15
  if (!isRootCredentialRequest(req) && getComponentAuth(req)?.role !== "dashboard") return error("operator token required to import secrets", 403);
16
16
  const parsed = await parseBody<unknown>(req);
17
17
  if (!parsed.ok) return error(parsed.error, parsed.status);
18
18
  if (!isRecord(parsed.body)) return error("import must be an object", 400);
19
- const ctx = authContextFromRequest(req);
20
19
  try {
21
- return json(preview ? await previewVaultImport(parsed.body.source) : await importVaultSecrets(ctx.actor.kind === "system" ? "operator" : ctx.actor.id, parsed.body), preview ? 200 : 201);
20
+ return json(preview ? await previewVaultImport(parsed.body.source) : await importVaultSecrets(vaultActorOf(req), parsed.body), preview ? 200 : 201);
22
21
  } catch (cause) {
23
22
  if (cause instanceof ValidationError) return error(cause.message, 400);
24
23
  if (cause instanceof VaultError) return error(cause.message, cause.code === "exists" ? 409 : cause.code === "not_found" ? 404 : 503);
@@ -2,7 +2,7 @@ import { listSecretAuditAsync } from "../db/secrets-broker-async";
2
2
  import { parseSecretName, scopedSecretName, secretEnvironment } from "../secrets-vault/scope";
3
3
  import { builtinVault, backendCall, readVaultLastResolved } from "../secrets-vault/backend";
4
4
  import { editSecretMetadata, getSecretMetadata, createOperatorSecret, deleteOperatorSecret, requireVault, rotateOperatorSecret } from "../secrets-vault/service";
5
- import { authContextFromRequest } from "../services/auth-context";
5
+ import { vaultActorOf } from "../services/auth-context";
6
6
  import { ValidationError } from "../db/connection";
7
7
  import { resolveProjectAsync } from "../db/projects-async";
8
8
  import { isRecord } from "@humwick/sdk";
@@ -13,7 +13,7 @@ import { resolveHostProviderEnv } from "../secrets-vault/provider-env";
13
13
  import { isOrchestratorSelfReportAuthorized } from "../orchestrator-self-report-authz";
14
14
 
15
15
  export const getVaultMetadataRoute: Handler = async (req) => {
16
- const denied = authorizeRoute(req, { scope: "secrets:write" });
16
+ const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
17
17
  if (denied) return denied;
18
18
  // health() opens a row, so a missing or wrong key answers 503 here instead of listing names that nothing can resolve.
19
19
  try {
@@ -39,8 +39,6 @@ export const getVaultMetadataRoute: Handler = async (req) => {
39
39
  } catch (cause) { return error(cause instanceof Error ? cause.message : "vault unavailable", cause instanceof ValidationError ? 400 : 503); }
40
40
  };
41
41
 
42
- const operatorActor = (req: Request) => { const ctx = authContextFromRequest(req); return ctx.actor.kind === "system" ? "operator" : ctx.actor.id; };
43
-
44
42
  function vaultWriteError(cause: unknown): Response {
45
43
  if (cause instanceof ValidationError) return error(cause.message, 400);
46
44
  if (cause instanceof VaultError) return error(cause.message, cause.code === "exists" ? 409 : cause.code === "not_found" ? 404 : 503);
@@ -49,32 +47,32 @@ function vaultWriteError(cause: unknown): Response {
49
47
 
50
48
  /** The operator creates a new secret straight from the dashboard; the value is never echoed or logged. */
51
49
  export const postVaultSecretRoute: Handler = async (req) => {
52
- const denied = authorizeRoute(req, { scope: "secrets:write" });
50
+ const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
53
51
  if (denied) return denied;
54
52
  const parsed = await parseBody<unknown>(req);
55
53
  if (!parsed.ok) return error(parsed.error, parsed.status);
56
54
  if (!isRecord(parsed.body)) return error("secret must be an object", 400);
57
- try { return json(await createOperatorSecret(operatorActor(req), parsed.body), 201); }
55
+ try { return json(await createOperatorSecret(vaultActorOf(req), parsed.body), 201); }
58
56
  catch (cause) { return vaultWriteError(cause); }
59
57
  };
60
58
 
61
59
  /** #3558 — the operator sets a new version of an existing secret (`:name` is `NAME` or `project:<id>:NAME`). */
62
60
  export const putVaultSecretRoute: Handler = async (req, params) => {
63
- const denied = authorizeRoute(req, { scope: "secrets:write" });
61
+ const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
64
62
  if (denied) return denied;
65
63
  const parsed = await parseBody<unknown>(req);
66
64
  if (!parsed.ok) return error(parsed.error, parsed.status);
67
65
  if (!isRecord(parsed.body)) return error("secret must be an object", 400);
68
66
  const environment = parsed.body.environment === undefined ? new URL(req.url).searchParams.get("environment") ?? undefined : parsed.body.environment;
69
- try { return json(await rotateOperatorSecret(operatorActor(req), params.name!, { ...parsed.body, environment })); }
67
+ try { return json(await rotateOperatorSecret(vaultActorOf(req), params.name!, { ...parsed.body, environment })); }
70
68
  catch (cause) { return vaultWriteError(cause); }
71
69
  };
72
70
 
73
71
  /** #3554 — the operator deletes every version of one secret. */
74
72
  export const deleteVaultSecretRoute: Handler = async (req, params) => {
75
- const denied = authorizeRoute(req, { scope: "secrets:write" });
73
+ const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
76
74
  if (denied) return denied;
77
- try { return json(await deleteOperatorSecret(operatorActor(req), params.name!, new URL(req.url).searchParams.get("environment") ?? undefined)); }
75
+ try { return json(await deleteOperatorSecret(vaultActorOf(req), params.name!, new URL(req.url).searchParams.get("environment") ?? undefined)); }
78
76
  catch (cause) { return vaultWriteError(cause); }
79
77
  };
80
78
 
@@ -91,7 +89,7 @@ export const getVaultAuditRoute: Handler = async (req, params) => {
91
89
  export const getOrchestratorProviderEnvRoute: Handler = async (req, params) => {
92
90
  const orch = getOrchestrator(params.id!);
93
91
  if (!orch) return error("orchestrator not found", 404);
94
- const denied = authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } });
92
+ const denied = (await authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } }));
95
93
  if (denied) return denied;
96
94
  // Plaintext keys: only this orchestrator's own host credential (or admin), never a runner token with command:write.
97
95
  if (!isOrchestratorSelfReportAuthorized(req, orch.id)) return error("forbidden", 403);
@@ -105,17 +103,17 @@ export const getOrchestratorProviderEnvRoute: Handler = async (req, params) => {
105
103
  };
106
104
 
107
105
  export const getVaultSecretRoute: Handler = async (req, params) => {
108
- const denied = authorizeRoute(req, { scope: "secrets:write" });
106
+ const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
109
107
  if (denied) return denied;
110
108
  try { return json(await getSecretMetadata(params.name!, new URL(req.url).searchParams.get("environment") ?? undefined)); }
111
109
  catch (cause) { return vaultWriteError(cause); }
112
110
  };
113
111
 
114
112
  export const patchVaultMetadataRoute: Handler = async (req, params) => {
115
- const denied = authorizeRoute(req, { scope: "secrets:write" });
113
+ const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
116
114
  if (denied) return denied;
117
115
  const parsed = await parseBody<unknown>(req);
118
116
  if (!parsed.ok) return error(parsed.error, parsed.status);
119
- try { return json(await editSecretMetadata(operatorActor(req), params.name!, parsed.body, new URL(req.url).searchParams.get("environment") ?? undefined)); }
117
+ try { return json(await editSecretMetadata(vaultActorOf(req), params.name!, parsed.body, new URL(req.url).searchParams.get("environment") ?? undefined)); }
120
118
  catch (cause) { return vaultWriteError(cause); }
121
119
  };
@@ -70,7 +70,7 @@ export async function setRegisteredSettingValue(namespace: string, key: string,
70
70
  const validation = validateSettingValue(namespace, key, merged);
71
71
  if (!validation.valid) throw new ValidationError(validation.errors.join("; "));
72
72
  if (descriptor.tier === "user") return setUserSettingAsync(DEFAULT_USER_ID, namespace, key, merged, updatedBy);
73
- return setConfigAsync(namespace, key, merged, updatedBy);
73
+ return (await setConfigAsync(namespace, key, merged, updatedBy));
74
74
  }
75
75
 
76
76
  async function putSetting(req: Request, namespaceRaw: string | undefined, keyRaw: string | undefined): Promise<Response> {
@@ -5,12 +5,13 @@ import { readGateStatsAsync, resolveProjectAsync } from "../db";
5
5
  import { getShippingBoard } from "../services/shipping-board";
6
6
  import { getShippingStats } from "../services/shipping-stats";
7
7
  import { abandonRedMainIncident } from "../services/red-main-incident";
8
+ import { baseKnownFailures } from "../db/land-boundaries";
8
9
  import { OpError } from "@humwick/kernel/contract";
9
10
  import { cleanString } from "../validation";
10
11
  import { authorizeRoute, error, json, parseBody, resolveActorLabel, type Handler } from "./_shared";
11
12
 
12
13
  export const postRedMainAbandonRoute: Handler = async (req, params) => {
13
- const denied = authorizeRoute(req, { scope: "command:write" });
14
+ const denied = (await authorizeRoute(req, { scope: "command:write" }));
14
15
  if (denied) return denied;
15
16
  const parsed = await parseBody<{ reason?: unknown }>(req);
16
17
  if (!parsed.ok) return error(parsed.error, parsed.status);
@@ -23,6 +24,13 @@ export const postRedMainAbandonRoute: Handler = async (req, params) => {
23
24
  }
24
25
  };
25
26
 
27
+ // #3362 §11: what a builder's delivery gate holds out of unrelated runs. agent:read, so every agent token reads it.
28
+ export const getKnownFailuresRoute: Handler = async (req) => {
29
+ const remote = new URL(req.url).searchParams.get("remote")?.trim();
30
+ if (!remote || !/^[\w.-]+\/[\w.-]+$/.test(remote)) return error("remote must be owner/repo", 400);
31
+ return json({ failures: baseKnownFailures(remote) });
32
+ };
33
+
26
34
  /** A `projectId` query names a project by id or slug; absent means all projects. */
27
35
  async function projectFilter(req: Request): Promise<{ projectId?: string } | Response> {
28
36
  const ref = new URL(req.url).searchParams.get("projectId")?.trim();
@@ -1,3 +1,4 @@
1
+ import { upsertManagedAgentStateAsync } from "../db/lifecycle-tail-async";
1
2
  // Auto-split from routes.ts (#299). Domain: spawn-policy.
2
3
  import { ValidationError, getCrashReport, getManagedPolicyTimelineAsync, getOrchestrator } from "../db";
3
4
  import { auditEvent, authAuditMetadata, dashboardAttribution, emitCommand, error, json, parseBody, parseQueryInt, spawnRequestId, type Handler } from "./_shared";
@@ -6,7 +7,7 @@ import { SYSTEM_LAUNCH } from "../runtime-tokens";
6
7
  import { cleanString } from "../validation";
7
8
  import { hostSpawnsDrained } from "../db/spawn-host-cap";
8
9
  import { createCommandAsync } from "../commands-write";
9
- import { getManagedAgentState, getSpawnPolicy, listSpawnPolicies, upsertManagedAgentState } from "../config-store";
10
+ import { getManagedAgentState, getSpawnPolicy, listSpawnPolicies } from "../config-store";
10
11
  import { deleteConfigAsync, setConfigAsync } from "../config-store-write";
11
12
  import { managedSpawnReservationCurrent, restoreDrainedSpawnReservation } from "../managed-spawn-reservation";
12
13
  import { emitConfigChanged, emitManagedAgentStateChanged } from "../sse";
@@ -72,7 +73,7 @@ async function enqueuePolicyStart(policy: SpawnPolicy, reason: string): Promise<
72
73
  if (stewardDeny) return error(`steward spawn refused: ${stewardDeny}`, 409);
73
74
  const requestId = spawnRequestId();
74
75
  const existing = getManagedAgentState(policy.name);
75
- const state = upsertManagedAgentState({
76
+ const state = (await upsertManagedAgentStateAsync({
76
77
  policyName: policy.name,
77
78
  status: "starting",
78
79
  orchestratorId: policy.orchestratorId,
@@ -82,7 +83,7 @@ async function enqueuePolicyStart(policy: SpawnPolicy, reason: string): Promise<
82
83
  // An operator start deliberately retries a failed policy after correcting its launch.
83
84
  restartCount: existing?.restartCount ?? 0,
84
85
  consecutiveFailures: 0,
85
- });
86
+ }));
86
87
  emitManagedAgentStateChanged(policy.name, state as unknown as Record<string, unknown>);
87
88
  const policySnapshot = JSON.stringify(policy);
88
89
  const spawnParams = await buildManagedSpawnParamsAsync(policy, requestId, { createdBy: "managed-agent", authority: SYSTEM_LAUNCH });
@@ -93,7 +94,7 @@ async function enqueuePolicyStart(policy: SpawnPolicy, reason: string): Promise<
93
94
  return error("managed policy start was superseded", 409);
94
95
  }
95
96
  if (hostSpawnsDrained(orch.agentId)) {
96
- restoreDrainedSpawnReservation(policy, requestId, existing);
97
+ (await restoreDrainedSpawnReservation(policy, requestId, existing));
97
98
  return error(`host ${orch.hostname} is draining: new spawns disabled`, 409);
98
99
  }
99
100
  const command = await createCommandAsync({
@@ -131,7 +132,7 @@ async function enqueuePolicyStop(policy: SpawnPolicy, action: "shutdown" | "rest
131
132
  })
132
133
  : undefined;
133
134
  if (action === "restart" && hostSpawnsDrained(orch.agentId)) return error(`host ${orch.hostname} is draining: new spawns disabled`, 409);
134
- const nextState = upsertManagedAgentState({
135
+ const nextState = (await upsertManagedAgentStateAsync({
135
136
  policyName: policy.name,
136
137
  status: "stopping",
137
138
  agentId: state?.agentId,
@@ -143,7 +144,7 @@ async function enqueuePolicyStop(policy: SpawnPolicy, action: "shutdown" | "rest
143
144
  lastStopAt: Date.now(),
144
145
  restartCount: state?.restartCount ?? 0,
145
146
  consecutiveFailures: state?.consecutiveFailures ?? 0,
146
- });
147
+ }));
147
148
  emitManagedAgentStateChanged(policy.name, nextState as unknown as Record<string, unknown>);
148
149
  const command = await createCommandAsync({
149
150
  type: action === "restart" ? "agent.restart" : "agent.shutdown",
@@ -209,7 +210,7 @@ export const putSpawnPolicyRoute: Handler = async (req, params) => {
209
210
  const updatedBy = isRecord(parsed.body) ? cleanString(parsed.body.updatedBy, "updatedBy", { max: 200 }) : undefined;
210
211
  const entry = await setConfigAsync("spawn-policy", params.name!, value, updatedBy);
211
212
  emitConfigChanged(entry.namespace, entry.key, entry.version);
212
- getLifecycleManager().onConfigChanged("spawn-policy", entry.key);
213
+ (await getLifecycleManager().onConfigChanged("spawn-policy", entry.key));
213
214
  return json(entry, entry.version === 1 ? 201 : 200);
214
215
  } catch (e) {
215
216
  if (e instanceof ValidationError) return error(e.message, 400);
package/src/routes/sse.ts CHANGED
@@ -5,13 +5,13 @@ import { isOtherHumanSink } from "../message-visibility";
5
5
  import { canViewAgentRoute, error, type Handler } from "./_shared";
6
6
  import { messageViewerForRequest } from "./message-viewer";
7
7
 
8
- export const getEvents: Handler = (req) => {
8
+ export const getEvents: Handler = async (req) => {
9
9
  const url = new URL(req.url);
10
10
  const agentId = url.searchParams.get("for") || null;
11
11
  const lastEventId = Number(req.headers.get("last-event-id") ?? "");
12
12
  // #3567 D6 — a signed-in human streams their own messages and notifications only.
13
13
  const viewer = messageViewerForRequest(req) ?? undefined;
14
- if (agentId && isOtherHumanSink(viewer, agentId)) return authorityDenied(req, "you can only read your own messages", 403, agentId, "read sink stream");
14
+ if (agentId && isOtherHumanSink(viewer, agentId)) return (await authorityDenied(req, "you can only read your own messages", 403, agentId, "read sink stream"));
15
15
  if (agentId && !canViewAgentRoute(req, agentId)) return error("agent not found", 404);
16
16
  return createSSEStream(agentId, Number.isSafeInteger(lastEventId) && lastEventId > 0 ? lastEventId : 0,
17
17
  url.searchParams.get("agentStatus") === "delta", viewer);
@@ -16,14 +16,14 @@ function slugParam(params: Record<string, string | undefined>): string {
16
16
  return cleanString(params.slug, "slug", { required: true, max: 120 })!;
17
17
  }
18
18
 
19
- export const getTeamTemplatesRoute: Handler = (req) => {
20
- const denied = authorizeRoute(req, { scope: "system:admin" });
19
+ export const getTeamTemplatesRoute: Handler = async (req) => {
20
+ const denied = (await authorizeRoute(req, { scope: "system:admin" }));
21
21
  if (denied) return denied;
22
22
  return json({ templates: listTeamTemplates() });
23
23
  };
24
24
 
25
- export const getTeamTemplateRoute: Handler = (req, params) => {
26
- const denied = authorizeRoute(req, { scope: "system:admin" });
25
+ export const getTeamTemplateRoute: Handler = async (req, params) => {
26
+ const denied = (await authorizeRoute(req, { scope: "system:admin" }));
27
27
  if (denied) return denied;
28
28
  try {
29
29
  const template = getTeamTemplate(slugParam(params));
@@ -34,7 +34,7 @@ export const getTeamTemplateRoute: Handler = (req, params) => {
34
34
  };
35
35
 
36
36
  export const postTeamTemplateRoute: Handler = async (req) => {
37
- const denied = authorizeRoute(req, { scope: "system:admin" });
37
+ const denied = (await authorizeRoute(req, { scope: "system:admin" }));
38
38
  if (denied) return denied;
39
39
  const parsed = await parseBody<Record<string, unknown>>(req);
40
40
  if (!parsed.ok) return error(parsed.error, parsed.status);
@@ -46,7 +46,7 @@ export const postTeamTemplateRoute: Handler = async (req) => {
46
46
  };
47
47
 
48
48
  export const putTeamTemplateRoute: Handler = async (req, params) => {
49
- const denied = authorizeRoute(req, { scope: "system:admin" });
49
+ const denied = (await authorizeRoute(req, { scope: "system:admin" }));
50
50
  if (denied) return denied;
51
51
  const parsed = await parseBody<Record<string, unknown>>(req);
52
52
  if (!parsed.ok) return error(parsed.error, parsed.status);
@@ -58,7 +58,7 @@ export const putTeamTemplateRoute: Handler = async (req, params) => {
58
58
  };
59
59
 
60
60
  export const deleteTeamTemplateRoute: Handler = async (req, params) => {
61
- const denied = authorizeRoute(req, { scope: "system:admin" });
61
+ const denied = (await authorizeRoute(req, { scope: "system:admin" }));
62
62
  if (denied) return denied;
63
63
  const slug = slugParam(params);
64
64
  return json({ slug, deleted: await deleteTeamTemplateAsync(slug, updatedBy(req)) });
@@ -43,9 +43,9 @@ export const getMyTeamRoute: Handler = (req) => {
43
43
  };
44
44
 
45
45
  // #3725 — a signed-in member lists the teams their agent scope can see; machine callers stay admin-only.
46
- export const getTeamsRoute: Handler = (req) => {
46
+ export const getTeamsRoute: Handler = async (req) => {
47
47
  const viewer = viewerScopeForRequest(req);
48
- const denied = authorizeRoute(req, { scope: viewer ? "teams:read" : "system:admin" });
48
+ const denied = (await authorizeRoute(req, { scope: viewer ? "teams:read" : "system:admin" }));
49
49
  if (denied) return denied;
50
50
  try {
51
51
  const status = optionalEnum(new URL(req.url).searchParams.get("status") ?? undefined, "status", TEAM_STATUSES) as Team["status"] | undefined;
@@ -67,7 +67,7 @@ export const getTeamsRoute: Handler = (req) => {
67
67
  };
68
68
 
69
69
  export const getTeamOutcomesRoute: Handler = async (req) => {
70
- const denied = authorizeRoute(req, { scope: "system:admin" });
70
+ const denied = (await authorizeRoute(req, { scope: "system:admin" }));
71
71
  if (denied) return denied;
72
72
  try {
73
73
  const recentLimit = parseQueryInt(new URL(req.url).searchParams.get("recentLimit"), { min: 1, max: 50, clamp: true }) ?? undefined;
@@ -83,11 +83,11 @@ export const putMyTeamBriefRoute: Handler = async (req) => {
83
83
  if (!parsed.ok) return error(parsed.error, parsed.status);
84
84
  try {
85
85
  const body = parsed.body ?? {};
86
- return json(setCallerTeamBrief(authContextFromRequest(req), {
86
+ return json((await setCallerTeamBrief(authContextFromRequest(req), {
87
87
  title: cleanString(body.title, "title", { max: 240 }),
88
88
  brief: cleanString(body.brief, "brief", { max: 16_000 }),
89
89
  definitionOfDone: cleanString(body.definitionOfDone, "definitionOfDone", { max: 4000 }),
90
- }));
90
+ })));
91
91
  } catch (err) {
92
92
  return routeError(err);
93
93
  }
@@ -98,28 +98,28 @@ export const postMyTeamDissolveRoute: Handler = async (req) => {
98
98
  if (!parsed.ok) return error(parsed.error, parsed.status);
99
99
  try {
100
100
  const body = parsed.body ?? {};
101
- return json(dissolveCallerTeam(authContextFromRequest(req), cleanDissolveInput(body)));
101
+ return json(await dissolveCallerTeam(authContextFromRequest(req), cleanDissolveInput(body)));
102
102
  } catch (err) {
103
103
  return routeError(err);
104
104
  }
105
105
  };
106
106
 
107
107
  export const postTeamDissolveByIdRoute: Handler = async (req, params) => {
108
- const denied = authorizeRoute(req, { scope: "system:admin" });
108
+ const denied = (await authorizeRoute(req, { scope: "system:admin" }));
109
109
  if (denied) return denied;
110
110
  const parsed = await parseBody<Record<string, unknown>>(req);
111
111
  if (!parsed.ok) return error(parsed.error, parsed.status);
112
112
  try {
113
113
  const id = params.id!;
114
114
  if (!getTeam(id)) return error("team not found", 404);
115
- return json(dissolveTeamById(id, cleanDissolveInput(parsed.body ?? {})));
115
+ return json(await dissolveTeamById(id, cleanDissolveInput(parsed.body ?? {})));
116
116
  } catch (err) {
117
117
  return routeError(err);
118
118
  }
119
119
  };
120
120
 
121
121
  export const patchTeamSpawnDelegationRoute: Handler = async (req, params) => {
122
- const denied = authorizeRoute(req, { scope: "teams:write" });
122
+ const denied = (await authorizeRoute(req, { scope: "teams:write" }));
123
123
  if (denied) return denied;
124
124
  const parsed = await parseBody<Record<string, unknown>>(req);
125
125
  if (!parsed.ok) return error(parsed.error, parsed.status);
@@ -132,7 +132,7 @@ export const patchTeamSpawnDelegationRoute: Handler = async (req, params) => {
132
132
  export const getTeamSpawnDelegationRoute: Handler = async (req, params) => {
133
133
  // #3725 — the grant names projects and launches across the tree; a member's session may not read it.
134
134
  const viewer = viewerScopeForRequest(req);
135
- const denied = authorizeRoute(req, { scope: viewer && !viewer.seesAll ? "system:admin" : "teams:read" });
135
+ const denied = (await authorizeRoute(req, { scope: viewer && !viewer.seesAll ? "system:admin" : "teams:read" }));
136
136
  if (denied) return denied;
137
137
  try {
138
138
  const state = await getTeamSpawnDelegation(authContextFromRequest(req), params.id!);