@velum-labs/routekit-eval-setup 1.4.0 → 1.5.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 (341) hide show
  1. package/dist/adapters/authoring-responses-request.d.ts +5 -0
  2. package/dist/adapters/authoring-responses-request.js +38 -0
  3. package/dist/adapters/evaluation-evidence-freshness.d.ts +7 -0
  4. package/dist/adapters/evaluation-evidence-freshness.js +76 -0
  5. package/dist/adapters/git-task-history.d.ts +67 -0
  6. package/dist/adapters/git-task-history.js +171 -0
  7. package/dist/adapters/integrated-repository-history.d.ts +21 -0
  8. package/dist/adapters/integrated-repository-history.js +175 -0
  9. package/dist/adapters/repository-command-diagnostic.d.ts +8 -0
  10. package/dist/adapters/repository-command-diagnostic.js +46 -0
  11. package/dist/adapters/repository-command-evidence.d.ts +13 -0
  12. package/dist/adapters/repository-command-evidence.js +102 -0
  13. package/dist/adapters/repository-command-runner.d.ts +238 -0
  14. package/dist/adapters/repository-command-runner.js +1483 -0
  15. package/dist/adapters/repository-import-context.d.ts +47 -0
  16. package/dist/adapters/repository-import-context.js +469 -0
  17. package/dist/adapters/repository-node-test-reporter.d.ts +3 -0
  18. package/dist/adapters/repository-node-test-reporter.js +27 -0
  19. package/dist/adapters/repository-review-evidence.d.ts +39 -0
  20. package/dist/adapters/repository-review-evidence.js +632 -0
  21. package/dist/adapters/repository-seed-selection.d.ts +7 -0
  22. package/dist/adapters/repository-seed-selection.js +79 -0
  23. package/dist/adapters/repository-solution-edits.d.ts +49 -0
  24. package/dist/adapters/repository-solution-edits.js +136 -0
  25. package/dist/adapters/repository-vitest-phase-adapter.d.ts +8 -0
  26. package/dist/adapters/repository-vitest-phase-adapter.js +310 -0
  27. package/dist/adapters/repository-vitest-reporter.d.ts +24 -0
  28. package/dist/adapters/repository-vitest-reporter.js +314 -0
  29. package/dist/adapters/strict-authoring-schema.d.ts +5 -0
  30. package/dist/adapters/strict-authoring-schema.js +158 -0
  31. package/dist/adapters/test-discovery.d.ts +30 -0
  32. package/dist/adapters/test-discovery.js +124 -0
  33. package/dist/adapters/typescript-repository-index.d.ts +51 -0
  34. package/dist/adapters/typescript-repository-index.js +226 -0
  35. package/dist/agentic-capabilities-protocol.d.ts +1373 -0
  36. package/dist/agentic-capabilities-protocol.js +786 -0
  37. package/dist/case-checkpoint-store.d.ts +29 -0
  38. package/dist/case-checkpoint-store.js +133 -0
  39. package/dist/case-pipeline-protocol-v2.d.ts +184 -0
  40. package/dist/case-pipeline-protocol-v2.js +193 -0
  41. package/dist/case-pipeline-protocol.d.ts +2626 -0
  42. package/dist/case-pipeline-protocol.js +371 -0
  43. package/dist/effect-api.d.ts +74 -12
  44. package/dist/effect-api.js +56 -7
  45. package/dist/errors.d.ts +31 -0
  46. package/dist/errors.js +10 -0
  47. package/dist/eval-capability-execution-envelope.d.ts +64 -0
  48. package/dist/eval-capability-execution-envelope.js +98 -0
  49. package/dist/eval-capability-policy.d.ts +90 -0
  50. package/dist/eval-capability-policy.js +107 -0
  51. package/dist/eval-event-log.d.ts +51 -0
  52. package/dist/eval-event-log.js +69 -10
  53. package/dist/evaluation-authoring-policy.d.ts +18 -0
  54. package/dist/evaluation-authoring-policy.js +19 -0
  55. package/dist/evaluation-authoring-validation.d.ts +22 -0
  56. package/dist/evaluation-authoring-validation.js +72 -0
  57. package/dist/evaluation-evidence.d.ts +20 -0
  58. package/dist/evaluation-evidence.js +319 -0
  59. package/dist/evaluation-grader-calibration-protocol.d.ts +108 -0
  60. package/dist/evaluation-grader-calibration-protocol.js +80 -0
  61. package/dist/evaluation-grader-calibration.d.ts +18 -0
  62. package/dist/evaluation-grader-calibration.js +334 -0
  63. package/dist/evaluation-grading-policy.d.ts +24 -0
  64. package/dist/evaluation-grading-policy.js +54 -0
  65. package/dist/evaluation-proposal-policy.d.ts +4 -0
  66. package/dist/evaluation-proposal-policy.js +91 -0
  67. package/dist/evaluation-source-retrieval.d.ts +68 -0
  68. package/dist/evaluation-source-retrieval.js +513 -0
  69. package/dist/evaluation-structure-policy.d.ts +29 -0
  70. package/dist/evaluation-structure-policy.js +138 -0
  71. package/dist/index.d.ts +124 -19
  72. package/dist/index.js +69 -12
  73. package/dist/inspection.js +2 -3
  74. package/dist/project-artifacts.d.ts +2 -2
  75. package/dist/project-artifacts.js +26 -121
  76. package/dist/project-authoring.d.ts +66 -5
  77. package/dist/project-authoring.js +783 -109
  78. package/dist/project-contracts.d.ts +292 -82
  79. package/dist/project-contracts.js +65 -7
  80. package/dist/project-store.js +2 -1
  81. package/dist/project-workflow.d.ts +3 -3
  82. package/dist/project-workflow.js +116 -18
  83. package/dist/repository-adversary-protocol.d.ts +64 -0
  84. package/dist/repository-adversary-protocol.js +105 -0
  85. package/dist/repository-behavior-protocol.d.ts +188 -0
  86. package/dist/repository-behavior-protocol.js +202 -0
  87. package/dist/repository-benchmark-protocol.d.ts +487 -0
  88. package/dist/repository-benchmark-protocol.js +96 -0
  89. package/dist/repository-execution-protocol.d.ts +150 -0
  90. package/dist/repository-execution-protocol.js +38 -0
  91. package/dist/repository-fixture-instructions.d.ts +3 -0
  92. package/dist/repository-fixture-instructions.js +91 -0
  93. package/dist/repository-fixture-protocol.d.ts +79 -0
  94. package/dist/repository-fixture-protocol.js +79 -0
  95. package/dist/repository-foundry-plan-protocol.d.ts +118 -0
  96. package/dist/repository-foundry-plan-protocol.js +296 -0
  97. package/dist/repository-foundry-progress-protocol.d.ts +52 -0
  98. package/dist/repository-foundry-progress-protocol.js +52 -0
  99. package/dist/repository-improvement-protocol.d.ts +100 -0
  100. package/dist/repository-improvement-protocol.js +106 -0
  101. package/dist/repository-language-model-protocol.d.ts +43 -0
  102. package/dist/repository-language-model-protocol.js +146 -0
  103. package/dist/repository-oracle-coverage-protocol.d.ts +18 -0
  104. package/dist/repository-oracle-coverage-protocol.js +39 -0
  105. package/dist/repository-oracle-execution-binding.d.ts +27 -0
  106. package/dist/repository-oracle-execution-binding.js +59 -0
  107. package/dist/repository-oracle-protocol.d.ts +230 -0
  108. package/dist/repository-oracle-protocol.js +156 -0
  109. package/dist/repository-oracle-scope-policy.d.ts +22 -0
  110. package/dist/repository-oracle-scope-policy.js +92 -0
  111. package/dist/repository-quality-policy.d.ts +15 -0
  112. package/dist/repository-quality-policy.js +357 -0
  113. package/dist/repository-routing-benchmark-protocol.d.ts +176 -0
  114. package/dist/repository-routing-benchmark-protocol.js +103 -0
  115. package/dist/repository-routing-model-protocol.d.ts +36 -0
  116. package/dist/repository-routing-model-protocol.js +89 -0
  117. package/dist/repository-routing-plan-protocol.d.ts +112 -0
  118. package/dist/repository-routing-plan-protocol.js +58 -0
  119. package/dist/repository-routing-quality-policy.d.ts +9 -0
  120. package/dist/repository-routing-quality-policy.js +191 -0
  121. package/dist/repository-seed-qualification-progress-protocol.d.ts +205 -0
  122. package/dist/repository-seed-qualification-progress-protocol.js +28 -0
  123. package/dist/repository-semantic-calibration-protocol.d.ts +768 -0
  124. package/dist/repository-semantic-calibration-protocol.js +276 -0
  125. package/dist/repository-semantic-calibration.d.ts +163 -0
  126. package/dist/repository-semantic-calibration.js +581 -0
  127. package/dist/repository-specification-contract-facts-protocol.d.ts +224 -0
  128. package/dist/repository-specification-contract-facts-protocol.js +276 -0
  129. package/dist/repository-specification-critique-protocol.d.ts +189 -0
  130. package/dist/repository-specification-critique-protocol.js +103 -0
  131. package/dist/repository-task-family-protocol.d.ts +24 -0
  132. package/dist/repository-task-family-protocol.js +37 -0
  133. package/dist/repository-task-seed-protocol.d.ts +384 -0
  134. package/dist/repository-task-seed-protocol.js +236 -0
  135. package/dist/repository-trajectory-protocol.d.ts +20 -0
  136. package/dist/repository-trajectory-protocol.js +42 -0
  137. package/dist/service.js +1 -1
  138. package/dist/services/adversary/service.d.ts +64 -0
  139. package/dist/services/adversary/service.js +330 -0
  140. package/dist/services/benchmark-compiler/service.d.ts +450 -0
  141. package/dist/services/benchmark-compiler/service.js +9 -0
  142. package/dist/services/budgeted-model/service.d.ts +118 -0
  143. package/dist/services/budgeted-model/service.js +460 -0
  144. package/dist/services/case-authoring/service.d.ts +163 -0
  145. package/dist/services/case-authoring/service.js +1456 -0
  146. package/dist/services/case-finalization/service.d.ts +283 -0
  147. package/dist/services/case-finalization/service.js +370 -0
  148. package/dist/services/case-generation/service.d.ts +619 -0
  149. package/dist/services/case-generation/service.js +2628 -0
  150. package/dist/services/case-pipeline/service.d.ts +31 -0
  151. package/dist/services/case-pipeline/service.js +485 -0
  152. package/dist/services/case-pipeline-v2/service.d.ts +70 -0
  153. package/dist/services/case-pipeline-v2/service.js +477 -0
  154. package/dist/services/command-observability/service.d.ts +13 -0
  155. package/dist/services/command-observability/service.js +3 -0
  156. package/dist/services/dimension-labeling/service.d.ts +77 -0
  157. package/dist/services/dimension-labeling/service.js +188 -0
  158. package/dist/services/eval-candidate/service.d.ts +208 -0
  159. package/dist/services/eval-candidate/service.js +64 -0
  160. package/dist/services/eval-capabilities/service.d.ts +183 -0
  161. package/dist/services/eval-capabilities/service.js +1433 -0
  162. package/dist/services/eval-environment/service.d.ts +173 -0
  163. package/dist/services/eval-environment/service.js +127 -0
  164. package/dist/services/evidence-reconstruction/service.d.ts +36 -0
  165. package/dist/services/evidence-reconstruction/service.js +145 -0
  166. package/dist/services/fixture-builder/service.d.ts +62 -0
  167. package/dist/services/fixture-builder/service.js +36 -0
  168. package/dist/services/fixture-validation/service.d.ts +75 -0
  169. package/dist/services/fixture-validation/service.js +295 -0
  170. package/dist/services/foundry/service.d.ts +831 -0
  171. package/dist/services/foundry/service.js +442 -0
  172. package/dist/services/foundry-progress/service.d.ts +62 -0
  173. package/dist/services/foundry-progress/service.js +149 -0
  174. package/dist/services/foundry-v2/service.d.ts +54 -0
  175. package/dist/services/foundry-v2/service.js +28 -0
  176. package/dist/services/grounded-authoring/service.d.ts +126 -0
  177. package/dist/services/grounded-authoring/service.js +822 -0
  178. package/dist/services/historical-case/service.d.ts +722 -0
  179. package/dist/services/historical-case/service.js +177 -0
  180. package/dist/services/improvement-loop/service.d.ts +59 -0
  181. package/dist/services/improvement-loop/service.js +176 -0
  182. package/dist/services/language-model/service.d.ts +52 -0
  183. package/dist/services/language-model/service.js +194 -0
  184. package/dist/services/oracle-builder/service.d.ts +146 -0
  185. package/dist/services/oracle-builder/service.js +513 -0
  186. package/dist/services/oracle-coverage/service.d.ts +28 -0
  187. package/dist/services/oracle-coverage/service.js +50 -0
  188. package/dist/services/oracle-coverage-witness/service.d.ts +130 -0
  189. package/dist/services/oracle-coverage-witness/service.js +538 -0
  190. package/dist/services/pipeline-challenge/service.d.ts +551 -0
  191. package/dist/services/pipeline-challenge/service.js +427 -0
  192. package/dist/services/pipeline-controls/service.d.ts +130 -0
  193. package/dist/services/pipeline-controls/service.js +483 -0
  194. package/dist/services/pipeline-oracle/service.d.ts +8 -0
  195. package/dist/services/pipeline-oracle/service.js +256 -0
  196. package/dist/services/pipeline-seed/service.d.ts +298 -0
  197. package/dist/services/pipeline-seed/service.js +428 -0
  198. package/dist/services/pipeline-spec/service.d.ts +103 -0
  199. package/dist/services/pipeline-spec/service.js +619 -0
  200. package/dist/services/pipeline-tournament/service.d.ts +258 -0
  201. package/dist/services/pipeline-tournament/service.js +476 -0
  202. package/dist/services/quality-gate/service.d.ts +233 -0
  203. package/dist/services/quality-gate/service.js +136 -0
  204. package/dist/services/repository-bundle/service.d.ts +33 -0
  205. package/dist/services/repository-bundle/service.js +114 -0
  206. package/dist/services/repository-model/service.d.ts +105 -0
  207. package/dist/services/repository-model/service.js +250 -0
  208. package/dist/services/repository-public-artifact/service.d.ts +133 -0
  209. package/dist/services/repository-public-artifact/service.js +330 -0
  210. package/dist/services/routing-benchmark/service.d.ts +362 -0
  211. package/dist/services/routing-benchmark/service.js +96 -0
  212. package/dist/services/specification-critic/service.d.ts +92 -0
  213. package/dist/services/specification-critic/service.js +172 -0
  214. package/dist/services/task-family/service.d.ts +40 -0
  215. package/dist/services/task-family/service.js +55 -0
  216. package/dist/services/task-seed/service.d.ts +906 -0
  217. package/dist/services/task-seed/service.js +1406 -0
  218. package/dist/services/task-specification/service.d.ts +27 -0
  219. package/dist/services/task-specification/service.js +40 -0
  220. package/dist/services/trajectory-policy/service.d.ts +110 -0
  221. package/dist/services/trajectory-policy/service.js +216 -0
  222. package/dist/test/agentic-capabilities-protocol.test.d.ts +1 -0
  223. package/dist/test/agentic-capabilities-protocol.test.js +570 -0
  224. package/dist/test/agentic-capabilities.test.d.ts +1 -0
  225. package/dist/test/agentic-capabilities.test.js +1461 -0
  226. package/dist/test/agentic-environment.test.d.ts +1 -0
  227. package/dist/test/agentic-environment.test.js +213 -0
  228. package/dist/test/case-pipeline-foundation.test.d.ts +1 -0
  229. package/dist/test/case-pipeline-foundation.test.js +535 -0
  230. package/dist/test/case-pipeline-protocol-v2.test.d.ts +1 -0
  231. package/dist/test/case-pipeline-protocol-v2.test.js +124 -0
  232. package/dist/test/case-pipeline-v2.test.d.ts +1 -0
  233. package/dist/test/case-pipeline-v2.test.js +286 -0
  234. package/dist/test/case-pipeline.test.d.ts +1 -0
  235. package/dist/test/case-pipeline.test.js +851 -0
  236. package/dist/test/eval-capability-policy.test.d.ts +1 -0
  237. package/dist/test/eval-capability-policy.test.js +50 -0
  238. package/dist/test/eval-event-log.test.js +34 -1
  239. package/dist/test/evaluation-evidence-freshness.test.d.ts +1 -0
  240. package/dist/test/evaluation-evidence-freshness.test.js +44 -0
  241. package/dist/test/evaluation-evidence.test.d.ts +1 -0
  242. package/dist/test/evaluation-evidence.test.js +230 -0
  243. package/dist/test/evaluation-grader-calibration.test.d.ts +1 -0
  244. package/dist/test/evaluation-grader-calibration.test.js +373 -0
  245. package/dist/test/evaluation-proposal-digest.test.d.ts +1 -0
  246. package/dist/test/evaluation-proposal-digest.test.js +187 -0
  247. package/dist/test/evaluation-source-retrieval.test.d.ts +1 -0
  248. package/dist/test/evaluation-source-retrieval.test.js +237 -0
  249. package/dist/test/evaluation-structure-policy.test.d.ts +1 -0
  250. package/dist/test/evaluation-structure-policy.test.js +196 -0
  251. package/dist/test/fixtures/repository-resource-panel.d.ts +39 -0
  252. package/dist/test/fixtures/repository-resource-panel.js +111 -0
  253. package/dist/test/fixtures/vitest-boundary-panel.d.ts +84 -0
  254. package/dist/test/fixtures/vitest-boundary-panel.js +120 -0
  255. package/dist/test/fixtures/vitest-phase-panel.d.ts +135 -0
  256. package/dist/test/fixtures/vitest-phase-panel.js +213 -0
  257. package/dist/test/fixtures/vitest-reporter-results.d.ts +76 -0
  258. package/dist/test/fixtures/vitest-reporter-results.js +94 -0
  259. package/dist/test/grounded-authoring.test.d.ts +1 -0
  260. package/dist/test/grounded-authoring.test.js +565 -0
  261. package/dist/test/integrated-repository-history.test.d.ts +1 -0
  262. package/dist/test/integrated-repository-history.test.js +227 -0
  263. package/dist/test/project-authoring.test.js +593 -43
  264. package/dist/test/project-workflow.test.js +395 -32
  265. package/dist/test/repository-authoring-artifacts.test.d.ts +1 -0
  266. package/dist/test/repository-authoring-artifacts.test.js +185 -0
  267. package/dist/test/repository-bundle.test.d.ts +1 -0
  268. package/dist/test/repository-bundle.test.js +52 -0
  269. package/dist/test/repository-case-generation.test.d.ts +1 -0
  270. package/dist/test/repository-case-generation.test.js +3465 -0
  271. package/dist/test/repository-command-diagnostic.test.d.ts +1 -0
  272. package/dist/test/repository-command-diagnostic.test.js +55 -0
  273. package/dist/test/repository-command-signals.test.d.ts +1 -0
  274. package/dist/test/repository-command-signals.test.js +124 -0
  275. package/dist/test/repository-fixture-scope-coverage.test.d.ts +1 -0
  276. package/dist/test/repository-fixture-scope-coverage.test.js +127 -0
  277. package/dist/test/repository-fixture-validation.test.d.ts +1 -0
  278. package/dist/test/repository-fixture-validation.test.js +362 -0
  279. package/dist/test/repository-foundry-progress.test.d.ts +1 -0
  280. package/dist/test/repository-foundry-progress.test.js +110 -0
  281. package/dist/test/repository-foundry-quality.test.d.ts +1 -0
  282. package/dist/test/repository-foundry-quality.test.js +1138 -0
  283. package/dist/test/repository-import-context.test.d.ts +1 -0
  284. package/dist/test/repository-import-context.test.js +354 -0
  285. package/dist/test/repository-model-authoring.test.d.ts +1 -0
  286. package/dist/test/repository-model-authoring.test.js +544 -0
  287. package/dist/test/repository-model.test.d.ts +1 -0
  288. package/dist/test/repository-model.test.js +2195 -0
  289. package/dist/test/repository-node-test-reporter.test.d.ts +1 -0
  290. package/dist/test/repository-node-test-reporter.test.js +104 -0
  291. package/dist/test/repository-oracle-concurrency.test.d.ts +1 -0
  292. package/dist/test/repository-oracle-concurrency.test.js +542 -0
  293. package/dist/test/repository-oracle-coverage-witness.test.d.ts +1 -0
  294. package/dist/test/repository-oracle-coverage-witness.test.js +511 -0
  295. package/dist/test/repository-oracle-coverage.test.d.ts +1 -0
  296. package/dist/test/repository-oracle-coverage.test.js +168 -0
  297. package/dist/test/repository-oracle-evidence.test.d.ts +1 -0
  298. package/dist/test/repository-oracle-evidence.test.js +185 -0
  299. package/dist/test/repository-oracle-plan.test.d.ts +1 -0
  300. package/dist/test/repository-oracle-plan.test.js +176 -0
  301. package/dist/test/repository-overlay-isolation.test.d.ts +1 -0
  302. package/dist/test/repository-overlay-isolation.test.js +85 -0
  303. package/dist/test/repository-preparation-cache.test.d.ts +1 -0
  304. package/dist/test/repository-preparation-cache.test.js +414 -0
  305. package/dist/test/repository-public-artifact.test.d.ts +1 -0
  306. package/dist/test/repository-public-artifact.test.js +273 -0
  307. package/dist/test/repository-qualification-diagnostics.test.d.ts +1 -0
  308. package/dist/test/repository-qualification-diagnostics.test.js +524 -0
  309. package/dist/test/repository-reference-authoring.test.d.ts +1 -0
  310. package/dist/test/repository-reference-authoring.test.js +1633 -0
  311. package/dist/test/repository-review-evidence-v2.test.d.ts +1 -0
  312. package/dist/test/repository-review-evidence-v2.test.js +183 -0
  313. package/dist/test/repository-review-evidence.test.d.ts +1 -0
  314. package/dist/test/repository-review-evidence.test.js +124 -0
  315. package/dist/test/repository-seed-exclusions.test.d.ts +1 -0
  316. package/dist/test/repository-seed-exclusions.test.js +96 -0
  317. package/dist/test/repository-seed-selection.test.d.ts +1 -0
  318. package/dist/test/repository-seed-selection.test.js +504 -0
  319. package/dist/test/repository-semantic-calibration.test.d.ts +1 -0
  320. package/dist/test/repository-semantic-calibration.test.js +688 -0
  321. package/dist/test/repository-solution-edits.test.d.ts +1 -0
  322. package/dist/test/repository-solution-edits.test.js +377 -0
  323. package/dist/test/repository-specification-budget.test.d.ts +1 -0
  324. package/dist/test/repository-specification-budget.test.js +171 -0
  325. package/dist/test/repository-specification-contract-checkpoint.test.d.ts +1 -0
  326. package/dist/test/repository-specification-contract-checkpoint.test.js +228 -0
  327. package/dist/test/repository-specification-contract-facts.test.d.ts +1 -0
  328. package/dist/test/repository-specification-contract-facts.test.js +177 -0
  329. package/dist/test/repository-trajectory-authoring.test.d.ts +1 -0
  330. package/dist/test/repository-trajectory-authoring.test.js +176 -0
  331. package/dist/test/repository-valid-control-plan.test.d.ts +1 -0
  332. package/dist/test/repository-valid-control-plan.test.js +45 -0
  333. package/dist/test/repository-vitest-phase.test.d.ts +1 -0
  334. package/dist/test/repository-vitest-phase.test.js +848 -0
  335. package/dist/test/repository-vitest-reporter.test.d.ts +1 -0
  336. package/dist/test/repository-vitest-reporter.test.js +158 -0
  337. package/dist/test/repository-workspace-build.test.d.ts +1 -0
  338. package/dist/test/repository-workspace-build.test.js +160 -0
  339. package/dist/test/strict-authoring-schema.test.d.ts +1 -0
  340. package/dist/test/strict-authoring-schema.test.js +169 -0
  341. package/package.json +48 -7
