@atolis-hq/wake 0.2.97 → 0.3.0

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 (442) hide show
  1. package/dist/src/activities/agent/agent-activity-definition.js +26 -0
  2. package/dist/src/activities/agent/agent-activity.js +171 -0
  3. package/dist/src/activities/agent/agent-result.js +149 -0
  4. package/dist/src/activities/contracts/activity.js +10 -0
  5. package/dist/src/activities/contracts/config.js +2 -0
  6. package/dist/src/activities/contracts/event-schema.js +302 -0
  7. package/dist/src/activities/contracts/events.js +42 -0
  8. package/dist/src/activities/contracts/identifiers.js +29 -0
  9. package/dist/src/activities/contracts/registry.js +71 -0
  10. package/dist/src/activities/contracts/streams.js +17 -0
  11. package/dist/src/activities/contracts/vocabulary.js +58 -0
  12. package/dist/src/activities/index.js +21 -0
  13. package/dist/src/activities/pr/activity-support.js +111 -0
  14. package/dist/src/activities/pr/application.js +158 -0
  15. package/dist/src/activities/pr/approve.js +85 -0
  16. package/dist/src/activities/pr/capability.js +11 -0
  17. package/dist/src/activities/pr/decision-claim.js +76 -0
  18. package/dist/src/activities/pr/event-drafts.js +66 -0
  19. package/dist/src/activities/pr/intent.js +37 -0
  20. package/dist/src/activities/pr/merge-authority-gate.js +14 -0
  21. package/dist/src/activities/pr/merge.js +110 -0
  22. package/dist/src/activities/pr/policy.js +135 -0
  23. package/dist/src/activities/pr/projection.js +130 -0
  24. package/dist/src/activities/pr/vocabulary.js +30 -0
  25. package/dist/src/activities/review/authorization.js +22 -0
  26. package/dist/src/activities/review/contracts.js +22 -0
  27. package/dist/src/activities/review/signals.js +3 -0
  28. package/dist/src/bootstrap/analytics-projection.js +26 -0
  29. package/dist/src/bootstrap/board-projection.js +337 -0
  30. package/dist/src/bootstrap/composition-root.js +382 -0
  31. package/dist/src/bootstrap/config/load-config.js +51 -0
  32. package/dist/src/bootstrap/config/root-schema.js +134 -0
  33. package/dist/src/bootstrap/external-ref.js +12 -0
  34. package/dist/src/bootstrap/fake-provider-files.js +44 -0
  35. package/dist/src/bootstrap/fake-scenarios.js +22 -0
  36. package/dist/src/bootstrap/index.js +48 -0
  37. package/dist/src/bootstrap/initialise.js +434 -0
  38. package/dist/src/bootstrap/paths.js +15 -0
  39. package/dist/src/bootstrap/projection-runtime.js +27 -0
  40. package/dist/src/bootstrap/runner-quota-reporter.js +21 -0
  41. package/dist/src/bootstrap/runner-registry.js +30 -0
  42. package/dist/src/bootstrap/schedule-checkpoint-store.js +49 -0
  43. package/dist/src/bootstrap/self-update-application.js +195 -0
  44. package/dist/src/bootstrap/self-update-failure-log.js +33 -0
  45. package/dist/src/bootstrap/source-update-port.js +47 -0
  46. package/dist/src/bootstrap/status-publish-activity.js +42 -0
  47. package/dist/src/bootstrap/surface-api-applications.js +325 -0
  48. package/dist/src/bootstrap/surface-api-execution-applications.js +95 -0
  49. package/dist/src/bootstrap/surface-api-metadata.js +12 -0
  50. package/dist/src/bootstrap/surface-api-projection-pages.js +22 -0
  51. package/dist/src/bootstrap/surface-api-run-context.js +5 -0
  52. package/dist/src/bootstrap/surface-api-transcripts.js +57 -0
  53. package/dist/src/bootstrap/surface-api-work-applications.js +199 -0
  54. package/dist/src/bootstrap/surface-applications.js +7 -0
  55. package/dist/src/bootstrap/surface-cli-applications.js +701 -0
  56. package/dist/src/bootstrap/update-ledger.js +61 -0
  57. package/dist/src/bootstrap/update-maintenance-lease.js +176 -0
  58. package/dist/src/{version.js → bootstrap/version.js} +35 -51
  59. package/dist/src/control-plane/application/advance-once.js +184 -0
  60. package/dist/src/control-plane/application/control-plane-projection.js +42 -0
  61. package/dist/src/control-plane/application/control-plane-service.js +42 -0
  62. package/dist/src/control-plane/application/intake-pipeline.js +29 -0
  63. package/dist/src/control-plane/application/runner-control-service.js +66 -0
  64. package/dist/src/control-plane/application/runner-pipeline.js +57 -0
  65. package/dist/src/control-plane/application/schedule-service.js +47 -0
  66. package/dist/src/control-plane/application/work-cancellation-policy.js +31 -0
  67. package/dist/src/control-plane/contracts/commands.js +10 -0
  68. package/dist/src/control-plane/contracts/config.js +22 -0
  69. package/dist/src/control-plane/contracts/events.js +81 -0
  70. package/dist/src/control-plane/contracts/streams.js +5 -0
  71. package/dist/src/control-plane/domain/dispatch-policy.js +15 -0
  72. package/dist/src/control-plane/domain/quota-policy.js +26 -0
  73. package/dist/src/control-plane/domain/runner-quota.js +35 -0
  74. package/dist/src/control-plane/domain/schedule-policy.js +46 -0
  75. package/dist/src/control-plane/index.js +20 -0
  76. package/dist/src/control-plane/infrastructure/intake-host.js +24 -0
  77. package/dist/src/control-plane/infrastructure/resident-host.js +45 -0
  78. package/dist/src/control-plane/infrastructure/tick-host.js +35 -0
  79. package/dist/src/execution/application/activation-claim.js +50 -0
  80. package/dist/src/execution/application/active-run-cancellation.js +14 -0
  81. package/dist/src/execution/application/execution-activity.js +97 -0
  82. package/dist/src/execution/application/execution-projection.js +17 -0
  83. package/dist/src/execution/application/execution-service.js +372 -0
  84. package/dist/src/execution/application/execution-validation.js +26 -0
  85. package/dist/src/execution/application/recovery-service.js +212 -0
  86. package/dist/src/execution/application/run-lifecycle.js +115 -0
  87. package/dist/src/execution/application/run-liveness-service.js +80 -0
  88. package/dist/src/execution/application/run-repository.js +27 -0
  89. package/dist/src/execution/contracts/commands.js +1 -0
  90. package/dist/src/execution/contracts/config.js +35 -0
  91. package/dist/src/execution/contracts/control-plane.js +1 -0
  92. package/dist/src/execution/contracts/event-factory.js +53 -0
  93. package/dist/src/execution/contracts/events.js +274 -0
  94. package/dist/src/execution/contracts/identifiers.js +5 -0
  95. package/dist/src/execution/contracts/liveness.js +1 -0
  96. package/dist/src/execution/contracts/results.js +1 -0
  97. package/dist/src/execution/contracts/runner.js +15 -0
  98. package/dist/src/execution/contracts/streams.js +10 -0
  99. package/dist/src/execution/contracts/views.js +1 -0
  100. package/dist/src/execution/contracts/vocabulary.js +43 -0
  101. package/dist/src/execution/contracts/workspace.js +1 -0
  102. package/dist/src/execution/domain/run-result.js +34 -0
  103. package/dist/src/execution/domain/run.js +142 -0
  104. package/dist/src/execution/index.js +31 -0
  105. package/dist/src/execution/infrastructure/agent-runner-adapter.js +114 -0
  106. package/dist/src/execution/infrastructure/process-execution.js +29 -0
  107. package/dist/src/execution/infrastructure/prompt-templates.js +42 -0
  108. package/dist/src/execution/infrastructure/runners/claude.js +120 -0
  109. package/dist/src/execution/infrastructure/runners/codex.js +143 -0
  110. package/dist/src/execution/infrastructure/runners/command.js +4 -0
  111. package/dist/src/execution/infrastructure/runners/cursor.js +69 -0
  112. package/dist/src/execution/infrastructure/runners/fake-scenarios.js +99 -0
  113. package/dist/src/execution/infrastructure/runners/fake.js +65 -0
  114. package/dist/src/execution/infrastructure/runners/registry.js +26 -0
  115. package/dist/src/execution/infrastructure/transcript-store.js +223 -0
  116. package/dist/src/execution/infrastructure/transcripts.js +11 -0
  117. package/dist/src/execution/infrastructure/workspace/fake-workspace.js +19 -0
  118. package/dist/src/execution/infrastructure/workspace/git-workspace.js +241 -0
  119. package/dist/src/integrations/application/agent-run-publication-reactor.js +111 -0
  120. package/dist/src/integrations/application/artifact-registration-reactor.js +159 -0
  121. package/dist/src/integrations/application/poll-service.js +25 -0
  122. package/dist/src/integrations/application/terminal-agent-run-report.js +40 -0
  123. package/dist/src/integrations/application/work-admission.js +31 -0
  124. package/dist/src/integrations/application/work-conclusion.js +19 -0
  125. package/dist/src/integrations/contracts/artifact-events.js +60 -0
  126. package/dist/src/integrations/contracts/artifact-vocabulary.js +9 -0
  127. package/dist/src/integrations/contracts/config.js +14 -0
  128. package/dist/src/integrations/contracts/identifiers.js +5 -0
  129. package/dist/src/integrations/contracts/intake-rules.js +14 -0
  130. package/dist/src/integrations/contracts/intake.js +1 -0
  131. package/dist/src/integrations/contracts/outcome-vocabulary.js +7 -0
  132. package/dist/src/integrations/contracts/provider.js +37 -0
  133. package/dist/src/integrations/contracts/streams.js +10 -0
  134. package/dist/src/integrations/delivery/application/delivery-outcome-reactor.js +75 -0
  135. package/dist/src/integrations/delivery/application/delivery-projector.js +165 -0
  136. package/dist/src/integrations/delivery/application/delivery-service.js +173 -0
  137. package/dist/src/integrations/delivery/contracts/commands.js +1 -0
  138. package/dist/src/integrations/delivery/contracts/config.js +1 -0
  139. package/dist/src/integrations/delivery/contracts/event-factory.js +18 -0
  140. package/dist/src/integrations/delivery/contracts/events.js +86 -0
  141. package/dist/src/integrations/delivery/contracts/intents.js +89 -0
  142. package/dist/src/integrations/delivery/contracts/views.js +1 -0
  143. package/dist/src/integrations/delivery/contracts/vocabulary.js +22 -0
  144. package/dist/src/integrations/fake/durable-delivery-provider.js +48 -0
  145. package/dist/src/integrations/fake/external-sink.js +9 -0
  146. package/dist/src/integrations/fake/external-source.js +44 -0
  147. package/dist/src/integrations/fake/inbound-translator.js +130 -0
  148. package/dist/src/integrations/fake/provider.js +95 -0
  149. package/dist/src/integrations/github/application/agent-context-reader.js +54 -0
  150. package/dist/src/integrations/github/application/agent-run-comment.js +94 -0
  151. package/dist/src/integrations/github/application/comment-history-reader.js +43 -0
  152. package/dist/src/integrations/github/application/inbound-context.js +10 -0
  153. package/dist/src/integrations/github/application/inbound-review-signals.js +159 -0
  154. package/dist/src/integrations/github/application/inbound-translator.js +231 -0
  155. package/dist/src/integrations/github/application/inbound-watch-gate-signals.js +84 -0
  156. package/dist/src/integrations/github/application/intake-policy.js +23 -0
  157. package/dist/src/integrations/github/application/outbound-translator.js +47 -0
  158. package/dist/src/integrations/github/application/poll-service.js +29 -0
  159. package/dist/src/integrations/github/application/pull-request-translation.js +10 -0
  160. package/dist/src/integrations/github/application/resource-links.js +8 -0
  161. package/dist/src/integrations/github/application/review-command-translator.js +16 -0
  162. package/dist/src/integrations/github/application/wake-labels.js +95 -0
  163. package/dist/src/integrations/github/contracts/config.js +47 -0
  164. package/dist/src/integrations/github/contracts/events.js +127 -0
  165. package/dist/src/integrations/github/contracts/external-key.js +19 -0
  166. package/dist/src/integrations/github/contracts/payloads.js +9 -0
  167. package/dist/src/integrations/github/contracts/vocabulary.js +55 -0
  168. package/dist/src/integrations/github/index.js +31 -0
  169. package/dist/src/integrations/github/infrastructure/client-reads.js +214 -0
  170. package/dist/src/integrations/github/infrastructure/client.js +132 -0
  171. package/dist/src/integrations/github/infrastructure/content-fingerprint.js +10 -0
  172. package/dist/src/integrations/github/infrastructure/delivery.js +31 -0
  173. package/dist/src/integrations/github/infrastructure/etag-cache.js +56 -0
  174. package/dist/src/integrations/github/infrastructure/gh-auth.js +19 -0
  175. package/dist/src/integrations/github/infrastructure/issue-source.js +109 -0
  176. package/dist/src/integrations/github/infrastructure/pr-source.js +186 -0
  177. package/dist/src/integrations/github/infrastructure/review-source.js +70 -0
  178. package/dist/src/integrations/github/infrastructure/source.js +108 -0
  179. package/dist/src/integrations/github/provider.js +96 -0
  180. package/dist/src/integrations/index.js +30 -0
  181. package/dist/src/kernel/contracts/checkpoint-store.js +1 -0
  182. package/dist/src/kernel/contracts/clock.js +1 -0
  183. package/dist/src/kernel/contracts/commands.js +1 -0
  184. package/dist/src/kernel/contracts/event-journal.js +2 -0
  185. package/dist/src/kernel/contracts/event-schema.js +54 -0
  186. package/dist/src/kernel/contracts/events.js +11 -0
  187. package/dist/src/kernel/contracts/id-generator.js +1 -0
  188. package/dist/src/kernel/contracts/identifiers.js +8 -0
  189. package/dist/src/kernel/contracts/projection-store.js +1 -0
  190. package/dist/src/kernel/contracts/relations.js +1 -0
  191. package/dist/src/kernel/contracts/schema.js +17 -0
  192. package/dist/src/kernel/contracts/vocabulary.js +6 -0
  193. package/dist/src/kernel/domain/event-envelope.js +29 -0
  194. package/dist/src/kernel/domain/match-mode.js +11 -0
  195. package/dist/src/kernel/domain/relation.js +10 -0
  196. package/dist/src/kernel/index.js +17 -0
  197. package/dist/src/{lib/clock.js → kernel/infrastructure/system-clock.js} +3 -3
  198. package/dist/src/kernel/infrastructure/ulid-id-generator.js +9 -0
  199. package/dist/src/main.js +137 -1030
  200. package/dist/src/orchestration/application/accept-activity-outcome.js +25 -0
  201. package/dist/src/orchestration/application/accept-signal.js +35 -0
  202. package/dist/src/orchestration/application/advance-workflow.js +160 -0
  203. package/dist/src/orchestration/application/coordination-claims.js +107 -0
  204. package/dist/src/orchestration/application/group-budget-recorder.js +43 -0
  205. package/dist/src/orchestration/application/orchestration-projection.js +20 -0
  206. package/dist/src/orchestration/application/orchestration-repository.js +36 -0
  207. package/dist/src/orchestration/application/orchestration-service.js +82 -0
  208. package/dist/src/orchestration/application/request-child.js +118 -0
  209. package/dist/src/orchestration/application/signal-reactor.js +17 -0
  210. package/dist/src/orchestration/application/start-workflow.js +51 -0
  211. package/dist/src/orchestration/application/watch-reactor.js +82 -0
  212. package/dist/src/orchestration/contracts/activity-outcome.js +18 -0
  213. package/dist/src/orchestration/contracts/commands.js +1 -0
  214. package/dist/src/orchestration/contracts/config.js +128 -0
  215. package/dist/src/orchestration/contracts/event-decoder.js +263 -0
  216. package/dist/src/orchestration/contracts/events.js +41 -0
  217. package/dist/src/orchestration/contracts/identifiers.js +35 -0
  218. package/dist/src/orchestration/contracts/streams.js +38 -0
  219. package/dist/src/orchestration/contracts/views.js +1 -0
  220. package/dist/src/orchestration/contracts/vocabulary.js +30 -0
  221. package/dist/src/orchestration/domain/activation-policy.js +55 -0
  222. package/dist/src/orchestration/domain/approval-defaults.js +17 -0
  223. package/dist/src/orchestration/domain/child-policy.js +63 -0
  224. package/dist/src/orchestration/domain/compiler.js +162 -0
  225. package/dist/src/orchestration/domain/coordination-events.js +25 -0
  226. package/dist/src/orchestration/domain/decision-events.js +47 -0
  227. package/dist/src/orchestration/domain/interpreter.js +49 -0
  228. package/dist/src/orchestration/domain/operator-retry-policy.js +34 -0
  229. package/dist/src/orchestration/domain/retry-policy.js +26 -0
  230. package/dist/src/orchestration/domain/signal-policy.js +120 -0
  231. package/dist/src/orchestration/domain/supplemental-policy.js +61 -0
  232. package/dist/src/orchestration/domain/transition.js +55 -0
  233. package/dist/src/orchestration/domain/workflow-graph.js +41 -0
  234. package/dist/src/orchestration/domain/workflow-instance-events.js +236 -0
  235. package/dist/src/orchestration/domain/workflow-instance.js +41 -0
  236. package/dist/src/orchestration/domain/workflow-selector.js +21 -0
  237. package/dist/src/orchestration/index.js +19 -0
  238. package/dist/src/persistence/application/projection-runner.js +79 -0
  239. package/dist/src/persistence/filesystem/file-checkpoint-store.js +35 -0
  240. package/dist/src/persistence/filesystem/file-event-journal.js +143 -0
  241. package/dist/src/persistence/filesystem/file-lock.js +91 -0
  242. package/dist/src/persistence/filesystem/file-projection-store.js +64 -0
  243. package/dist/src/persistence/index.js +8 -0
  244. package/dist/src/persistence/memory/in-memory-checkpoint-store.js +14 -0
  245. package/dist/src/persistence/memory/in-memory-event-journal.js +88 -0
  246. package/dist/src/persistence/memory/in-memory-projection-store.js +17 -0
  247. package/dist/src/resources/application/lookup-projections.js +48 -0
  248. package/dist/src/resources/application/resource-lookup.js +16 -0
  249. package/dist/src/resources/application/resource-projections.js +81 -0
  250. package/dist/src/resources/application/resource-repository.js +18 -0
  251. package/dist/src/resources/application/resource-service.js +83 -0
  252. package/dist/src/resources/contracts/commands.js +1 -0
  253. package/dist/src/resources/contracts/config.js +2 -0
  254. package/dist/src/resources/contracts/events.js +83 -0
  255. package/dist/src/resources/contracts/identifiers.js +15 -0
  256. package/dist/src/resources/contracts/streams.js +6 -0
  257. package/dist/src/resources/contracts/views.js +1 -0
  258. package/dist/src/resources/contracts/vocabulary.js +67 -0
  259. package/dist/src/resources/domain/correlation.js +8 -0
  260. package/dist/src/resources/domain/resource.js +58 -0
  261. package/dist/src/resources/index.js +14 -0
  262. package/dist/src/surfaces/api/contracts/activities.js +1 -0
  263. package/dist/src/surfaces/api/contracts/board.js +2 -0
  264. package/dist/src/surfaces/api/contracts/common.js +46 -0
  265. package/dist/src/surfaces/api/contracts/control-plane.js +5 -0
  266. package/dist/src/surfaces/api/contracts/events.js +1 -0
  267. package/dist/src/surfaces/api/contracts/execution.js +1 -0
  268. package/dist/src/surfaces/api/contracts/index.js +13 -0
  269. package/dist/src/surfaces/api/contracts/observability.js +1 -0
  270. package/dist/src/surfaces/api/contracts/orchestration.js +1 -0
  271. package/dist/src/surfaces/api/contracts/resources.js +1 -0
  272. package/dist/src/surfaces/api/contracts/status.js +1 -0
  273. package/dist/src/surfaces/api/contracts/system.js +1 -0
  274. package/dist/src/surfaces/api/contracts/transport-values.js +39 -0
  275. package/dist/src/surfaces/api/contracts/work.js +17 -0
  276. package/dist/src/surfaces/api/http-server.js +121 -0
  277. package/dist/src/surfaces/api/presenters/activities.js +1 -0
  278. package/dist/src/surfaces/api/presenters/board.js +3 -0
  279. package/dist/src/surfaces/api/presenters/control-plane.js +1 -0
  280. package/dist/src/surfaces/api/presenters/events.js +1 -0
  281. package/dist/src/surfaces/api/presenters/execution.js +59 -0
  282. package/dist/src/surfaces/api/presenters/observability.js +1 -0
  283. package/dist/src/surfaces/api/presenters/orchestration.js +19 -0
  284. package/dist/src/surfaces/api/presenters/resources.js +15 -0
  285. package/dist/src/surfaces/api/presenters/status.js +3 -0
  286. package/dist/src/surfaces/api/presenters/system.js +14 -0
  287. package/dist/src/surfaces/api/presenters/work.js +16 -0
  288. package/dist/src/surfaces/api/problem-details.js +9 -0
  289. package/dist/src/surfaces/api/router.js +13 -0
  290. package/dist/src/surfaces/api/routes/activities.js +1 -0
  291. package/dist/src/surfaces/api/routes/applications.js +1 -0
  292. package/dist/src/surfaces/api/routes/commands.js +82 -0
  293. package/dist/src/surfaces/api/routes/control-plane.js +6 -0
  294. package/dist/src/surfaces/api/routes/events.js +1 -0
  295. package/dist/src/surfaces/api/routes/execution.js +8 -0
  296. package/dist/src/surfaces/api/routes/index.js +18 -0
  297. package/dist/src/surfaces/api/routes/observability.js +1 -0
  298. package/dist/src/surfaces/api/routes/orchestration.js +1 -0
  299. package/dist/src/surfaces/api/routes/pagination.js +78 -0
  300. package/dist/src/surfaces/api/routes/read.js +135 -0
  301. package/dist/src/surfaces/api/routes/resources.js +1 -0
  302. package/dist/src/surfaces/api/routes/responses.js +67 -0
  303. package/dist/src/surfaces/api/routes/system.js +1 -0
  304. package/dist/src/surfaces/api/routes/work.js +9 -0
  305. package/dist/src/surfaces/cli/commands/api.js +1 -0
  306. package/dist/src/surfaces/cli/commands/audit.js +10 -0
  307. package/dist/src/surfaces/cli/commands/correlate.js +2 -0
  308. package/dist/src/surfaces/cli/commands/doctor.js +6 -0
  309. package/dist/src/surfaces/cli/commands/init.js +39 -0
  310. package/dist/src/surfaces/cli/commands/sandbox-entrypoint.js +33 -0
  311. package/dist/src/surfaces/cli/commands/sandbox-setup.js +29 -0
  312. package/dist/src/surfaces/cli/commands/sandbox.js +105 -0
  313. package/dist/src/surfaces/cli/commands/self-update.js +38 -0
  314. package/dist/src/surfaces/cli/commands/smoke.js +16 -0
  315. package/dist/src/surfaces/cli/commands/start.js +1 -0
  316. package/dist/src/surfaces/cli/commands/stop.js +13 -0
  317. package/dist/src/surfaces/cli/commands/tick.js +1 -0
  318. package/dist/src/surfaces/cli/commands/ui.js +2 -0
  319. package/dist/src/surfaces/cli/commands/validate-state.js +5 -0
  320. package/dist/src/surfaces/cli/infrastructure/docker-cli.js +221 -0
  321. package/dist/src/surfaces/cli/infrastructure/process-log.js +86 -0
  322. package/dist/src/surfaces/cli/main.js +140 -0
  323. package/dist/src/surfaces/cli/usage.js +33 -0
  324. package/dist/src/surfaces/contracts/config.js +34 -0
  325. package/dist/src/surfaces/index.js +47 -0
  326. package/dist/src/surfaces/web-assets/assets/index-Bfn4FwZG.css +1 -0
  327. package/dist/src/surfaces/web-assets/assets/index-ipB6JPGU.js +1090 -0
  328. package/dist/src/surfaces/web-assets/index.html +13 -0
  329. package/dist/src/surfaces/web-host/asset-source.js +1 -0
  330. package/dist/src/surfaces/web-host/packaged-assets.js +44 -0
  331. package/dist/src/work/application/work-projection.js +59 -0
  332. package/dist/src/work/application/work-repository.js +18 -0
  333. package/dist/src/work/application/work-service.js +117 -0
  334. package/dist/src/work/contracts/commands.js +1 -0
  335. package/dist/src/work/contracts/config.js +2 -0
  336. package/dist/src/work/contracts/events.js +103 -0
  337. package/dist/src/work/contracts/identifiers.js +5 -0
  338. package/dist/src/work/contracts/streams.js +6 -0
  339. package/dist/src/work/contracts/views.js +1 -0
  340. package/dist/src/work/contracts/vocabulary.js +6 -0
  341. package/dist/src/work/domain/work-item.js +89 -0
  342. package/dist/src/work/index.js +11 -0
  343. package/docker/Dockerfile +10 -6
  344. package/docker/Dockerfile.packaged +3 -3
  345. package/package.json +29 -4
  346. package/prompts/implement.md +2 -2
  347. package/templates/SETUP.md +7 -7
  348. package/dist/src/adapters/claude/claude-runner.js +0 -529
  349. package/dist/src/adapters/codex/codex-runner.js +0 -503
  350. package/dist/src/adapters/cursor/cursor-runner.js +0 -418
  351. package/dist/src/adapters/docker/docker-cli.js +0 -150
  352. package/dist/src/adapters/fake/fake-artifact-verifier.js +0 -14
  353. package/dist/src/adapters/fake/fake-github-pull-request-activity-source.js +0 -77
  354. package/dist/src/adapters/fake/fake-resource-index.js +0 -21
  355. package/dist/src/adapters/fake/fake-runner.js +0 -77
  356. package/dist/src/adapters/fake/fake-ticketing-system.js +0 -185
  357. package/dist/src/adapters/fake/fake-workspace-manager.js +0 -81
  358. package/dist/src/adapters/fs/resource-index.js +0 -126
  359. package/dist/src/adapters/fs/self-update-ledger.js +0 -17
  360. package/dist/src/adapters/fs/state-store.js +0 -775
  361. package/dist/src/adapters/git/git-workspace-manager.js +0 -289
  362. package/dist/src/adapters/github/github-artifact-verifier.js +0 -38
  363. package/dist/src/adapters/github/github-auth.js +0 -16
  364. package/dist/src/adapters/github/github-client.js +0 -249
  365. package/dist/src/adapters/github/github-etag-cache.js +0 -57
  366. package/dist/src/adapters/github/github-issues-work-source.js +0 -692
  367. package/dist/src/adapters/github/github-pull-request-activity-source.js +0 -584
  368. package/dist/src/adapters/github/github-pull-request-merge-actor.js +0 -45
  369. package/dist/src/adapters/http/ui-assets.js +0 -1188
  370. package/dist/src/adapters/http/ui-data.js +0 -1107
  371. package/dist/src/adapters/http/ui-server.js +0 -458
  372. package/dist/src/adapters/runner/cli-command.js +0 -73
  373. package/dist/src/adapters/runner/prompt-templates.js +0 -76
  374. package/dist/src/adapters/runner/runner-cli-adapter.js +0 -112
  375. package/dist/src/adapters/runner/runner-registry.js +0 -139
  376. package/dist/src/adapters/runner/runtime-events.js +0 -32
  377. package/dist/src/adapters/runner/stage-prompt.js +0 -268
  378. package/dist/src/adapters/runner/transcripts.js +0 -25
  379. package/dist/src/cli/audit-command.js +0 -36
  380. package/dist/src/cli/correlate-command.js +0 -62
  381. package/dist/src/cli/doctor-command.js +0 -48
  382. package/dist/src/cli/init-command.js +0 -18
  383. package/dist/src/cli/sandbox-command.js +0 -258
  384. package/dist/src/cli/sandbox-entrypoint-command.js +0 -88
  385. package/dist/src/cli/sandbox-exec-logging.js +0 -7
  386. package/dist/src/cli/sandbox-resume.js +0 -79
  387. package/dist/src/cli/sandbox-setup-command.js +0 -31
  388. package/dist/src/cli/scaffold-assets.js +0 -100
  389. package/dist/src/cli/self-update-command.js +0 -198
  390. package/dist/src/cli/startup-preflight.js +0 -134
  391. package/dist/src/cli/stop-command.js +0 -46
  392. package/dist/src/cli/ui-command.js +0 -27
  393. package/dist/src/config/defaults.js +0 -10
  394. package/dist/src/config/discover-config-files.js +0 -11
  395. package/dist/src/config/load-config.js +0 -69
  396. package/dist/src/config/split-config.js +0 -14
  397. package/dist/src/core/active-run-recovery.js +0 -44
  398. package/dist/src/core/approval-intents.js +0 -16
  399. package/dist/src/core/audit-events.js +0 -82
  400. package/dist/src/core/control-plane.js +0 -192
  401. package/dist/src/core/event-builders.js +0 -153
  402. package/dist/src/core/event-resolver.js +0 -249
  403. package/dist/src/core/lifecycle-service.js +0 -8
  404. package/dist/src/core/live-execution.js +0 -81
  405. package/dist/src/core/outbox.js +0 -198
  406. package/dist/src/core/policy-engine.js +0 -389
  407. package/dist/src/core/projection-updater.js +0 -693
  408. package/dist/src/core/quota-backoff.js +0 -69
  409. package/dist/src/core/run-lease.js +0 -38
  410. package/dist/src/core/scheduled-workflow-source.js +0 -199
  411. package/dist/src/core/sink-router.js +0 -107
  412. package/dist/src/core/stale-run-reconciler.js +0 -352
  413. package/dist/src/core/tick-runner.js +0 -2442
  414. package/dist/src/core/workspace-cleanup.js +0 -117
  415. package/dist/src/domain/branch-naming.js +0 -14
  416. package/dist/src/domain/custom-commands.js +0 -58
  417. package/dist/src/domain/event-types.js +0 -158
  418. package/dist/src/domain/manual-labels.js +0 -1
  419. package/dist/src/domain/resource-uri.js +0 -38
  420. package/dist/src/domain/runner-routing.js +0 -127
  421. package/dist/src/domain/runtime-events.js +0 -36
  422. package/dist/src/domain/schema.js +0 -1233
  423. package/dist/src/domain/sources.js +0 -16
  424. package/dist/src/domain/stages.js +0 -36
  425. package/dist/src/domain/work-item-labels.js +0 -48
  426. package/dist/src/domain/work-item-lifecycle.js +0 -10
  427. package/dist/src/domain/work-item-status.js +0 -33
  428. package/dist/src/domain/workflows.js +0 -159
  429. package/dist/src/lib/deep-merge.js +0 -14
  430. package/dist/src/lib/detached-process-logging.js +0 -46
  431. package/dist/src/lib/event-log.js +0 -21
  432. package/dist/src/lib/format.js +0 -41
  433. package/dist/src/lib/json-file.js +0 -23
  434. package/dist/src/lib/lock.js +0 -181
  435. package/dist/src/lib/log-rotation.js +0 -42
  436. package/dist/src/lib/paths.js +0 -52
  437. package/dist/src/lib/process-identity.js +0 -54
  438. package/dist/src/lib/state-health.js +0 -30
  439. package/dist/src/lib/work-id.js +0 -19
  440. package/dist/src/lib/yaml-file.js +0 -20
  441. /package/dist/src/{core → activities/pr}/contracts.js +0 -0
  442. /package/dist/src/{domain/types.js → control-plane/contracts/views.js} +0 -0
