@humwick/server 0.130.1 → 0.130.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (811) hide show
  1. package/README.md +5 -0
  2. package/bundled/prompts/manifest.json +1 -0
  3. package/bundled/prompts/task.hydration.md +1 -1
  4. package/bundled/roles/builder.md +1 -1
  5. package/docs/guides/sub-coordinators.md +12 -5
  6. package/docs/guides/tools-administration.md +4 -0
  7. package/docs/guides/tools-coordination.md +2 -0
  8. package/docs/guides/tools-tasks.md +8 -0
  9. package/docs/guides/workflows.md +74 -0
  10. package/docs/openapi.json +486 -4
  11. package/package.json +10 -18
  12. package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-Bq9kr21N.js} +2 -2
  13. package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-Dqiroy06.js} +2 -2
  14. package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-DYU962-H.js} +2 -2
  15. package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-DhPfzioE.js} +2 -2
  16. package/public/assets/{activity-yLztXEBt.js → activity-DzCcQTee.js} +2 -2
  17. package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-SgDt9i3T.js} +2 -2
  18. package/public/assets/agent-liveness-Bq-s73jW.js +2 -0
  19. package/public/assets/{agent-name-CTZBrSD9.js → agent-name-CcY3Aijy.js} +2 -2
  20. package/public/assets/agent-profiles-cxtRBn6O.js +2 -0
  21. package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-DGYbIhaI.js} +2 -2
  22. package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-DHbftV0N.js} +2 -2
  23. package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-CY113sp-.js} +2 -2
  24. package/public/assets/{agents-BYDslkJc.js → agents-BPzY7IlQ.js} +2 -2
  25. package/public/assets/{analytics-B-XSbEMC.js → analytics-DENFPv_a.js} +2 -2
  26. package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-KRvSc7sl.js} +2 -2
  27. package/public/assets/{artifacts-DPN1q4pA.js → artifacts-C9gSmL3s.js} +2 -2
  28. package/public/assets/{artifacts-oBOqks-2.js → artifacts-DT-HkI5O.js} +2 -2
  29. package/public/assets/{automation-4KcRFXEu.js → automation-BsmjQhKD.js} +2 -2
  30. package/public/assets/{backlog-Cw9xPTCF.js → backlog-8NYH_62t.js} +2 -2
  31. package/public/assets/{busy-health-CTu32MZt.js → busy-health-D3hwvYb4.js} +2 -2
  32. package/public/assets/{channels-BiXzg1G9.js → channels-DCJ5WL7O.js} +2 -2
  33. package/public/assets/{chat-Ctk2qwvA.js → chat-DAIl357U.js} +3 -3
  34. package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-CzrZfr9U.js} +2 -2
  35. package/public/assets/{connectors-C36ax4Vw.js → connectors-xTxtlyou.js} +2 -2
  36. package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BpebFLK2.js} +2 -2
  37. package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-BHvI5wXC.js} +2 -2
  38. package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-DGT0o3wJ.js} +2 -2
  39. package/public/assets/{deploys-Bwfq146q.js → deploys-hqWOHSHE.js} +2 -2
  40. package/public/assets/{display-CfO7rTuF.js → display-CDeH4I8T.js} +2 -2
  41. package/public/assets/{files-DhhZI2Ih.js → files-BTeGVmTg.js} +2 -2
  42. package/public/assets/{fleet-B_rFEbnL.js → fleet-DgXtNgCa.js} +2 -2
  43. package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BHEt5yc_.js} +2 -2
  44. package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-MLtodyPp.js} +3 -3
  45. package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-CAe664Z8.js} +2 -2
  46. package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-mapF4Fj9.js} +2 -2
  47. package/public/assets/index-CqqgOI5R.js +15 -0
  48. package/public/assets/index-MYAIwYTX.css +2 -0
  49. package/public/assets/{insights-fH1EL-qZ.js → insights-DNyf7IzF.js} +2 -2
  50. package/public/assets/{integrations-C5Oix6ng.js → integrations-DlYOHq7T.js} +2 -2
  51. package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-CeWBNWn7.js} +2 -2
  52. package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-Cib8nqdE.js} +2 -2
  53. package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-DSn1cPm7.js} +2 -2
  54. package/public/assets/{managed-agents-egllbpij.js → managed-agents-C3CkM81m.js} +2 -2
  55. package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-W4VQQPAv.js} +3 -3
  56. package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-CMsTdhjq.js} +2 -2
  57. package/public/assets/{memory-C8WmXsyr.js → memory-BV17qtO4.js} +2 -2
  58. package/public/assets/{messages-BzQdqlO6.js → messages-Bm_1AqSA.js} +2 -2
  59. package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Dg-vfP09.js} +2 -2
  60. package/public/assets/{overview-DCUnI4Z7.js → overview-DcYCrvlr.js} +2 -2
  61. package/public/assets/{pairs-ftCd2XcD.js → pairs-8o9nuG3V.js} +2 -2
  62. package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-BsRyBMea.js} +2 -2
  63. package/public/assets/project-profile-instructions-DETKFn_E.js +2 -0
  64. package/public/assets/projects-M_m6AHws.js +2 -0
  65. package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-C_mNCgeL.js} +2 -2
  66. package/public/assets/provider-display-BEeLXC_D.js +2 -0
  67. package/public/assets/{registry-DWCU5c8q.js → registry-DDHHHE5N.js} +2 -2
  68. package/public/assets/run-card-Dt4I4jaP.js +2 -0
  69. package/public/assets/scroll-text-BKXS1ahr.js +2 -0
  70. package/public/assets/{secrets-C7GIUATz.js → secrets-BkVwxI5O.js} +2 -2
  71. package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-Crq-6a-B.js} +2 -2
  72. package/public/assets/{settings-C6sZ9eBa.js → settings-CYcavMFu.js} +2 -2
  73. package/public/assets/shipping-H6gzEeZB.js +2 -0
  74. package/public/assets/{stats-V9Z-GxUd.js → stats-BJVeWkpV.js} +2 -2
  75. package/public/assets/{status-dot-CVv0iGHL.js → status-dot-BcHyw1Vw.js} +2 -2
  76. package/public/assets/store-DKPDIZBe.js +9 -0
  77. package/public/assets/{tasks-CXU75HRF.js → tasks-qJjlQPpx.js} +2 -2
  78. package/public/assets/{teams-BPf976zb.js → teams-Cd5Sk1uX.js} +2 -2
  79. package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-CpY5_m7W.js} +3 -3
  80. package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-DI_2llFR.js} +2 -2
  81. package/public/assets/token-estimate-Co-Jdphh.js +2 -0
  82. package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-0yJA_buM.js} +2 -2
  83. package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-uJXHf34W.js} +2 -2
  84. package/public/assets/use-project-list-CpWl6eHQ.js +2 -0
  85. package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BdxBW8mL.js} +2 -2
  86. package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-3IndfpOc.js} +2 -2
  87. package/public/assets/versioned-prompt-editor-CIVg7XB1.js +8 -0
  88. package/public/assets/{work-queue-TCjJxeT-.js → work-queue-B9rnLwHZ.js} +2 -2
  89. package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-X8wxyhzC.js} +2 -2
  90. package/public/assets/{workflows-CXQX20Qj.js → workflows-o5YyMFW7.js} +2 -2
  91. package/public/assets/{workspaces-qSYzKYMA.js → workspaces-CzEGoAng.js} +2 -2
  92. package/public/cosmos.html +4 -4
  93. package/public/index.html +31 -29
  94. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  95. package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
  96. package/runner/src/adapters/claude-effort.ts +2 -4
  97. package/runner/src/adapters/claude-headless.ts +1 -1
  98. package/runner/src/adapters/claude-launch-exit.ts +26 -0
  99. package/runner/src/adapters/claude-session-probe.ts +1 -1
  100. package/runner/src/adapters/claude-tmux.ts +38 -10
  101. package/runner/src/adapters/claude.ts +28 -75
  102. package/runner/src/adapters/codex-launch-config.ts +4 -5
  103. package/runner/src/adapters/codex.ts +1 -1
  104. package/runner/src/adapters/opencode-provider.ts +7 -22
  105. package/runner/src/adapters/opencode.ts +4 -4
  106. package/runner/src/adapters/provider-quota-harvest.ts +20 -71
  107. package/runner/src/agent-runner/credentials.ts +42 -12
  108. package/runner/src/agent-runner/inbox.ts +27 -0
  109. package/runner/src/agent-runner/lifecycle-milestones.ts +2 -4
  110. package/runner/src/agent-runner/liveness-exchange.ts +104 -0
  111. package/runner/src/bin/claude.ts +4 -0
  112. package/runner/src/bin/codex.ts +4 -0
  113. package/runner/src/bin/opencode.ts +4 -0
  114. package/runner/src/claude-system-prompt.ts +49 -0
  115. package/runner/src/index.ts +5 -2
  116. package/runner/src/launch-assembly.ts +14 -10
  117. package/runner/src/profile-home.ts +1 -1
  118. package/runner/src/project-instructions.ts +2 -2
  119. package/runner/src/provider-command.ts +18 -0
  120. package/runner/src/provider-setup.ts +35 -0
  121. package/runner/src/providers.ts +2 -1
  122. package/runner/src/runner-core.ts +32 -38
  123. package/runner/src/runner-helpers.ts +0 -8
  124. package/runner/src/session-scratch.ts +6 -2
  125. package/runner/src/spawn-input.ts +2 -1
  126. package/runner/src/test-run-dedup.ts +59 -56
  127. package/runner/test-support/provisioning-context.ts +4 -2
  128. package/runner/test-support/runner-harness.ts +2 -1
  129. package/scripts/cd-config.ts +8 -0
  130. package/scripts/gate-run-lease.ts +10 -7
  131. package/scripts/gate.sh +5 -1
  132. package/scripts/steward-policy-cleanup.ts +2 -2
  133. package/src/agent-authz.ts +2 -2
  134. package/src/agent-drive-arbiter.ts +3 -8
  135. package/src/agent-exit-cleanup-async.ts +2 -2
  136. package/src/agent-exit-cleanup.ts +23 -19
  137. package/src/agent-lifecycle-events.ts +112 -85
  138. package/src/agent-ref.ts +3 -2
  139. package/src/agent-status-events.ts +43 -14
  140. package/src/auth/password.ts +4 -3
  141. package/src/auth/session-refresh.ts +1 -1
  142. package/src/auth/session.test-fixture.ts +2 -2
  143. package/src/auth/session.ts +7 -7
  144. package/src/automations/crud.ts +8 -81
  145. package/src/automations/dispatch.ts +33 -58
  146. package/src/automations/index.ts +1 -1
  147. package/src/automations/persistence.ts +65 -0
  148. package/src/automations/precheck.ts +18 -16
  149. package/src/automations/read-async.ts +11 -0
  150. package/src/automations/reconcile.ts +30 -39
  151. package/src/automations/storage.ts +33 -10
  152. package/src/automations/write-async.ts +33 -0
  153. package/src/branch-land-notice.ts +93 -0
  154. package/src/branch-landed.ts +31 -98
  155. package/src/bus.ts +40 -39
  156. package/src/cd-deploy-notify.ts +32 -4
  157. package/src/cd-host-lag-notify.ts +7 -6
  158. package/src/ci/incidents.ts +2 -2
  159. package/src/ci/monitor.ts +5 -8
  160. package/src/ci/notifications.ts +4 -4
  161. package/src/ci/root-missing.ts +4 -9
  162. package/src/ci/transition-notify.ts +12 -44
  163. package/src/claude-app/oauth-http.ts +3 -3
  164. package/src/cli/cd-pauses.ts +19 -0
  165. package/src/cli/orchestrator.ts +1 -1
  166. package/src/cli/state.ts +2 -19
  167. package/src/cli/task-edit.ts +22 -0
  168. package/src/cli/task.ts +3 -1
  169. package/src/cli/workflow.ts +19 -4
  170. package/src/commands-db.ts +7 -7
  171. package/src/commands-write.ts +8 -0
  172. package/src/compaction-watch.ts +10 -8
  173. package/src/config-store-write.ts +13 -1
  174. package/src/config-store.ts +25 -14
  175. package/src/config.ts +4 -11
  176. package/src/connectors.ts +10 -8
  177. package/src/context-advisory.ts +22 -21
  178. package/src/db/activity-async.ts +6 -1
  179. package/src/db/activity-write-ops.ts +12 -1
  180. package/src/db/activity.ts +1 -14
  181. package/src/db/agent-action-write.ts +36 -0
  182. package/src/db/agent-control-async.ts +9 -0
  183. package/src/db/agent-control-write.ts +49 -0
  184. package/src/db/agent-effort-observe.ts +22 -0
  185. package/src/db/agent-meta.ts +14 -3
  186. package/src/db/agent-search.ts +1 -15
  187. package/src/db/agents-async.ts +59 -9
  188. package/src/db/agents-write-ops.ts +12 -3
  189. package/src/db/agents.ts +95 -65
  190. package/src/db/auth-identities.ts +2 -2
  191. package/src/db/automation-read-ops.ts +11 -0
  192. package/src/db/automation-write-ops.ts +46 -0
  193. package/src/db/blackboard.ts +2 -2
  194. package/src/db/browser-session-write.ts +32 -0
  195. package/src/db/bus-outbox-write-ops.ts +3 -1
  196. package/src/db/checkout-refresh-schema.ts +47 -0
  197. package/src/db/checkout-refresh.ts +5 -5
  198. package/src/db/ci-incidents-async.ts +5 -5
  199. package/src/db/ci-incidents-write-ops.ts +2 -2
  200. package/src/db/command-agent-profile-backfill.ts +39 -0
  201. package/src/db/command-agent-profiles.ts +5 -1
  202. package/src/db/command-retention.ts +126 -0
  203. package/src/db/command-row.ts +10 -2
  204. package/src/db/commands-list-query.ts +2 -0
  205. package/src/db/commands-planner-stats.test-fixture.ts +8 -0
  206. package/src/db/commands-read-ops.ts +16 -0
  207. package/src/db/commands-spawn-read.ts +1 -1
  208. package/src/db/config-store-write-ops.ts +7 -2
  209. package/src/db/connection.ts +1 -182
  210. package/src/db/context-carry-write.ts +74 -0
  211. package/src/db/continuation-archives-async.ts +5 -0
  212. package/src/db/continuation-archives-write-ops.ts +7 -0
  213. package/src/db/continuations.ts +6 -6
  214. package/src/db/db-error-registry.ts +12 -0
  215. package/src/db/db-writer-worker.ts +8 -1
  216. package/src/db/deploy-events-async.ts +1 -0
  217. package/src/db/deploy-events-read-ops.ts +2 -1
  218. package/src/db/deploy-events.ts +35 -4
  219. package/src/db/gateway.ts +26 -133
  220. package/src/db/history-retention-ops.ts +13 -0
  221. package/src/db/hosts-registration.ts +10 -2
  222. package/src/db/hosts.ts +9 -6
  223. package/src/db/inbox-async.ts +2 -2
  224. package/src/db/inbox-read-ops.ts +1 -1
  225. package/src/db/inbox.ts +9 -17
  226. package/src/db/index.ts +2 -0
  227. package/src/db/integrations-async.ts +8 -0
  228. package/src/db/integrations-ops.ts +15 -0
  229. package/src/db/integrations.ts +15 -21
  230. package/src/db/issue-associations.ts +2 -2
  231. package/src/db/issue-lifecycle.ts +3 -4
  232. package/src/db/issue-refs-async.ts +23 -0
  233. package/src/db/issue-refs-read-ops.ts +6 -0
  234. package/src/db/issue-refs-write-ops.ts +29 -0
  235. package/src/db/issue-refs.ts +15 -16
  236. package/src/db/kernel-event-log-schema.ts +2 -0
  237. package/src/db/land-boundaries.ts +51 -5
  238. package/src/db/land-gate-attestations.ts +2 -2
  239. package/src/db/landing-receipts.ts +2 -2
  240. package/src/db/lifecycle-context-write.ts +5 -0
  241. package/src/db/lifecycle-tail-async.ts +76 -0
  242. package/src/db/lifecycle-tail-write-ops.ts +62 -0
  243. package/src/db/lifecycle-write-window.ts +2 -1
  244. package/src/db/lineage-pair-dedupe-sql.ts +3 -3
  245. package/src/db/long-running-work.ts +2 -2
  246. package/src/db/main-connection-mode.ts +11 -0
  247. package/src/db/main-connection-writes.ts +41 -2
  248. package/src/db/maintenance-job-reconcile.ts +61 -0
  249. package/src/db/maintenance-job-runs-async.ts +14 -0
  250. package/src/db/maintenance-job-write-ops.ts +9 -0
  251. package/src/db/maintenance-pauses.ts +2 -2
  252. package/src/db/mappers.ts +2 -14
  253. package/src/db/merge-lease.ts +1 -15
  254. package/src/db/message-send.ts +4 -0
  255. package/src/db/messages.ts +31 -25
  256. package/src/db/migrations.ts +25 -16
  257. package/src/db/notification-write-ops.ts +19 -0
  258. package/src/db/operator-answer-write.ts +19 -0
  259. package/src/db/orchestrators.ts +14 -76
  260. package/src/db/pairs-async.ts +22 -1
  261. package/src/db/pairs-write-ops.ts +8 -3
  262. package/src/db/pairs.ts +42 -61
  263. package/src/db/plan-dispatch-schema.ts +5 -1
  264. package/src/db/plan-ready-notices.ts +43 -0
  265. package/src/db/plan-tools-include-migration.ts +36 -0
  266. package/src/db/plans-write-ops.ts +2 -0
  267. package/src/db/presence-buffer.ts +5 -0
  268. package/src/db/presence-loop.ts +18 -23
  269. package/src/db/presence-write.ts +0 -6
  270. package/src/db/project-entries-async.ts +14 -0
  271. package/src/db/project-entries-read-ops.ts +5 -1
  272. package/src/db/project-entries-write-ops.ts +8 -0
  273. package/src/db/project-entries.ts +15 -12
  274. package/src/db/project-journal.ts +2 -2
  275. package/src/db/project-profile-instructions.ts +50 -0
  276. package/src/db/project-trust-approvals.ts +2 -2
  277. package/src/db/prompt-templates.ts +4 -4
  278. package/src/db/prompt-versions.ts +9 -2
  279. package/src/db/provider-config-history.ts +8 -3
  280. package/src/db/provider-model-seed.ts +34 -0
  281. package/src/db/read-op-marshaling-fixtures.ts +23 -0
  282. package/src/db/read-ops.ts +8 -0
  283. package/src/db/retention.ts +13 -2
  284. package/src/db/review-publish-write.ts +8 -0
  285. package/src/db/routing-policy.ts +2 -3
  286. package/src/db/runtime-admin-async.ts +19 -0
  287. package/src/db/runtime-admin-write-ops.ts +36 -0
  288. package/src/db/runtime-tail-async.ts +288 -0
  289. package/src/db/runtime-tail-write-ops.ts +97 -0
  290. package/src/db/schema.ts +13 -4
  291. package/src/db/spawn-budget.ts +5 -0
  292. package/src/db/spawn-delegation-state.ts +11 -4
  293. package/src/db/spawn-delegation.ts +1 -11
  294. package/src/db/sql-audit-indexes.ts +3 -0
  295. package/src/db/stats-async.ts +9 -6
  296. package/src/db/task-entity.ts +28 -6
  297. package/src/db/task-list.ts +3 -1
  298. package/src/db/tasks.ts +1 -17
  299. package/src/db/team-claim-policy.ts +60 -0
  300. package/src/db/teams-async.ts +4 -0
  301. package/src/db/teams-write-ops.ts +4 -0
  302. package/src/db/terminal-events.ts +15 -0
  303. package/src/db/timer-cutover-bodies.ts +292 -0
  304. package/src/db/timer-cutover-core.ts +37 -278
  305. package/src/db/timer-cutover-state.ts +40 -0
  306. package/src/db/timer-cutover-write-ops.ts +1 -40
  307. package/src/db/timer-ingress.ts +7 -1
  308. package/src/db/token-db-write-ops.ts +19 -0
  309. package/src/db/token-standing-async.ts +12 -0
  310. package/src/db/token-standing.ts +21 -20
  311. package/src/db/token-usage-retention.ts +33 -0
  312. package/src/db/token-usage-write-ops.ts +1 -1
  313. package/src/db/token-usage.ts +4 -1
  314. package/src/db/user-invites-async.ts +13 -0
  315. package/src/db/user-invites.ts +3 -3
  316. package/src/db/users.ts +14 -6
  317. package/src/db/workflow-contact.ts +1 -1
  318. package/src/db/workflow-task-read-ops.ts +30 -0
  319. package/src/db/workspaces.ts +8 -5
  320. package/src/db/write-ops.ts +37 -12
  321. package/src/db/writer-fault-seam.ts +2 -9
  322. package/src/db/writer-fault-test-ops.ts +18 -0
  323. package/src/db/writer-gateway.ts +58 -56
  324. package/src/dev.ts +8 -3
  325. package/src/dispatch-availability.ts +10 -6
  326. package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
  327. package/src/event-loop-lag.ts +4 -2
  328. package/src/event-loop-yield.ts +2 -2
  329. package/src/events.ts +10 -8
  330. package/src/host/disk-alert.ts +121 -0
  331. package/src/host-provider-store.ts +5 -4
  332. package/src/hub-metrics-report.ts +5 -1
  333. package/src/hub-metrics.ts +38 -18
  334. package/src/injection-sweep-pacing.ts +6 -8
  335. package/src/land-gate-notifications.ts +11 -10
  336. package/src/land-gate-queue-progress.ts +3 -3
  337. package/src/land-settle-dispatch.ts +52 -92
  338. package/src/lifecycle-context-pressure.ts +11 -10
  339. package/src/lifecycle-manager.ts +107 -100
  340. package/src/maintenance/breaker.ts +18 -16
  341. package/src/maintenance/cd-watcher.ts +3 -3
  342. package/src/maintenance/checkout-refresh.ts +18 -1
  343. package/src/maintenance/critical-job-watchdog.ts +19 -20
  344. package/src/maintenance/events.ts +3 -3
  345. package/src/maintenance/history-retention-job.ts +30 -0
  346. package/src/maintenance/index.ts +1 -0
  347. package/src/maintenance/jobs.ts +32 -69
  348. package/src/maintenance/long-running-work.ts +3 -1
  349. package/src/maintenance/offline-agent-prune-job.ts +28 -0
  350. package/src/maintenance/orphaned-sessions.ts +5 -4
  351. package/src/maintenance/pauses.ts +4 -10
  352. package/src/maintenance/plan-ready-notice-job.ts +71 -0
  353. package/src/maintenance/scheduler.ts +98 -137
  354. package/src/maintenance/stalled-delivery-pager.ts +10 -9
  355. package/src/maintenance/teams.ts +19 -30
  356. package/src/maintenance/workspaces.ts +18 -28
  357. package/src/managed-policy-escalation.ts +7 -7
  358. package/src/managed-policy.ts +32 -28
  359. package/src/managed-provider-gate.ts +5 -4
  360. package/src/managed-spawn-reservation.ts +5 -4
  361. package/src/mcp/index.ts +12 -9
  362. package/src/mcp/output-descriptions.ts +8 -8
  363. package/src/mcp/presentation.ts +6 -5
  364. package/src/mcp/project-profile-instructions.ts +32 -0
  365. package/src/mcp/runtime-output.ts +6 -1
  366. package/src/mcp/self-care-visibility.ts +2 -2
  367. package/src/mcp/spawn-targets-matrix.ts +10 -1
  368. package/src/mcp/tool-groups.ts +4 -3
  369. package/src/mcp/tool-roles.ts +81 -0
  370. package/src/mcp/tools-spawn.ts +4 -3
  371. package/src/mcp/tools-workspace.ts +1 -1
  372. package/src/mcp-agent-action.ts +1 -2
  373. package/src/mcp-blackboard-tools.ts +6 -5
  374. package/src/mcp-decision-tools.ts +7 -7
  375. package/src/mcp-egress-tools.ts +10 -9
  376. package/src/mcp-issue-activity-tools.ts +2 -2
  377. package/src/mcp-issue-association-tools.ts +4 -4
  378. package/src/mcp-issue-ref-tools.ts +13 -12
  379. package/src/mcp-maintenance-tools.ts +2 -2
  380. package/src/mcp-merge-tools.ts +5 -5
  381. package/src/mcp-notification-subscription-tools.ts +14 -15
  382. package/src/mcp-output-levels.test-fixture.ts +1 -1
  383. package/src/mcp-profile-trust-tools.ts +5 -5
  384. package/src/mcp-project-journal-tools.ts +4 -12
  385. package/src/mcp-project-tools.ts +17 -18
  386. package/src/mcp-provider-catalog.ts +2 -2
  387. package/src/mcp-routing-policy-tools.ts +3 -2
  388. package/src/mcp-task-tools.ts +11 -5
  389. package/src/mcp-team-template-tools.ts +3 -3
  390. package/src/mcp-team-tools.ts +6 -6
  391. package/src/mcp-workflow-tools.ts +13 -4
  392. package/src/memory-area-injection.ts +13 -12
  393. package/src/memory-boundary-capture.ts +6 -6
  394. package/src/memory-injection.ts +45 -43
  395. package/src/merge-pause-maintenance.ts +5 -4
  396. package/src/notification-router.ts +44 -17
  397. package/src/notification-types.ts +2 -1
  398. package/src/notify.ts +5 -5
  399. package/src/observed-reset-refresh.ts +4 -4
  400. package/src/operator-alarm.ts +23 -11
  401. package/src/project-ingest.ts +6 -6
  402. package/src/project-instructions.ts +12 -1
  403. package/src/project-profile-instruction-text.ts +6 -0
  404. package/src/project-profile-instructions.ts +20 -0
  405. package/src/project-trust.ts +12 -11
  406. package/src/prompt-resolver.ts +3 -3
  407. package/src/provider-catalog-store.ts +3 -49
  408. package/src/provider-config-store.ts +12 -11
  409. package/src/provider-model-seed.ts +1 -18
  410. package/src/provider-quota-async.ts +5 -7
  411. package/src/provider-quota-config-store.ts +5 -4
  412. package/src/provider-secrets.test-fixture.ts +3 -3
  413. package/src/provider-timeline-event.ts +4 -7
  414. package/src/quota-band-delivery.ts +2 -2
  415. package/src/recipe-runner.ts +6 -5
  416. package/src/repo-config-source.ts +10 -4
  417. package/src/retention-config-store.ts +4 -3
  418. package/src/reviewer-pipeline.ts +11 -10
  419. package/src/routes/_route.ts +4 -4
  420. package/src/routes/_shared.ts +13 -12
  421. package/src/routes/agent-effort.ts +5 -5
  422. package/src/routes/agent-heartbeat-quota.ts +23 -0
  423. package/src/routes/agent-keep.ts +1 -1
  424. package/src/routes/agent-profiles.ts +6 -6
  425. package/src/routes/agent-reporting.ts +1 -1
  426. package/src/routes/agent-self-effort.ts +5 -5
  427. package/src/routes/agent-sessions.ts +24 -24
  428. package/src/routes/agents-spawn.ts +2 -2
  429. package/src/routes/agents.ts +19 -121
  430. package/src/routes/auth.ts +14 -15
  431. package/src/routes/authority-audit.ts +2 -2
  432. package/src/routes/automations.ts +6 -5
  433. package/src/routes/channel-binding-delete.ts +1 -1
  434. package/src/routes/channel-output.ts +3 -3
  435. package/src/routes/claude-api-budget.ts +5 -5
  436. package/src/routes/commands-listing.ts +5 -1
  437. package/src/routes/commands.ts +31 -29
  438. package/src/routes/context-resets.ts +2 -2
  439. package/src/routes/continuation-archives.ts +2 -2
  440. package/src/routes/coordinator-teams.ts +1 -1
  441. package/src/routes/decisions.ts +2 -2
  442. package/src/routes/host-secret-files.ts +1 -1
  443. package/src/routes/hosts.ts +11 -11
  444. package/src/routes/inbox.ts +3 -2
  445. package/src/routes/index.ts +12 -2
  446. package/src/routes/integrations.ts +32 -56
  447. package/src/routes/issue-activity.ts +2 -2
  448. package/src/routes/issue-associations.ts +4 -4
  449. package/src/routes/issue-refs.ts +9 -9
  450. package/src/routes/kernel-timers-operator.ts +1 -1
  451. package/src/routes/memory.ts +1 -1
  452. package/src/routes/merges.ts +11 -11
  453. package/src/routes/messages.ts +23 -17
  454. package/src/routes/orchestrator-bootstrap.ts +2 -2
  455. package/src/routes/orchestrator-host-registration.ts +4 -2
  456. package/src/routes/orchestrator-host-utilization.ts +5 -3
  457. package/src/routes/orchestrator-proxy.ts +4 -4
  458. package/src/routes/orchestrator.ts +28 -19
  459. package/src/routes/pairs.ts +8 -8
  460. package/src/routes/project-profile-instructions.ts +27 -0
  461. package/src/routes/project-trust.ts +3 -3
  462. package/src/routes/projects.ts +16 -16
  463. package/src/routes/prompt-templates.ts +12 -12
  464. package/src/routes/provider-config.ts +6 -6
  465. package/src/routes/provider-quota-config.ts +2 -2
  466. package/src/routes/provider-quotas.ts +10 -10
  467. package/src/routes/run-command.ts +1 -1
  468. package/src/routes/secrets-backup.ts +2 -2
  469. package/src/routes/secrets-import.ts +1 -1
  470. package/src/routes/secrets-vault.ts +7 -7
  471. package/src/routes/settings.ts +6 -6
  472. package/src/routes/shipping.ts +9 -1
  473. package/src/routes/spawn-policy.ts +8 -7
  474. package/src/routes/sse.ts +2 -2
  475. package/src/routes/stats.ts +6 -6
  476. package/src/routes/task-http.ts +15 -1
  477. package/src/routes/task-issues.ts +11 -26
  478. package/src/routes/tasks.ts +22 -53
  479. package/src/routes/team-templates.ts +12 -12
  480. package/src/routes/teams-config.ts +2 -2
  481. package/src/routes/teams.ts +10 -10
  482. package/src/routes/tokens.ts +30 -22
  483. package/src/routes/users.ts +24 -24
  484. package/src/routes/viewer-read.ts +3 -3
  485. package/src/routes/web-tool-calls.ts +4 -4
  486. package/src/routes/workflows.ts +22 -7
  487. package/src/routes/workspaces.ts +17 -16
  488. package/src/routing-policy-normalize.ts +1 -2
  489. package/src/routing-policy-push.ts +6 -6
  490. package/src/routing-step-defaults.ts +0 -2
  491. package/src/runner-token-mint-limit.ts +63 -0
  492. package/src/runtime-grant.ts +21 -13
  493. package/src/runtime-tokens.ts +59 -35
  494. package/src/secrets-broker/config.ts +1 -1
  495. package/src/secrets-broker/service.ts +2 -2
  496. package/src/security.ts +16 -21
  497. package/src/self-resume-carry.ts +21 -110
  498. package/src/self-resume-supersede.ts +4 -3
  499. package/src/self-resume.ts +54 -66
  500. package/src/server-background.ts +2 -2
  501. package/src/server.ts +26 -24
  502. package/src/services/agent-action.ts +12 -31
  503. package/src/services/agent-effort.ts +7 -32
  504. package/src/services/agent-hang-watchdog-job.ts +2 -2
  505. package/src/services/agent-heartbeat.ts +166 -0
  506. package/src/services/agent-reporting.ts +1 -1
  507. package/src/services/browser-inventory.ts +3 -3
  508. package/src/services/browser-session-state.ts +3 -2
  509. package/src/services/browser-session.ts +21 -27
  510. package/src/services/bus-command-update.ts +9 -9
  511. package/src/services/checkout-refresh-state.ts +1 -0
  512. package/src/services/checkout-refresh.test-fixture.ts +3 -2
  513. package/src/services/command-host.ts +7 -2
  514. package/src/services/coordinator-digest.ts +3 -2
  515. package/src/services/dispatch-command.ts +12 -13
  516. package/src/services/effective-launch-driver.ts +14 -9
  517. package/src/services/host-changed-paths.test-fixture.ts +5 -6
  518. package/src/services/host-project-readiness.ts +2 -2
  519. package/src/services/host-providers.ts +1 -1
  520. package/src/services/host-utilization.ts +27 -4
  521. package/src/services/idle-agent-digest.ts +17 -12
  522. package/src/services/idle-epics.ts +9 -10
  523. package/src/services/interrupt-agent.ts +12 -9
  524. package/src/services/issue-activity.ts +3 -3
  525. package/src/services/issue-associations.ts +15 -18
  526. package/src/services/issue-lifecycle-comments.ts +3 -2
  527. package/src/services/issue-lifecycle.ts +69 -72
  528. package/src/services/issue-refs.ts +10 -15
  529. package/src/services/kernel-timers-cutover-chaos-worker.ts +11 -8
  530. package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
  531. package/src/services/kernel-timers-ingress.ts +4 -4
  532. package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
  533. package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
  534. package/src/services/kernel-timers-outbox.ts +1 -1
  535. package/src/services/kernel-timers-stage10-operator.ts +1 -1
  536. package/src/services/kernel-timers.ts +4 -3
  537. package/src/services/land-gate-placement.ts +11 -2
  538. package/src/services/land-issue-relations.ts +5 -4
  539. package/src/services/land-restart-retry.ts +7 -6
  540. package/src/services/landed-ancestry.ts +25 -8
  541. package/src/services/legacy-landing-host.ts +4 -1
  542. package/src/services/legacy-landing-recovery.ts +8 -6
  543. package/src/services/managed-running.ts +17 -17
  544. package/src/services/memory-areas.ts +17 -53
  545. package/src/services/merge-pause.ts +9 -15
  546. package/src/services/operator-decisions.ts +37 -41
  547. package/src/services/orchestrator-registration-recovery.ts +6 -2
  548. package/src/services/orchestrator-upgrade.ts +14 -12
  549. package/src/services/permission-decision.ts +4 -3
  550. package/src/services/plan-ci-notice.ts +57 -0
  551. package/src/services/plan-ci-recovery.ts +2 -55
  552. package/src/services/plan-conformance.ts +4 -4
  553. package/src/services/plan-dispatch-policy.ts +10 -3
  554. package/src/services/plan-dispatch.ts +35 -14
  555. package/src/services/plan-graph.ts +39 -261
  556. package/src/services/plan-import.ts +1 -1
  557. package/src/services/plan-live-bindings.ts +8 -37
  558. package/src/services/plan-task-create.ts +1 -1
  559. package/src/services/plan-terminal-refs.ts +2 -12
  560. package/src/services/plan-wake-digest.ts +9 -3
  561. package/src/services/profile-trust.ts +6 -5
  562. package/src/services/project-config-read.ts +70 -0
  563. package/src/services/project-profile-instructions.ts +54 -0
  564. package/src/services/project.ts +11 -10
  565. package/src/services/prompt-templates.ts +6 -5
  566. package/src/services/provider-hold-nudge.ts +9 -9
  567. package/src/services/provider-hold-record.ts +13 -12
  568. package/src/services/provider-state-audit.ts +19 -18
  569. package/src/services/provisioning-harness/budget-baseline.json +4 -4
  570. package/src/services/provisioning-harness/driver.ts +1 -1
  571. package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
  572. package/src/services/provisioning-harness/lifecycle.ts +24 -22
  573. package/src/services/provisioning-harness/prepare.ts +16 -17
  574. package/src/services/rate-limit-resume.ts +10 -9
  575. package/src/services/red-main-auto-revert.ts +7 -5
  576. package/src/services/red-main-controller-deps.ts +20 -3
  577. package/src/services/red-main-incident.ts +3 -1
  578. package/src/services/red-main-quarantine.ts +2 -3
  579. package/src/services/register-agent.ts +22 -22
  580. package/src/services/restart-project-role.ts +1 -1
  581. package/src/services/restart-spawn.ts +74 -61
  582. package/src/services/review-publish.ts +7 -24
  583. package/src/services/review-ref-reconcile.ts +29 -38
  584. package/src/services/runtime-dependency-alert.ts +27 -0
  585. package/src/services/scheduler-command.ts +11 -9
  586. package/src/services/scheduler.ts +5 -5
  587. package/src/services/self-care-state.ts +2 -1
  588. package/src/services/self-effort-grant.ts +5 -25
  589. package/src/services/self-effort.ts +5 -5
  590. package/src/services/send-message.ts +21 -34
  591. package/src/services/shutdown-agent.ts +17 -14
  592. package/src/services/spawn-agent.ts +25 -43
  593. package/src/services/spawn-chain-inspector.ts +7 -14
  594. package/src/services/spawn-cwd-placement.ts +21 -5
  595. package/src/services/spawn-issue-activity.ts +8 -6
  596. package/src/services/spawn-launch.ts +17 -1
  597. package/src/services/spawn-loss-escalation.ts +1 -1
  598. package/src/services/spawn-policy.ts +68 -0
  599. package/src/services/spawn-registration-watchdog.ts +2 -2
  600. package/src/services/spawn-repo-probe.ts +7 -5
  601. package/src/services/spawn-tree-cleanup.ts +8 -9
  602. package/src/services/steward-reaper.ts +4 -4
  603. package/src/services/task-context-hydration.ts +25 -1
  604. package/src/services/task-delivery.ts +20 -34
  605. package/src/services/task-dispatch.ts +3 -0
  606. package/src/services/task-entity.ts +40 -203
  607. package/src/services/task-issue-link.ts +13 -20
  608. package/src/services/task-issue-weave.ts +12 -11
  609. package/src/services/task-lifecycle.ts +27 -31
  610. package/src/services/task-repo-cwd.ts +37 -0
  611. package/src/services/task-review-hold.ts +4 -17
  612. package/src/services/task-semantic-events.ts +13 -11
  613. package/src/services/task-state-reconcile.ts +8 -17
  614. package/src/services/task-validation.ts +2 -2
  615. package/src/services/team-templates.ts +12 -11
  616. package/src/services/team.ts +31 -98
  617. package/src/services/terminal-provider-exit.ts +6 -5
  618. package/src/services/timer-message-fire-chaos-worker.ts +7 -3
  619. package/src/services/timer-message-fire-outbox.ts +1 -1
  620. package/src/services/transient-agent-reaper.ts +25 -20
  621. package/src/services/turn-reconcile-audit.ts +9 -9
  622. package/src/services/user-onboarding.ts +8 -6
  623. package/src/services/user-profile.ts +6 -9
  624. package/src/services/work-finality.ts +16 -4
  625. package/src/services/workflow-auto-start.ts +26 -13
  626. package/src/services/workflow-caller.ts +61 -4
  627. package/src/services/workflow-child-proof-worker.ts +1 -1
  628. package/src/services/workflow-ci-main.ts +1 -1
  629. package/src/services/workflow-control-proof-worker.ts +1 -1
  630. package/src/services/workflow-coordinator.ts +8 -2
  631. package/src/services/workflow-decisions.ts +5 -5
  632. package/src/services/workflow-deferred-cleanup.ts +5 -3
  633. package/src/services/workflow-effect-driver.ts +42 -17
  634. package/src/services/workflow-effects.ts +58 -37
  635. package/src/services/workflow-land-notice.ts +10 -0
  636. package/src/services/workflow-pause-text.ts +43 -0
  637. package/src/services/workflow-pins.ts +7 -4
  638. package/src/services/workflow-reconcile.ts +14 -11
  639. package/src/services/workflow-resume-pins.ts +3 -3
  640. package/src/services/workflow-routing-defaults.ts +18 -0
  641. package/src/services/workflow-run-view.ts +6 -3
  642. package/src/services/workflow-run.test-fixture.ts +1 -1
  643. package/src/services/workflow-runs.ts +61 -33
  644. package/src/services/workflow-supervisor-state.ts +26 -1
  645. package/src/services/workflow-supervisor.ts +11 -6
  646. package/src/services/workspace-recovery.ts +4 -3
  647. package/src/settings/registry.ts +1 -2
  648. package/src/spawn-admission.ts +10 -2
  649. package/src/spawn-command.ts +4 -4
  650. package/src/spawn-models.ts +10 -12
  651. package/src/spawn-placement.ts +28 -10
  652. package/src/spawn-targets.ts +9 -9
  653. package/src/sse-agent-status.ts +15 -6
  654. package/src/sse.ts +49 -24
  655. package/src/startup-context-injection.ts +62 -57
  656. package/src/state-adoption/cd-cutover.ts +53 -7
  657. package/src/state-adoption/fleet-cutover.ts +35 -0
  658. package/src/state-adoption/fleet-plan.ts +36 -0
  659. package/src/state-adoption/index.ts +2 -2
  660. package/src/state-adoption/linux-plan.ts +2 -2
  661. package/src/state-adoption/linux.ts +2 -2
  662. package/src/state-adoption/macos-plan.ts +2 -2
  663. package/src/state-adoption/macos.ts +1 -1
  664. package/src/steward-handoff.ts +4 -3
  665. package/src/steward-policy-cleanup.ts +9 -8
  666. package/src/steward.ts +9 -8
  667. package/src/task-dispatch-live.ts +6 -3
  668. package/src/task-dispatcher.ts +3 -3
  669. package/src/teams-config-store.ts +4 -3
  670. package/src/token-db-write.ts +10 -0
  671. package/src/token-db.ts +2 -2
  672. package/src/token-usage-async.ts +2 -4
  673. package/src/user-awaiting-reply.ts +5 -5
  674. package/src/workspace-actions.ts +24 -29
  675. package/src/workspace-auto-merge.ts +14 -12
  676. package/src/workspace-changed-paths-client.ts +16 -5
  677. package/src/workspace-cleanup-stale.ts +30 -7
  678. package/src/workspace-command-settle.ts +26 -17
  679. package/src/workspace-config.ts +1 -1
  680. package/src/workspace-conflict-resolver.ts +9 -7
  681. package/src/workspace-dead-owner-recovery.ts +5 -4
  682. package/src/workspace-escalation.ts +12 -11
  683. package/src/workspace-human-escalation.ts +3 -3
  684. package/src/workspace-land-gate-watchdog.ts +3 -3
  685. package/src/workspace-land-refusal.ts +20 -0
  686. package/src/workspace-land-stopped.ts +1 -0
  687. package/src/workspace-merge.ts +10 -26
  688. package/src/workspace-nothing-to-land-notice.ts +2 -2
  689. package/src/workspace-orphans.ts +18 -37
  690. package/src/workspace-pr-completion.ts +10 -8
  691. package/src/workspace-rekey.ts +3 -3
  692. package/src/workspace-steward-failure.ts +2 -2
  693. package/src/workspace-steward-wake.ts +4 -4
  694. package/node_modules/@humwick/kernel/LICENSE +0 -167
  695. package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
  696. package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
  697. package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
  698. package/node_modules/@humwick/kernel/config.ts +0 -111
  699. package/node_modules/@humwick/kernel/contract.ts +0 -572
  700. package/node_modules/@humwick/kernel/control-authz.ts +0 -281
  701. package/node_modules/@humwick/kernel/control.ts +0 -645
  702. package/node_modules/@humwick/kernel/effects.ts +0 -493
  703. package/node_modules/@humwick/kernel/event-log.ts +0 -319
  704. package/node_modules/@humwick/kernel/http-transport.ts +0 -384
  705. package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
  706. package/node_modules/@humwick/kernel/identity.ts +0 -248
  707. package/node_modules/@humwick/kernel/index.ts +0 -28
  708. package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
  709. package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
  710. package/node_modules/@humwick/kernel/landing.ts +0 -953
  711. package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
  712. package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
  713. package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
  714. package/node_modules/@humwick/kernel/message-authority.ts +0 -281
  715. package/node_modules/@humwick/kernel/module-host.ts +0 -722
  716. package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
  717. package/node_modules/@humwick/kernel/package.json +0 -39
  718. package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
  719. package/node_modules/@humwick/kernel/persistence.ts +0 -510
  720. package/node_modules/@humwick/kernel/registry.ts +0 -60
  721. package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
  722. package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
  723. package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
  724. package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
  725. package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
  726. package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
  727. package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
  728. package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
  729. package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
  730. package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
  731. package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
  732. package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
  733. package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
  734. package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
  735. package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
  736. package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
  737. package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
  738. package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
  739. package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
  740. package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
  741. package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
  742. package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
  743. package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
  744. package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
  745. package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
  746. package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
  747. package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
  748. package/node_modules/@humwick/offload/LICENSE +0 -167
  749. package/node_modules/@humwick/offload/README.md +0 -57
  750. package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
  751. package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
  752. package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
  753. package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
  754. package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
  755. package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
  756. package/node_modules/@humwick/offload/dist/envelope.js +0 -80
  757. package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
  758. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
  759. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
  760. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
  761. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
  762. package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
  763. package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
  764. package/node_modules/@humwick/offload/dist/index.js +0 -5
  765. package/node_modules/@humwick/offload/dist/index.js.map +0 -1
  766. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
  767. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
  768. package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
  769. package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
  770. package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
  771. package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
  772. package/node_modules/@humwick/offload/dist/types.js +0 -176
  773. package/node_modules/@humwick/offload/dist/types.js.map +0 -1
  774. package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
  775. package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
  776. package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
  777. package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
  778. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
  779. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
  780. package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
  781. package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
  782. package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
  783. package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
  784. package/node_modules/@humwick/offload/dist/worker.js +0 -1
  785. package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
  786. package/node_modules/@humwick/offload/package.json +0 -42
  787. package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
  788. package/node_modules/@humwick/offload/src/envelope.ts +0 -92
  789. package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
  790. package/node_modules/@humwick/offload/src/index.ts +0 -4
  791. package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
  792. package/node_modules/@humwick/offload/src/types.ts +0 -235
  793. package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
  794. package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
  795. package/node_modules/@humwick/offload/src/worker.ts +0 -5
  796. package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
  797. package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
  798. package/public/assets/index-B7ZerHLY.css +0 -2
  799. package/public/assets/index-BU3uWo2t.js +0 -15
  800. package/public/assets/projects-B_lmcqfO.js +0 -2
  801. package/public/assets/provider-display-DbLWpP3j.js +0 -2
  802. package/public/assets/run-card-CO_bguQf.js +0 -2
  803. package/public/assets/shipping-Bu8p1gEw.js +0 -2
  804. package/public/assets/store-BvtFdlGX.js +0 -9
  805. package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
  806. package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
  807. package/runner/src/agent-runner/http-liveness.ts +0 -85
  808. package/runner/src/gate-run-lease-probe.ts +0 -38
  809. package/src/db/claude-catalog-reconcile.ts +0 -27
  810. package/src/db/on-loop-write-transaction.ts +0 -34
  811. package/src/routing-model-aliases.ts +0 -21
