@vercel/factory 0.0.14 → 0.0.16

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 (510) hide show
  1. package/CHANGELOG.md +356 -0
  2. package/README.md +96 -2
  3. package/dist/agent-routes.d.mts +113 -0
  4. package/dist/agent-routes.mjs +91 -0
  5. package/dist/agent-routes.mjs.map +1 -0
  6. package/dist/api-contracts.d.mts +1768 -0
  7. package/dist/api-contracts.mjs +119 -0
  8. package/dist/api-contracts.mjs.map +1 -0
  9. package/dist/api-images.d.mts +30 -0
  10. package/dist/api-images.mjs +28 -0
  11. package/dist/api-images.mjs.map +1 -0
  12. package/dist/api-task-graph.mjs +57 -0
  13. package/dist/api-task-graph.mjs.map +1 -0
  14. package/dist/api.d.mts +111 -216
  15. package/dist/api.mjs +1063 -99
  16. package/dist/api.mjs.map +1 -1
  17. package/dist/approval-access.d.mts +39 -0
  18. package/dist/approval-access.mjs +62 -0
  19. package/dist/approval-access.mjs.map +1 -0
  20. package/dist/approval-contracts.d.mts +698 -0
  21. package/dist/approval-contracts.mjs +27 -0
  22. package/dist/approval-contracts.mjs.map +1 -0
  23. package/dist/approval.d.mts +49 -0
  24. package/dist/approval.mjs +39 -0
  25. package/dist/approval.mjs.map +1 -0
  26. package/dist/blob/artifacts.d.mts +37 -0
  27. package/dist/blob/artifacts.mjs +45 -0
  28. package/dist/blob/artifacts.mjs.map +1 -0
  29. package/dist/blob/index.d.mts +84 -12
  30. package/dist/blob/index.mjs +179 -45
  31. package/dist/blob/index.mjs.map +1 -1
  32. package/dist/budget.d.mts +115 -0
  33. package/dist/budget.mjs +147 -0
  34. package/dist/budget.mjs.map +1 -0
  35. package/dist/budgets.d.mts +4 -0
  36. package/dist/budgets.mjs +4 -0
  37. package/dist/build-factory.d.mts +7 -4
  38. package/dist/build-factory.mjs +2 -1
  39. package/dist/build-factory.mjs.map +1 -1
  40. package/dist/change-verification/brief.d.mts +9 -0
  41. package/dist/change-verification/brief.mjs +13 -0
  42. package/dist/change-verification/brief.mjs.map +1 -0
  43. package/dist/change-verification/dispatch.d.mts +37 -0
  44. package/dist/change-verification/dispatch.mjs +83 -0
  45. package/dist/change-verification/dispatch.mjs.map +1 -0
  46. package/dist/change-verification/eve-tool.d.mts +61 -0
  47. package/dist/change-verification/eve-tool.mjs +89 -0
  48. package/dist/change-verification/eve-tool.mjs.map +1 -0
  49. package/dist/change-verification/result.mjs +130 -0
  50. package/dist/change-verification/result.mjs.map +1 -0
  51. package/dist/changes/eve-record-change.d.mts +56 -0
  52. package/dist/changes/eve-record-change.mjs +131 -0
  53. package/dist/changes/eve-record-change.mjs.map +1 -0
  54. package/dist/changes/presentation.d.mts +14 -0
  55. package/dist/changes.d.mts +24 -0
  56. package/dist/changes.mjs +29 -0
  57. package/dist/changes.mjs.map +1 -0
  58. package/dist/client-events.d.mts +25 -0
  59. package/dist/client-events.mjs +45 -0
  60. package/dist/client-events.mjs.map +1 -0
  61. package/dist/client-stream.d.mts +28 -0
  62. package/dist/client-stream.mjs +210 -0
  63. package/dist/client-stream.mjs.map +1 -0
  64. package/dist/client-transcript.d.mts +41 -0
  65. package/dist/client-transcript.mjs +233 -0
  66. package/dist/client-transcript.mjs.map +1 -0
  67. package/dist/client.d.mts +343 -0
  68. package/dist/client.mjs +366 -0
  69. package/dist/client.mjs.map +1 -0
  70. package/dist/code-review/contracts.d.mts +27 -0
  71. package/dist/code-review/eve-post-review.d.mts +70 -0
  72. package/dist/code-review/eve-post-review.mjs +195 -0
  73. package/dist/code-review/eve-post-review.mjs.map +1 -0
  74. package/dist/code-review/eve-review-comments.d.mts +75 -0
  75. package/dist/code-review/eve-review-comments.mjs +193 -0
  76. package/dist/code-review/eve-review-comments.mjs.map +1 -0
  77. package/dist/code-review/github-contracts.d.mts +10 -0
  78. package/dist/code-review/github-reporter.d.mts +46 -0
  79. package/dist/code-review/github-reporter.mjs +262 -0
  80. package/dist/code-review/github-reporter.mjs.map +1 -0
  81. package/dist/code-review/preparation.d.mts +34 -0
  82. package/dist/code-review/preparation.mjs +23 -0
  83. package/dist/code-review/preparation.mjs.map +1 -0
  84. package/dist/code-review/stall.d.mts +17 -0
  85. package/dist/code-review/stall.mjs +30 -0
  86. package/dist/code-review/stall.mjs.map +1 -0
  87. package/dist/code-review.d.mts +7 -0
  88. package/dist/code-review.mjs +5 -0
  89. package/dist/communication.d.mts +9 -0
  90. package/dist/communication.mjs +9 -0
  91. package/dist/connectors/github.d.mts +26 -0
  92. package/dist/connectors/github.mjs +55 -0
  93. package/dist/connectors/github.mjs.map +1 -0
  94. package/dist/connectors/index.d.mts +35 -3
  95. package/dist/connectors/index.mjs +3 -52
  96. package/dist/connectors/index.mjs.map +1 -1
  97. package/dist/connectors/outbox.d.mts +34 -0
  98. package/dist/connectors/outbox.mjs +50 -0
  99. package/dist/connectors/outbox.mjs.map +1 -0
  100. package/dist/connectors/slack-approval-blocks.mjs +136 -0
  101. package/dist/connectors/slack-approval-blocks.mjs.map +1 -0
  102. package/dist/connectors/slack-approvals.d.mts +29 -0
  103. package/dist/connectors/slack-approvals.mjs +346 -0
  104. package/dist/connectors/slack-approvals.mjs.map +1 -0
  105. package/dist/connectors/slack.d.mts +35 -52
  106. package/dist/connectors/slack.mjs +13 -85
  107. package/dist/connectors/slack.mjs.map +1 -1
  108. package/dist/deepsec/eve-tool.d.mts +110 -0
  109. package/dist/deepsec/eve-tool.mjs +166 -0
  110. package/dist/deepsec/eve-tool.mjs.map +1 -0
  111. package/dist/deepsec/finding.d.mts +84 -0
  112. package/dist/deepsec/finding.mjs +56 -0
  113. package/dist/deepsec/finding.mjs.map +1 -0
  114. package/dist/deepsec.d.mts +3 -0
  115. package/dist/delivery-metrics/metrics.d.mts +93 -0
  116. package/dist/delivery-metrics/metrics.mjs +200 -0
  117. package/dist/delivery-metrics/metrics.mjs.map +1 -0
  118. package/dist/delivery-metrics.d.mts +2 -0
  119. package/dist/delivery-metrics.mjs +2 -0
  120. package/dist/dispatch.d.mts +152 -0
  121. package/dist/dispatch.mjs +199 -0
  122. package/dist/dispatch.mjs.map +1 -0
  123. package/dist/errors.d.mts +15 -0
  124. package/dist/errors.mjs +38 -0
  125. package/dist/errors.mjs.map +1 -0
  126. package/dist/eve/index.d.mts +209 -1277
  127. package/dist/eve/index.mjs +312 -1073
  128. package/dist/eve/index.mjs.map +1 -1
  129. package/dist/eve/invoke.d.mts +144 -0
  130. package/dist/eve/invoke.mjs +254 -0
  131. package/dist/eve/invoke.mjs.map +1 -0
  132. package/dist/eve/session-client.d.mts +186 -0
  133. package/dist/eve/session-client.mjs +245 -0
  134. package/dist/eve/session-client.mjs.map +1 -0
  135. package/dist/eve/task-execution.d.mts +380 -0
  136. package/dist/eve/task-execution.mjs +73 -0
  137. package/dist/eve/task-execution.mjs.map +1 -0
  138. package/dist/eve/task-session.d.mts +129 -0
  139. package/dist/eve/task-session.mjs +245 -0
  140. package/dist/eve/task-session.mjs.map +1 -0
  141. package/dist/eve/transcript.d.mts +37 -0
  142. package/dist/eve/transcript.mjs +69 -0
  143. package/dist/eve/transcript.mjs.map +1 -0
  144. package/dist/execution-public.d.mts +8 -0
  145. package/dist/execution-public.mjs +7 -0
  146. package/dist/execution.d.mts +183 -0
  147. package/dist/execution.mjs +223 -0
  148. package/dist/execution.mjs.map +1 -0
  149. package/dist/finding-remediation/admission.d.mts +53 -0
  150. package/dist/finding-remediation/admission.mjs +90 -0
  151. package/dist/finding-remediation/admission.mjs.map +1 -0
  152. package/dist/finding-remediation/brief.d.mts +14 -0
  153. package/dist/finding-remediation/brief.mjs +25 -0
  154. package/dist/finding-remediation/brief.mjs.map +1 -0
  155. package/dist/finding-remediation/eve-tool.d.mts +29 -0
  156. package/dist/finding-remediation/eve-tool.mjs +34 -0
  157. package/dist/finding-remediation/eve-tool.mjs.map +1 -0
  158. package/dist/findings/fingerprint.d.mts +14 -0
  159. package/dist/findings/fingerprint.mjs +28 -0
  160. package/dist/findings/fingerprint.mjs.map +1 -0
  161. package/dist/findings.d.mts +7 -0
  162. package/dist/findings.mjs +6 -0
  163. package/dist/github-app.d.mts +54 -0
  164. package/dist/github-app.mjs +121 -0
  165. package/dist/github-app.mjs.map +1 -0
  166. package/dist/github-publication.d.mts +199 -0
  167. package/dist/github-publication.mjs +442 -0
  168. package/dist/github-publication.mjs.map +1 -0
  169. package/dist/github-transfer.d.mts +81 -0
  170. package/dist/github-transfer.mjs +273 -0
  171. package/dist/github-transfer.mjs.map +1 -0
  172. package/dist/github.d.mts +446 -2
  173. package/dist/github.mjs +357 -56
  174. package/dist/github.mjs.map +1 -1
  175. package/dist/image-input.d.mts +51 -0
  176. package/dist/image-input.mjs +63 -0
  177. package/dist/image-input.mjs.map +1 -0
  178. package/dist/inbox-activity.d.mts +53 -0
  179. package/dist/inbox-activity.mjs +41 -0
  180. package/dist/inbox-activity.mjs.map +1 -0
  181. package/dist/index.d.mts +16 -484
  182. package/dist/index.mjs +15 -522
  183. package/dist/intake-contracts.d.mts +55 -0
  184. package/dist/intake-contracts.mjs +33 -0
  185. package/dist/intake-contracts.mjs.map +1 -0
  186. package/dist/integrations/deepsec.d.mts +5 -0
  187. package/dist/integrations/deepsec.mjs +3 -0
  188. package/dist/integrations/github.d.mts +11 -0
  189. package/dist/integrations/github.mjs +9 -0
  190. package/dist/integrations/slack.d.mts +5 -0
  191. package/dist/integrations/slack.mjs +5 -0
  192. package/dist/integrations/vercel.d.mts +5 -0
  193. package/dist/integrations/vercel.mjs +4 -0
  194. package/dist/merge-resolution/contracts.d.mts +17 -0
  195. package/dist/merge-resolution/contracts.mjs +19 -0
  196. package/dist/merge-resolution/contracts.mjs.map +1 -0
  197. package/dist/merge-resolution/eve-tools.d.mts +47 -0
  198. package/dist/merge-resolution/eve-tools.mjs +122 -0
  199. package/dist/merge-resolution/eve-tools.mjs.map +1 -0
  200. package/dist/model-settings.d.mts +41 -0
  201. package/dist/model-settings.mjs +35 -0
  202. package/dist/model-settings.mjs.map +1 -0
  203. package/dist/multi-repository-changes/coordination.d.mts +49 -0
  204. package/dist/multi-repository-changes/coordination.mjs +115 -0
  205. package/dist/multi-repository-changes/coordination.mjs.map +1 -0
  206. package/dist/planning/cancellation.mjs +82 -0
  207. package/dist/planning/cancellation.mjs.map +1 -0
  208. package/dist/planning/configuration.d.mts +23 -0
  209. package/dist/planning/configuration.mjs +56 -0
  210. package/dist/planning/configuration.mjs.map +1 -0
  211. package/dist/planning/contracts.d.mts +136 -0
  212. package/dist/planning/contracts.mjs +42 -0
  213. package/dist/planning/contracts.mjs.map +1 -0
  214. package/dist/planning/dependencies.mjs +44 -0
  215. package/dist/planning/dependencies.mjs.map +1 -0
  216. package/dist/planning/effects.mjs +122 -0
  217. package/dist/planning/effects.mjs.map +1 -0
  218. package/dist/planning/reconcile.mjs +279 -0
  219. package/dist/planning/reconcile.mjs.map +1 -0
  220. package/dist/planning/runtime.d.mts +27 -0
  221. package/dist/planning/runtime.mjs +25 -0
  222. package/dist/planning/runtime.mjs.map +1 -0
  223. package/dist/planning/state.mjs +92 -0
  224. package/dist/planning/state.mjs.map +1 -0
  225. package/dist/planning/turns.mjs +262 -0
  226. package/dist/planning/turns.mjs.map +1 -0
  227. package/dist/planning/validation.mjs +106 -0
  228. package/dist/planning/validation.mjs.map +1 -0
  229. package/dist/postgres/index.d.mts +48 -1
  230. package/dist/postgres/index.mjs +45 -3
  231. package/dist/postgres/index.mjs.map +1 -1
  232. package/dist/presets/software-development/approval.d.mts +14 -0
  233. package/dist/presets/software-development/approval.mjs +21 -0
  234. package/dist/presets/software-development/approval.mjs.map +1 -0
  235. package/dist/presets/software-development/deepsec-brief.d.mts +8 -0
  236. package/dist/presets/software-development/deepsec-brief.mjs +14 -0
  237. package/dist/presets/software-development/deepsec-brief.mjs.map +1 -0
  238. package/dist/presets/software-development/dispatch.d.mts +56 -0
  239. package/dist/presets/software-development/dispatch.mjs +67 -0
  240. package/dist/presets/software-development/dispatch.mjs.map +1 -0
  241. package/dist/presets/software-development/eve-delegation-policy.d.mts +7 -0
  242. package/dist/presets/software-development/eve-delegation-policy.mjs +34 -0
  243. package/dist/presets/software-development/eve-delegation-policy.mjs.map +1 -0
  244. package/dist/presets/software-development/eve.d.mts +18 -0
  245. package/dist/presets/software-development/eve.mjs +19 -0
  246. package/dist/presets/software-development/eve.mjs.map +1 -0
  247. package/dist/presets/software-development/finish-task-policy.d.mts +7 -0
  248. package/dist/presets/software-development/finish-task-policy.mjs +9 -0
  249. package/dist/presets/software-development/finish-task-policy.mjs.map +1 -0
  250. package/dist/presets/software-development/recovery.d.mts +32 -0
  251. package/dist/presets/software-development/recovery.mjs +120 -0
  252. package/dist/presets/software-development/recovery.mjs.map +1 -0
  253. package/dist/presets/software-development/task-communication.d.mts +24 -0
  254. package/dist/presets/software-development/task-communication.mjs +157 -0
  255. package/dist/presets/software-development/task-communication.mjs.map +1 -0
  256. package/dist/presets/software-development.d.mts +10 -0
  257. package/dist/presets/software-development.mjs +9 -0
  258. package/dist/pull-requests/contracts.d.mts +72 -0
  259. package/dist/pull-requests/eve-fetch.d.mts +57 -0
  260. package/dist/pull-requests/eve-fetch.mjs +151 -0
  261. package/dist/pull-requests/eve-fetch.mjs.map +1 -0
  262. package/dist/pull-requests/github-label-manager.d.mts +27 -0
  263. package/dist/pull-requests/github-label-manager.mjs +40 -0
  264. package/dist/pull-requests/github-label-manager.mjs.map +1 -0
  265. package/dist/pull-requests/github-publisher.d.mts +67 -0
  266. package/dist/pull-requests/github-publisher.mjs +405 -0
  267. package/dist/pull-requests/github-publisher.mjs.map +1 -0
  268. package/dist/pull-requests.d.mts +6 -0
  269. package/dist/pull-requests.mjs +4 -0
  270. package/dist/receipts.d.mts +4 -0
  271. package/dist/receipts.mjs +3 -0
  272. package/dist/repositories.d.mts +18 -0
  273. package/dist/repositories.mjs +33 -0
  274. package/dist/repositories.mjs.map +1 -0
  275. package/dist/sandbox/command.d.mts +18 -0
  276. package/dist/sandbox/execution-abort.d.mts +16 -0
  277. package/dist/sandbox/execution-abort.mjs +49 -0
  278. package/dist/sandbox/execution-abort.mjs.map +1 -0
  279. package/dist/sandbox/execution-environment.d.mts +25 -0
  280. package/dist/sandbox/execution-run-ledger.d.mts +115 -0
  281. package/dist/sandbox/execution-run-ledger.mjs +209 -0
  282. package/dist/sandbox/execution-run-ledger.mjs.map +1 -0
  283. package/dist/sandbox/execution.d.mts +54 -0
  284. package/dist/sandbox/execution.mjs +228 -0
  285. package/dist/sandbox/execution.mjs.map +1 -0
  286. package/dist/sandbox/harness-runner.d.mts +79 -0
  287. package/dist/sandbox/harness-runner.mjs +162 -0
  288. package/dist/sandbox/harness-runner.mjs.map +1 -0
  289. package/dist/sandbox/index.d.mts +10 -0
  290. package/dist/sandbox/index.mjs +7 -0
  291. package/dist/sandbox/task-environment.d.mts +50 -0
  292. package/dist/sandbox/task-environment.mjs +140 -0
  293. package/dist/sandbox/task-environment.mjs.map +1 -0
  294. package/dist/sandbox/workspace.d.mts +29 -0
  295. package/dist/sandbox/workspace.mjs +28 -0
  296. package/dist/sandbox/workspace.mjs.map +1 -0
  297. package/dist/schema/agent-route.d.mts +40 -0
  298. package/dist/schema/agent-route.mjs +33 -0
  299. package/dist/schema/agent-route.mjs.map +1 -0
  300. package/dist/schema/answer.d.mts +23 -0
  301. package/dist/schema/answer.mjs +21 -0
  302. package/dist/schema/answer.mjs.map +1 -0
  303. package/dist/schema/budget.d.mts +38 -0
  304. package/dist/schema/budget.mjs +30 -0
  305. package/dist/schema/budget.mjs.map +1 -0
  306. package/dist/schema/catalog.mjs +72 -0
  307. package/dist/schema/catalog.mjs.map +1 -0
  308. package/dist/schema/change.d.mts +117 -0
  309. package/dist/schema/change.mjs +68 -0
  310. package/dist/schema/change.mjs.map +1 -0
  311. package/dist/schema/common.d.mts +33 -0
  312. package/dist/{id-BLIkCVue.mjs → schema/common.mjs} +7 -16
  313. package/dist/schema/common.mjs.map +1 -0
  314. package/dist/schema/communication.d.mts +52 -0
  315. package/dist/{communication-Kd9nU5RP.mjs → schema/communication.mjs} +8 -3
  316. package/dist/schema/communication.mjs.map +1 -0
  317. package/dist/schema/execution.d.mts +101 -0
  318. package/dist/schema/execution.mjs +86 -0
  319. package/dist/schema/execution.mjs.map +1 -0
  320. package/dist/schema/factory-config.d.mts +122 -0
  321. package/dist/schema/factory-config.mjs +90 -0
  322. package/dist/schema/factory-config.mjs.map +1 -0
  323. package/dist/schema/finding.d.mts +125 -0
  324. package/dist/schema/finding.mjs +67 -0
  325. package/dist/schema/finding.mjs.map +1 -0
  326. package/dist/schema/id.d.mts +43 -0
  327. package/dist/schema/id.mjs +32 -0
  328. package/dist/schema/id.mjs.map +1 -0
  329. package/dist/schema/outbox.d.mts +240 -0
  330. package/dist/schema/outbox.mjs +53 -0
  331. package/dist/schema/outbox.mjs.map +1 -0
  332. package/dist/schema/question-route.mjs +16 -0
  333. package/dist/schema/question-route.mjs.map +1 -0
  334. package/dist/schema/receipt.d.mts +81 -0
  335. package/dist/schema/receipt.mjs +94 -0
  336. package/dist/schema/receipt.mjs.map +1 -0
  337. package/dist/schema/repository.d.mts +30 -0
  338. package/dist/schema/repository.mjs +29 -0
  339. package/dist/schema/repository.mjs.map +1 -0
  340. package/dist/schema/session.d.mts +136 -0
  341. package/dist/schema/session.mjs +54 -0
  342. package/dist/schema/session.mjs.map +1 -0
  343. package/dist/schema/signal.d.mts +105 -0
  344. package/dist/schema/signal.mjs +81 -0
  345. package/dist/schema/signal.mjs.map +1 -0
  346. package/dist/schema/slack-pr-notifications.d.mts +12 -0
  347. package/dist/schema/slack-pr-notifications.mjs +11 -0
  348. package/dist/schema/slack-pr-notifications.mjs.map +1 -0
  349. package/dist/schema/stored-session.mjs +10 -0
  350. package/dist/schema/stored-session.mjs.map +1 -0
  351. package/dist/schema/stored-task.mjs +20 -0
  352. package/dist/schema/stored-task.mjs.map +1 -0
  353. package/dist/schema/task-effect.d.mts +39 -0
  354. package/dist/schema/task-effect.mjs +29 -0
  355. package/dist/schema/task-effect.mjs.map +1 -0
  356. package/dist/schema/task-graph.d.mts +3173 -0
  357. package/dist/schema/task-graph.mjs +97 -0
  358. package/dist/schema/task-graph.mjs.map +1 -0
  359. package/dist/schema/task-message.d.mts +254 -0
  360. package/dist/schema/task-message.mjs +189 -0
  361. package/dist/schema/task-message.mjs.map +1 -0
  362. package/dist/schema/task.d.mts +273 -0
  363. package/dist/schema/task.mjs +200 -0
  364. package/dist/schema/task.mjs.map +1 -0
  365. package/dist/schema/transcript.d.mts +176 -0
  366. package/dist/schema/transcript.mjs +87 -0
  367. package/dist/schema/transcript.mjs.map +1 -0
  368. package/dist/schema/transitions.d.mts +50 -0
  369. package/dist/schema/transitions.mjs +303 -0
  370. package/dist/schema/transitions.mjs.map +1 -0
  371. package/dist/schema/work.d.mts +150 -0
  372. package/dist/schema/work.mjs +102 -0
  373. package/dist/schema/work.mjs.map +1 -0
  374. package/dist/session-previews.d.mts +76 -0
  375. package/dist/session-previews.mjs +55 -0
  376. package/dist/session-previews.mjs.map +1 -0
  377. package/dist/session-review.d.mts +120 -0
  378. package/dist/session-review.mjs +79 -0
  379. package/dist/session-review.mjs.map +1 -0
  380. package/dist/signal-triage.d.mts +20 -0
  381. package/dist/signal-triage.mjs +85 -0
  382. package/dist/signal-triage.mjs.map +1 -0
  383. package/dist/signals.d.mts +20 -0
  384. package/dist/signals.mjs +19 -0
  385. package/dist/signals.mjs.map +1 -0
  386. package/dist/stall.d.mts +41 -0
  387. package/dist/stall.mjs +83 -0
  388. package/dist/stall.mjs.map +1 -0
  389. package/dist/storage.d.mts +4 -0
  390. package/dist/storage.mjs +4 -0
  391. package/dist/store/driver.d.mts +65 -0
  392. package/dist/store/driver.mjs +42 -0
  393. package/dist/store/driver.mjs.map +1 -0
  394. package/dist/store/engine.d.mts +683 -0
  395. package/dist/store/engine.mjs +2309 -0
  396. package/dist/store/engine.mjs.map +1 -0
  397. package/dist/store/memory.d.mts +24 -0
  398. package/dist/store/memory.mjs +69 -0
  399. package/dist/store/memory.mjs.map +1 -0
  400. package/dist/store/slack-pr-notifications.d.mts +44 -0
  401. package/dist/store/slack-pr-notifications.mjs +121 -0
  402. package/dist/store/slack-pr-notifications.mjs.map +1 -0
  403. package/dist/store/task-effects.d.mts +38 -0
  404. package/dist/store/task-effects.mjs +118 -0
  405. package/dist/store/task-effects.mjs.map +1 -0
  406. package/dist/store/task-graphs.d.mts +60 -0
  407. package/dist/store/task-graphs.mjs +212 -0
  408. package/dist/store/task-graphs.mjs.map +1 -0
  409. package/dist/store/task-messages.d.mts +136 -0
  410. package/dist/store/task-messages.mjs +475 -0
  411. package/dist/store/task-messages.mjs.map +1 -0
  412. package/dist/store/task-work.d.mts +180 -0
  413. package/dist/store/task-work.mjs +137 -0
  414. package/dist/store/task-work.mjs.map +1 -0
  415. package/dist/store/work-notifications.d.mts +19 -0
  416. package/dist/store/work-notifications.mjs +48 -0
  417. package/dist/store/work-notifications.mjs.map +1 -0
  418. package/dist/sweep.d.mts +79 -0
  419. package/dist/sweep.mjs +171 -0
  420. package/dist/sweep.mjs.map +1 -0
  421. package/dist/task-communication.d.mts +35 -0
  422. package/dist/task-communication.mjs +47 -0
  423. package/dist/task-communication.mjs.map +1 -0
  424. package/dist/task-graph-view.d.mts +267 -0
  425. package/dist/task-graph-view.mjs +17 -0
  426. package/dist/task-graph-view.mjs.map +1 -0
  427. package/dist/task-message-processing.d.mts +60 -0
  428. package/dist/task-message-processing.mjs +200 -0
  429. package/dist/task-message-processing.mjs.map +1 -0
  430. package/dist/task-protocols.d.mts +80 -0
  431. package/dist/task-protocols.mjs +47 -0
  432. package/dist/task-protocols.mjs.map +1 -0
  433. package/dist/tasks.d.mts +17 -0
  434. package/dist/tasks.mjs +17 -0
  435. package/dist/vercel-git.d.mts +53 -0
  436. package/dist/vercel-git.mjs +344 -0
  437. package/dist/vercel-git.mjs.map +1 -0
  438. package/dist/vercel-github-api.d.mts +103 -0
  439. package/dist/vercel-github-api.mjs +363 -0
  440. package/dist/vercel-github-api.mjs.map +1 -0
  441. package/dist/vercel.d.mts +34 -2
  442. package/dist/vercel.mjs +49 -3
  443. package/dist/vercel.mjs.map +1 -1
  444. package/dist/work-triage/eve-tool.d.mts +29 -0
  445. package/dist/work-triage/eve-tool.mjs +32 -0
  446. package/dist/work-triage/eve-tool.mjs.map +1 -0
  447. package/dist/work-triage/find-existing-work.d.mts +32 -0
  448. package/dist/work-triage/find-existing-work.mjs +31 -0
  449. package/dist/work-triage/find-existing-work.mjs.map +1 -0
  450. package/dist/work-triage/github.d.mts +15 -0
  451. package/dist/work-triage/github.mjs +14 -0
  452. package/dist/work-triage/github.mjs.map +1 -0
  453. package/dist/work-triage.d.mts +4 -0
  454. package/dist/work-triage.mjs +3 -0
  455. package/dist/workflows.d.mts +146 -0
  456. package/dist/workflows.mjs +139 -0
  457. package/dist/workflows.mjs.map +1 -0
  458. package/dist/workspace-diff-assembly.d.mts +33 -0
  459. package/dist/workspace-diff-assembly.mjs +95 -0
  460. package/dist/workspace-diff-assembly.mjs.map +1 -0
  461. package/dist/workspace-diff.d.mts +90 -0
  462. package/dist/workspace-diff.mjs +61 -0
  463. package/dist/workspace-diff.mjs.map +1 -0
  464. package/dist/workspace-files-git.d.mts +15 -0
  465. package/dist/workspace-files-git.mjs +61 -0
  466. package/dist/workspace-files-git.mjs.map +1 -0
  467. package/dist/workspace-files.d.mts +107 -0
  468. package/dist/workspace-files.mjs +74 -0
  469. package/dist/workspace-files.mjs.map +1 -0
  470. package/dist/workspace-snapshot.d.mts +26 -0
  471. package/dist/workspace-snapshot.mjs +80 -0
  472. package/dist/workspace-snapshot.mjs.map +1 -0
  473. package/docs/getting-started.md +104 -0
  474. package/docs/index.md +100 -0
  475. package/docs/recipes/cancellation.md +215 -0
  476. package/docs/recipes/custom-workflow.md +153 -0
  477. package/docs/recipes/dependent-tasks.md +207 -0
  478. package/docs/recipes/eve-agent.md +277 -0
  479. package/docs/recipes/human-input.md +204 -0
  480. package/docs/recipes/persistence-recovery.md +268 -0
  481. package/docs/recipes/retry-recovery.md +241 -0
  482. package/docs/recipes/task-messaging.md +215 -0
  483. package/docs/recipes/typed-eve-result.md +161 -0
  484. package/docs/runtime-integration.md +137 -0
  485. package/package.json +142 -46
  486. package/dist/approval-JX2Px9IC.mjs +0 -132
  487. package/dist/approval-JX2Px9IC.mjs.map +0 -1
  488. package/dist/budget-DzSiIA4t.mjs +0 -42
  489. package/dist/budget-DzSiIA4t.mjs.map +0 -1
  490. package/dist/change-D2U6v7Ek.mjs +0 -554
  491. package/dist/change-D2U6v7Ek.mjs.map +0 -1
  492. package/dist/communication-Kd9nU5RP.mjs.map +0 -1
  493. package/dist/coordination-Cq08hb1l.mjs +0 -76
  494. package/dist/coordination-Cq08hb1l.mjs.map +0 -1
  495. package/dist/dispatch-BaZS3PT8.d.mts +0 -76
  496. package/dist/driver-BC0Mt5KG.d.mts +0 -34
  497. package/dist/driver-Bbd25rNM.mjs +0 -23
  498. package/dist/driver-Bbd25rNM.mjs.map +0 -1
  499. package/dist/engine-DFHU2Pe-.d.mts +0 -781
  500. package/dist/engine-WaUM2cGA.mjs +0 -1068
  501. package/dist/engine-WaUM2cGA.mjs.map +0 -1
  502. package/dist/factory-config-BoRXOw43.mjs +0 -50
  503. package/dist/factory-config-BoRXOw43.mjs.map +0 -1
  504. package/dist/factory-config-D2yU3G0c.d.mts +0 -58
  505. package/dist/github-C5HNBN6p.d.mts +0 -279
  506. package/dist/id-BLIkCVue.mjs.map +0 -1
  507. package/dist/index-Bw6hggoH.d.mts +0 -40
  508. package/dist/index.mjs.map +0 -1
  509. package/dist/task-CcOyOJ3k.mjs +0 -154
  510. package/dist/task-CcOyOJ3k.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.mjs","names":[],"sources":["../src/budget.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { DateClock } from \"./schema/common\";\nimport { factoryIdSchema, type FactoryId, type TaskId } from \"./schema/id\";\nimport { budgetMonthSchema, type BudgetLimits, type BudgetMonth } from \"./schema/budget\";\nimport type { Task } from \"./schema/task\";\nimport type { FactoryStores } from \"./store/engine\";\n\n/**\n * Stable factory identity for budget rows. Nothing mints factory ids yet, so\n * the app derives one from a deployment-stable seed such as the Vercel\n * project id.\n */\nexport function deriveFactoryId(seed: string): FactoryId {\n return factoryIdSchema.parse(\n `fac_${createHash(\"sha256\").update(seed).digest(\"hex\").slice(0, 32)}`,\n );\n}\n\n/** The budget month (\"YYYY-MM\", UTC) a timestamp falls into. */\nexport function budgetMonthOf(isoDateTime: string): BudgetMonth {\n return budgetMonthSchema.parse(isoDateTime.slice(0, 7));\n}\n\n// Currency math runs in integer micro-dollars so decimal limits compare\n// exactly; 0.1 + 0.2 must never refuse an exact-fit reservation.\nfunction microsOf(usd: number): number {\n return Math.round(usd * 1_000_000);\n}\n\n/**\n * Monthly spend is derived from task rows, never stored: each task counts its\n * settled cost once that exists, otherwise its held reservation. A task\n * settles once, so a settled row never also counts its reservation.\n * Attribution uses the reservation time so tasks that wait across a month\n * boundary charge the month they actually ran in.\n */\nexport function computeMonthSpendUsd(tasks: readonly Task[], month: BudgetMonth): number {\n let spendMicros = 0;\n for (const task of tasks) {\n if (budgetMonthOf(task.reservedAt ?? task.createdAt) !== month) {\n continue;\n }\n spendMicros += microsOf(task.settledUsd ?? task.reservedUsd ?? 0);\n }\n return spendMicros / 1_000_000;\n}\n\n/** Derived monthly capacity state before another per-Task reservation. */\nexport type BudgetStatus = \"ok\" | \"warning\" | \"exhausted\";\n\n/**\n * True when one more per-task slice fits under the monthly total. Dispatch\n * refuses on this exact predicate and budgetStatus reports \"exhausted\" on its\n * negation, so refusing and reporting can never disagree.\n */\nexport function canReserve(\n spendUsd: number,\n limits: Pick<BudgetLimits, \"totalUsd\" | \"perTaskReservationUsd\">,\n): boolean {\n return microsOf(spendUsd) + microsOf(limits.perTaskReservationUsd) <= microsOf(limits.totalUsd);\n}\n\n/** Classify monthly spend using the same exact-fit predicate enforced by dispatch. */\nexport function budgetStatus(\n spendUsd: number,\n limits: Pick<BudgetLimits, \"totalUsd\" | \"perTaskReservationUsd\" | \"warningPercent\">,\n): BudgetStatus {\n if (!canReserve(spendUsd, limits)) {\n return \"exhausted\";\n }\n // Integer comparison: spend/total * 100 >= warningPercent without float\n // drift on decimal limits.\n if (microsOf(spendUsd) * 100 >= microsOf(limits.totalUsd) * limits.warningPercent) {\n return \"warning\";\n }\n return \"ok\";\n}\n\nconst TERMINAL_TASK_STATES = new Set<Task[\"state\"]>([\"succeeded\", \"failed\", \"cancelled\"]);\n\n/** Grace period, clock, and optional snapshot for terminal usage settlement. */\nexport interface SweepSettlementsOptions {\n /** How long a terminal task waits for late usage before the sweep settles it. */\n graceMinutes?: number;\n now?: DateClock;\n /** A dispatcher-wide snapshot avoids another complete task read. */\n tasks?: readonly Task[];\n}\n\n/** Task-local charges newly settled by one reconciliation pass. */\nexport interface SweepSettlementsResult {\n readonly settled: readonly { readonly taskId: TaskId; readonly totalUsd: number }[];\n}\n\n/** Task capability required to settle terminal reservations. */\nexport type SettlementSweepStores = Pick<FactoryStores, \"tasks\">;\n\n/**\n * Settle reserved terminal tasks the session hook did not: a task that ended\n * after its session (a change verified later) or whose session died. Settles\n * at the recorded usage, or at zero with a warning reason when none was\n * recorded within the grace window.\n */\nexport async function sweepSettlements(\n stores: SettlementSweepStores,\n options: SweepSettlementsOptions = {},\n): Promise<SweepSettlementsResult> {\n const graceMs = (options.graceMinutes ?? 10) * 60_000;\n const nowMs = (options.now ?? (() => new Date()))().getTime();\n const settled: { taskId: TaskId; totalUsd: number }[] = [];\n for (const task of options.tasks ?? (await stores.tasks.list())) {\n if (task.reservedUsd === undefined || task.settledUsd !== undefined) {\n continue;\n }\n if (!TERMINAL_TASK_STATES.has(task.state)) {\n continue;\n }\n if (nowMs - Date.parse(task.updatedAt) < graceMs) {\n continue;\n }\n // A concurrent writer (operator retry, another sweep) may move the task\n // between the list and the settle; skip it rather than aborting the pass.\n const totalUsd = task.usage?.costUsd ?? 0;\n try {\n const result = await stores.tasks.settle(task.id, {\n cost: { totalUsd },\n ...{\n reason:\n task.usage === undefined\n ? \"usage missing after ten minutes; settled at zero\"\n : \"measured usage settled by sweep\",\n },\n });\n // Report this settlement's amount, not the task's accumulated total.\n settled.push({ taskId: result.id, totalUsd });\n } catch {\n continue;\n }\n }\n return { settled };\n}\n\n/** Owner-only notification emitted when monthly spend crosses a budget threshold. */\nexport interface BudgetNotice {\n outcome: \"budget_warning\" | \"budget_exhausted\";\n month: BudgetMonth;\n spendUsd: number;\n limits: BudgetLimits;\n}\n\n/** Monthly limits, delivery hook, and optional snapshot used for budget reconciliation. */\nexport interface BudgetSweepOptions {\n factoryId: FactoryId;\n limits: BudgetLimits;\n /** Defaults to true. False reports spending without threshold checks or budget notices. */\n enforce?: boolean;\n /** Defaults to the current UTC month. */\n month?: BudgetMonth;\n now?: DateClock;\n /** Owner-only delivery; invoked at most once per month per outcome. */\n notify?: (notice: BudgetNotice) => Promise<void>;\n /** A dispatcher-wide snapshot avoids another complete task read. */\n tasks?: readonly Task[];\n}\n\n/**\n * Derived monthly spend and exact notice outcome produced by budget reconciliation.\n * `stamped` means this sweep recorded the threshold, `already_stamped` means no\n * new stamp was needed, and `delivery_failed` remains eligible for retry.\n */\nexport type BudgetSweepResult =\n | {\n readonly month: BudgetMonth;\n readonly spendUsd: number;\n readonly status: \"disabled\";\n readonly noticeState: \"not_applicable\";\n }\n | {\n readonly month: BudgetMonth;\n readonly spendUsd: number;\n readonly status: \"ok\";\n readonly noticeState: \"not_applicable\";\n }\n | {\n readonly month: BudgetMonth;\n readonly spendUsd: number;\n readonly status: \"warning\";\n readonly noticeState: \"stamped\" | \"already_stamped\" | \"delivery_failed\";\n }\n | {\n readonly month: BudgetMonth;\n readonly spendUsd: number;\n readonly status: \"exhausted\";\n readonly noticeState: \"stamped\" | \"already_stamped\" | \"delivery_failed\";\n };\n\n/** Budget and Task capabilities required to reconcile monthly budget thresholds. */\nexport type BudgetSweepStores = Pick<FactoryStores, \"budgets\" | \"tasks\">;\n\n/**\n * Ensure the month's budget row, derive spend, and record threshold crossings\n * write-once. Delivery comes first and the stamp only lands after it, so a\n * failed notification retries on the next sweep instead of being lost; the\n * write-once stamp still keeps each threshold to one message per month.\n */\nexport async function sweepBudget(\n stores: BudgetSweepStores,\n options: BudgetSweepOptions,\n): Promise<BudgetSweepResult> {\n const now = options.now ?? (() => new Date());\n const month = options.month ?? budgetMonthOf(now().toISOString());\n const budget = await stores.budgets.ensure({\n factoryId: options.factoryId,\n month,\n limits: options.limits,\n });\n const spendUsd = computeMonthSpendUsd(options.tasks ?? (await stores.tasks.list()), month);\n if (options.enforce === false)\n return { month, spendUsd, status: \"disabled\", noticeState: \"not_applicable\" };\n const status = budgetStatus(spendUsd, options.limits);\n\n async function crossThreshold(\n notice: \"warning\" | \"exhausted\",\n outcome: BudgetNotice[\"outcome\"],\n ): Promise<\"stamped\" | \"already_stamped\" | \"delivery_failed\"> {\n const field = notice === \"warning\" ? \"warningAt\" : \"exhaustedAt\";\n if (budget.notices[field] !== undefined) {\n return \"already_stamped\";\n }\n if (options.notify !== undefined) {\n try {\n await options.notify({ outcome, month, spendUsd, limits: options.limits });\n } catch {\n // Leave the notice unstamped so the next sweep retries delivery.\n return \"delivery_failed\";\n }\n }\n return (await stores.budgets.stampNotice(month, notice)).stamped\n ? \"stamped\"\n : \"already_stamped\";\n }\n\n if (status === \"exhausted\") {\n const noticeState = await crossThreshold(\"exhausted\", \"budget_exhausted\");\n // The warning threshold was necessarily crossed too; stamp it silently so\n // a later settle-down cannot deliver \"warning\" after \"exhausted\".\n if (budget.notices.warningAt === undefined) {\n await stores.budgets.stampNotice(month, \"warning\");\n }\n return { month, spendUsd, status, noticeState };\n }\n if (status === \"warning\") {\n const noticeState = await crossThreshold(\"warning\", \"budget_warning\");\n return { month, spendUsd, status, noticeState };\n }\n return { month, spendUsd, status, noticeState: \"not_applicable\" };\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Budget, BudgetLimits, BudgetMonth, budgetLimitsSchema, budgetMonthSchema, budgetSchema } from "./schema/budget.mjs";