@@ -0,0 +1,76 @@
1
+ import { createEventDraft, EventSourceKind, } from '../../kernel/index.js';
2
+ import { ActivityEventType, decodeActivityEvent, decodeActivityEventDraft, } from '../contracts/events.js';
3
+ import { activityDecisionStream } from '../contracts/streams.js';
4
+ import { ActivityFailureCode, ActivityOutcomeKind, IntentAppendStatus, } from '../contracts/vocabulary.js';
5
+ import { appendResolved } from './activity-support.js';
6
+ export async function readDecisionClaim(journal, activationId, action) {
7
+ const claimId = decisionClaimId(activationId, action);
8
+ const event = (await journal.readStream(activityDecisionStream(activationId, action))).find((candidate) => candidate.eventId === claimId);
9
+ return event === undefined ? null : parseClaim(event, activationId, action);
10
+ }
11
+ export async function claimDecision(journal, activationId, action, proposal) {
12
+ const existing = await readDecisionClaim(journal, activationId, action);
13
+ if (existing !== null)
14
+ return existing;
15
+ const stream = activityDecisionStream(activationId, action);
16
+ const claim = createEventDraft({
17
+ eventId: decisionClaimId(activationId, action),
18
+ eventType: decisionEventType(action),
19
+ occurredAt: proposal.fact.occurredAt,
20
+ correlationId: proposal.fact.correlationId,
21
+ causationId: proposal.fact.causationId,
22
+ actor: proposal.fact.actor,
23
+ source: { kind: EventSourceKind.Internal, id: 'activities-pr' },
24
+ stream,
25
+ payload: {
26
+ action,
27
+ activationId,
28
+ decisionKind: proposal.decisionKind,
29
+ outcome: proposal.outcome,
30
+ fact: proposal.fact,
31
+ },
32
+ });
33
+ decodeActivityEventDraft(claim);
34
+ try {
35
+ await journal.append(stream, 0, [claim]);
36
+ return proposal;
37
+ }
38
+ catch (error) {
39
+ const winner = await readDecisionClaim(journal, activationId, action);
40
+ if (winner !== null)
41
+ return winner;
42
+ throw error;
43
+ }
44
+ }
45
+ export async function completeDecisionClaim(journal, appender, decision) {
46
+ const result = await appendResolved(journal, appender, decision.fact.stream, decision.fact);
47
+ return result === IntentAppendStatus.Failed
48
+ ? { kind: ActivityOutcomeKind.Failed, data: { reason: ActivityFailureCode.IntentWriteFailed } }
49
+ : decision.outcome;
50
+ }
51
+ export async function claimAndCompleteDecision(journal, appender, activationId, action, proposal) {
52
+ const claimed = await claimDecision(journal, activationId, action, proposal);
53
+ return completeDecisionClaim(journal, appender, claimed);
54
+ }
55
+ function decisionClaimId(activationId, action) {
56
+ return `${activationId}:${decisionEventType(action)}`;
57
+ }
58
+ function parseClaim(event, activationId, action) {
59
+ const decoded = decodeActivityEvent(event);
60
+ const expectedType = decisionEventType(action);
61
+ if (decoded.eventType !== expectedType ||
62
+ decoded.payload.activationId !== activationId ||
63
+ decoded.payload.action !== action) {
64
+ throw new Error(`Invalid pull-request decision claim ${event.eventId}`);
65
+ }
66
+ return {
67
+ decisionKind: decoded.payload.decisionKind,
68
+ outcome: decoded.payload.outcome,
69
+ fact: decoded.payload.fact,
70
+ };
71
+ }
72
+ function decisionEventType(action) {
73
+ return action === 'approve'
74
+ ? ActivityEventType.PrApproveDecisionClaimed
75
+ : ActivityEventType.PrMergeDecisionClaimed;
76
+ }
@@ -0,0 +1,66 @@
1
+ import { createEventDraft, EventSourceKind } from '../../kernel/index.js';
2
+ import { resourceStream } from '../../resources/index.js';
3
+ import { ActivityEventType, } from '../contracts/events.js';
4
+ import { activationId } from '../contracts/identifiers.js';
5
+ import { isReviewAuthorized } from '../review/authorization.js';
6
+ export const discovered = ({ resourceId, ...command }, context) => fact(resourceId, ActivityEventType.PrDiscovered, command, context);
7
+ export const revisionChanged = (command, context) => fact(command.resourceId, ActivityEventType.PrRevisionChanged, {
8
+ headRevision: command.headRevision,
9
+ baseRevision: command.baseRevision,
10
+ ...(command.changedFiles === undefined ? {} : { changedFiles: command.changedFiles }),
11
+ }, context);
12
+ export const stateChanged = (command, context) => fact(command.resourceId, ActivityEventType.PrStateChanged, { state: command.state }, context);
13
+ export const checksChanged = (command, context) => fact(command.resourceId, ActivityEventType.PrChecksChanged, { checks: command.checks }, context);
14
+ export const reviewAccepted = (command, context) => fact(command.resourceId, ActivityEventType.PrReviewAccepted, { revision: command.revision, actorId: command.actorId }, context);
15
+ export const reviewAcceptanceSignalRecorded = (command, context) => fact(command.resourceId, ActivityEventType.ReviewAcceptanceSignalRecorded, {
16
+ revision: command.revision,
17
+ actorId: command.actorId,
18
+ actorKind: command.actorKind,
19
+ acceptedEventId: `${context.commandId}:${ActivityEventType.PrReviewAccepted}`,
20
+ providerEventId: command.acceptedEventId,
21
+ trusted: isReviewAuthorized(command),
22
+ }, context);
23
+ export const reviewChangesRequested = (command, context) => fact(command.resourceId, ActivityEventType.PrReviewChangesRequested, { revision: command.revision, actorId: command.actorId }, context);
24
+ export const reviewRejected = (resourceId, reason, context) => fact(resourceId, ActivityEventType.PrReviewRejected, { reason }, context);
25
+ export const mergeDenied = (stream, reason, context, audit = {}) => denialDraft(ActivityEventType.PrMergeDenied, stream, reason, context, audit);
26
+ export const approveDenied = (stream, reason, context, audit = {}) => denialDraft(ActivityEventType.PrApproveDenied, stream, reason, context, audit);
27
+ export const mergeAuthorized = (stream, revision, context) => createEventDraft({
28
+ ...metadata(ActivityEventType.PrMergeAuthorized, context),
29
+ stream,
30
+ payload: { revision },
31
+ });
32
+ export const deliveryIntentRequested = (resourceId, type, payload, context) => createEventDraft({
33
+ ...metadata(type, context),
34
+ stream: resourceStream(resourceId),
35
+ payload: { idempotencyKey: `${context.commandId}:${type}`, ...payload },
36
+ });
37
+ function fact(resourceId, eventType, payload, context) {
38
+ return createEventDraft({
39
+ ...metadata(eventType, context),
40
+ stream: resourceStream(resourceId),
41
+ payload,
42
+ });
43
+ }
44
+ function denialDraft(eventType, stream, reason, context, audit) {
45
+ return createEventDraft({
46
+ ...metadata(eventType, context),
47
+ stream,
48
+ payload: {
49
+ activationId: activationId(context.commandId),
50
+ idempotencyKey: `${context.commandId}:${eventType}`,
51
+ reason,
52
+ ...audit,
53
+ },
54
+ });
55
+ }
56
+ function metadata(eventType, context) {
57
+ return {
58
+ eventId: `${context.commandId}:${eventType}`,
59
+ eventType,
60
+ occurredAt: context.occurredAt,
61
+ correlationId: context.correlationId,
62
+ causationId: context.commandId,
63
+ actor: context.actor,
64
+ source: { kind: EventSourceKind.Internal, id: 'activities-pr' },
65
+ };
66
+ }
@@ -0,0 +1,37 @@
1
+ import { EventActorKind, WrongExpectedSequenceError, } from '../../kernel/index.js';
2
+ import { IntentAppendStatus } from '../contracts/vocabulary.js';
3
+ export function createJournalIntentAppender(journal) {
4
+ return {
5
+ append: (stream, intent) => appendIntentOnce(journal, stream, intent),
6
+ };
7
+ }
8
+ export async function appendIntentOnce(journal, stream, intent) {
9
+ for (let attempt = 0; attempt < 3; attempt += 1) {
10
+ const events = await journal.readStream(stream);
11
+ if (events.some((event) => event.eventId === intent.eventId))
12
+ return IntentAppendStatus.Known;
13
+ try {
14
+ await journal.append(stream, events.length, [intent]);
15
+ return IntentAppendStatus.Appended;
16
+ }
17
+ catch (error) {
18
+ const observed = await journal.readStream(stream);
19
+ if (observed.some((event) => event.eventId === intent.eventId))
20
+ return IntentAppendStatus.Known;
21
+ if (!(error instanceof WrongExpectedSequenceError))
22
+ return IntentAppendStatus.Failed;
23
+ }
24
+ }
25
+ const reconciled = await journal.readStream(stream);
26
+ return reconciled.some((event) => event.eventId === intent.eventId)
27
+ ? IntentAppendStatus.Known
28
+ : IntentAppendStatus.Failed;
29
+ }
30
+ export function activityCommandContext(activationId, orchestrationGroupId, occurredAt) {
31
+ return {
32
+ commandId: activationId,
33
+ correlationId: orchestrationGroupId,
34
+ occurredAt,
35
+ actor: { kind: EventActorKind.System, id: 'activities-pr' },
36
+ };
37
+ }
@@ -0,0 +1,14 @@
1
+ import { EventActorKind } from '../../kernel/index.js';
2
+ export function createPullRequestMergeAuthorityGate(service) {
3
+ return {
4
+ async evaluate(input, occurredAt) {
5
+ const allowed = await service.authorizeMerge(input.workItemId, {
6
+ commandId: `${input.activationId}:pr.merge`,
7
+ correlationId: input.orchestrationGroupId,
8
+ occurredAt,
9
+ actor: { kind: EventActorKind.System, id: 'activities-pr' },
10
+ });
11
+ return { kind: allowed ? 'merge-authorized' : 'merge-denied' };
12
+ },
13
+ };
14
+ }
@@ -0,0 +1,110 @@
1
+ import { z } from 'zod';
2
+ import { ActivityOutcomeKind } from '../contracts/vocabulary.js';
3
+ import { MergeMethod } from './vocabulary.js';
4
+ import { BuiltInResourceCapability, resourceStream } from '../../resources/index.js';
5
+ import { workItemStream } from '../../work/index.js';
6
+ import { ActivityEventType } from '../contracts/events.js';
7
+ import { ActivityExecutionKind, BuiltInActivityName } from '../contracts/vocabulary.js';
8
+ import { pullRequestOutcomeSchema, pullRequestTargetSchema, resolvePrimaryCapability, selectedDenialAudit, selectionDenialAudit, } from './activity-support.js';
9
+ import { claimAndCompleteDecision, completeDecisionClaim, readDecisionClaim, } from './decision-claim.js';
10
+ import { deliveryIntentRequested, mergeDenied } from './event-drafts.js';
11
+ import { activityCommandContext, createJournalIntentAppender, } from './intent.js';
12
+ import { decidePullRequestAuthority } from './policy.js';
13
+ const inputSchema = z
14
+ .object({
15
+ target: pullRequestTargetSchema,
16
+ method: z.enum([MergeMethod.Merge, MergeMethod.Squash, MergeMethod.Rebase]),
17
+ requireChecks: z.boolean(),
18
+ requireApproval: z.boolean().default(true),
19
+ autoMerge: z.boolean().default(false),
20
+ maxFilesChanged: z.number().int().positive().optional(),
21
+ blockedPaths: z.array(z.string().min(1)).default([]),
22
+ })
23
+ .strict()
24
+ .superRefine((input, context) => {
25
+ if (!input.requireApproval && !input.autoMerge)
26
+ context.addIssue({
27
+ code: 'custom',
28
+ path: ['requireApproval'],
29
+ message: 'requireApproval may be false only when autoMerge is true',
30
+ });
31
+ });
32
+ export function createPullRequestMergeActivity(journal, pullRequests, appender = createJournalIntentAppender(journal)) {
33
+ return {
34
+ name: BuiltInActivityName.PullRequestMerge,
35
+ inputSchema,
36
+ outcomeSchema: pullRequestOutcomeSchema,
37
+ outcomeKinds: [
38
+ ActivityOutcomeKind.Waiting,
39
+ ActivityOutcomeKind.Done,
40
+ ActivityOutcomeKind.Blocked,
41
+ ActivityOutcomeKind.Failed,
42
+ ],
43
+ resources: [],
44
+ executionKind: ActivityExecutionKind.Deterministic,
45
+ handler: {
46
+ execute: (invocation, context) => executeMerge(journal, pullRequests, appender, invocation, context),
47
+ },
48
+ };
49
+ }
50
+ async function executeMerge(journal, pullRequests, appender, invocation, context) {
51
+ const requireApproval = invocation.input.requireApproval ?? true;
52
+ const autoMerge = invocation.input.autoMerge ?? false;
53
+ const command = activityCommandContext(invocation.activationId, invocation.orchestrationGroupId, context.occurredAt);
54
+ const prior = await readDecisionClaim(journal, invocation.activationId, MergeMethod.Merge);
55
+ if (prior !== null)
56
+ return completeDecisionClaim(journal, appender, prior);
57
+ const authority = await pullRequests.authorityInput(invocation.workItemId);
58
+ const resource = resolvePrimaryCapability(invocation.resources, authority, invocation.workItemId, invocation.input.target, BuiltInResourceCapability.Mergeable);
59
+ if (!resource.allowed) {
60
+ const denial = mergeDenied(workItemStream(invocation.workItemId), resource.reason, command, {
61
+ ...selectionDenialAudit(invocation.input.target, resource.candidates),
62
+ method: invocation.input.method,
63
+ });
64
+ return claimAndCompleteDecision(journal, appender, invocation.activationId, MergeMethod.Merge, {
65
+ decisionKind: 'denied',
66
+ outcome: { kind: ActivityOutcomeKind.Blocked, data: { reason: resource.reason } },
67
+ fact: denial,
68
+ });
69
+ }
70
+ const decision = decidePullRequestAuthority(authority, {
71
+ target: { resourceId: resource.resourceId },
72
+ requireAcceptedReview: requireApproval,
73
+ requireChecks: invocation.input.requireChecks,
74
+ allowPendingChecks: autoMerge,
75
+ mergePolicy: {
76
+ ...(invocation.input.maxFilesChanged === undefined
77
+ ? {}
78
+ : { maxFilesChanged: invocation.input.maxFilesChanged }),
79
+ blockedPaths: invocation.input.blockedPaths,
80
+ },
81
+ });
82
+ if (!decision.allowed) {
83
+ const denial = mergeDenied(resourceStream(resource.resourceId), decision.reason, command, {
84
+ ...selectedDenialAudit(authority, resource.resourceId),
85
+ method: invocation.input.method,
86
+ });
87
+ return claimAndCompleteDecision(journal, appender, invocation.activationId, MergeMethod.Merge, {
88
+ decisionKind: 'denied',
89
+ outcome: { kind: ActivityOutcomeKind.Blocked, data: { reason: decision.reason } },
90
+ fact: denial,
91
+ });
92
+ }
93
+ const intent = deliveryIntentRequested(decision.resourceId, ActivityEventType.PrMergeRequested, {
94
+ activationId: invocation.activationId,
95
+ workflowInstanceId: invocation.workflowInstanceId,
96
+ resourceId: decision.resourceId,
97
+ revision: decision.revision,
98
+ method: invocation.input.method,
99
+ requireChecks: invocation.input.requireChecks,
100
+ autoMerge,
101
+ }, command);
102
+ return claimAndCompleteDecision(journal, appender, invocation.activationId, MergeMethod.Merge, {
103
+ decisionKind: 'requested',
104
+ outcome: {
105
+ kind: ActivityOutcomeKind.Waiting,
106
+ data: { intentEventId: intent.eventId, signalKind: 'delivery-result' },
107
+ },
108
+ fact: intent,
109
+ });
110
+ }
@@ -0,0 +1,135 @@
1
+ import { BuiltInResourceCapability } from '../../resources/index.js';
2
+ import { ActivityEventType } from '../contracts/events.js';
3
+ import { ActivityResourceRole } from '../contracts/vocabulary.js';
4
+ import { isPullRequestLikeResource } from './capability.js';
5
+ import { PullRequestCheckState, PullRequestDenialCode, PullRequestState } from './vocabulary.js';
6
+ export function decidePullRequestAuthority(input, options = {
7
+ target: ActivityResourceRole.Primary,
8
+ requireAcceptedReview: true,
9
+ requireChecks: true,
10
+ }) {
11
+ if (input.work === null)
12
+ return denied(PullRequestDenialCode.MissingResource);
13
+ const resource = selectResource(input, input.work.workItemId, options.target);
14
+ if (isDenial(resource))
15
+ return resource;
16
+ const pullRequest = selectPullRequest(input, resource, input.work.workItemId);
17
+ if (isDenial(pullRequest))
18
+ return pullRequest;
19
+ if (pullRequest.state !== PullRequestState.Open)
20
+ return denied(PullRequestDenialCode.Closed);
21
+ const authority = finalizeAuthority(input, resource, pullRequest, options);
22
+ if (authority !== null)
23
+ return authority;
24
+ return { allowed: true, resourceId: pullRequest.resourceId, revision: pullRequest.headRevision };
25
+ }
26
+ function finalizeAuthority(input, resource, pullRequest, options) {
27
+ if (options.requireAcceptedReview) {
28
+ const review = reviewAuthority(pullRequest, input.acceptedSignals);
29
+ if (review !== null)
30
+ return review;
31
+ }
32
+ if (options.requireChecks) {
33
+ const checks = checkAuthority(pullRequest, options.allowPendingChecks ?? false);
34
+ if (checks !== null)
35
+ return checks;
36
+ }
37
+ if (options.mergePolicy !== undefined) {
38
+ const files = changedFilesAuthority(pullRequest, resource, options.mergePolicy);
39
+ if (files !== null)
40
+ return files;
41
+ }
42
+ return null;
43
+ }
44
+ export function createPullRequestMergeDenial(decision) {
45
+ if (decision.allowed)
46
+ return null;
47
+ return {
48
+ eventType: ActivityEventType.PrMergeDenied,
49
+ payload: { reason: decision.reason },
50
+ };
51
+ }
52
+ function hasPrimaryCorrelationConflict(resource, workItemId) {
53
+ const primary = resource.correlations.filter((correlation) => correlation.role === ActivityResourceRole.Primary);
54
+ return (resource.resource.primaryCorrelationConflict !== undefined ||
55
+ primary.length !== 1 ||
56
+ primary[0].workItemId !== workItemId);
57
+ }
58
+ function selectResource(input, workItemId, target) {
59
+ const resources = input.resources.filter((entry) => isPrimaryPullRequest(entry, workItemId) &&
60
+ (target === ActivityResourceRole.Primary || entry.resource.resourceId === target.resourceId));
61
+ if (resources.length === 0)
62
+ return denied(PullRequestDenialCode.MissingResource);
63
+ if (resources.length !== 1)
64
+ return denied(PullRequestDenialCode.AmbiguousResource);
65
+ const resource = resources[0];
66
+ return hasPrimaryCorrelationConflict(resource, workItemId)
67
+ ? denied(PullRequestDenialCode.CorrelationConflict)
68
+ : resource;
69
+ }
70
+ function isPrimaryPullRequest(resource, workItemId) {
71
+ if (!isPullRequestLikeResource(resource.resource.capabilities))
72
+ return false;
73
+ return resource.correlations.some((correlation) => correlation.role === ActivityResourceRole.Primary && correlation.workItemId === workItemId);
74
+ }
75
+ function selectPullRequest(input, resource, workItemId) {
76
+ const pullRequests = input.pullRequests.filter((view) => view.resourceId === resource.resource.resourceId && view.workItemId === workItemId);
77
+ if (pullRequests.length === 0)
78
+ return denied(PullRequestDenialCode.MissingResource);
79
+ return pullRequests.length === 1
80
+ ? pullRequests[0]
81
+ : denied(PullRequestDenialCode.AmbiguousResource);
82
+ }
83
+ function reviewAuthority(pullRequest, signals) {
84
+ const accepted = pullRequest.acceptedReview;
85
+ if (accepted === undefined || accepted.revision !== pullRequest.headRevision) {
86
+ if (hasCurrentUntrustedSignal(pullRequest, signals))
87
+ return denied(PullRequestDenialCode.UntrustedActor);
88
+ return denied(PullRequestDenialCode.StaleApproval);
89
+ }
90
+ const signal = signals.find((candidate) => matchesAcceptedReview(candidate, pullRequest));
91
+ return signal?.trusted === true ? null : denied(PullRequestDenialCode.UntrustedActor);
92
+ }
93
+ function hasCurrentUntrustedSignal(pullRequest, signals) {
94
+ return signals.some((signal) => signal.resourceId === pullRequest.resourceId &&
95
+ signal.revision === pullRequest.headRevision &&
96
+ !signal.trusted);
97
+ }
98
+ function matchesAcceptedReview(candidate, pullRequest) {
99
+ const accepted = pullRequest.acceptedReview;
100
+ return (accepted !== undefined &&
101
+ candidate.resourceId === pullRequest.resourceId &&
102
+ candidate.acceptedEventId === accepted.acceptedEventId &&
103
+ candidate.revision === accepted.revision &&
104
+ candidate.actorId === accepted.actorId);
105
+ }
106
+ function changedFilesAuthority(pullRequest, resource, policy) {
107
+ const configured = policy.maxFilesChanged !== undefined || policy.blockedPaths.length > 0;
108
+ if (!configured)
109
+ return null;
110
+ const changedFiles = resource.resource.capabilities.includes(BuiltInResourceCapability.ChangedFiles)
111
+ ? pullRequest.changedFiles
112
+ : undefined;
113
+ if (changedFiles === undefined)
114
+ return denied(PullRequestDenialCode.ChangedFilesUnavailable);
115
+ if (policy.maxFilesChanged !== undefined && changedFiles.length > policy.maxFilesChanged)
116
+ return denied(PullRequestDenialCode.TooManyFilesChanged);
117
+ return policy.blockedPaths.some((blocked) => changedFiles.includes(blocked))
118
+ ? denied(PullRequestDenialCode.BlockedPathChanged)
119
+ : null;
120
+ }
121
+ function checkAuthority(pullRequest, allowPendingChecks) {
122
+ if (pullRequest.checks === PullRequestCheckState.Unknown)
123
+ return denied(PullRequestDenialCode.ChecksPending);
124
+ if (pullRequest.checks === PullRequestCheckState.Pending && !allowPendingChecks)
125
+ return denied(PullRequestDenialCode.ChecksPending);
126
+ return pullRequest.checks === PullRequestCheckState.Failing
127
+ ? denied(PullRequestDenialCode.ChecksFailing)
128
+ : null;
129
+ }
130
+ function isDenial(value) {
131
+ return 'allowed' in value;
132
+ }
133
+ function denied(reason) {
134
+ return { allowed: false, reason };
135
+ }
@@ -0,0 +1,130 @@
1
+ import { isResourceStream } from '../../resources/index.js';
2
+ import { ActivityEventType, selectActivityEvent } from '../contracts/events.js';
3
+ export const pullRequestProjection = {
4
+ name: 'activities-pr',
5
+ select(event) {
6
+ const owned = selectActivityEvent(event);
7
+ return owned !== null && isResourceStream(owned.stream) ? { key: owned.stream.id } : null;
8
+ },
9
+ initial: () => null,
10
+ project(previous, event) {
11
+ const owned = selectActivityEvent(event);
12
+ if (owned === null || !isResourceStream(owned.stream))
13
+ return previous;
14
+ return projectPullRequest(previous, owned);
15
+ },
16
+ };
17
+ export const acceptedReviewSignalProjection = {
18
+ name: 'activities-pr-accepted-signals',
19
+ select(event) {
20
+ const owned = selectActivityEvent(event);
21
+ return owned !== null && isResourceStream(owned.stream) ? { key: owned.stream.id } : null;
22
+ },
23
+ initial: () => [],
24
+ project(previous, event) {
25
+ const owned = selectActivityEvent(event);
26
+ if (owned === null || !isResourceStream(owned.stream))
27
+ return previous;
28
+ return projectAcceptedReviewSignal(previous, owned);
29
+ },
30
+ };
31
+ export const activityProjectionDefinitions = [
32
+ pullRequestProjection,
33
+ acceptedReviewSignalProjection,
34
+ ];
35
+ function clearReview(view) {
36
+ const copy = { ...view };
37
+ delete copy.acceptedReview;
38
+ return copy;
39
+ }
40
+ // A new revision invalidates prior review and prior changed-file evidence;
41
+ // the projected event payload re-supplies changedFiles only if the provider
42
+ // reported it for this new revision.
43
+ function clearRevisionEvidence(view) {
44
+ const copy = { ...view };
45
+ delete copy.acceptedReview;
46
+ delete copy.changedFiles;
47
+ return copy;
48
+ }
49
+ function projectPullRequest(previous, event) {
50
+ switch (event.eventType) {
51
+ case ActivityEventType.PrDiscovered:
52
+ return { resourceId: event.stream.id, ...event.payload };
53
+ case ActivityEventType.PrRevisionChanged:
54
+ return previous === null
55
+ ? previous
56
+ : { ...clearRevisionEvidence(previous), ...event.payload };
57
+ case ActivityEventType.PrStateChanged:
58
+ return previous === null ? previous : { ...previous, state: event.payload.state };
59
+ case ActivityEventType.PrChecksChanged:
60
+ return previous === null ? previous : { ...previous, checks: event.payload.checks };
61
+ case ActivityEventType.PrReviewAccepted:
62
+ return previous === null
63
+ ? previous
64
+ : {
65
+ ...previous,
66
+ acceptedReview: {
67
+ revision: event.payload.revision,
68
+ actorId: event.payload.actorId,
69
+ acceptedEventId: event.eventId,
70
+ },
71
+ };
72
+ case ActivityEventType.PrReviewChangesRequested:
73
+ return previous === null ? previous : clearReview(previous);
74
+ default:
75
+ return ignorePullRequestEvent(previous, event);
76
+ }
77
+ }
78
+ function ignorePullRequestEvent(previous, event) {
79
+ switch (event.eventType) {
80
+ case ActivityEventType.ReviewAcceptanceSignalRecorded:
81
+ case ActivityEventType.PrReviewRejected:
82
+ case ActivityEventType.PrMergeDenied:
83
+ case ActivityEventType.PrApproveDenied:
84
+ case ActivityEventType.PrMergeAuthorized:
85
+ case ActivityEventType.PrApproveRequested:
86
+ case ActivityEventType.PrMergeRequested:
87
+ case ActivityEventType.PrApproveDecisionClaimed:
88
+ case ActivityEventType.PrMergeDecisionClaimed:
89
+ return previous;
90
+ default:
91
+ return assertNever(event);
92
+ }
93
+ }
94
+ function projectAcceptedReviewSignal(previous, event) {
95
+ switch (event.eventType) {
96
+ case ActivityEventType.ReviewAcceptanceSignalRecorded: {
97
+ const signal = { resourceId: event.stream.id, ...event.payload };
98
+ return previous.some((candidate) => candidate.acceptedEventId === signal.acceptedEventId)
99
+ ? previous
100
+ : [...previous, signal];
101
+ }
102
+ case ActivityEventType.PrMergeDenied:
103
+ case ActivityEventType.PrApproveDenied:
104
+ case ActivityEventType.PrApproveDecisionClaimed:
105
+ case ActivityEventType.PrMergeDecisionClaimed:
106
+ return previous;
107
+ default:
108
+ return ignoreAcceptedSignalFact(previous, event);
109
+ }
110
+ }
111
+ function ignoreAcceptedSignalFact(previous, event) {
112
+ switch (event.eventType) {
113
+ case ActivityEventType.PrDiscovered:
114
+ case ActivityEventType.PrRevisionChanged:
115
+ case ActivityEventType.PrStateChanged:
116
+ case ActivityEventType.PrChecksChanged:
117
+ case ActivityEventType.PrReviewAccepted:
118
+ case ActivityEventType.PrReviewChangesRequested:
119
+ case ActivityEventType.PrReviewRejected:
120
+ case ActivityEventType.PrMergeAuthorized:
121
+ case ActivityEventType.PrApproveRequested:
122
+ case ActivityEventType.PrMergeRequested:
123
+ return previous;
124
+ default:
125
+ return assertNever(event);
126
+ }
127
+ }
128
+ function assertNever(value) {
129
+ throw new Error(`Unhandled Activity event: ${JSON.stringify(value)}`);
130
+ }
@@ -0,0 +1,30 @@
1
+ import { defineClosedVocabulary } from '../../kernel/index.js';
2
+ export const PullRequestState = defineClosedVocabulary({
3
+ Open: 'open',
4
+ Closed: 'closed',
5
+ Merged: 'merged',
6
+ });
7
+ export const PullRequestCheckState = defineClosedVocabulary({
8
+ Unknown: 'unknown',
9
+ Pending: 'pending',
10
+ Passing: 'passing',
11
+ Failing: 'failing',
12
+ });
13
+ export const MergeMethod = defineClosedVocabulary({
14
+ Merge: 'merge',
15
+ Squash: 'squash',
16
+ Rebase: 'rebase',
17
+ });
18
+ export const PullRequestDenialCode = defineClosedVocabulary({
19
+ MissingResource: 'missing-resource',
20
+ AmbiguousResource: 'ambiguous-resource',
21
+ CorrelationConflict: 'correlation-conflict',
22
+ Closed: 'closed',
23
+ StaleApproval: 'stale-approval',
24
+ ChecksPending: 'checks-pending',
25
+ ChecksFailing: 'checks-failing',
26
+ UntrustedActor: 'untrusted-actor',
27
+ TooManyFilesChanged: 'too-many-files-changed',
28
+ BlockedPathChanged: 'blocked-path-changed',
29
+ ChangedFilesUnavailable: 'changed-files-unavailable',
30
+ });
@@ -0,0 +1,22 @@
1
+ import { ProviderPermission, ReviewActorKind, ReviewerAuthorizationSource } from './contracts.js';
2
+ export function isReviewAuthorized(input) {
3
+ if (input.origin === 'provider-native-review')
4
+ return true;
5
+ if (input.actorKind !== ReviewActorKind.Human)
6
+ return false;
7
+ if (sameIdentity(input.actorId, input.resourceAuthorId))
8
+ return false;
9
+ if (input.authorization.source === ReviewerAuthorizationSource.ConfiguredReviewer)
10
+ return sameIdentity(input.actorId, input.authorization.reviewerId);
11
+ if (input.authorization.source !== ReviewerAuthorizationSource.ProviderPermission)
12
+ return false;
13
+ return trustedPermissions.has(input.authorization.permission);
14
+ }
15
+ function sameIdentity(left, right) {
16
+ return left.toLowerCase() === right.toLowerCase();
17
+ }
18
+ const trustedPermissions = new Set([
19
+ ProviderPermission.Write,
20
+ ProviderPermission.Maintain,
21
+ ProviderPermission.Admin,
22
+ ]);
@@ -0,0 +1,22 @@
1
+ import { defineClosedVocabulary } from '../../kernel/index.js';
2
+ export const ReviewerAuthorizationSource = defineClosedVocabulary({
3
+ ConfiguredReviewer: 'configured-reviewer',
4
+ ProviderPermission: 'provider-permission',
5
+ None: 'none',
6
+ });
7
+ export const ProviderPermission = defineClosedVocabulary({
8
+ None: 'none',
9
+ Read: 'read',
10
+ Triage: 'triage',
11
+ Write: 'write',
12
+ Maintain: 'maintain',
13
+ Admin: 'admin',
14
+ });
15
+ export const ReviewActorKind = defineClosedVocabulary({
16
+ Human: 'human',
17
+ Bot: 'bot',
18
+ });
19
+ export const ReviewDecisionKind = defineClosedVocabulary({
20
+ Accepted: 'accepted',
21
+ ChangesRequested: 'changes-requested',
22
+ });
@@ -0,0 +1,3 @@
1
+ export function proposeReviewSignal(input) {
2
+ return input;
3
+ }