@@ -1,953 +0,0 @@
1
- import { z } from "zod";
2
- import { landingIncidentEntities, landingIncidentOps } from "./landing-incident";
3
- import { type EntityStore, type JsonValue, type ModuleCtx, type StepResult, OpError, defineModule } from "./contract";
4
-
5
- export const LANDING_STATES = [
6
- "controller_wait",
7
- "queued",
8
- "supersession_wait",
9
- "lane_wait",
10
- "authorization_required",
11
- "preparing",
12
- "gating",
13
- "gate_failed",
14
- "publish_ready",
15
- "publishing",
16
- "verifying",
17
- "cleanup",
18
- "receipt_ready",
19
- "external_retire_pending",
20
- "retry_wait",
21
- "reconciliation_required",
22
- "supersede_pending",
23
- "cancel_pending",
24
- "landed",
25
- "superseded",
26
- "canceled",
27
- "failed",
28
- ] as const;
29
-
30
- const landingStateSchema = z.enum(LANDING_STATES);
31
- const terminalProcessProofSchema = z.enum(["never_started", "completed", "process_tree_dead"]);
32
-
33
- const workspaceHeadSchema = z.object({
34
- id: z.string(),
35
- workspaceId: z.string(),
36
- currentRunId: z.string(),
37
- generation: z.number().int(),
38
- authorizationEventId: z.number().int(),
39
- updatedAt: z.number().int(),
40
- });
41
-
42
- const runSchema = z.object({
43
- id: z.string(),
44
- workspaceId: z.string(),
45
- laneKey: z.string().optional(),
46
- generation: z.number().int(),
47
- authorizationEventId: z.number().int(),
48
- workflowInstanceId: z.string().optional(),
49
- sourceRef: z.string(),
50
- sourceHeadSha: z.string(),
51
- repoRoot: z.string(),
52
- remoteIdentity: z.string(),
53
- baseRef: z.string(),
54
- strategy: z.string(),
55
- gateSnapshot: z.string(),
56
- requesterSnapshot: z.string(),
57
- baseHeadSha: z.string().optional(),
58
- candidateHeadSha: z.string().optional(),
59
- candidateTreeSha: z.string().optional(),
60
- pushRemote: z.string().optional(),
61
- selectedOrchestratorId: z.string().optional(),
62
- selectedCapabilityDigest: z.string().optional(),
63
- selectedSafetyDigest: z.string().optional(),
64
- candidateWorktreePath: z.string().optional(),
65
- executionTreeHandle: z.string().optional(),
66
- controllerVersion: z.number().int().optional(),
67
- controllerToken: z.string().optional(),
68
- laneToken: z.string().optional(),
69
- gateTreeSha: z.string().optional(),
70
- gateConfigDigest: z.string().optional(),
71
- gateAttestation: z.string().optional(),
72
- receiptId: z.string().optional(),
73
- receiptTargetSha: z.string().optional(),
74
- receiptVerifiedAt: z.number().int().optional(),
75
- receiptVerificationGeneration: z.number().int().optional(),
76
- receiptKind: z.enum(["kernel", "external"]).optional(),
77
- state: landingStateSchema,
78
- stateVersion: z.number().int(),
79
- stateSince: z.number().int(),
80
- queuedAt: z.number().int(),
81
- attempt: z.number().int(),
82
- phaseOrdinal: z.number().int(),
83
- commandGeneration: z.number().int(),
84
- // Optional for migration safety: Phase 3 rows predate this dedicated legacy projection clock.
85
- // commandGeneration remains reserved for the Phase 4 Kernel command fence.
86
- legacyProgressSequence: z.number().int().optional(),
87
- commandId: z.string().optional(),
88
- lastDryRunCommandId: z.string().optional(),
89
- nextRetryAt: z.number().int().optional(),
90
- transientFailures: z.number().int(),
91
- gateFailures: z.number().int(),
92
- pushRaces: z.number().int(),
93
- executorRecoveries: z.number().int(),
94
- blockerCode: z.string().optional(),
95
- blockerDetail: z.string().optional(),
96
- blockedAt: z.number().int().optional(),
97
- supersededBy: z.string().optional(),
98
- landedSha: z.string().optional(),
99
- landedAt: z.number().int().optional(),
100
- terminalProcessProof: terminalProcessProofSchema.optional(),
101
- legacyCommandId: z.string().optional(),
102
- legacyStatus: z.string().optional(),
103
- shadowVerdict: z.enum(["parity", "mismatch"]).optional(),
104
- shadowSummaryDigest: z.string().optional(),
105
- lastComparisonDigest: z.string().optional(),
106
- lastComparisonVersion: z.number().int().optional(),
107
- consecutiveStaleComparisons: z.number().int().optional(),
108
- shadowDetail: z.string().optional(),
109
- durableExitKind: z.enum(["command_wait", "event_wait", "sleep", "supervisor_reconcile", "explicit_action"]).optional(),
110
- observationGeneration: z.number().int().optional(),
111
- lastObservedAt: z.number().int().optional(),
112
- nextObservationAt: z.number().int().optional(),
113
- lastObservationDigest: z.string().optional(),
114
- observationRepeatCount: z.number().int().optional(),
115
- predictedOutcome: z.enum(["none", "external_retire", "reconciliation_required"]).optional(),
116
- lastReconciledAt: z.number().int().optional(),
117
- createdAt: z.number().int(),
118
- updatedAt: z.number().int(),
119
- });
120
-
121
- const laneSchema = z.object({
122
- id: z.string(),
123
- laneKey: z.string(),
124
- repoRoot: z.string(),
125
- remoteIdentity: z.string(),
126
- baseRef: z.string(),
127
- identityDigest: z.string(),
128
- currentRunId: z.string().optional(),
129
- retiringRunId: z.string().optional(),
130
- laneToken: z.string().optional(),
131
- leaseExpiresAt: z.number().int().optional(),
132
- activeCommandId: z.string().optional(),
133
- activeExecutionGeneration: z.number().int().optional(),
134
- drainEpochId: z.string().optional(),
135
- lastTerminalProcessProof: terminalProcessProofSchema.optional(),
136
- updatedAt: z.number().int(),
137
- });
138
-
139
- const noticeSchema = z.object({
140
- id: z.string(),
141
- runId: z.string(),
142
- stateVersion: z.number().int(),
143
- audience: z.string(),
144
- kind: z.string(),
145
- status: z.enum(["pending", "sent"]),
146
- payload: z.string(),
147
- createdAt: z.number().int(),
148
- sentAt: z.number().int().optional(),
149
- });
150
-
151
- const effectSchema = z.object({
152
- id: z.string(),
153
- runId: z.string(),
154
- stateVersion: z.number().int(),
155
- kind: z.string(),
156
- status: z.enum(["pending", "completed"]),
157
- payload: z.string(),
158
- createdAt: z.number().int(),
159
- completedAt: z.number().int().optional(),
160
- deliveryKey: z.string().optional(),
161
- claimedAt: z.number().int().optional(),
162
- attempts: z.number().int().optional(),
163
- });
164
-
165
- const comparisonSchema = z.object({
166
- id: z.string(),
167
- runId: z.string(),
168
- generation: z.number().int(),
169
- comparisonVersion: z.number().int(),
170
- verdict: z.enum(["parity", "mismatch", "stale"]),
171
- legacyState: z.string(),
172
- shadowState: landingStateSchema,
173
- summaryDigest: z.string(),
174
- detail: z.string(),
175
- createdAt: z.number().int(),
176
- });
177
-
178
- const targetObservationSchema = z.object({
179
- id: z.string(),
180
- runId: z.string(),
181
- generation: z.number().int(),
182
- observationGeneration: z.number().int(),
183
- sourceHeadSha: z.string(),
184
- candidateHeadSha: z.string().optional(),
185
- targetRef: z.string(),
186
- targetHeadSha: z.string().optional(),
187
- sourceContained: z.boolean().optional(),
188
- candidateContained: z.boolean().optional(),
189
- containmentMethod: z.string().optional(),
190
- status: z.enum(["positive", "negative", "unknown"]),
191
- observedAt: z.number().int(),
192
- });
193
-
194
- const receiptSchema = z.object({
195
- id: z.string(),
196
- runId: z.string(),
197
- workspaceId: z.string(),
198
- generation: z.number().int(),
199
- laneKey: z.string(),
200
- kind: z.enum(["kernel", "external"]),
201
- sourceRef: z.string(),
202
- sourceHeadSha: z.string(),
203
- targetRef: z.string(),
204
- targetHeadSha: z.string(),
205
- candidateHeadSha: z.string().optional(),
206
- gateAttestation: z.string().optional(),
207
- verificationGeneration: z.number().int(),
208
- verifiedAt: z.number().int(),
209
- createdAt: z.number().int(),
210
- });
211
-
212
- type LandingStores = {
213
- workspaceHead: EntityStore<{ schema: typeof workspaceHeadSchema }>;
214
- run: EntityStore<{ schema: typeof runSchema }>;
215
- lane: EntityStore<{ schema: typeof laneSchema }>;
216
- notice: EntityStore<{ schema: typeof noticeSchema }>;
217
- effect: EntityStore<{ schema: typeof effectSchema }>;
218
- targetObservation: EntityStore<{ schema: typeof targetObservationSchema }>;
219
- comparison: EntityStore<{ schema: typeof comparisonSchema }>;
220
- receipt: EntityStore<{ schema: typeof receiptSchema }>;
221
- };
222
-
223
- function stores(ctx: ModuleCtx): LandingStores {
224
- return ctx.entities as unknown as LandingStores;
225
- }
226
-
227
- export function landingRunId(workspaceId: string, authorizationEventId: number): string {
228
- return `land:${workspaceId}:event:${authorizationEventId}`;
229
- }
230
-
231
- const frozenIntentSchema = z.object({
232
- repoRoot: z.string().min(1),
233
- remoteIdentity: z.string().min(1),
234
- baseRef: z.string().min(1),
235
- strategy: z.string().min(1),
236
- gateSnapshot: z.record(z.string(), z.unknown()),
237
- requester: z.object({ actor: z.string().min(1), agentId: z.string().optional() }),
238
- });
239
-
240
- const admissionInputSchema = z.object({
241
- authorizationEventId: z.number().int().positive(),
242
- workspaceId: z.string().min(1),
243
- laneKey: z.string().min(1).optional(),
244
- sourceRef: z.string().min(1),
245
- sourceHeadSha: z.string().min(1),
246
- queuedAt: z.number().int(),
247
- frozenIntent: frozenIntentSchema,
248
- });
249
-
250
- const dryRunTupleSchema = z.object({
251
- runId: z.string(), generation: z.number().int(), commandGeneration: z.number().int(),
252
- attempt: z.number().int(), phaseOrdinal: z.number().int(), stateVersion: z.number().int(),
253
- });
254
-
255
- const dryRunCommandResultInputSchema = z.object({
256
- commandId: z.string().min(1),
257
- type: z.enum(["landing.prepare", "landing.gate", "landing.publish", "landing.verify", "landing.observe-target", "landing.cleanup"]),
258
- tuple: dryRunTupleSchema,
259
- terminalProcessProof: z.literal("completed"),
260
- result: z.record(z.string(), z.unknown()),
261
- });
262
-
263
- const admissionOutputSchema = z.object({
264
- runId: z.string(),
265
- generation: z.number().int(),
266
- state: landingStateSchema,
267
- current: z.boolean(),
268
- workflowInstanceId: z.string().optional(),
269
- });
270
-
271
- const observationInputSchema = z.object({
272
- runId: z.string(),
273
- expectedGeneration: z.number().int(),
274
- expectedStateVersion: z.number().int(),
275
- observationGeneration: z.number().int().positive(),
276
- factDigest: z.string().min(1).max(200),
277
- sourceHeadSha: z.string(),
278
- candidateHeadSha: z.string().optional(),
279
- targetRef: z.string(),
280
- targetHeadSha: z.string().optional(),
281
- sourceContained: z.boolean().optional(),
282
- candidateContained: z.boolean().optional(),
283
- containmentMethod: z.string().optional(),
284
- status: z.enum(["positive", "negative", "unknown"]),
285
- });
286
-
287
- const finalizeControlInputSchema = z.object({
288
- runId: z.string(), expectedGeneration: z.number().int(), expectedStateVersion: z.number().int(),
289
- commandId: z.string(), terminalProcessProof: terminalProcessProofSchema,
290
- });
291
-
292
- const landingHostCommandInputSchema = z.object({
293
- type: z.enum(["landing.prepare", "landing.gate", "landing.publish", "landing.verify", "landing.cleanup"]),
294
- params: z.record(z.string(), z.unknown()),
295
- });
296
-
297
- const LANDING_ADMIN_GRANT = "landing:admin" as const;
298
-
299
- type ControllerWaitState = { runId: string; commandId?: string };
300
- type LandingState = z.output<typeof landingStateSchema>;
301
- type LandingControlAction = "cancel" | "fail" | "supersede" | "retry" | "reconcile";
302
-
303
- const NONTERMINAL_LANDING_STATES = LANDING_STATES.filter(
304
- (state): state is Exclude<LandingState, "landed" | "superseded" | "canceled" | "failed"> =>
305
- state !== "landed" && state !== "superseded" && state !== "canceled" && state !== "failed",
306
- );
307
-
308
- export type LandingDurableExit = "command_wait" | "event_wait" | "sleep" | "supervisor_reconcile" | "explicit_action";
309
-
310
- // Persisted exit labels retained for historical landing command/control compatibility.
311
- export const LANDING_DURABLE_EXITS = Object.freeze({
312
- controller_wait: "event_wait",
313
- queued: "supervisor_reconcile",
314
- supersession_wait: "event_wait",
315
- lane_wait: "event_wait",
316
- authorization_required: "sleep",
317
- preparing: "supervisor_reconcile",
318
- gating: "supervisor_reconcile",
319
- gate_failed: "explicit_action",
320
- publish_ready: "supervisor_reconcile",
321
- publishing: "supervisor_reconcile",
322
- verifying: "supervisor_reconcile",
323
- cleanup: "supervisor_reconcile",
324
- receipt_ready: "supervisor_reconcile",
325
- external_retire_pending: "supervisor_reconcile",
326
- retry_wait: "sleep",
327
- reconciliation_required: "explicit_action",
328
- supersede_pending: "supervisor_reconcile",
329
- cancel_pending: "supervisor_reconcile",
330
- } satisfies Record<(typeof NONTERMINAL_LANDING_STATES)[number], LandingDurableExit>);
331
-
332
- const LANDING_OBSERVATION_BASE_MS = 30_000;
333
- const LANDING_OBSERVATION_MAX_MS = 30 * 60_000;
334
-
335
- function repeatedObservationDelayMs(repeats: number): number {
336
- return Math.min(LANDING_OBSERVATION_MAX_MS, LANDING_OBSERVATION_BASE_MS * 2 ** Math.min(6, repeats));
337
- }
338
-
339
- function commandForRun(row: z.output<typeof runSchema>): z.input<typeof landingHostCommandInputSchema> | undefined {
340
- if (!row.laneKey || !row.baseHeadSha || !row.controllerToken || !row.laneToken || !row.selectedOrchestratorId
341
- || !row.selectedCapabilityDigest || !row.selectedSafetyDigest || !row.executionTreeHandle) return undefined;
342
- const common = { workspaceId: row.workspaceId, laneKey: row.laneKey, repoRoot: row.repoRoot,
343
- sourceRef: row.sourceRef, sourceHeadSha: row.sourceHeadSha, baseRef: row.baseRef,
344
- baseHeadSha: row.baseHeadSha, laneToken: row.laneToken,
345
- runTuple: { runId: row.id, generation: row.generation, commandGeneration: row.commandGeneration,
346
- attempt: row.attempt, phaseOrdinal: row.phaseOrdinal, stateVersion: row.stateVersion },
347
- selectedHost: { orchestratorId: row.selectedOrchestratorId,
348
- capabilityDigest: row.selectedCapabilityDigest, safetyDigest: row.selectedSafetyDigest },
349
- executionTreeHandle: row.executionTreeHandle };
350
- if (row.state === "preparing" && row.candidateWorktreePath) return {
351
- type: "landing.prepare", params: { ...common, candidateWorktreePath: row.candidateWorktreePath },
352
- };
353
- if (row.state === "gating" && row.candidateWorktreePath && row.candidateHeadSha) return {
354
- type: "landing.gate", params: { ...common, candidateWorktreePath: row.candidateWorktreePath,
355
- candidateHeadSha: row.candidateHeadSha, gates: [] },
356
- };
357
- if (row.state === "publish_ready" && (row.observationGeneration ?? 0) > 0
358
- && row.candidateWorktreePath && row.candidateHeadSha
359
- && row.pushRemote && row.gateTreeSha && row.gateConfigDigest && row.gateAttestation) return {
360
- type: "landing.publish", params: { ...common, candidateWorktreePath: row.candidateWorktreePath,
361
- pushRemote: row.pushRemote, candidateHeadSha: row.candidateHeadSha, gateTreeSha: row.gateTreeSha,
362
- gateConfigDigest: row.gateConfigDigest, gateAttestationDigest: row.gateAttestation,
363
- observationGeneration: row.observationGeneration ?? 0, expectedRestartEpoch: null,
364
- pushAttemptId: `push:${row.id}:${row.commandGeneration}`,
365
- timing: { pushTimeoutMs: 300_000, reapTimeoutMs: 60_000, reportTimeoutMs: 30_000,
366
- refreshedLaneLeaseMs: 15 * 60_000 } },
367
- };
368
- if (row.state === "verifying" && row.pushRemote) return { type: "landing.verify",
369
- params: { ...common, pushRemote: row.pushRemote,
370
- ...(row.candidateHeadSha ? { candidateHeadSha: row.candidateHeadSha } : {}) } };
371
- if (row.state === "cleanup" && row.candidateWorktreePath) return { type: "landing.cleanup",
372
- params: { ...common, candidateWorktreePath: row.candidateWorktreePath,
373
- ...(row.candidateHeadSha ? { candidateHeadSha: row.candidateHeadSha } : {}) } };
374
- return undefined;
375
- }
376
-
377
- const LANDING_CONTROL_TRANSITIONS = {
378
- cancel: { allowedFrom: new Set<LandingState>(NONTERMINAL_LANDING_STATES), target: "canceled", workflow: "cancel" },
379
- fail: { allowedFrom: new Set<LandingState>(NONTERMINAL_LANDING_STATES), target: "failed", workflow: "fail" },
380
- supersede: { allowedFrom: new Set<LandingState>(NONTERMINAL_LANDING_STATES), target: "superseded", workflow: "cancel" },
381
- retry: { allowedFrom: new Set<LandingState>(["failed", "gate_failed", "retry_wait", "authorization_required"]), target: "controller_wait", workflow: "reopen" },
382
- reconcile: { allowedFrom: new Set<LandingState>(["reconciliation_required"]), target: "controller_wait", workflow: "reopen" },
383
- } as const satisfies Record<LandingControlAction, {
384
- allowedFrom: ReadonlySet<LandingState>;
385
- target: LandingState;
386
- workflow: "cancel" | "fail" | "reopen";
387
- }>;
388
-
389
- function landingControlTransition(action: LandingControlAction, source: LandingState) {
390
- const transition = LANDING_CONTROL_TRANSITIONS[action];
391
- return transition.allowedFrom.has(source) ? transition : undefined;
392
- }
393
-
394
- async function stageWorkflowControl(
395
- ctx: ModuleCtx,
396
- operation: "cancel" | "fail" | "reopen",
397
- workflowInstanceId: string | undefined,
398
- failure?: JsonValue,
399
- ): Promise<void> {
400
- if (!workflowInstanceId) throw new OpError("workflow_control_unavailable", 500, "landing run has no enlisted workflow instance");
401
- if (!ctx.workflows.control) throw new OpError("workflow_control_unavailable", 500, "enlisted workflow controls are unavailable");
402
- const workflow = await ctx.workflows.status(workflowInstanceId);
403
- if (!workflow) throw new OpError("workflow_control_unavailable", 500,
404
- `landing workflow instance '${workflowInstanceId}' was not found`);
405
- // Terminal workflows are absorbing. For cancel/fail the desired convergence has already happened,
406
- // even when its exact terminal status differs; staging another control would be refused during
407
- // opCommit and roll the landing entity/event/comparison transaction back forever. Reopen remains
408
- // strict because it is the one operation whose desired result is a live workflow.
409
- if (operation !== "reopen" && ["done", "failed", "canceled"].includes(workflow.status)) return;
410
- await ctx.workflows.control(operation, workflowInstanceId, failure);
411
- }
412
-
413
- async function transitionRun(
414
- ctx: ModuleCtx,
415
- input: { runId: string; expectedGeneration: number; expectedStateVersion: number; blockerCode?: string; blockerDetail?: string },
416
- action: LandingControlAction,
417
- ) {
418
- const store = stores(ctx).run;
419
- const row = await store.get(input.runId);
420
- if (!row) throw new OpError("not_found", 404, `landing run '${input.runId}' was not found`);
421
- if (row.generation !== input.expectedGeneration || row.stateVersion !== input.expectedStateVersion) {
422
- throw new OpError("conflict", 409, `landing run '${input.runId}' fence mismatch`);
423
- }
424
- const transition = landingControlTransition(action, row.state);
425
- if (!transition) {
426
- throw new OpError(
427
- "invalid_state_transition",
428
- 409,
429
- `landing run '${input.runId}' cannot ${action} from state '${row.state}'`,
430
- );
431
- }
432
- const now = ctx.clock.now();
433
- const restart = action === "retry" || action === "reconcile";
434
- if (restart && row.commandId && !row.terminalProcessProof) {
435
- throw new OpError(
436
- "retirement_required",
437
- 409,
438
- `landing run '${input.runId}' cannot ${action} while command '${row.commandId}' is bound; cancel the landing to retire the active command before starting recovery`,
439
- );
440
- }
441
- const retirementPending = Boolean(row.commandId) && !restart;
442
- const target: LandingState = retirementPending
443
- ? action === "supersede" ? "supersede_pending" : "cancel_pending"
444
- : restart ? "queued" : transition.target;
445
- const updated = await store.update(input.runId, {
446
- state: target,
447
- stateVersion: row.stateVersion + 1,
448
- stateSince: now,
449
- updatedAt: now,
450
- ...(restart ? { attempt: row.attempt + 1, commandGeneration: row.commandGeneration + 1,
451
- phaseOrdinal: 0, commandId: undefined, candidateHeadSha: undefined, candidateTreeSha: undefined,
452
- gateTreeSha: undefined, gateConfigDigest: undefined, gateAttestation: undefined,
453
- receiptId: undefined, receiptTargetSha: undefined, receiptVerifiedAt: undefined,
454
- receiptVerificationGeneration: undefined, receiptKind: undefined,
455
- laneToken: undefined, selectedOrchestratorId: undefined, selectedCapabilityDigest: undefined,
456
- selectedSafetyDigest: undefined, candidateWorktreePath: undefined, executionTreeHandle: undefined,
457
- blockerCode: undefined, blockerDetail: undefined, blockedAt: undefined } : {}),
458
- ...(input.blockerCode ? { blockerCode: input.blockerCode, blockerDetail: input.blockerDetail, blockedAt: now } : {}),
459
- });
460
- if (!retirementPending && row.laneKey) {
461
- const lane = await stores(ctx).lane.get(row.laneKey);
462
- if (lane?.currentRunId === row.id) await stores(ctx).lane.update(lane.id, {
463
- currentRunId: undefined, retiringRunId: undefined, laneToken: undefined,
464
- leaseExpiresAt: undefined, activeCommandId: undefined, activeExecutionGeneration: undefined,
465
- lastTerminalProcessProof: row.terminalProcessProof, updatedAt: now,
466
- });
467
- }
468
- const workflow = restart && row.workflowInstanceId
469
- ? await ctx.workflows.status(row.workflowInstanceId) : undefined;
470
- if (!retirementPending && (!restart
471
- || (workflow !== undefined && !["pending", "running", "waiting", "sleeping"].includes(workflow.status)))) {
472
- await stageWorkflowControl(ctx, transition.workflow, row.workflowInstanceId,
473
- input.blockerCode ? { code: input.blockerCode, detail: input.blockerDetail ?? "" } : undefined);
474
- }
475
- await ctx.events.emit("landing.run_transitioned", { runId: row.id, state: target, stateVersion: updated.stateVersion });
476
- if (restart || retirementPending) {
477
- await ctx.events.emit("landing.controller_activated", { runId: row.id, correlationId: row.id });
478
- }
479
- return updated;
480
- }
481
-
482
- export const landing = defineModule({
483
- id: "landing",
484
- title: "Durable landing controller",
485
- description: "Kernel-owned durable landing authorization and controller state.",
486
- entities: {
487
- workspaceHead: { schema: workspaceHeadSchema, indexes: ["authorizationEventId"] },
488
- run: { schema: runSchema, indexes: ["workspaceId", "authorizationEventId", "state", "blockerCode", "shadowVerdict", ["workspaceId", "state"]] },
489
- lane: { schema: laneSchema, indexes: ["identityDigest", "currentRunId", "retiringRunId"] },
490
- notice: { schema: noticeSchema, indexes: ["runId", "status", ["runId", "stateVersion"]] },
491
- effect: { schema: effectSchema, indexes: ["runId", "status", ["runId", "stateVersion"]] },
492
- targetObservation: { schema: targetObservationSchema, indexes: ["runId", ["runId", "observationGeneration"]] },
493
- comparison: { schema: comparisonSchema, indexes: ["runId", "verdict", ["runId", "comparisonVersion"]] },
494
- receipt: { schema: receiptSchema, indexes: ["runId", "workspaceId", ["laneKey", "createdAt"]] },
495
- ...landingIncidentEntities,
496
- },
497
- events: {
498
- "landing.authorization_admitted": z.object({ runId: z.string(), authorizationEventId: z.number().int(), current: z.boolean() }),
499
- "landing.run_transitioned": z.object({ runId: z.string(), state: landingStateSchema, stateVersion: z.number().int() }),
500
- "landing.controller_activated": z.object({ runId: z.string(), correlationId: z.string() }),
501
- "landing.target_observed": z.object({ runId: z.string(), status: z.enum(["positive", "negative", "unknown"]), observationGeneration: z.number().int() }),
502
- "landing.receipt_finalized": z.object({ runId: z.string(), receiptId: z.string(), targetHeadSha: z.string(), kind: z.enum(["kernel", "external"]) }),
503
- },
504
- commands: {
505
- execute: {
506
- input: landingHostCommandInputSchema,
507
- result: z.record(z.string(), z.unknown()),
508
- target: "host-agent",
509
- grant: "command:landing",
510
- idempotencyKey: (input) => {
511
- const tuple = input.params.runTuple as Record<string, unknown> | undefined;
512
- return `${input.type}:${String(tuple?.runId)}:${String(tuple?.generation)}:${String(tuple?.commandGeneration)}`;
513
- },
514
- timeoutMs: 15 * 60_000,
515
- whenDegraded: "queue",
516
- },
517
- },
518
- workflows: {
519
- controller: {
520
- input: z.object({ runId: z.string() }),
521
- state: z.object({ runId: z.string(), commandId: z.string().optional() }),
522
- init: (input): ControllerWaitState => ({ runId: input.runId }),
523
- start: "controller_wait",
524
- steps: {
525
- controller_wait: {
526
- run: async (ctx, state: ControllerWaitState): Promise<StepResult<ControllerWaitState>> => {
527
- const run = await stores(ctx).run.get(state.runId);
528
- if (run && ["landed", "superseded", "canceled", "failed"].includes(run.state)) {
529
- return { state, next: "done", output: { runId: state.runId, state: run.state } };
530
- }
531
- const command = run ? commandForRun(run) : undefined;
532
- if (run && command && run.selectedOrchestratorId) {
533
- const issued = await ctx.commands.issue("execute", command, { host: run.selectedOrchestratorId });
534
- return { state: { ...state, commandId: issued.id }, next: "command_wait",
535
- waitFor: { kind: "command", commandId: issued.id } };
536
- }
537
- return { state, next: "controller_wait", waitFor: { kind: "event", topic: "landing.controller_activated", correlationId: state.runId } };
538
- },
539
- },
540
- command_wait: {
541
- run: async (_ctx, state: ControllerWaitState): Promise<StepResult<ControllerWaitState>> => ({
542
- state: { runId: state.runId }, next: "controller_wait",
543
- }),
544
- },
545
- },
546
- },
547
- },
548
- ops: {
549
- ...landingIncidentOps,
550
- admitAuthorization: {
551
- kind: "mutation",
552
- idempotent: true,
553
- grant: LANDING_ADMIN_GRANT,
554
- summary: "Admit one immutable landing authorization in event order.",
555
- expose: { http: false, mcp: false, cli: false },
556
- emits: ["landing.authorization_admitted", "landing.run_transitioned"],
557
- input: admissionInputSchema,
558
- output: admissionOutputSchema,
559
- handler: async (ctx, input) => {
560
- const entity = stores(ctx);
561
- const runId = landingRunId(input.workspaceId, input.authorizationEventId);
562
- const existing = await entity.run.get(runId);
563
- if (existing) {
564
- const head = await entity.workspaceHead.get(input.workspaceId);
565
- return {
566
- runId,
567
- generation: existing.generation,
568
- state: existing.state,
569
- current: head?.currentRunId === runId,
570
- ...(existing.workflowInstanceId ? { workflowInstanceId: existing.workflowInstanceId } : {}),
571
- };
572
- }
573
-
574
- const head = await entity.workspaceHead.get(input.workspaceId);
575
- const isCurrent = !head || input.authorizationEventId > head.authorizationEventId;
576
- const now = ctx.clock.now();
577
- if (!isCurrent) {
578
- await entity.run.create({
579
- id: runId,
580
- workspaceId: input.workspaceId,
581
- laneKey: input.laneKey,
582
- generation: input.authorizationEventId,
583
- authorizationEventId: input.authorizationEventId,
584
- sourceRef: input.sourceRef,
585
- sourceHeadSha: input.sourceHeadSha,
586
- repoRoot: input.frozenIntent.repoRoot,
587
- remoteIdentity: input.frozenIntent.remoteIdentity,
588
- baseRef: input.frozenIntent.baseRef,
589
- strategy: input.frozenIntent.strategy,
590
- gateSnapshot: JSON.stringify(input.frozenIntent.gateSnapshot),
591
- requesterSnapshot: JSON.stringify(input.frozenIntent.requester),
592
- state: "superseded",
593
- stateVersion: 0,
594
- stateSince: now,
595
- queuedAt: input.queuedAt,
596
- attempt: 0,
597
- phaseOrdinal: 0,
598
- commandGeneration: 0,
599
- legacyProgressSequence: 0,
600
- transientFailures: 0,
601
- gateFailures: 0,
602
- pushRaces: 0,
603
- executorRecoveries: 0,
604
- supersededBy: head!.currentRunId,
605
- terminalProcessProof: "never_started",
606
- createdAt: now,
607
- updatedAt: now,
608
- });
609
- await ctx.events.emit("landing.authorization_admitted", { runId, authorizationEventId: input.authorizationEventId, current: false });
610
- return { runId, generation: input.authorizationEventId, state: "superseded", current: false };
611
- }
612
-
613
- const workflow = await ctx.workflows.start("controller", { runId }, { idempotencyKey: runId, enlist: "op-commit" });
614
- await entity.run.create({
615
- id: runId,
616
- workspaceId: input.workspaceId,
617
- laneKey: input.laneKey,
618
- generation: input.authorizationEventId,
619
- authorizationEventId: input.authorizationEventId,
620
- workflowInstanceId: workflow.id,
621
- sourceRef: input.sourceRef,
622
- sourceHeadSha: input.sourceHeadSha,
623
- repoRoot: input.frozenIntent.repoRoot,
624
- remoteIdentity: input.frozenIntent.remoteIdentity,
625
- baseRef: input.frozenIntent.baseRef,
626
- strategy: input.frozenIntent.strategy,
627
- gateSnapshot: JSON.stringify(input.frozenIntent.gateSnapshot),
628
- requesterSnapshot: JSON.stringify(input.frozenIntent.requester),
629
- state: "controller_wait",
630
- stateVersion: 0,
631
- stateSince: now,
632
- queuedAt: input.queuedAt,
633
- attempt: 0,
634
- phaseOrdinal: 0,
635
- commandGeneration: 0,
636
- legacyProgressSequence: 0,
637
- transientFailures: 0,
638
- gateFailures: 0,
639
- pushRaces: 0,
640
- executorRecoveries: 0,
641
- createdAt: now,
642
- updatedAt: now,
643
- });
644
- if (head) {
645
- const prior = await entity.run.get(head.currentRunId);
646
- const supersession = prior ? landingControlTransition("supersede", prior.state) : undefined;
647
- if (prior && supersession) {
648
- await entity.run.update(prior.id, {
649
- state: supersession.target,
650
- stateVersion: prior.stateVersion + 1,
651
- stateSince: now,
652
- supersededBy: runId,
653
- terminalProcessProof: "never_started",
654
- updatedAt: now,
655
- });
656
- await stageWorkflowControl(ctx, supersession.workflow, prior.workflowInstanceId);
657
- await ctx.events.emit("landing.run_transitioned", { runId: prior.id, state: supersession.target, stateVersion: prior.stateVersion + 1 });
658
- }
659
- await entity.workspaceHead.update(input.workspaceId, {
660
- currentRunId: runId,
661
- generation: input.authorizationEventId,
662
- authorizationEventId: input.authorizationEventId,
663
- updatedAt: now,
664
- });
665
- } else {
666
- await entity.workspaceHead.create({
667
- id: input.workspaceId,
668
- workspaceId: input.workspaceId,
669
- currentRunId: runId,
670
- generation: input.authorizationEventId,
671
- authorizationEventId: input.authorizationEventId,
672
- updatedAt: now,
673
- });
674
- }
675
- await ctx.events.emit("landing.authorization_admitted", { runId, authorizationEventId: input.authorizationEventId, current: true });
676
- return { runId, generation: input.authorizationEventId, state: "controller_wait", current: true, workflowInstanceId: workflow.id };
677
- },
678
- },
679
- acceptDryRunCommandResult: {
680
- kind: "mutation", idempotent: true, grant: LANDING_ADMIN_GRANT,
681
- summary: "Atomically commit one fenced terminal landing command attestation into the current run.",
682
- expose: { http: false, mcp: false, cli: false }, emits: ["landing.run_transitioned", "landing.controller_activated"],
683
- input: dryRunCommandResultInputSchema, output: runSchema,
684
- handler: async (ctx, input) => {
685
- const entity = stores(ctx);
686
- const row = await entity.run.get(input.tuple.runId);
687
- if (!row) throw new OpError("not_found", 404, `landing run '${input.tuple.runId}' was not found`);
688
- if (row.lastDryRunCommandId === input.commandId) return row;
689
- const tuple = input.tuple;
690
- if (row.generation !== tuple.generation || row.commandGeneration !== tuple.commandGeneration
691
- || row.attempt !== tuple.attempt || row.phaseOrdinal !== tuple.phaseOrdinal
692
- || row.stateVersion !== tuple.stateVersion) {
693
- throw new OpError("conflict", 409, `landing run '${row.id}' command tuple is stale`);
694
- }
695
- const result = input.result;
696
- const status = typeof result.status === "string" ? result.status : "";
697
- const required = (name: string): string => {
698
- const value = result[name];
699
- if (typeof value !== "string" || !value) throw new OpError("invalid_input", 400, `${input.type} result.${name} is required`);
700
- return value;
701
- };
702
- const now = ctx.clock.now();
703
- let state: LandingState = row.state;
704
- const patch: Record<string, string | number | undefined> = {
705
- lastDryRunCommandId: input.commandId,
706
- commandId: undefined,
707
- terminalProcessProof: input.terminalProcessProof,
708
- commandGeneration: row.commandGeneration + 1,
709
- phaseOrdinal: row.phaseOrdinal + 1,
710
- updatedAt: now,
711
- };
712
- if (input.type === "landing.prepare") {
713
- if (status === "prepared") {
714
- patch.baseHeadSha = required("baseHeadSha");
715
- patch.candidateHeadSha = required("candidateHeadSha");
716
- patch.candidateTreeSha = required("candidateTreeSha");
717
- patch.pushRemote = required("pushRemote");
718
- state = "gating";
719
- } else state = status === "source-drift" ? "authorization_required" : "retry_wait";
720
- } else if (input.type === "landing.gate") {
721
- if (status === "passed") {
722
- patch.candidateHeadSha = required("candidateHeadSha");
723
- patch.gateTreeSha = required("gateTreeSha");
724
- patch.gateConfigDigest = required("gateConfigDigest");
725
- patch.gateAttestation = required("gateAttestationDigest");
726
- state = "publish_ready";
727
- } else if (status === "red") {
728
- patch.gateFailures = row.gateFailures + 1;
729
- state = "gate_failed";
730
- } else {
731
- patch.transientFailures = row.transientFailures + 1;
732
- state = "retry_wait";
733
- }
734
- } else if (input.type === "landing.publish") {
735
- if (status === "published" || status === "ambiguous") state = "verifying";
736
- else if (status === "base-race") {
737
- patch.pushRaces = row.pushRaces + 1;
738
- state = "retry_wait";
739
- } else state = "authorization_required";
740
- } else if (input.type === "landing.verify") {
741
- if (status === "contained") {
742
- const targetHeadSha = required("targetHeadSha");
743
- if (!row.candidateHeadSha || targetHeadSha !== row.candidateHeadSha) {
744
- throw new OpError("conflict", 409, "Kernel verification did not prove the exact gated candidate");
745
- }
746
- patch.receiptTargetSha = targetHeadSha;
747
- patch.receiptVerifiedAt = now;
748
- patch.receiptVerificationGeneration = row.commandGeneration + 1;
749
- patch.receiptKind = "kernel";
750
- state = "cleanup";
751
- } else state = status === "unknown" ? "reconciliation_required" : "retry_wait";
752
- } else if (input.type === "landing.observe-target") {
753
- state = status === "unknown" ? "reconciliation_required" : row.state;
754
- } else if (input.type === "landing.cleanup") {
755
- state = status === "removed" || status === "already-clean" ? "receipt_ready" : "reconciliation_required";
756
- }
757
- const changedState = state !== row.state;
758
- patch.state = state;
759
- patch.stateVersion = row.stateVersion + 1;
760
- patch.stateSince = changedState ? now : row.stateSince;
761
- const updated = await entity.run.update(row.id, patch);
762
- const lane = row.laneKey ? await entity.lane.get(row.laneKey) : undefined;
763
- if (lane && lane.activeCommandId === input.commandId) await entity.lane.update(lane.id, {
764
- activeCommandId: undefined, activeExecutionGeneration: undefined,
765
- lastTerminalProcessProof: input.terminalProcessProof, updatedAt: now,
766
- });
767
- if (changedState) await ctx.events.emit("landing.run_transitioned", { runId: row.id, state, stateVersion: updated.stateVersion });
768
- if (!["landed", "superseded", "canceled", "failed"].includes(state)) {
769
- await ctx.events.emit("landing.controller_activated", { runId: row.id, correlationId: row.id });
770
- }
771
- return updated;
772
- },
773
- },
774
- cancelLanding: {
775
- kind: "mutation", idempotent: false, grant: LANDING_ADMIN_GRANT, summary: "Cancel a fenced inert landing run.", expose: { http: false, mcp: false, cli: false },
776
- emits: ["landing.run_transitioned"],
777
- input: z.object({ runId: z.string(), expectedGeneration: z.number().int(), expectedStateVersion: z.number().int() }), output: runSchema,
778
- handler: (ctx, input) => transitionRun(ctx, input, "cancel"),
779
- },
780
- failLanding: {
781
- kind: "mutation", idempotent: false, grant: LANDING_ADMIN_GRANT, summary: "Fail a fenced landing run with a structured blocker.", expose: { http: false, mcp: false, cli: false },
782
- emits: ["landing.run_transitioned"],
783
- input: z.object({ runId: z.string(), expectedGeneration: z.number().int(), expectedStateVersion: z.number().int(), blockerCode: z.string(), blockerDetail: z.string().optional() }), output: runSchema,
784
- handler: (ctx, input) => transitionRun(ctx, input, "fail"),
785
- },
786
- supersedeLanding: {
787
- kind: "mutation", idempotent: false, grant: LANDING_ADMIN_GRANT, summary: "Supersede a fenced inert landing run.", expose: { http: false, mcp: false, cli: false },
788
- emits: ["landing.run_transitioned"],
789
- input: z.object({ runId: z.string(), expectedGeneration: z.number().int(), expectedStateVersion: z.number().int() }), output: runSchema,
790
- handler: (ctx, input) => transitionRun(ctx, input, "supersede"),
791
- },
792
- retryLanding: {
793
- kind: "mutation", idempotent: false, grant: LANDING_ADMIN_GRANT, summary: "Reopen a fenced failed run into inert controller wait.", expose: { http: false, mcp: false, cli: false },
794
- emits: ["landing.run_transitioned", "landing.controller_activated"],
795
- input: z.object({ runId: z.string(), expectedGeneration: z.number().int(), expectedStateVersion: z.number().int() }), output: runSchema,
796
- handler: (ctx, input) => transitionRun(ctx, input, "retry"),
797
- },
798
- reconcileLanding: {
799
- kind: "mutation", idempotent: false, grant: LANDING_ADMIN_GRANT, summary: "Re-arm a fenced reconciliation blocker for canonical controller recovery.", expose: { http: false, mcp: false, cli: false },
800
- emits: ["landing.run_transitioned", "landing.controller_activated"],
801
- input: z.object({ runId: z.string(), expectedGeneration: z.number().int(), expectedStateVersion: z.number().int() }), output: runSchema,
802
- handler: (ctx, input) => transitionRun(ctx, input, "reconcile"),
803
- },
804
- finalizeControl: {
805
- kind: "mutation", idempotent: true, grant: LANDING_ADMIN_GRANT,
806
- summary: "Finalize cancel/fail/supersede only after the exact active process is positively retired.",
807
- expose: { http: false, mcp: false, cli: false }, emits: ["landing.run_transitioned"],
808
- input: finalizeControlInputSchema, output: runSchema,
809
- handler: async (ctx, input) => {
810
- const entity = stores(ctx);
811
- const row = await entity.run.get(input.runId);
812
- if (!row) throw new OpError("not_found", 404, `landing run '${input.runId}' was not found`);
813
- if (row.generation !== input.expectedGeneration || row.stateVersion !== input.expectedStateVersion
814
- || row.commandId !== input.commandId
815
- || (row.state !== "cancel_pending" && row.state !== "supersede_pending")) {
816
- throw new OpError("conflict", 409, "landing control finalization fence mismatch");
817
- }
818
- const terminal: LandingState = row.state === "supersede_pending" ? "superseded"
819
- : row.blockerCode ? "failed" : "canceled";
820
- const now = ctx.clock.now();
821
- const lane = row.laneKey ? await entity.lane.get(row.laneKey) : undefined;
822
- if (lane?.activeCommandId && lane.activeCommandId !== input.commandId) {
823
- throw new OpError("conflict", 409, "landing control active-command fence changed");
824
- }
825
- const updated = await entity.run.update(row.id, { state: terminal,
826
- stateVersion: row.stateVersion + 1, stateSince: now, commandId: undefined,
827
- terminalProcessProof: input.terminalProcessProof, durableExitKind: "explicit_action", updatedAt: now });
828
- if (lane && lane.currentRunId === row.id) await entity.lane.update(lane.id, { currentRunId: undefined,
829
- retiringRunId: undefined, laneToken: undefined, leaseExpiresAt: undefined,
830
- activeCommandId: undefined, activeExecutionGeneration: undefined,
831
- lastTerminalProcessProof: input.terminalProcessProof, updatedAt: now });
832
- await stageWorkflowControl(ctx, terminal === "failed" ? "fail" : "cancel", row.workflowInstanceId,
833
- terminal === "failed" ? { code: row.blockerCode ?? "landing_failed", detail: row.blockerDetail ?? "" } : undefined);
834
- await ctx.events.emit("landing.run_transitioned", { runId: row.id, state: terminal,
835
- stateVersion: updated.stateVersion });
836
- return updated;
837
- },
838
- },
839
- acceptTargetObservation: {
840
- kind: "mutation", idempotent: true, grant: LANDING_ADMIN_GRANT,
841
- summary: "Persist one fenced three-valued dry target observation and its shadow-only prediction.",
842
- expose: { http: false, mcp: false, cli: false },
843
- emits: ["landing.run_transitioned", "landing.controller_activated", "landing.target_observed"],
844
- input: observationInputSchema,
845
- output: z.object({ run: runSchema, observation: targetObservationSchema.optional() }),
846
- handler: async (ctx, input) => {
847
- const entity = stores(ctx);
848
- const observationId = `${input.runId}:observation:${input.observationGeneration}`;
849
- const replay = await entity.targetObservation.get(observationId);
850
- if (replay) {
851
- const replayRun = await entity.run.get(input.runId);
852
- if (!replayRun) throw new OpError("not_found", 404, `landing run '${input.runId}' was not found`);
853
- return { run: replayRun, observation: replay };
854
- }
855
- const row = await entity.run.get(input.runId);
856
- if (!row) throw new OpError("not_found", 404, `landing run '${input.runId}' was not found`);
857
- if (row.generation !== input.expectedGeneration || row.stateVersion !== input.expectedStateVersion) {
858
- throw new OpError("conflict", 409, `landing run '${input.runId}' fence mismatch`);
859
- }
860
- if (input.observationGeneration <= (row.observationGeneration ?? 0)) {
861
- throw new OpError("conflict", 409, `landing run '${input.runId}' observation is stale`);
862
- }
863
- if (input.status === "positive" && input.sourceContained !== true && input.candidateContained !== true) {
864
- throw new OpError("invalid_input", 400, "positive target observation requires positive remote containment evidence");
865
- }
866
- const now = ctx.clock.now();
867
- if (row.lastObservationDigest === input.factDigest) {
868
- const observationRepeatCount = (row.observationRepeatCount ?? 0) + 1;
869
- const repeated = await entity.run.update(row.id, { observationGeneration: input.observationGeneration,
870
- lastObservedAt: now, nextObservationAt: now + repeatedObservationDelayMs(observationRepeatCount),
871
- observationRepeatCount, updatedAt: now });
872
- return { run: repeated };
873
- }
874
- const observation = await entity.targetObservation.create({ id: observationId, runId: row.id,
875
- generation: row.generation, observationGeneration: input.observationGeneration,
876
- sourceHeadSha: input.sourceHeadSha, candidateHeadSha: input.candidateHeadSha,
877
- targetRef: input.targetRef, targetHeadSha: input.targetHeadSha,
878
- sourceContained: input.sourceContained, candidateContained: input.candidateContained,
879
- containmentMethod: input.containmentMethod, status: input.status, observedAt: now });
880
- const terminal = ["landed", "superseded", "canceled", "failed"].includes(row.state);
881
- const targetState = terminal ? row.state : input.status === "positive" ? "external_retire_pending"
882
- : input.status === "unknown" ? "reconciliation_required" : row.state;
883
- const updated = await entity.run.update(row.id, {
884
- state: targetState,
885
- stateVersion: row.stateVersion + (targetState === row.state ? 0 : 1),
886
- stateSince: targetState === row.state ? row.stateSince : now,
887
- observationGeneration: input.observationGeneration,
888
- lastObservedAt: now,
889
- nextObservationAt: now + LANDING_OBSERVATION_BASE_MS,
890
- lastObservationDigest: input.factDigest,
891
- observationRepeatCount: 0,
892
- predictedOutcome: input.status === "positive" ? "external_retire" : input.status === "unknown" ? "reconciliation_required" : "none",
893
- durableExitKind: terminal ? row.durableExitKind : LANDING_DURABLE_EXITS[targetState as keyof typeof LANDING_DURABLE_EXITS],
894
- lastReconciledAt: now,
895
- updatedAt: now,
896
- });
897
- if (input.status === "unknown") {
898
- const noticeId = `${row.id}:observation-unknown:${input.factDigest}`;
899
- const payload = JSON.stringify({ targetRef: input.targetRef,
900
- containmentMethod: input.containmentMethod ?? "unavailable", action: "reconcile_remote_evidence" });
901
- if (!await entity.notice.get(noticeId)) await entity.notice.create({ id: noticeId, runId: row.id,
902
- stateVersion: updated.stateVersion, audience: "landing-operator", kind: "observation-unknown",
903
- status: "pending", payload, createdAt: now });
904
- if (!await entity.effect.get(noticeId)) await entity.effect.create({ id: noticeId, runId: row.id,
905
- stateVersion: updated.stateVersion, kind: "observation-unknown", status: "pending", payload,
906
- deliveryKey: noticeId, attempts: 0, createdAt: now });
907
- }
908
- if (targetState !== row.state) await ctx.events.emit("landing.run_transitioned", { runId: row.id, state: targetState, stateVersion: updated.stateVersion });
909
- await ctx.events.emit("landing.target_observed", { runId: row.id, status: input.status, observationGeneration: input.observationGeneration });
910
- if (targetState !== row.state || (input.status === "negative" && row.state === "publish_ready")) {
911
- await ctx.events.emit("landing.controller_activated", { runId: row.id, correlationId: row.id });
912
- }
913
- return { run: updated, observation };
914
- },
915
- },
916
- reconcileTerminal: {
917
- kind: "mutation", idempotent: true, grant: LANDING_ADMIN_GRANT,
918
- summary: "Converge generic workflow and landing-domain terminal state without guessing.",
919
- expose: { http: false, mcp: false, cli: false }, emits: ["landing.run_transitioned", "landing.controller_activated"],
920
- input: z.object({ runId: z.string(), expectedGeneration: z.number().int(), expectedStateVersion: z.number().int(), workflowStatus: z.enum(["pending", "running", "waiting", "sleeping", "paused", "done", "failed", "canceled"]) }),
921
- output: runSchema,
922
- handler: async (ctx, input) => {
923
- const row = await stores(ctx).run.get(input.runId);
924
- if (!row) throw new OpError("not_found", 404, `landing run '${input.runId}' was not found`);
925
- if (row.generation !== input.expectedGeneration || row.stateVersion !== input.expectedStateVersion) throw new OpError("conflict", 409, `landing run '${input.runId}' fence mismatch`);
926
- const domainTerminal = ["landed", "superseded", "canceled", "failed"].includes(row.state);
927
- const workflowTerminal = ["done", "failed", "canceled"].includes(input.workflowStatus);
928
- if (domainTerminal && !workflowTerminal) {
929
- if (row.state === "canceled" || row.state === "superseded") await stageWorkflowControl(ctx, "cancel", row.workflowInstanceId);
930
- else if (row.state === "failed") await stageWorkflowControl(ctx, "fail", row.workflowInstanceId, { code: "landing_domain_failed" });
931
- else await ctx.events.emit("landing.controller_activated", { runId: row.id, correlationId: row.id });
932
- return row;
933
- }
934
- if (!domainTerminal && workflowTerminal) {
935
- const now = ctx.clock.now();
936
- const state: LandingState = input.workflowStatus === "canceled" ? "canceled"
937
- : input.workflowStatus === "failed" ? "failed" : "reconciliation_required";
938
- if (row.state === state) return row;
939
- const updated = await stores(ctx).run.update(row.id, { state, stateVersion: row.stateVersion + 1,
940
- stateSince: now, durableExitKind: state === "reconciliation_required" ? "explicit_action" : row.durableExitKind,
941
- blockerCode: "workflow_domain_disagreement", blockerDetail: `workflow=${input.workflowStatus}; domain=${row.state}`,
942
- blockedAt: now, updatedAt: now });
943
- await ctx.events.emit("landing.run_transitioned", { runId: row.id, state, stateVersion: updated.stateVersion });
944
- return updated;
945
- }
946
- return row;
947
- },
948
- },
949
- },
950
- });
951
-
952
- export type LandingRun = z.output<typeof runSchema>;
953
- export type LandingWorkspaceHead = z.output<typeof workspaceHeadSchema>;