2
+ import { BudgetNoticeStampResult, EnsureBudgetInput, SettleTaskInput, SettlementError } from "./store/engine.mjs";
3
+ import { BudgetNotice, BudgetStatus, BudgetSweepOptions, BudgetSweepResult, BudgetSweepStores, SettlementSweepStores, SweepSettlementsOptions, SweepSettlementsResult, budgetMonthOf, budgetStatus, canReserve, computeMonthSpendUsd, sweepBudget, sweepSettlements } from "./budget.mjs";
4
+ export { type Budget, type BudgetLimits, type BudgetMonth, type BudgetNotice, type BudgetNoticeStampResult, type BudgetStatus, type BudgetSweepOptions, type BudgetSweepResult, type BudgetSweepStores, type EnsureBudgetInput, type SettleTaskInput, SettlementError, type SettlementSweepStores, type SweepSettlementsOptions, type SweepSettlementsResult, budgetLimitsSchema, budgetMonthOf, budgetMonthSchema, budgetSchema, budgetStatus, canReserve, computeMonthSpendUsd, sweepBudget, sweepSettlements };
@@ -0,0 +1,4 @@
1
+ import { budgetLimitsSchema, budgetMonthSchema, budgetSchema } from "./schema/budget.mjs";
2
+ import { budgetMonthOf, budgetStatus, canReserve, computeMonthSpendUsd, sweepBudget, sweepSettlements } from "./budget.mjs";
3
+ import { SettlementError } from "./store/engine.mjs";
4
+ export { SettlementError, budgetLimitsSchema, budgetMonthOf, budgetMonthSchema, budgetSchema, budgetStatus, canReserve, computeMonthSpendUsd, sweepBudget, sweepSettlements };
@@ -1,12 +1,15 @@
1
- import { r as FactoryConfigInput } from "./factory-config-D2yU3G0c.mjs";
1
+ /// <reference types="node" />
2
+ import { FactoryConfigInput } from "./schema/factory-config.mjs";
2
3
  import { EveNextConfig, EveNextConfigFunction, EveNextConfigInput } from "eve/next";