@@ -14,6 +14,7 @@ const storeFailure = (operation, path, cause) => new EvalProjectStoreError({
14
14
  export const makeFileEvalProjectStore = Effect.gen(function* () {
15
15
  const fs = yield* FileSystem.FileSystem;
16
16
  const paths = yield* Path.Path;
17
+ const platform = yield* Effect.context();
17
18
  const projectPath = (root) => paths.join(paths.resolve(root), ".routekit", "evals", PROJECT_FILE);
18
19
  const loadDocument = (repositoryRoot) => Effect.gen(function* () {
19
20
  const root = yield* fs
@@ -45,7 +46,7 @@ export const makeFileEvalProjectStore = Effect.gen(function* () {
45
46
  .pipe(Effect.mapError((cause) => storeFailure("creating", directory, cause)));
46
47
  yield* writeFileAtomicEffect(target, `${JSON.stringify(state, null, 2)}\n`, {
47
48
  mode: 0o600
48
- }).pipe(Effect.mapError((cause) => storeFailure("committing", target, cause)), Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, paths));
49
+ }).pipe(Effect.mapError((cause) => storeFailure("committing", target, cause)), Effect.provide(platform));
49
50
  });
50
51
  return EvalProjectStore.of({
51
52
  loadDocument,
@@ -1,5 +1,5 @@
1
1
  import { CostService } from "@velum-labs/routekit-registry";
2
- import { Context, Effect, Layer, Path } from "effect";
2
+ import { Context, Effect, FileSystem, Layer, Path } from "effect";
3
3
  import type { EvalProjectArtifactError, EvalSetupInspectionError } from "./errors.js";
4
4
  import { EvalDimensionContrastError, type EvalModelCatalogError, type EvalProjectStoreError, EvalProjectTransitionError } from "./errors.js";
5
5
  import { EvalRepositoryInspector } from "./inspection.js";
@@ -29,6 +29,6 @@ export type EvalProjectWorkflowShape = {
29
29
  declare const EvalProjectWorkflow_base: Context.ServiceClass<EvalProjectWorkflow, "@velum-labs/routekit-eval-setup/EvalProjectWorkflow", EvalProjectWorkflowShape>;
30
30
  export declare class EvalProjectWorkflow extends EvalProjectWorkflow_base {
31
31
  }
32
- export declare const makeEvalProjectWorkflow: Effect.Effect<EvalProjectWorkflowShape, never, EvalProjectArtifacts | Path.Path | EvalProjectStore | EvalRepositoryInspector | EvalModelCatalog | CostService>;
33
- export declare const EvalProjectWorkflowLive: Layer.Layer<EvalProjectWorkflow, never, EvalProjectArtifacts | Path.Path | EvalProjectStore | EvalRepositoryInspector | EvalModelCatalog | CostService>;
32
+ export declare const makeEvalProjectWorkflow: Effect.Effect<EvalProjectWorkflowShape, never, EvalProjectArtifacts | Path.Path | FileSystem.FileSystem | EvalRepositoryInspector | EvalProjectStore | EvalModelCatalog | CostService>;
33
+ export declare const EvalProjectWorkflowLive: Layer.Layer<EvalProjectWorkflow, never, EvalProjectArtifacts | Path.Path | FileSystem.FileSystem | EvalRepositoryInspector | EvalProjectStore | EvalModelCatalog | CostService>;
34
34
  export {};
@@ -2,13 +2,16 @@ import { assertDecompositionResult, assertPublishedRoutingActivation, assertRout
2
2
  import { RoutingActivationConstraints, RoutingObjectivePolicy } from "@velum-labs/routekit-eval-contracts";
3
3
  import { CostService } from "@velum-labs/routekit-registry";
4
4
  import { Clock, Context, Effect, Layer, Path, Schema } from "effect";
5
+ import { assertCurrentEvaluationEvidence } from "./adapters/evaluation-evidence-freshness.js";
5
6
  import { EvalDimensionContrastError, EvalProjectTransitionError } from "./errors.js";
7
+ import { EVAL_STRUCTURE_POLICY_VERSION, assertEvaluationStructure, evaluationStructureReportDigest } from "./evaluation-structure-policy.js";
6
8
  import { EvalRepositoryInspector } from "./inspection.js";
7
9
  import { candidateReasoningEffortFromAnswer } from "./model-selection.js";
8
10
  import { EvalProjectArtifacts, evaluationProposalDigest, routingBasisDigest } from "./project-artifacts.js";
9
11
  import { EVAL_PROJECT_VERSION, estimateEvalPlanCost, scopedExpectedCalls, summarizeEvalRunLedger } from "./project-contracts.js";
10
12
  import { EvalProjectStore } from "./project-store.js";
11
13
  import { EvalModelCatalog } from "./services/model-catalog/service.js";
14
+ import { assertEvalRunCanFail } from "./eval-event-log.js";
12
15
  const isoNow = Effect.map(Clock.currentTimeMillis, (millis) => new Date(millis).toISOString());
13
16
  const questionForProgress = (progress) => {
14
17
  switch (progress._tag) {
@@ -93,7 +96,7 @@ const nextAction = (state, artifacts) => {
93
96
  ? "propose-evaluations"
94
97
  : "approve-evaluations";
95
98
  case "ready":
96
- return "run";
99
+ return artifacts.evaluationsApproved ? "run" : "approve-evaluations";
97
100
  case "running":
98
101
  return "none";
99
102
  case "qualified":
@@ -161,13 +164,15 @@ const sameLedger = (left, right) => left.expectedCalls === right.expectedCalls &
161
164
  left.unpricedCalls === right.unpricedCalls &&
162
165
  left.subscriptionUnitCalls === right.subscriptionUnitCalls;
163
166
  const validateQualifiedReport = (state, plan, proposal, report, costService) => Effect.gen(function* () {
164
- assertPublishedRoutingActivation(report.activation, {
165
- dimensionIds: plan.selectedCaseIds.map((entry) => entry.dimensionId)
166
- });
167
- if (report.activation.basisDigest !== state.basisDigest ||
168
- report.activation.classifierModel !== state.configuration.classifierModel ||
169
- !sameStrings(report.activation.candidateModels, plan.candidateModels)) {
170
- throw new Error("published activation does not match the immutable execution plan");
167
+ if (report.status === "passed") {
168
+ assertPublishedRoutingActivation(report.activation, {
169
+ dimensionIds: plan.selectedCaseIds.map((entry) => entry.dimensionId)
170
+ });
171
+ if (report.activation.basisDigest !== state.basisDigest ||
172
+ report.activation.classifierModel !== state.configuration.classifierModel ||
173
+ !sameStrings(report.activation.candidateModels, plan.candidateModels)) {
174
+ throw new Error("published activation does not match the immutable execution plan");
175
+ }
171
176
  }
172
177
  const expectedDimensions = new Map(plan.selectedCaseIds.map((entry) => [entry.dimensionId, new Set(entry.caseIds)]));
173
178
  const comparisons = new Map();
@@ -287,21 +292,51 @@ const validateQualifiedReport = (state, plan, proposal, report, costService) =>
287
292
  observedCompositionCases.size !== 0 ||
288
293
  qualification.composition.comparableCases !== 0 ||
289
294
  qualification.composition.agreeingCases !== 0 ||
295
+ qualification.composition.winnerAgreement !== undefined ||
296
+ qualification.composition.conclusion !== "inconclusive" ||
297
+ qualification.composition.publishable ||
290
298
  qualification.composition.cases.length !== 0) {
291
299
  throw new Error("composition qualification summary does not meet the reviewed threshold");
292
300
  }
293
301
  }
294
302
  else if (qualification.composition.expectedCases !== expectedCompositionCases.size ||
295
303
  observedCompositionCases.size !== expectedCompositionCases.size ||
296
- qualification.composition.comparableCases < 1 ||
297
304
  qualification.composition.agreeingCases !==
298
305
  qualification.composition.cases.filter((result) => result.passed).length ||
299
- Math.abs(qualification.composition.winnerAgreement -
300
- qualification.composition.agreeingCases / qualification.composition.comparableCases) > 1e-6 ||
301
- qualification.composition.winnerAgreement <
302
- proposal.compositionSuite.minimumWinnerAgreement) {
306
+ qualification.composition.comparableCases !==
307
+ qualification.composition.cases.filter((result) => result.comparable).length ||
308
+ qualification.composition.cases.some((result) => result.comparable !==
309
+ (result.predictedWinner !== null &&
310
+ result.observedWinner !== null &&
311
+ result.predictedScoreGap >= proposal.compositionSuite.minimumWinnerScoreGap &&
312
+ result.observedScoreGap >= proposal.compositionSuite.minimumWinnerScoreGap) ||
313
+ result.passed !==
314
+ (result.comparable && result.predictedWinner === result.observedWinner))) {
303
315
  throw new Error("composition qualification summary does not meet the reviewed threshold");
304
316
  }
317
+ if (expectedCompositionCases.size > 0) {
318
+ const comparableCases = qualification.composition.comparableCases;
319
+ const expectedAgreement = comparableCases === 0
320
+ ? undefined
321
+ : qualification.composition.agreeingCases / comparableCases;
322
+ const meetsThreshold = expectedAgreement !== undefined &&
323
+ expectedAgreement >= proposal.compositionSuite.minimumWinnerAgreement;
324
+ if ((expectedAgreement === undefined
325
+ ? qualification.composition.winnerAgreement !== undefined
326
+ : qualification.composition.winnerAgreement === undefined ||
327
+ Math.abs(qualification.composition.winnerAgreement - expectedAgreement) > 1e-6) ||
328
+ qualification.composition.conclusion !==
329
+ (expectedAgreement === undefined
330
+ ? "inconclusive"
331
+ : meetsThreshold
332
+ ? "passed"
333
+ : "failed") ||
334
+ qualification.composition.publishable !==
335
+ (plan.scope === "full" && meetsThreshold) ||
336
+ (plan.scope === "full" && !meetsThreshold)) {
337
+ throw new Error("composition qualification summary does not meet the reviewed threshold");
338
+ }
339
+ }
305
340
  }
306
341
  const expected = scopedExpectedCalls(plan);
307
342
  const ledger = yield* summarizeEvalRunLedger(report.comparisons, expected.expectedCallCount, costService, qualification?.decomposition.observations ?? [], plan.classifierModel);
@@ -516,7 +551,24 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
516
551
  const modelCatalog = yield* EvalModelCatalog;
517
552
  const costService = yield* CostService;
518
553
  const paths = yield* Path.Path;
554
+ const platform = yield* Effect.context();
519
555
  const resolveRoot = (repositoryRoot) => paths.resolve(repositoryRoot);
556
+ const evaluationStructureFor = (root, state, proposal) => Effect.gen(function* () {
557
+ const report = yield* Effect.try({
558
+ try: () => assertEvaluationStructure({
559
+ proposal,
560
+ sourceInventory: state.sourceInventory
561
+ }),
562
+ catch: (cause) => transitionError(state.stage, cause instanceof Error
563
+ ? cause.message
564
+ : "evaluation proposal failed structure validation")
565
+ });
566
+ yield* assertCurrentEvaluationEvidence({
567
+ repositoryRoot: root,
568
+ evidenceSources: proposal.evidenceSources ?? []
569
+ }).pipe(Effect.provide(platform), Effect.mapError((cause) => transitionError(state.stage, cause.message)));
570
+ return report;
571
+ });
520
572
  const statusOf = (root, state) => Effect.gen(function* () {
521
573
  const [basis, basisApproval, evaluations, evaluationsApproval, plans] = yield* Effect.all([
522
574
  artifacts.loadBasisProposal(root),
@@ -525,6 +577,15 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
525
577
  artifacts.loadEvaluationsApproval(root),
526
578
  artifacts.listPlans(root)
527
579
  ]);
580
+ const structureReport = evaluations === undefined
581
+ ? undefined
582
+ : yield* evaluationStructureFor(root, state, evaluations).pipe(Effect.match({
583
+ onFailure: () => undefined,
584
+ onSuccess: (report) => report
585
+ }));
586
+ const structureReportDigest = structureReport === undefined
587
+ ? undefined
588
+ : evaluationStructureReportDigest(structureReport);
528
589
  const artifactStatus = {
529
590
  ...(basis === undefined ? {} : { basisProposalDigest: basis.basisDigest }),
530
591
  basisApproved: basis !== undefined &&
@@ -535,7 +596,10 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
535
596
  : { evaluationProposalDigest: evaluations.evaluationDigest }),
536
597
  evaluationsApproved: evaluations !== undefined &&
537
598
  evaluationsApproval?.kind === "evaluations" &&
538
- evaluationsApproval.digest === evaluations.evaluationDigest,
599
+ evaluationsApproval.digest === evaluations.evaluationDigest &&
600
+ evaluationsApproval.structurePolicyVersion ===
601
+ EVAL_STRUCTURE_POLICY_VERSION &&
602
+ evaluationsApproval.structureReportDigest === structureReportDigest,
539
603
  plans
540
604
  };
541
605
  return {
@@ -700,7 +764,9 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
700
764
  const proposeEvaluations = (repositoryRoot, input) => Effect.gen(function* () {
701
765
  const root = resolveRoot(repositoryRoot);
702
766
  const state = yield* loadRequired(root);
703
- if (state.stage !== "evaluations-review") {
767
+ if (state.stage !== "evaluations-review" &&
768
+ state.stage !== "ready" &&
769
+ state.stage !== "qualified") {
704
770
  return yield* transitionError(state.stage, "dimension evaluations can only be proposed after routing-basis approval");
705
771
  }
706
772
  const basis = yield* artifacts.loadBasisProposal(root);
@@ -746,6 +812,9 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
746
812
  candidateReasoningEfforts: state.configuration.candidateReasoningEfforts
747
813
  }),
748
814
  judgeModel: state.configuration.judgeModel,
815
+ ...(input.evidenceSources === undefined
816
+ ? {}
817
+ : { evidenceSources: input.evidenceSources }),
749
818
  suites: input.suites,
750
819
  decompositionBenchmark: input.decompositionBenchmark,
751
820
  compositionSuite: input.compositionSuite
@@ -760,7 +829,9 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
760
829
  const approveEvaluations = (repositoryRoot, expectedDigest) => Effect.gen(function* () {
761
830
  const root = resolveRoot(repositoryRoot);
762
831
  const state = yield* loadRequired(root);
763
- if (state.stage !== "evaluations-review") {
832
+ if (state.stage !== "evaluations-review" &&
833
+ state.stage !== "ready" &&
834
+ state.stage !== "qualified") {
764
835
  return yield* transitionError(state.stage, "dimension evaluations are not awaiting approval");
765
836
  }
766
837
  const proposal = yield* artifacts.loadEvaluationProposal(root);
@@ -771,13 +842,19 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
771
842
  proposal.basisDigest !== state.basisDigest) {
772
843
  return yield* transitionError(state.stage, "evaluation proposal changed after review; approve its current digest");
773
844
  }
845
+ const structureReport = yield* evaluationStructureFor(root, state, proposal);
774
846
  const now = yield* isoNow;
775
847
  yield* artifacts.saveEvaluationsApproval(root, {
776
848
  version: EVAL_PROJECT_VERSION,
777
849
  kind: "evaluations",
778
850
  digest: proposal.evaluationDigest,
779
- approvedAt: now
851
+ approvedAt: now,
852
+ structurePolicyVersion: EVAL_STRUCTURE_POLICY_VERSION,
853
+ structureReportDigest: evaluationStructureReportDigest(structureReport)
780
854
  });
855
+ if (state.stage !== "evaluations-review") {
856
+ return yield* statusOf(root, state);
857
+ }
781
858
  const next = {
782
859
  version: state.version,
783
860
  projectId: state.projectId,
@@ -801,9 +878,17 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
801
878
  }
802
879
  const proposal = yield* artifacts.loadEvaluationProposal(root);
803
880
  const approval = yield* artifacts.loadEvaluationsApproval(root);
881
+ const structureReport = proposal === undefined
882
+ ? undefined
883
+ : yield* evaluationStructureFor(root, state, proposal);
804
884
  if (proposal === undefined ||
805
885
  approval?.kind !== "evaluations" ||
806
886
  approval.digest !== proposal.evaluationDigest ||
887
+ approval.structurePolicyVersion !== EVAL_STRUCTURE_POLICY_VERSION ||
888
+ approval.structureReportDigest !==
889
+ (structureReport === undefined
890
+ ? undefined
891
+ : evaluationStructureReportDigest(structureReport)) ||
807
892
  proposal.evaluationDigest !== state.evaluationDigest ||
808
893
  proposal.basisDigest !== state.basisDigest) {
809
894
  return yield* transitionError(state.stage, "approved evaluation artifacts are stale");
@@ -912,6 +997,15 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
912
997
  proposal.basisDigest !== plan.basisDigest) {
913
998
  return yield* transitionError(state.stage, "the approved evaluation proposal for the execution plan is missing or stale");
914
999
  }
1000
+ const approval = yield* artifacts.loadEvaluationsApproval(root);
1001
+ const structureReport = yield* evaluationStructureFor(root, state, proposal);
1002
+ if (approval?.kind !== "evaluations" ||
1003
+ approval.digest !== proposal.evaluationDigest ||
1004
+ approval.structurePolicyVersion !== EVAL_STRUCTURE_POLICY_VERSION ||
1005
+ approval.structureReportDigest !==
1006
+ evaluationStructureReportDigest(structureReport)) {
1007
+ return yield* transitionError(state.stage, "the evaluation approval is stale under the current structure policy");
1008
+ }
915
1009
  yield* artifacts.materializePlanSuites(root, plan, proposal, "rematerialize");
916
1010
  const now = yield* isoNow;
917
1011
  const runId = crypto.randomUUID();
@@ -947,7 +1041,7 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
947
1041
  if ((report.target.kind === "configured"
948
1042
  ? !report.cleanup.sessionOpened || !report.cleanup.sessionClosed
949
1043
  : report.cleanup.sessionOpened || report.cleanup.sessionClosed) ||
950
- report.activation.basisDigest !== state.basisDigest) {
1044
+ (report.status === "passed" && report.activation.basisDigest !== state.basisDigest)) {
951
1045
  return yield* transitionError(state.stage, "a run cannot qualify before session cleanup and activation validation complete");
952
1046
  }
953
1047
  const plan = yield* artifacts.loadPlan(root, state.planId);
@@ -1003,6 +1097,10 @@ export const makeEvalProjectWorkflow = Effect.gen(function* () {
1003
1097
  report.evaluationDigest !== state.evaluationDigest) {
1004
1098
  return yield* transitionError(state.stage, "failure report does not match the active run");
1005
1099
  }
1100
+ yield* Effect.try({
1101
+ try: () => assertEvalRunCanFail(report.events ?? []),
1102
+ catch: (cause) => transitionError(state.stage, cause instanceof Error ? cause.message : "failure report has no terminal event")
1103
+ });
1006
1104
  yield* artifacts.saveRunReport(root, report);
1007
1105
  const next = {
1008
1106
  version: state.version,
@@ -0,0 +1,64 @@
1
+ import { Schema } from "effect";
2
+ export declare const RepositoryAdversaryMutationOperatorV1: Schema.Literals<readonly ["condition-negation", "boundary-operator", "partial-output-drop", "cross-file-omission"]>;
3
+ export type RepositoryAdversaryMutationOperatorV1 = typeof RepositoryAdversaryMutationOperatorV1.Type;
4
+ export declare const RepositoryAdversaryValidationObservationV1: Schema.Struct<{
5
+ readonly repetition: Schema.Finite;
6
+ readonly outcome: Schema.Literals<readonly ["pass", "fail"]>;
7
+ readonly detail: Schema.String;
8
+ }>;
9
+ export type RepositoryAdversaryValidationObservationV1 = typeof RepositoryAdversaryValidationObservationV1.Type;
10
+ export declare const RepositoryAdversaryCandidateV1: Schema.Struct<{
11
+ readonly version: Schema.Literal<1>;
12
+ readonly id: Schema.String;
13
+ readonly solutionId: Schema.String;
14
+ readonly family: Schema.String;
15
+ readonly operator: Schema.Literals<readonly ["condition-negation", "boundary-operator", "partial-output-drop", "cross-file-omission"]>;
16
+ readonly sourcePath: Schema.String;
17
+ readonly relatedPaths: Schema.$Array<Schema.String>;
18
+ readonly sourceCommit: Schema.String;
19
+ readonly originalSnippet: Schema.String;
20
+ readonly mutatedSnippet: Schema.String;
21
+ readonly validationRecipeId: Schema.String;
22
+ readonly compilationStatus: Schema.Literals<readonly ["passed", "failed"]>;
23
+ readonly validationObservations: Schema.$Array<Schema.Struct<{
24
+ readonly repetition: Schema.Finite;
25
+ readonly outcome: Schema.Literals<readonly ["pass", "fail"]>;
26
+ readonly detail: Schema.String;
27
+ }>>;
28
+ readonly rejectionReasons: Schema.$Array<Schema.String>;
29
+ }>;
30
+ export type RepositoryAdversaryCandidateV1 = typeof RepositoryAdversaryCandidateV1.Type;
31
+ export declare const RepositoryAdversaryGenerationReportV1: Schema.Struct<{
32
+ readonly version: Schema.Literal<1>;
33
+ readonly seedId: Schema.String;
34
+ readonly generationCoverage: Schema.Struct<{
35
+ readonly implementationPathCount: Schema.Finite;
36
+ readonly changedPathCount: Schema.Finite;
37
+ readonly generatedCrossFileCandidateCount: Schema.Finite;
38
+ readonly omittedCrossFileCandidateCount: Schema.Finite;
39
+ }>;
40
+ readonly candidates: Schema.$Array<Schema.Struct<{
41
+ readonly version: Schema.Literal<1>;
42
+ readonly id: Schema.String;
43
+ readonly solutionId: Schema.String;
44
+ readonly family: Schema.String;
45
+ readonly operator: Schema.Literals<readonly ["condition-negation", "boundary-operator", "partial-output-drop", "cross-file-omission"]>;
46
+ readonly sourcePath: Schema.String;
47
+ readonly relatedPaths: Schema.$Array<Schema.String>;
48
+ readonly sourceCommit: Schema.String;
49
+ readonly originalSnippet: Schema.String;
50
+ readonly mutatedSnippet: Schema.String;
51
+ readonly validationRecipeId: Schema.String;
52
+ readonly compilationStatus: Schema.Literals<readonly ["passed", "failed"]>;
53
+ readonly validationObservations: Schema.$Array<Schema.Struct<{
54
+ readonly repetition: Schema.Finite;
55
+ readonly outcome: Schema.Literals<readonly ["pass", "fail"]>;
56
+ readonly detail: Schema.String;
57
+ }>>;
58
+ readonly rejectionReasons: Schema.$Array<Schema.String>;
59
+ }>>;
60
+ readonly admittedCandidateIds: Schema.$Array<Schema.String>;
61
+ readonly rejectedCandidateIds: Schema.$Array<Schema.String>;
62
+ }>;
63
+ export type RepositoryAdversaryGenerationReportV1 = typeof RepositoryAdversaryGenerationReportV1.Type;
64
+ export declare function assertRepositoryAdversaryGenerationReportV1(value: unknown): asserts value is RepositoryAdversaryGenerationReportV1;
@@ -0,0 +1,105 @@
1
+ import { Schema } from "effect";
2
+ export const RepositoryAdversaryMutationOperatorV1 = Schema.Literals([
3
+ "condition-negation",
4
+ "boundary-operator",
5
+ "partial-output-drop",
6
+ "cross-file-omission"
7
+ ]);
8
+ export const RepositoryAdversaryValidationObservationV1 = Schema.Struct({
9
+ repetition: Schema.Finite,
10
+ outcome: Schema.Literals(["pass", "fail"]),
11
+ detail: Schema.String
12
+ });
13
+ export const RepositoryAdversaryCandidateV1 = Schema.Struct({
14
+ version: Schema.Literal(1),
15
+ id: Schema.String,
16
+ solutionId: Schema.String,
17
+ family: Schema.String,
18
+ operator: RepositoryAdversaryMutationOperatorV1,
19
+ sourcePath: Schema.String,
20
+ relatedPaths: Schema.Array(Schema.String),
21
+ sourceCommit: Schema.String,
22
+ originalSnippet: Schema.String,
23
+ mutatedSnippet: Schema.String,
24
+ validationRecipeId: Schema.String,
25
+ compilationStatus: Schema.Literals(["passed", "failed"]),
26
+ validationObservations: Schema.Array(RepositoryAdversaryValidationObservationV1),
27
+ rejectionReasons: Schema.Array(Schema.String)
28
+ });
29
+ export const RepositoryAdversaryGenerationReportV1 = Schema.Struct({
30
+ version: Schema.Literal(1),
31
+ seedId: Schema.String,
32
+ generationCoverage: Schema.Struct({
33
+ implementationPathCount: Schema.Finite,
34
+ changedPathCount: Schema.Finite,
35
+ generatedCrossFileCandidateCount: Schema.Finite,
36
+ omittedCrossFileCandidateCount: Schema.Finite
37
+ }),
38
+ candidates: Schema.Array(RepositoryAdversaryCandidateV1),
39
+ admittedCandidateIds: Schema.Array(Schema.String),
40
+ rejectedCandidateIds: Schema.Array(Schema.String)
41
+ });
42
+ export function assertRepositoryAdversaryGenerationReportV1(value) {
43
+ const report = Schema.decodeUnknownSync(RepositoryAdversaryGenerationReportV1)(value);
44
+ const candidateIds = new Set(report.candidates.map((candidate) => candidate.id));
45
+ const solutionIds = new Set(report.candidates.map((candidate) => candidate.solutionId));
46
+ const crossFileCandidateCount = report.candidates.filter((candidate) => candidate.operator === "cross-file-omission").length;
47
+ if (candidateIds.size !== report.candidates.length ||
48
+ solutionIds.size !== report.candidates.length) {
49
+ throw new Error("repository adversary candidate ids must be unique");
50
+ }
51
+ if (!Number.isInteger(report.generationCoverage.implementationPathCount) ||
52
+ !Number.isInteger(report.generationCoverage.changedPathCount) ||
53
+ !Number.isInteger(report.generationCoverage.generatedCrossFileCandidateCount) ||
54
+ !Number.isInteger(report.generationCoverage.omittedCrossFileCandidateCount) ||
55
+ report.generationCoverage.implementationPathCount < 0 ||
56
+ report.generationCoverage.changedPathCount < 0 ||
57
+ report.generationCoverage.generatedCrossFileCandidateCount < 0 ||
58
+ report.generationCoverage.omittedCrossFileCandidateCount < 0 ||
59
+ report.generationCoverage.changedPathCount >
60
+ report.generationCoverage.implementationPathCount ||
61
+ report.generationCoverage.generatedCrossFileCandidateCount !==
62
+ crossFileCandidateCount ||
63
+ (report.generationCoverage.changedPathCount >= 2
64
+ ? report.generationCoverage.generatedCrossFileCandidateCount +
65
+ report.generationCoverage.omittedCrossFileCandidateCount !==
66
+ report.generationCoverage.changedPathCount
67
+ : report.generationCoverage.generatedCrossFileCandidateCount !== 0 ||
68
+ report.generationCoverage.omittedCrossFileCandidateCount !== 0)) {
69
+ throw new Error("repository adversary generation coverage must account for every eligible cross-file path");
70
+ }
71
+ const classified = new Set([
72
+ ...report.admittedCandidateIds,
73
+ ...report.rejectedCandidateIds
74
+ ]);
75
+ if (classified.size !== report.candidates.length ||
76
+ [...classified].some((id) => !candidateIds.has(id))) {
77
+ throw new Error("every repository adversary candidate must be classified exactly once");
78
+ }
79
+ for (const candidate of report.candidates) {
80
+ if (new Set(candidate.relatedPaths).size !== candidate.relatedPaths.length ||
81
+ candidate.relatedPaths.includes(candidate.sourcePath) ||
82
+ (candidate.operator === "cross-file-omission"
83
+ ? candidate.relatedPaths.length === 0
84
+ : candidate.relatedPaths.length !== 0)) {
85
+ throw new Error("repository adversary related paths must identify only the coupled files for cross-file mutations");
86
+ }
87
+ if (candidate.validationObservations.length < 2 ||
88
+ candidate.validationObservations.some((observation) => !Number.isInteger(observation.repetition) ||
89
+ observation.repetition < 1)) {
90
+ throw new Error("repository adversary candidates require repeated validation observations");
91
+ }
92
+ const passed = candidate.validationObservations.every((observation) => observation.outcome === "pass");
93
+ if ((candidate.compilationStatus === "passed") !== passed ||
94
+ (candidate.compilationStatus === "passed") !==
95
+ report.admittedCandidateIds.includes(candidate.id) ||
96
+ (candidate.compilationStatus === "failed") !==
97
+ report.rejectedCandidateIds.includes(candidate.id)) {
98
+ throw new Error("repository adversary classification must match compilation observations");
99
+ }
100
+ if (candidate.compilationStatus === "passed" &&
101
+ candidate.rejectionReasons.length > 0) {
102
+ throw new Error("admitted repository adversaries cannot have rejection reasons");
103
+ }
104
+ }
105
+ }