3
4
  //#region src/build-factory.d.ts
4
- interface FactoryArgs<TConfig extends EveNextConfig = EveNextConfig> {
5
+ /** Inputs for validating a Factory configuration and discovering its Eve agents at build time. */
6
+ interface BuildFactoryOptions<TConfig extends EveNextConfig = EveNextConfig> {
5
7
  factoryConfig: FactoryConfigInput;
6
8
  nextConfig: EveNextConfigInput<TConfig>;
7
9
  root?: string;
8
10
  }
9
- declare function buildFactory<TConfig extends EveNextConfig>({ factoryConfig, nextConfig, root }: FactoryArgs<TConfig>): EveNextConfigFunction<TConfig>;
11
+ /** Create an Eve Next.js configuration wrapper for the agents beneath a Factory project root. */
12
+ declare function buildFactory<TConfig extends EveNextConfig>({ factoryConfig, nextConfig, root }: BuildFactoryOptions<TConfig>): EveNextConfigFunction<TConfig>;
10
13
  //#endregion
11
- export { FactoryArgs, buildFactory };
14
+ export { BuildFactoryOptions, buildFactory };
12
15
  //# sourceMappingURL=build-factory.d.mts.map
@@ -1,7 +1,8 @@
1
- import { n as defineFactory } from "./factory-config-BoRXOw43.mjs";
1
+ import { defineFactory } from "./schema/factory-config.mjs";
2
2
  import { readdirSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  //#region src/build-factory.ts
5
+ /** Create an Eve Next.js configuration wrapper for the agents beneath a Factory project root. */
5
6
  function buildFactory({ factoryConfig, nextConfig, root = process.cwd() }) {
6
7
  defineFactory(factoryConfig);
7
8
  const agentDefinitions = Object.fromEntries(readdirSync(path.join(root, "agents"), { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => [entry.name, path.join(root, "agents", entry.name)]));
@@ -1 +1 @@
1
- {"version":3,"file":"build-factory.mjs","names":[],"sources":["../src/build-factory.ts"],"sourcesContent":["import { readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n type EveNextConfig,\n type EveNextConfigFunction,\n type EveNextConfigInput,\n type WithEveAgentsConfig,\n} from \"eve/next\";\nimport { defineFactory, type FactoryConfigInput } from \"./schema/factory-config\";\n\nexport interface FactoryArgs<TConfig extends EveNextConfig = EveNextConfig> {\n factoryConfig: FactoryConfigInput;\n nextConfig: EveNextConfigInput<TConfig>;\n root?: string;\n}\n\nexport function buildFactory<TConfig extends EveNextConfig>({\n factoryConfig,\n nextConfig,\n root = process.cwd(),\n}: FactoryArgs<TConfig>): EveNextConfigFunction<TConfig> {\n defineFactory(factoryConfig);\n const agentDefinitions: WithEveAgentsConfig = Object.fromEntries(\n readdirSync(path.join(root, \"agents\"), { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => [entry.name, path.join(root, \"agents\", entry.name)]),\n );\n return async (phase, context) => {\n const { withEve } = await import(\"eve/next\");\n return withEve(nextConfig, { agents: agentDefinitions })(phase, context);\n };\n}\n"],"mappings":";;;;AAgBA,SAAgB,aAA4C,EAC1D,eACA,YACA,OAAO,QAAQ,IAAI,KACoC;CACvD,cAAc,aAAa;CAC3B,MAAM,mBAAwC,OAAO,YACnD,YAAY,KAAK,KAAK,MAAM,QAAQ,GAAG,EAAE,eAAe,KAAK,CAAC,CAAC,CAC5D,QAAQ,UAAU,MAAM,YAAY,CAAC,CAAC,CACtC,KAAK,UAAU,CAAC,MAAM,MAAM,KAAK,KAAK,MAAM,UAAU,MAAM,IAAI,CAAC,CAAC,CACvE;CACA,OAAO,OAAO,OAAO,YAAY;EAC/B,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,OAAO,QAAQ,YAAY,EAAE,QAAQ,iBAAiB,CAAC,CAAC,CAAC,OAAO,OAAO;CACzE;AACF"}
1
+ {"version":3,"file":"build-factory.mjs","names":[],"sources":["../src/build-factory.ts"],"sourcesContent":["import { readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n type EveNextConfig,\n type EveNextConfigFunction,\n type EveNextConfigInput,\n type WithEveAgentsConfig,\n} from \"eve/next\";\nimport { defineFactory, type FactoryConfigInput } from \"./schema/factory-config\";\n\n/** Inputs for validating a Factory configuration and discovering its Eve agents at build time. */\nexport interface BuildFactoryOptions<TConfig extends EveNextConfig = EveNextConfig> {\n factoryConfig: FactoryConfigInput;\n nextConfig: EveNextConfigInput<TConfig>;\n root?: string;\n}\n\n/** Create an Eve Next.js configuration wrapper for the agents beneath a Factory project root. */\nexport function buildFactory<TConfig extends EveNextConfig>({\n factoryConfig,\n nextConfig,\n root = process.cwd(),\n}: BuildFactoryOptions<TConfig>): EveNextConfigFunction<TConfig> {\n defineFactory(factoryConfig);\n const agentDefinitions: WithEveAgentsConfig = Object.fromEntries(\n readdirSync(path.join(root, \"agents\"), { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => [entry.name, path.join(root, \"agents\", entry.name)]),\n );\n return async (phase, context) => {\n const { withEve } = await import(\"eve/next\");\n return withEve(nextConfig, { agents: agentDefinitions })(phase, context);\n };\n}\n"],"mappings":";;;;;AAkBA,SAAgB,aAA4C,EAC1D,eACA,YACA,OAAO,QAAQ,IAAI,KAC4C;CAC/D,cAAc,aAAa;CAC3B,MAAM,mBAAwC,OAAO,YACnD,YAAY,KAAK,KAAK,MAAM,QAAQ,GAAG,EAAE,eAAe,KAAK,CAAC,CAAC,CAC5D,QAAQ,UAAU,MAAM,YAAY,CAAC,CAAC,CACtC,KAAK,UAAU,CAAC,MAAM,MAAM,KAAK,KAAK,MAAM,UAAU,MAAM,IAAI,CAAC,CAAC,CACvE;CACA,OAAO,OAAO,OAAO,YAAY;EAC/B,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,OAAO,QAAQ,YAAY,EAAE,QAAQ,iBAAiB,CAAC,CAAC,CAAC,OAAO,OAAO;CACzE;AACF"}
@@ -0,0 +1,9 @@
1
+ import { Repository } from "../schema/repository.mjs";
2
+ import { Task } from "../schema/task.mjs";
3
+ import { Change } from "../schema/change.mjs";
4
+ //#region src/change-verification/brief.d.ts
5
+ /** Format the starting brief for independently verifying a recorded Change. */
6
+ declare function formatChangeVerificationBrief(task: Task, repository: Repository, change: Change): string;
7
+ //#endregion
8
+ export { formatChangeVerificationBrief };
9
+ //# sourceMappingURL=brief.d.mts.map
@@ -0,0 +1,13 @@
1
+ //#region src/change-verification/brief.ts
2
+ /** Format the starting brief for independently verifying a recorded Change. */
3
+ function formatChangeVerificationBrief(task, repository, change) {
4
+ return [
5
+ `You are assigned factory verification task ${task.id} in repository ${repository.slug}.`,
6
+ `Change under review: ${change.id} (${change.prUrl}).`,
7
+ "Read the task with get_task, independently inspect and test the change, then call record_verification with every evidence field."
8
+ ].join("\n");
9
+ }
10
+ //#endregion
11
+ export { formatChangeVerificationBrief };
12
+
13
+ //# sourceMappingURL=brief.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brief.mjs","names":[],"sources":["../../src/change-verification/brief.ts"],"sourcesContent":["import type { Change } from \"../schema/change\";\nimport type { Repository } from \"../schema/repository\";\nimport type { Task } from \"../schema/task\";\n\n/** Format the starting brief for independently verifying a recorded Change. */\nexport function formatChangeVerificationBrief(\n task: Task,\n repository: Repository,\n change: Change,\n): string {\n return [\n `You are assigned factory verification task ${task.id} in repository ${repository.slug}.`,\n `Change under review: ${change.id} (${change.prUrl}).`,\n \"Read the task with get_task, independently inspect and test the change, then call record_verification with every evidence field.\",\n ].join(\"\\n\");\n}\n"],"mappings":";;AAKA,SAAgB,8BACd,MACA,YACA,QACQ;CACR,OAAO;EACL,8CAA8C,KAAK,GAAG,iBAAiB,WAAW,KAAK;EACvF,wBAAwB,OAAO,GAAG,IAAI,OAAO,MAAM;EACnD;CACF,CAAC,CAAC,KAAK,IAAI;AACb"}
@@ -0,0 +1,37 @@
1
+ import { TaskId } from "../schema/id.mjs";
2
+ import { AgentRouteBinding } from "../schema/agent-route.mjs";
3
+ import { Task } from "../schema/task.mjs";
4
+ import "../agent-routes.mjs";
5
+ import { FactoryStores } from "../store/engine.mjs";
6
+ import { PresentVerificationResultInput } from "./eve-tool.mjs";
7
+ //#region src/change-verification/dispatch.d.ts
8
+ /** Store capabilities required to inspect and create verification Tasks. */
9
+ type ChangeVerificationStores = Pick<FactoryStores, "tasks" | "changes" | "signals">;
10
+ /** Verification Tasks admitted or found idempotently by one reconciliation pass. */
11
+ interface EnsureChangeVerificationTasksResult {
12
+ readonly created: readonly TaskId[];
13
+ readonly existing: readonly TaskId[];
14
+ }
15
+ /** Stores, optional snapshot, and exact verifier route used by one admission pass. */
16
+ interface EnsureChangeVerificationTasksOptions {
17
+ readonly stores: ChangeVerificationStores;
18
+ readonly tasks?: readonly Task[];
19
+ readonly route?: AgentRouteBinding;
20
+ /** Idempotent presentation callback, replayed from the saved outcome after interruption. */
21
+ readonly presentResult?: (input: PresentVerificationResultInput) => Promise<void>;
22
+ }
23
+ /** One verifier snapshot and the workflow adapters needed to recover its saved result. */
24
+ interface RecoverChangeVerificationResultOptions extends Omit<EnsureChangeVerificationTasksOptions, "tasks"> {
25
+ readonly task: Task;
26
+ }
27
+ /**
28
+ * Recover an exact verifier attempt before generic lifecycle policy replaces or escalates it.
29
+ * Returns false when no eligible report exists; storage or presentation errors propagate so callers
30
+ * can defer lifecycle changes and retry the same attempt.
31
+ */
32
+ declare function recoverChangeVerificationResult(options: RecoverChangeVerificationResultOptions): Promise<boolean>;
33
+ /** Admit one verification child per producer attempt and recover its recorded outcome. */
34
+ declare function ensureChangeVerificationTasks(options: EnsureChangeVerificationTasksOptions): Promise<EnsureChangeVerificationTasksResult>;
35
+ //#endregion
36
+ export { ChangeVerificationStores, EnsureChangeVerificationTasksOptions, EnsureChangeVerificationTasksResult, RecoverChangeVerificationResultOptions, ensureChangeVerificationTasks, recoverChangeVerificationResult };
37
+ //# sourceMappingURL=dispatch.d.mts.map
@@ -0,0 +1,83 @@
1
+ import { parseAgentRouteBinding } from "../schema/agent-route.mjs";
2
+ import { routeKey, routeTaskWork } from "../agent-routes.mjs";
3
+ import { applyVerificationReport, verificationDelivery, verificationParentAttempt, verificationReportSchema } from "./result.mjs";
4
+ //#region src/change-verification/dispatch.ts
5
+ /**
6
+ * Recover an exact verifier attempt before generic lifecycle policy replaces or escalates it.
7
+ * Returns false when no eligible report exists; storage or presentation errors propagate so callers
8
+ * can defer lifecycle changes and retry the same attempt.
9
+ */
10
+ async function recoverChangeVerificationResult(options) {
11
+ const { stores, task } = options;
12
+ const route = options.route ?? parseAgentRouteBinding({
13
+ id: "verification",
14
+ version: 1
15
+ });
16
+ if (!task.work.route || routeKey(task.work.route) !== routeKey(route) || ![
17
+ "running",
18
+ "succeeded",
19
+ "failed"
20
+ ].includes(task.state)) return false;
21
+ const report = await stores.signals.getByDelivery(verificationDelivery(task));
22
+ if (!report) return false;
23
+ if (!(await applyVerificationReport(stores, report)).recorded) return false;
24
+ const { output } = verificationReportSchema.parse(report.payload);
25
+ await options.presentResult?.({
26
+ taskId: task.id,
27
+ changeId: output.changeId,
28
+ verdict: output.verdict,
29
+ summary: output.summary
30
+ });
31
+ return true;
32
+ }
33
+ /** Admit one verification child per producer attempt and recover its recorded outcome. */
34
+ async function ensureChangeVerificationTasks(options) {
35
+ const { stores } = options;
36
+ const route = options.route ?? parseAgentRouteBinding({
37
+ id: "verification",
38
+ version: 1
39
+ });
40
+ const tasks = options.tasks ?? await stores.tasks.list();
41
+ const existingIds = new Set(tasks.map((task) => task.id));
42
+ const result = {
43
+ created: [],
44
+ existing: []
45
+ };
46
+ for (const task of tasks) if (await recoverChangeVerificationResult({
47
+ ...options,
48
+ task
49
+ })) result.existing.push(task.id);
50
+ const sources = tasks.filter((task) => task.work.route?.id === "code-change" && task.state === "verifying" && task.changeId !== void 0);
51
+ for (const snapshot of sources) {
52
+ const source = await stores.tasks.get(snapshot.id);
53
+ if (!source || source.state !== "verifying" || source.attempt !== snapshot.attempt || source.changeId !== snapshot.changeId) continue;
54
+ const existing = tasks.find((task) => task.work.route !== void 0 && routeKey(task.work.route) === routeKey(route) && task.parentTaskId === source.id && task.changeId === source.changeId && verificationParentAttempt(task) === source.attempt);
55
+ if (existing !== void 0) {
56
+ if (!result.existing.includes(existing.id)) result.existing.push(existing.id);
57
+ continue;
58
+ }
59
+ const verification = await stores.tasks.create({
60
+ repositoryIds: source.repositoryIds,
61
+ kind: "verification",
62
+ work: routeTaskWork({
63
+ route,
64
+ title: `Verify change ${source.changeId}`,
65
+ input: {
66
+ changeId: source.changeId,
67
+ parentAttempt: source.attempt
68
+ }
69
+ }),
70
+ origin: {},
71
+ parentTaskId: source.id,
72
+ replyTo: source.replyTo,
73
+ changeId: source.changeId,
74
+ dedupeKey: `verification:${source.id}:${source.attempt}:${source.changeId}:${routeKey(route)}`
75
+ });
76
+ (existingIds.has(verification.id) ? result.existing : result.created).push(verification.id);
77
+ }
78
+ return result;
79
+ }
80
+ //#endregion
81
+ export { ensureChangeVerificationTasks, recoverChangeVerificationResult };
82
+
83
+ //# sourceMappingURL=dispatch.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.mjs","names":[],"sources":["../../src/change-verification/dispatch.ts"],"sourcesContent":["import {\n parseAgentRouteBinding,\n routeKey,\n routeTaskWork,\n type AgentRouteBinding,\n} from \"../agent-routes\";\nimport type { TaskId } from \"../schema/id\";\nimport type { Task } from \"../schema/task\";\nimport type { FactoryStores } from \"../store/engine\";\nimport {\n applyVerificationReport,\n verificationDelivery,\n verificationParentAttempt,\n verificationReportSchema,\n} from \"./result\";\nimport type { PresentVerificationResultInput } from \"./eve-tool\";\n\n/** Store capabilities required to inspect and create verification Tasks. */\nexport type ChangeVerificationStores = Pick<FactoryStores, \"tasks\" | \"changes\" | \"signals\">;\n\n/** Verification Tasks admitted or found idempotently by one reconciliation pass. */\nexport interface EnsureChangeVerificationTasksResult {\n readonly created: readonly TaskId[];\n readonly existing: readonly TaskId[];\n}\n\n/** Stores, optional snapshot, and exact verifier route used by one admission pass. */\nexport interface EnsureChangeVerificationTasksOptions {\n readonly stores: ChangeVerificationStores;\n readonly tasks?: readonly Task[];\n readonly route?: AgentRouteBinding;\n /** Idempotent presentation callback, replayed from the saved outcome after interruption. */\n readonly presentResult?: (input: PresentVerificationResultInput) => Promise<void>;\n}\n\n/** One verifier snapshot and the workflow adapters needed to recover its saved result. */\nexport interface RecoverChangeVerificationResultOptions extends Omit<\n EnsureChangeVerificationTasksOptions,\n \"tasks\"\n> {\n readonly task: Task;\n}\n\n/**\n * Recover an exact verifier attempt before generic lifecycle policy replaces or escalates it.\n * Returns false when no eligible report exists; storage or presentation errors propagate so callers\n * can defer lifecycle changes and retry the same attempt.\n */\nexport async function recoverChangeVerificationResult(\n options: RecoverChangeVerificationResultOptions,\n): Promise<boolean> {\n const { stores, task } = options;\n const route = options.route ?? parseAgentRouteBinding({ id: \"verification\", version: 1 });\n if (\n !task.work.route ||\n routeKey(task.work.route) !== routeKey(route) ||\n ![\"running\", \"succeeded\", \"failed\"].includes(task.state)\n )\n return false;\n const report = await stores.signals.getByDelivery(verificationDelivery(task));\n if (!report) return false;\n const outcome = await applyVerificationReport(stores, report);\n if (!outcome.recorded) return false;\n const { output } = verificationReportSchema.parse(report.payload);\n await options.presentResult?.({\n taskId: task.id,\n changeId: output.changeId,\n verdict: output.verdict,\n summary: output.summary,\n });\n return true;\n}\n\n/** Admit one verification child per producer attempt and recover its recorded outcome. */\nexport async function ensureChangeVerificationTasks(\n options: EnsureChangeVerificationTasksOptions,\n): Promise<EnsureChangeVerificationTasksResult> {\n const { stores } = options;\n const route = options.route ?? parseAgentRouteBinding({ id: \"verification\", version: 1 });\n const tasks = options.tasks ?? (await stores.tasks.list());\n const existingIds = new Set(tasks.map((task) => task.id));\n const result: { created: TaskId[]; existing: TaskId[] } = { created: [], existing: [] };\n for (const task of tasks) {\n if (await recoverChangeVerificationResult({ ...options, task })) result.existing.push(task.id);\n }\n const sources = tasks.filter(\n (task) =>\n task.work.route?.id === \"code-change\" &&\n task.state === \"verifying\" &&\n task.changeId !== undefined,\n );\n\n for (const snapshot of sources) {\n const source = await stores.tasks.get(snapshot.id);\n if (\n !source ||\n source.state !== \"verifying\" ||\n source.attempt !== snapshot.attempt ||\n source.changeId !== snapshot.changeId\n )\n continue;\n const existing = tasks.find(\n (task) =>\n task.work.route !== undefined &&\n routeKey(task.work.route) === routeKey(route) &&\n task.parentTaskId === source.id &&\n task.changeId === source.changeId &&\n verificationParentAttempt(task) === source.attempt,\n );\n if (existing !== undefined) {\n if (!result.existing.includes(existing.id)) result.existing.push(existing.id);\n continue;\n }\n const verification = await stores.tasks.create({\n repositoryIds: source.repositoryIds,\n kind: \"verification\",\n work: routeTaskWork({\n route: route,\n title: `Verify change ${source.changeId}`,\n input: {\n changeId: source.changeId!,\n parentAttempt: source.attempt,\n },\n }),\n origin: {},\n parentTaskId: source.id,\n replyTo: source.replyTo,\n changeId: source.changeId,\n dedupeKey: `verification:${source.id}:${source.attempt}:${source.changeId}:${routeKey(route)}`,\n });\n (existingIds.has(verification.id) ? result.existing : result.created).push(verification.id);\n }\n\n return result;\n}\n"],"mappings":";;;;;;;;;AAgDA,eAAsB,gCACpB,SACkB;CAClB,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,QAAQ,QAAQ,SAAS,uBAAuB;EAAE,IAAI;EAAgB,SAAS;CAAE,CAAC;CACxF,IACE,CAAC,KAAK,KAAK,SACX,SAAS,KAAK,KAAK,KAAK,MAAM,SAAS,KAAK,KAC5C,CAAC;EAAC;EAAW;EAAa;CAAQ,CAAC,CAAC,SAAS,KAAK,KAAK,GAEvD,OAAO;CACT,MAAM,SAAS,MAAM,OAAO,QAAQ,cAAc,qBAAqB,IAAI,CAAC;CAC5E,IAAI,CAAC,QAAQ,OAAO;CAEpB,IAAI,EAAC,MADiB,wBAAwB,QAAQ,MAAM,EAAA,CAC/C,UAAU,OAAO;CAC9B,MAAM,EAAE,WAAW,yBAAyB,MAAM,OAAO,OAAO;CAChE,MAAM,QAAQ,gBAAgB;EAC5B,QAAQ,KAAK;EACb,UAAU,OAAO;EACjB,SAAS,OAAO;EAChB,SAAS,OAAO;CAClB,CAAC;CACD,OAAO;AACT;;AAGA,eAAsB,8BACpB,SAC8C;CAC9C,MAAM,EAAE,WAAW;CACnB,MAAM,QAAQ,QAAQ,SAAS,uBAAuB;EAAE,IAAI;EAAgB,SAAS;CAAE,CAAC;CACxF,MAAM,QAAQ,QAAQ,SAAU,MAAM,OAAO,MAAM,KAAK;CACxD,MAAM,cAAc,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,EAAE,CAAC;CACxD,MAAM,SAAoD;EAAE,SAAS,CAAC;EAAG,UAAU,CAAC;CAAE;CACtF,KAAK,MAAM,QAAQ,OACjB,IAAI,MAAM,gCAAgC;EAAE,GAAG;EAAS;CAAK,CAAC,GAAG,OAAO,SAAS,KAAK,KAAK,EAAE;CAE/F,MAAM,UAAU,MAAM,QACnB,SACC,KAAK,KAAK,OAAO,OAAO,iBACxB,KAAK,UAAU,eACf,KAAK,aAAa,KAAA,CACtB;CAEA,KAAK,MAAM,YAAY,SAAS;EAC9B,MAAM,SAAS,MAAM,OAAO,MAAM,IAAI,SAAS,EAAE;EACjD,IACE,CAAC,UACD,OAAO,UAAU,eACjB,OAAO,YAAY,SAAS,WAC5B,OAAO,aAAa,SAAS,UAE7B;EACF,MAAM,WAAW,MAAM,MACpB,SACC,KAAK,KAAK,UAAU,KAAA,KACpB,SAAS,KAAK,KAAK,KAAK,MAAM,SAAS,KAAK,KAC5C,KAAK,iBAAiB,OAAO,MAC7B,KAAK,aAAa,OAAO,YACzB,0BAA0B,IAAI,MAAM,OAAO,OAC/C;EACA,IAAI,aAAa,KAAA,GAAW;GAC1B,IAAI,CAAC,OAAO,SAAS,SAAS,SAAS,EAAE,GAAG,OAAO,SAAS,KAAK,SAAS,EAAE;GAC5E;EACF;EACA,MAAM,eAAe,MAAM,OAAO,MAAM,OAAO;GAC7C,eAAe,OAAO;GACtB,MAAM;GACN,MAAM,cAAc;IACX;IACP,OAAO,iBAAiB,OAAO;IAC/B,OAAO;KACL,UAAU,OAAO;KACjB,eAAe,OAAO;IACxB;GACF,CAAC;GACD,QAAQ,CAAC;GACT,cAAc,OAAO;GACrB,SAAS,OAAO;GAChB,UAAU,OAAO;GACjB,WAAW,gBAAgB,OAAO,GAAG,GAAG,OAAO,QAAQ,GAAG,OAAO,SAAS,GAAG,SAAS,KAAK;EAC7F,CAAC;EACD,CAAC,YAAY,IAAI,aAAa,EAAE,IAAI,OAAO,WAAW,OAAO,QAAA,CAAS,KAAK,aAAa,EAAE;CAC5F;CAEA,OAAO;AACT"}
@@ -0,0 +1,61 @@
1
+ import { ChangeId, TaskId } from "../schema/id.mjs";
2
+ import { ChangeEvidence, ChangeLevel, ChangeState } from "../schema/change.mjs";
3
+ import { FactoryStores } from "../store/engine.mjs";
4
+ import { ToolContext, ToolDefinition } from "eve/tools";
5
+ //#region src/change-verification/eve-tool.d.ts
6
+ /** Change and Task capabilities required by the verification-result tool. */
7
+ type RecordVerificationToolStores = Pick<FactoryStores, "changes" | "tasks" | "signals">;
8
+ /** Verified outcome presented after its Task and Change updates commit. */
9
+ interface PresentVerificationResultInput {
10
+ taskId: TaskId;
11
+ changeId: ChangeId;
12
+ verdict: "pass" | "fail";
13
+ summary: string;
14
+ }
15
+ /** Configures presentation after a verification verdict has been durably recorded. */
16
+ interface RecordVerificationToolOptions {
17
+ /** Idempotent delivery, retried with the saved verdict after interrupted completion. */
18
+ presentResult?: (input: PresentVerificationResultInput) => Promise<void>;
19
+ }
20
+ /** Evidence and verdict supplied by the verifier for one Change. */
21
+ interface RecordVerificationInput {
22
+ taskId: TaskId;
23
+ changeId: ChangeId;
24
+ verdict: "pass" | "fail";
25
+ evidence: ChangeEvidence;
26
+ confidence: ChangeLevel;
27
+ summary: string;
28
+ }
29
+ /** Bounded refusal returned when a verification result cannot be associated safely. */
30
+ interface RecordVerificationRefusal {
31
+ readonly recorded: false;
32
+ readonly reason: string;
33
+ }
34
+ /** Durable lifecycle state returned after a verification verdict is recorded. */
35
+ interface RecordVerificationSuccess {
36
+ readonly recorded: true;
37
+ readonly verdict: "pass" | "fail";
38
+ readonly changeState: ChangeState;
39
+ readonly taskState: "succeeded" | "failed";
40
+ }
41
+ /** Recorded verification state or bounded association refusal. */
42
+ type RecordVerificationResult = RecordVerificationRefusal | RecordVerificationSuccess;
43
+ /** Eve outcome tool that records evidence and a verdict for one Change. */
44
+ interface RecordVerificationTool extends ToolDefinition<RecordVerificationInput, RecordVerificationResult> {
45
+ execute(input: RecordVerificationInput, ctx: ToolContext): Promise<RecordVerificationResult>;
46
+ }
47
+ /**
48
+ * The verifier's outcome tool. Writes evidence onto the change and moves it
49
+ * to ready only when the verdict is pass; a failed verdict leaves the change
50
+ * verifying with the evidence recorded, and the verification task itself
51
+ * ends with a receipt either way. The change's own code_change task follows
52
+ * the verdict too: succeeded on pass, failed on fail with the verifier's
53
+ * summary as the reason, so the ledger never shows a verified-and-rejected fix
54
+ * as still in progress. Fail closed: the agent cannot mark a change ready
55
+ * without supplying every evidence field. Requires the authenticated current
56
+ * Task execution and matching parent, Change, and repository associations.
57
+ */
58
+ declare function createRecordVerificationTool(stores: RecordVerificationToolStores, options?: RecordVerificationToolOptions): RecordVerificationTool;
59
+ //#endregion
60
+ export { PresentVerificationResultInput, RecordVerificationInput, RecordVerificationRefusal, RecordVerificationResult, RecordVerificationSuccess, RecordVerificationTool, RecordVerificationToolOptions, RecordVerificationToolStores, createRecordVerificationTool };
61
+ //# sourceMappingURL=eve-tool.d.mts.map
@@ -0,0 +1,89 @@
1
+ import { changeIdSchema, taskIdSchema } from "../schema/id.mjs";
2
+ import { requireTaskExecution, requireTaskExecutionIdentity } from "../eve/task-execution.mjs";
3
+ import { changeEvidenceSchema, changeLevelSchema } from "../schema/change.mjs";
4
+ import { applyVerificationReport, saveVerificationReport, verificationDelivery, verificationOutputSchema, verificationParentAttempt } from "./result.mjs";
5
+ import { z } from "zod";
6
+ import { defineTool } from "eve/tools";
7
+ import { isDeepStrictEqual } from "node:util";
8
+ //#region src/change-verification/eve-tool.ts
9
+ /**
10
+ * The verifier's outcome tool. Writes evidence onto the change and moves it
11
+ * to ready only when the verdict is pass; a failed verdict leaves the change
12
+ * verifying with the evidence recorded, and the verification task itself
13
+ * ends with a receipt either way. The change's own code_change task follows
14
+ * the verdict too: succeeded on pass, failed on fail with the verifier's
15
+ * summary as the reason, so the ledger never shows a verified-and-rejected fix
16
+ * as still in progress. Fail closed: the agent cannot mark a change ready
17
+ * without supplying every evidence field. Requires the authenticated current
18
+ * Task execution and matching parent, Change, and repository associations.
19
+ */
20
+ function createRecordVerificationTool(stores, options = {}) {
21
+ return defineTool({
22
+ description: "Record the outcome of a verification task: the evidence you gathered and whether the change passed. Pass moves the change to ready for human review; fail keeps it out of review.",
23
+ inputSchema: z.object({
24
+ taskId: taskIdSchema.describe("Your verification task."),
25
+ changeId: changeIdSchema.describe("The change you verified."),
26
+ verdict: z.enum(["pass", "fail"]),
27
+ evidence: changeEvidenceSchema,
28
+ confidence: changeLevelSchema.describe("How certain you are in the verdict."),
29
+ summary: z.string().min(1).max(2e3).describe("What you checked and what you found.")
30
+ }),
31
+ async execute({ taskId, changeId, verdict, evidence, confidence, summary }, ctx) {
32
+ const task = await requireTaskExecutionIdentity(stores, ctx, taskId);
33
+ const output = verificationOutputSchema.parse({
34
+ changeId,
35
+ verdict,
36
+ evidence,
37
+ confidence,
38
+ summary
39
+ });
40
+ if (![
41
+ "running",
42
+ "succeeded",
43
+ "failed"
44
+ ].includes(task.state)) throw new Error("Task execution is missing, inactive, or replaced");
45
+ const saved = await stores.signals.getByDelivery(verificationDelivery(task));
46
+ if (saved) {
47
+ const recorded = z.object({ output: verificationOutputSchema }).parse(saved.payload).output;
48
+ if (!isDeepStrictEqual(recorded, output)) throw new Error("This verification attempt already recorded a different result");
49
+ const result = await applyVerificationReport(stores, saved);
50
+ if (result.recorded) await options.presentResult?.({
51
+ taskId,
52
+ changeId,
53
+ verdict,
54
+ summary
55
+ });
56
+ return result;
57
+ }
58
+ await requireTaskExecution(stores, ctx, taskId);
59
+ const change = await stores.changes.get(changeId);
60
+ if (change === null) return {
61
+ recorded: false,
62
+ reason: `change ${changeId} does not exist`
63
+ };
64
+ if (change.state !== "verifying" && change.state !== "ready") return {
65
+ recorded: false,
66
+ reason: `change is ${change.state}, not open for verification; nothing to record`
67
+ };
68
+ const parent = task.parentTaskId === void 0 ? null : await stores.tasks.get(task.parentTaskId);
69
+ if (task.changeId !== changeId || parent === null || parent.changeId !== changeId || parent.state !== "verifying" || parent.attempt !== verificationParentAttempt(task) || task.rootTaskId !== parent.rootTaskId || task.repositoryIds.length !== 1 || task.repositoryIds[0] !== change.repositoryId || parent.repositoryIds.length !== 1 || parent.repositoryIds[0] !== change.repositoryId) return {
70
+ recorded: false,
71
+ reason: "Verification Task, parent, Change, and repository must match"
72
+ };
73
+ await requireTaskExecution(stores, ctx, taskId);
74
+ const report = await saveVerificationReport(stores, task, output);
75
+ const result = await applyVerificationReport(stores, report);
76
+ if (result.recorded) await options.presentResult?.({
77
+ taskId,
78
+ changeId,
79
+ verdict,
80
+ summary
81
+ });
82
+ return result;
83
+ }
84
+ });
85
+ }
86
+ //#endregion
87
+ export { createRecordVerificationTool };
88
+
89
+ //# sourceMappingURL=eve-tool.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eve-tool.mjs","names":[],"sources":["../../src/change-verification/eve-tool.ts"],"sourcesContent":["import { defineTool, type ToolContext, type ToolDefinition } from \"eve/tools\";\nimport { z } from \"zod\";\nimport {\n changeEvidenceSchema,\n changeLevelSchema,\n type ChangeEvidence,\n type ChangeLevel,\n type ChangeState,\n} from \"../schema/change\";\nimport { changeIdSchema, taskIdSchema } from \"../schema/id\";\nimport type { ChangeId, TaskId } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\nimport { requireTaskExecution, requireTaskExecutionIdentity } from \"../eve/task-execution\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport {\n applyVerificationReport,\n saveVerificationReport,\n verificationDelivery,\n verificationOutputSchema,\n verificationParentAttempt,\n} from \"./result\";\n\n/** Change and Task capabilities required by the verification-result tool. */\nexport type RecordVerificationToolStores = Pick<FactoryStores, \"changes\" | \"tasks\" | \"signals\">;\n\n/** Verified outcome presented after its Task and Change updates commit. */\nexport interface PresentVerificationResultInput {\n taskId: TaskId;\n changeId: ChangeId;\n verdict: \"pass\" | \"fail\";\n summary: string;\n}\n\n/** Configures presentation after a verification verdict has been durably recorded. */\nexport interface RecordVerificationToolOptions {\n /** Idempotent delivery, retried with the saved verdict after interrupted completion. */\n presentResult?: (input: PresentVerificationResultInput) => Promise<void>;\n}\n\n/** Evidence and verdict supplied by the verifier for one Change. */\nexport interface RecordVerificationInput {\n taskId: TaskId;\n changeId: ChangeId;\n verdict: \"pass\" | \"fail\";\n evidence: ChangeEvidence;\n confidence: ChangeLevel;\n summary: string;\n}\n\n/** Bounded refusal returned when a verification result cannot be associated safely. */\nexport interface RecordVerificationRefusal {\n readonly recorded: false;\n readonly reason: string;\n}\n\n/** Durable lifecycle state returned after a verification verdict is recorded. */\nexport interface RecordVerificationSuccess {\n readonly recorded: true;\n readonly verdict: \"pass\" | \"fail\";\n readonly changeState: ChangeState;\n readonly taskState: \"succeeded\" | \"failed\";\n}\n\n/** Recorded verification state or bounded association refusal. */\nexport type RecordVerificationResult = RecordVerificationRefusal | RecordVerificationSuccess;\n\n/** Eve outcome tool that records evidence and a verdict for one Change. */\nexport interface RecordVerificationTool extends ToolDefinition<\n RecordVerificationInput,\n RecordVerificationResult\n> {\n execute(input: RecordVerificationInput, ctx: ToolContext): Promise<RecordVerificationResult>;\n}\n\n/**\n * The verifier's outcome tool. Writes evidence onto the change and moves it\n * to ready only when the verdict is pass; a failed verdict leaves the change\n * verifying with the evidence recorded, and the verification task itself\n * ends with a receipt either way. The change's own code_change task follows\n * the verdict too: succeeded on pass, failed on fail with the verifier's\n * summary as the reason, so the ledger never shows a verified-and-rejected fix\n * as still in progress. Fail closed: the agent cannot mark a change ready\n * without supplying every evidence field. Requires the authenticated current\n * Task execution and matching parent, Change, and repository associations.\n */\nexport function createRecordVerificationTool(\n stores: RecordVerificationToolStores,\n options: RecordVerificationToolOptions = {},\n): RecordVerificationTool {\n return defineTool({\n description:\n \"Record the outcome of a verification task: the evidence you gathered and whether the change passed. Pass moves the change to ready for human review; fail keeps it out of review.\",\n inputSchema: z.object({\n taskId: taskIdSchema.describe(\"Your verification task.\"),\n changeId: changeIdSchema.describe(\"The change you verified.\"),\n verdict: z.enum([\"pass\", \"fail\"]),\n evidence: changeEvidenceSchema,\n confidence: changeLevelSchema.describe(\"How certain you are in the verdict.\"),\n summary: z.string().min(1).max(2000).describe(\"What you checked and what you found.\"),\n }),\n async execute(\n { taskId, changeId, verdict, evidence, confidence, summary },\n ctx,\n ): Promise<RecordVerificationResult> {\n const task = await requireTaskExecutionIdentity(stores, ctx, taskId);\n const output = verificationOutputSchema.parse({\n changeId,\n verdict,\n evidence,\n confidence,\n summary,\n });\n if (![\"running\", \"succeeded\", \"failed\"].includes(task.state))\n throw new Error(\"Task execution is missing, inactive, or replaced\");\n const saved = await stores.signals.getByDelivery(verificationDelivery(task));\n if (saved) {\n const recorded = z.object({ output: verificationOutputSchema }).parse(saved.payload).output;\n if (!isDeepStrictEqual(recorded, output))\n throw new Error(\"This verification attempt already recorded a different result\");\n const result = await applyVerificationReport(stores, saved);\n if (result.recorded) await options.presentResult?.({ taskId, changeId, verdict, summary });\n return result;\n }\n await requireTaskExecution(stores, ctx, taskId);\n const change = await stores.changes.get(changeId);\n if (change === null) {\n return { recorded: false as const, reason: `change ${changeId} does not exist` };\n }\n if (change.state !== \"verifying\" && change.state !== \"ready\") {\n return {\n recorded: false as const,\n reason: `change is ${change.state}, not open for verification; nothing to record`,\n };\n }\n\n const parent =\n task.parentTaskId === undefined ? null : await stores.tasks.get(task.parentTaskId);\n if (\n task.changeId !== changeId ||\n parent === null ||\n parent.changeId !== changeId ||\n parent.state !== \"verifying\" ||\n parent.attempt !== verificationParentAttempt(task) ||\n task.rootTaskId !== parent.rootTaskId ||\n task.repositoryIds.length !== 1 ||\n task.repositoryIds[0] !== change.repositoryId ||\n parent.repositoryIds.length !== 1 ||\n parent.repositoryIds[0] !== change.repositoryId\n ) {\n return {\n recorded: false as const,\n reason: \"Verification Task, parent, Change, and repository must match\",\n };\n }\n\n await requireTaskExecution(stores, ctx, taskId);\n\n const report = await saveVerificationReport(stores, task, output);\n const result = await applyVerificationReport(stores, report);\n if (result.recorded) await options.presentResult?.({ taskId, changeId, verdict, summary });\n return result;\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqFA,SAAgB,6BACd,QACA,UAAyC,CAAC,GAClB;CACxB,OAAO,WAAW;EAChB,aACE;EACF,aAAa,EAAE,OAAO;GACpB,QAAQ,aAAa,SAAS,yBAAyB;GACvD,UAAU,eAAe,SAAS,0BAA0B;GAC5D,SAAS,EAAE,KAAK,CAAC,QAAQ,MAAM,CAAC;GAChC,UAAU;GACV,YAAY,kBAAkB,SAAS,qCAAqC;GAC5E,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAI,CAAC,CAAC,SAAS,sCAAsC;EACtF,CAAC;EACD,MAAM,QACJ,EAAE,QAAQ,UAAU,SAAS,UAAU,YAAY,WACnD,KACmC;GACnC,MAAM,OAAO,MAAM,6BAA6B,QAAQ,KAAK,MAAM;GACnE,MAAM,SAAS,yBAAyB,MAAM;IAC5C;IACA;IACA;IACA;IACA;GACF,CAAC;GACD,IAAI,CAAC;IAAC;IAAW;IAAa;GAAQ,CAAC,CAAC,SAAS,KAAK,KAAK,GACzD,MAAM,IAAI,MAAM,kDAAkD;GACpE,MAAM,QAAQ,MAAM,OAAO,QAAQ,cAAc,qBAAqB,IAAI,CAAC;GAC3E,IAAI,OAAO;IACT,MAAM,WAAW,EAAE,OAAO,EAAE,QAAQ,yBAAyB,CAAC,CAAC,CAAC,MAAM,MAAM,OAAO,CAAC,CAAC;IACrF,IAAI,CAAC,kBAAkB,UAAU,MAAM,GACrC,MAAM,IAAI,MAAM,+DAA+D;IACjF,MAAM,SAAS,MAAM,wBAAwB,QAAQ,KAAK;IAC1D,IAAI,OAAO,UAAU,MAAM,QAAQ,gBAAgB;KAAE;KAAQ;KAAU;KAAS;IAAQ,CAAC;IACzF,OAAO;GACT;GACA,MAAM,qBAAqB,QAAQ,KAAK,MAAM;GAC9C,MAAM,SAAS,MAAM,OAAO,QAAQ,IAAI,QAAQ;GAChD,IAAI,WAAW,MACb,OAAO;IAAE,UAAU;IAAgB,QAAQ,UAAU,SAAS;GAAiB;GAEjF,IAAI,OAAO,UAAU,eAAe,OAAO,UAAU,SACnD,OAAO;IACL,UAAU;IACV,QAAQ,aAAa,OAAO,MAAM;GACpC;GAGF,MAAM,SACJ,KAAK,iBAAiB,KAAA,IAAY,OAAO,MAAM,OAAO,MAAM,IAAI,KAAK,YAAY;GACnF,IACE,KAAK,aAAa,YAClB,WAAW,QACX,OAAO,aAAa,YACpB,OAAO,UAAU,eACjB,OAAO,YAAY,0BAA0B,IAAI,KACjD,KAAK,eAAe,OAAO,cAC3B,KAAK,cAAc,WAAW,KAC9B,KAAK,cAAc,OAAO,OAAO,gBACjC,OAAO,cAAc,WAAW,KAChC,OAAO,cAAc,OAAO,OAAO,cAEnC,OAAO;IACL,UAAU;IACV,QAAQ;GACV;GAGF,MAAM,qBAAqB,QAAQ,KAAK,MAAM;GAE9C,MAAM,SAAS,MAAM,uBAAuB,QAAQ,MAAM,MAAM;GAChE,MAAM,SAAS,MAAM,wBAAwB,QAAQ,MAAM;GAC3D,IAAI,OAAO,UAAU,MAAM,QAAQ,gBAAgB;IAAE;IAAQ;IAAU;IAAS;GAAQ,CAAC;GACzF,OAAO;EACT;CACF,CAAC;AACH"}
@@ -0,0 +1,130 @@
1
+ import { changeIdSchema, taskIdSchema } from "../schema/id.mjs";
2
+ import { executionReferenceSchema } from "../schema/task.mjs";
3
+ import { changeEvidenceSchema, changeLevelSchema } from "../schema/change.mjs";
4
+ import { z } from "zod";
5
+ import { isDeepStrictEqual } from "node:util";
6
+ //#region src/change-verification/result.ts
7
+ const verificationOutputSchema = z.object({
8
+ changeId: changeIdSchema,
9
+ verdict: z.enum(["pass", "fail"]),
10
+ evidence: changeEvidenceSchema,
11
+ confidence: changeLevelSchema,
12
+ summary: z.string().min(1).max(2e3)
13
+ });
14
+ const verificationReportSchema = z.object({
15
+ taskId: taskIdSchema,
16
+ attempt: z.number().int().positive(),
17
+ execution: executionReferenceSchema,
18
+ parentTaskId: taskIdSchema,
19
+ parentAttempt: z.number().int().positive(),
20
+ output: verificationOutputSchema
21
+ });
22
+ function verificationParentAttempt(task) {
23
+ return z.object({ parentAttempt: z.number().int().positive().default(1) }).parse(task.work.input).parentAttempt;
24
+ }
25
+ function verificationDelivery(task) {
26
+ return {
27
+ source: "change_verification",
28
+ deliveryId: `${task.id}:${task.attempt}`
29
+ };
30
+ }
31
+ async function saveVerificationReport(stores, task, output) {
32
+ const payload = verificationReportSchema.parse({
33
+ taskId: task.id,
34
+ attempt: task.attempt,
35
+ execution: task.execution,
36
+ parentTaskId: task.parentTaskId,
37
+ parentAttempt: verificationParentAttempt(task),
38
+ output
39
+ });
40
+ const report = await stores.signals.create({
41
+ ...verificationDelivery(task),
42
+ repositoryId: task.repositoryIds[0],
43
+ replyTo: task.replyTo,
44
+ payload
45
+ });
46
+ if (report.repositoryId !== task.repositoryIds[0] || !isDeepStrictEqual(report.payload, payload)) throw new Error("This verification attempt already recorded a different result");
47
+ return report;
48
+ }
49
+ async function applyVerificationReport(stores, report) {
50
+ const saved = verificationReportSchema.parse(report.payload);
51
+ const task = await stores.tasks.get(saved.taskId);
52
+ const parent = await stores.tasks.get(saved.parentTaskId);
53
+ const { output } = saved;
54
+ const terminal = output.verdict === "pass" ? "succeeded" : "failed";
55
+ const change = await stores.changes.get(output.changeId);
56
+ if (report.source !== "change_verification" || !task || !parent || !change || report.deliveryId !== verificationDelivery(task).deliveryId || task.attempt !== saved.attempt || !isDeepStrictEqual(task.execution, saved.execution) || task.parentTaskId !== parent.id || verificationParentAttempt(task) !== saved.parentAttempt || parent.attempt !== saved.parentAttempt || task.rootTaskId !== parent.rootTaskId || task.changeId !== change.id || parent.changeId !== change.id || task.repositoryIds.length !== 1 || parent.repositoryIds.length !== 1 || task.repositoryIds[0] !== change.repositoryId || parent.repositoryIds[0] !== change.repositoryId || report.repositoryId !== change.repositoryId || task.state !== "running" && !(task.state === terminal && task.reportRef === report.id) || parent.state !== "verifying" && !(parent.state === terminal && parent.reportRef === report.id)) return {
57
+ recorded: false,
58
+ reason: "Verification result no longer belongs to the current Task and producer attempt"
59
+ };
60
+ let updatedChange = change;
61
+ if (task.state === "running") {
62
+ if (parent.state !== "verifying" || !["verifying", "ready"].includes(change.state)) return {
63
+ recorded: false,
64
+ reason: "Change and producer are no longer open for verification"
65
+ };
66
+ const target = output.verdict === "pass" ? "ready" : "verifying";
67
+ if (change.state !== target) updatedChange = await stores.changes.transition(change.id, target, {
68
+ reason: output.summary,
69
+ patch: {
70
+ evidence: output.evidence,
71
+ confidence: output.confidence
72
+ }
73
+ });
74
+ if (!isDeepStrictEqual(updatedChange.evidence, output.evidence) || updatedChange.confidence !== output.confidence) updatedChange = await stores.changes.updateEvidence(change.id, {
75
+ evidence: output.evidence,
76
+ confidence: output.confidence,
77
+ expected: updatedChange
78
+ });
79
+ const fence = {
80
+ expectFrom: "running",
81
+ expectAttempt: saved.attempt,
82
+ expectExecution: saved.execution,
83
+ patch: { reportRef: report.id },
84
+ phase: "verification"
85
+ };
86
+ if (output.verdict === "pass") await stores.tasks.transition(task.id, "succeeded", {
87
+ ...fence,
88
+ output
89
+ });
90
+ else await stores.tasks.transition(task.id, "failed", {
91
+ ...fence,
92
+ reason: output.summary
93
+ });
94
+ }
95
+ if (parent.state === "verifying") {
96
+ const fence = {
97
+ expectFrom: "verifying",
98
+ expectAttempt: saved.parentAttempt,
99
+ expectExecution: parent.execution,
100
+ patch: { reportRef: report.id },
101
+ phase: "verification"
102
+ };
103
+ if (output.verdict === "pass") await stores.tasks.transition(parent.id, "succeeded", {
104
+ ...fence,
105
+ output
106
+ });
107
+ else await stores.tasks.transition(parent.id, "failed", {
108
+ ...fence,
109
+ reason: `verification failed: ${output.summary}`
110
+ });
111
+ }
112
+ if (report.outcome === "pending") try {
113
+ await stores.signals.decide(report.id, {
114
+ outcome: "accepted",
115
+ reason: "Verification outcome applied"
116
+ });
117
+ } catch (error) {
118
+ if ((await stores.signals.get(report.id))?.outcome !== "accepted") throw error;
119
+ }
120
+ return {
121
+ recorded: true,
122
+ verdict: output.verdict,
123
+ changeState: updatedChange.state,
124
+ taskState: terminal
125
+ };
126
+ }
127
+ //#endregion
128
+ export { applyVerificationReport, saveVerificationReport, verificationDelivery, verificationOutputSchema, verificationParentAttempt, verificationReportSchema };
129
+
130
+ //# sourceMappingURL=result.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.mjs","names":[],"sources":["../../src/change-verification/result.ts"],"sourcesContent":["import { isDeepStrictEqual } from \"node:util\";\nimport { z } from \"zod\";\nimport { changeEvidenceSchema, changeLevelSchema } from \"../schema/change\";\nimport { changeIdSchema, taskIdSchema } from \"../schema/id\";\nimport type { Signal } from \"../schema/signal\";\nimport { executionReferenceSchema, type Task } from \"../schema/task\";\nimport type { FactoryStores } from \"../store/engine\";\nimport type { RecordVerificationResult } from \"./eve-tool\";\n\nexport const verificationOutputSchema = z.object({\n changeId: changeIdSchema,\n verdict: z.enum([\"pass\", \"fail\"]),\n evidence: changeEvidenceSchema,\n confidence: changeLevelSchema,\n summary: z.string().min(1).max(2000),\n});\n\nexport const verificationReportSchema = z.object({\n taskId: taskIdSchema,\n attempt: z.number().int().positive(),\n execution: executionReferenceSchema,\n parentTaskId: taskIdSchema,\n parentAttempt: z.number().int().positive(),\n output: verificationOutputSchema,\n});\n\ntype Stores = Pick<FactoryStores, \"tasks\" | \"changes\" | \"signals\">;\n\nexport function verificationParentAttempt(task: Task): number {\n // Pre-binding verification Tasks only authorize the initial producer attempt.\n return z.object({ parentAttempt: z.number().int().positive().default(1) }).parse(task.work.input)\n .parentAttempt;\n}\n\nexport function verificationDelivery(task: Task) {\n return { source: \"change_verification\", deliveryId: `${task.id}:${task.attempt}` };\n}\n\nexport async function saveVerificationReport(\n stores: Stores,\n task: Task,\n output: z.infer<typeof verificationOutputSchema>,\n) {\n const payload = verificationReportSchema.parse({\n taskId: task.id,\n attempt: task.attempt,\n execution: task.execution,\n parentTaskId: task.parentTaskId,\n parentAttempt: verificationParentAttempt(task),\n output,\n });\n const report = await stores.signals.create({\n ...verificationDelivery(task),\n repositoryId: task.repositoryIds[0]!,\n replyTo: task.replyTo,\n payload,\n });\n if (report.repositoryId !== task.repositoryIds[0] || !isDeepStrictEqual(report.payload, payload))\n throw new Error(\"This verification attempt already recorded a different result\");\n return report;\n}\n\nexport async function applyVerificationReport(\n stores: Stores,\n report: Signal,\n): Promise<RecordVerificationResult> {\n const saved = verificationReportSchema.parse(report.payload);\n const task = await stores.tasks.get(saved.taskId);\n const parent = await stores.tasks.get(saved.parentTaskId);\n const { output } = saved;\n const terminal = output.verdict === \"pass\" ? \"succeeded\" : \"failed\";\n const change = await stores.changes.get(output.changeId);\n if (\n report.source !== \"change_verification\" ||\n !task ||\n !parent ||\n !change ||\n report.deliveryId !== verificationDelivery(task).deliveryId ||\n task.attempt !== saved.attempt ||\n !isDeepStrictEqual(task.execution, saved.execution) ||\n task.parentTaskId !== parent.id ||\n verificationParentAttempt(task) !== saved.parentAttempt ||\n parent.attempt !== saved.parentAttempt ||\n task.rootTaskId !== parent.rootTaskId ||\n task.changeId !== change.id ||\n parent.changeId !== change.id ||\n task.repositoryIds.length !== 1 ||\n parent.repositoryIds.length !== 1 ||\n task.repositoryIds[0] !== change.repositoryId ||\n parent.repositoryIds[0] !== change.repositoryId ||\n report.repositoryId !== change.repositoryId ||\n (task.state !== \"running\" && !(task.state === terminal && task.reportRef === report.id)) ||\n (parent.state !== \"verifying\" && !(parent.state === terminal && parent.reportRef === report.id))\n )\n return {\n recorded: false,\n reason: \"Verification result no longer belongs to the current Task and producer attempt\",\n };\n\n let updatedChange = change;\n if (task.state === \"running\") {\n if (parent.state !== \"verifying\" || ![\"verifying\", \"ready\"].includes(change.state))\n return { recorded: false, reason: \"Change and producer are no longer open for verification\" };\n const target = output.verdict === \"pass\" ? \"ready\" : \"verifying\";\n if (change.state !== target)\n updatedChange = await stores.changes.transition(change.id, target, {\n reason: output.summary,\n patch: { evidence: output.evidence, confidence: output.confidence },\n });\n if (\n !isDeepStrictEqual(updatedChange.evidence, output.evidence) ||\n updatedChange.confidence !== output.confidence\n )\n updatedChange = await stores.changes.updateEvidence(change.id, {\n evidence: output.evidence,\n confidence: output.confidence,\n expected: updatedChange,\n });\n const fence = {\n expectFrom: \"running\" as const,\n expectAttempt: saved.attempt,\n expectExecution: saved.execution,\n patch: { reportRef: report.id },\n phase: \"verification\",\n };\n if (output.verdict === \"pass\")\n await stores.tasks.transition(task.id, \"succeeded\", { ...fence, output });\n else await stores.tasks.transition(task.id, \"failed\", { ...fence, reason: output.summary });\n }\n if (parent.state === \"verifying\") {\n const fence = {\n expectFrom: \"verifying\" as const,\n expectAttempt: saved.parentAttempt,\n expectExecution: parent.execution,\n patch: { reportRef: report.id },\n phase: \"verification\",\n };\n if (output.verdict === \"pass\")\n await stores.tasks.transition(parent.id, \"succeeded\", { ...fence, output });\n else\n await stores.tasks.transition(parent.id, \"failed\", {\n ...fence,\n reason: `verification failed: ${output.summary}`,\n });\n }\n if (report.outcome === \"pending\") {\n try {\n await stores.signals.decide(report.id, {\n outcome: \"accepted\",\n reason: \"Verification outcome applied\",\n });\n } catch (error) {\n if ((await stores.signals.get(report.id))?.outcome !== \"accepted\") throw error;\n }\n }\n return {\n recorded: true,\n verdict: output.verdict,\n changeState: updatedChange.state,\n taskState: terminal,\n };\n}\n"],"mappings":"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"}