@velum-labs/routekit-eval-setup 1.3.2 → 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 (342) 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 -10
  44. package/dist/effect-api.js +56 -6
  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 +140 -0
  52. package/dist/eval-event-log.js +220 -0
  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 -17
  72. package/dist/index.js +69 -11
  73. package/dist/inspection.js +2 -3
  74. package/dist/project-artifacts.d.ts +7 -2
  75. package/dist/project-artifacts.js +49 -136
  76. package/dist/project-authoring.d.ts +66 -5
  77. package/dist/project-authoring.js +783 -109
  78. package/dist/project-contracts.d.ts +419 -84
  79. package/dist/project-contracts.js +160 -52
  80. package/dist/project-store.js +2 -1
  81. package/dist/project-workflow.d.ts +5 -4
  82. package/dist/project-workflow.js +154 -35
  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.d.ts +1 -0
  239. package/dist/test/eval-event-log.test.js +125 -0
  240. package/dist/test/evaluation-evidence-freshness.test.d.ts +1 -0
  241. package/dist/test/evaluation-evidence-freshness.test.js +44 -0
  242. package/dist/test/evaluation-evidence.test.d.ts +1 -0
  243. package/dist/test/evaluation-evidence.test.js +230 -0
  244. package/dist/test/evaluation-grader-calibration.test.d.ts +1 -0
  245. package/dist/test/evaluation-grader-calibration.test.js +373 -0
  246. package/dist/test/evaluation-proposal-digest.test.d.ts +1 -0
  247. package/dist/test/evaluation-proposal-digest.test.js +187 -0
  248. package/dist/test/evaluation-source-retrieval.test.d.ts +1 -0
  249. package/dist/test/evaluation-source-retrieval.test.js +237 -0
  250. package/dist/test/evaluation-structure-policy.test.d.ts +1 -0
  251. package/dist/test/evaluation-structure-policy.test.js +196 -0
  252. package/dist/test/fixtures/repository-resource-panel.d.ts +39 -0
  253. package/dist/test/fixtures/repository-resource-panel.js +111 -0
  254. package/dist/test/fixtures/vitest-boundary-panel.d.ts +84 -0
  255. package/dist/test/fixtures/vitest-boundary-panel.js +120 -0
  256. package/dist/test/fixtures/vitest-phase-panel.d.ts +135 -0
  257. package/dist/test/fixtures/vitest-phase-panel.js +213 -0
  258. package/dist/test/fixtures/vitest-reporter-results.d.ts +76 -0
  259. package/dist/test/fixtures/vitest-reporter-results.js +94 -0
  260. package/dist/test/grounded-authoring.test.d.ts +1 -0
  261. package/dist/test/grounded-authoring.test.js +565 -0
  262. package/dist/test/integrated-repository-history.test.d.ts +1 -0
  263. package/dist/test/integrated-repository-history.test.js +227 -0
  264. package/dist/test/project-authoring.test.js +593 -43
  265. package/dist/test/project-workflow.test.js +419 -40
  266. package/dist/test/repository-authoring-artifacts.test.d.ts +1 -0
  267. package/dist/test/repository-authoring-artifacts.test.js +185 -0
  268. package/dist/test/repository-bundle.test.d.ts +1 -0
  269. package/dist/test/repository-bundle.test.js +52 -0
  270. package/dist/test/repository-case-generation.test.d.ts +1 -0
  271. package/dist/test/repository-case-generation.test.js +3465 -0
  272. package/dist/test/repository-command-diagnostic.test.d.ts +1 -0
  273. package/dist/test/repository-command-diagnostic.test.js +55 -0
  274. package/dist/test/repository-command-signals.test.d.ts +1 -0
  275. package/dist/test/repository-command-signals.test.js +124 -0
  276. package/dist/test/repository-fixture-scope-coverage.test.d.ts +1 -0
  277. package/dist/test/repository-fixture-scope-coverage.test.js +127 -0
  278. package/dist/test/repository-fixture-validation.test.d.ts +1 -0
  279. package/dist/test/repository-fixture-validation.test.js +362 -0
  280. package/dist/test/repository-foundry-progress.test.d.ts +1 -0
  281. package/dist/test/repository-foundry-progress.test.js +110 -0
  282. package/dist/test/repository-foundry-quality.test.d.ts +1 -0
  283. package/dist/test/repository-foundry-quality.test.js +1138 -0
  284. package/dist/test/repository-import-context.test.d.ts +1 -0
  285. package/dist/test/repository-import-context.test.js +354 -0
  286. package/dist/test/repository-model-authoring.test.d.ts +1 -0
  287. package/dist/test/repository-model-authoring.test.js +544 -0
  288. package/dist/test/repository-model.test.d.ts +1 -0
  289. package/dist/test/repository-model.test.js +2195 -0
  290. package/dist/test/repository-node-test-reporter.test.d.ts +1 -0
  291. package/dist/test/repository-node-test-reporter.test.js +104 -0
  292. package/dist/test/repository-oracle-concurrency.test.d.ts +1 -0
  293. package/dist/test/repository-oracle-concurrency.test.js +542 -0
  294. package/dist/test/repository-oracle-coverage-witness.test.d.ts +1 -0
  295. package/dist/test/repository-oracle-coverage-witness.test.js +511 -0
  296. package/dist/test/repository-oracle-coverage.test.d.ts +1 -0
  297. package/dist/test/repository-oracle-coverage.test.js +168 -0
  298. package/dist/test/repository-oracle-evidence.test.d.ts +1 -0
  299. package/dist/test/repository-oracle-evidence.test.js +185 -0
  300. package/dist/test/repository-oracle-plan.test.d.ts +1 -0
  301. package/dist/test/repository-oracle-plan.test.js +176 -0
  302. package/dist/test/repository-overlay-isolation.test.d.ts +1 -0
  303. package/dist/test/repository-overlay-isolation.test.js +85 -0
  304. package/dist/test/repository-preparation-cache.test.d.ts +1 -0
  305. package/dist/test/repository-preparation-cache.test.js +414 -0
  306. package/dist/test/repository-public-artifact.test.d.ts +1 -0
  307. package/dist/test/repository-public-artifact.test.js +273 -0
  308. package/dist/test/repository-qualification-diagnostics.test.d.ts +1 -0
  309. package/dist/test/repository-qualification-diagnostics.test.js +524 -0
  310. package/dist/test/repository-reference-authoring.test.d.ts +1 -0
  311. package/dist/test/repository-reference-authoring.test.js +1633 -0
  312. package/dist/test/repository-review-evidence-v2.test.d.ts +1 -0
  313. package/dist/test/repository-review-evidence-v2.test.js +183 -0
  314. package/dist/test/repository-review-evidence.test.d.ts +1 -0
  315. package/dist/test/repository-review-evidence.test.js +124 -0
  316. package/dist/test/repository-seed-exclusions.test.d.ts +1 -0
  317. package/dist/test/repository-seed-exclusions.test.js +96 -0
  318. package/dist/test/repository-seed-selection.test.d.ts +1 -0
  319. package/dist/test/repository-seed-selection.test.js +504 -0
  320. package/dist/test/repository-semantic-calibration.test.d.ts +1 -0
  321. package/dist/test/repository-semantic-calibration.test.js +688 -0
  322. package/dist/test/repository-solution-edits.test.d.ts +1 -0
  323. package/dist/test/repository-solution-edits.test.js +377 -0
  324. package/dist/test/repository-specification-budget.test.d.ts +1 -0
  325. package/dist/test/repository-specification-budget.test.js +171 -0
  326. package/dist/test/repository-specification-contract-checkpoint.test.d.ts +1 -0
  327. package/dist/test/repository-specification-contract-checkpoint.test.js +228 -0
  328. package/dist/test/repository-specification-contract-facts.test.d.ts +1 -0
  329. package/dist/test/repository-specification-contract-facts.test.js +177 -0
  330. package/dist/test/repository-trajectory-authoring.test.d.ts +1 -0
  331. package/dist/test/repository-trajectory-authoring.test.js +176 -0
  332. package/dist/test/repository-valid-control-plan.test.d.ts +1 -0
  333. package/dist/test/repository-valid-control-plan.test.js +45 -0
  334. package/dist/test/repository-vitest-phase.test.d.ts +1 -0
  335. package/dist/test/repository-vitest-phase.test.js +848 -0
  336. package/dist/test/repository-vitest-reporter.test.d.ts +1 -0
  337. package/dist/test/repository-vitest-reporter.test.js +158 -0
  338. package/dist/test/repository-workspace-build.test.d.ts +1 -0
  339. package/dist/test/repository-workspace-build.test.js +160 -0
  340. package/dist/test/strict-authoring-schema.test.d.ts +1 -0
  341. package/dist/test/strict-authoring-schema.test.js +169 -0
  342. package/package.json +48 -6
@@ -0,0 +1,362 @@
1
+ import assert from "node:assert/strict";
2
+ import { execFile } from "node:child_process";
3
+ import { mkdtemp, readFile, realpath, rm, writeFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { test } from "node:test";
7
+ import { promisify } from "node:util";
8
+ import { Effect } from "effect";
9
+ import { RepositoryCommandExecutionPort } from "../adapters/repository-command-runner.js";
10
+ import { makeCaseCheckpointStoreV1 } from "../case-checkpoint-store.js";
11
+ import { RepositoryFoundryError } from "../errors.js";
12
+ import { EvalAuthoringTransport } from "../project-authoring.js";
13
+ import { repositoryFoundryModelPlanV1 } from "../repository-language-model-protocol.js";
14
+ import { repositoryFixturePreflightFeedbackV1, validateRepositoryFixturesV1 } from "../services/fixture-validation/service.js";
15
+ import { RepositoryFoundryProgressLive } from "../services/foundry-progress/service.js";
16
+ import { RepositoryFoundryLanguageModelLive } from "../services/language-model/service.js";
17
+ const execute = promisify(execFile);
18
+ const modelPlan = repositoryFoundryModelPlanV1({ primaryModel: "openai/gpt-6-astra" });
19
+ const goodCode = `import assert from "node:assert/strict";
20
+ import test from "node:test";
21
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
22
+ import { value } from "./subject.mjs";
23
+ test("frozen public behavior", () => {
24
+ assert.equal(existsSync("candidate-ran.txt"), false);
25
+ writeFileSync("candidate-ran.txt", "fresh candidate only");
26
+ assert.equal(readFileSync("control.json", "utf8"), "reference");
27
+ assert.equal(value, 1);
28
+ });
29
+ `;
30
+ const brokenCode = `${goodCode}\nconst syntaxError = ;\n`;
31
+ async function fixture(t) {
32
+ const root = await realpath(await mkdtemp(join(tmpdir(), "fixture-validation-test-")));
33
+ t.after(() => rm(root, { recursive: true, force: true }));
34
+ const git = (...args) => execute("git", ["-C", root, ...args]);
35
+ await git("init", "-q");
36
+ await writeFile(join(root, "case.test.mjs"), goodCode);
37
+ const commit = async (value, control) => {
38
+ await writeFile(join(root, "subject.mjs"), `export const value = ${value};\n`);
39
+ await writeFile(join(root, "control.json"), control);
40
+ await git("add", ".");
41
+ await git("-c", "core.hooksPath=/dev/null", "-c", "commit.gpgSign=false", "-c", "user.name=Fixture Validation", "-c", "user.email=fixture@example.test", "commit", "-qm", "fixture");
42
+ return (await git("rev-parse", "HEAD")).stdout.trim();
43
+ };
44
+ const initialCommit = await commit(0, "initial");
45
+ const referenceCommit = await commit(1, "reference");
46
+ // Ambient dirty source must not influence the pinned reference replay.
47
+ await writeFile(join(root, "control.json"), "untrusted working tree");
48
+ const grade = {
49
+ id: "grade",
50
+ kind: "test",
51
+ cwd: ".",
52
+ executable: "node",
53
+ args: ["--test", "case.test.mjs"],
54
+ timeoutMs: 5000
55
+ };
56
+ const observation = (id, subjectId, outcome) => ({
57
+ id,
58
+ kind: "test-command",
59
+ subjectId,
60
+ outcome,
61
+ detail: "Synthetic qualified seed evidence."
62
+ });
63
+ const seed = {
64
+ version: 1,
65
+ id: "synthetic-seed",
66
+ status: "qualified",
67
+ source: { kind: "historical-fix", changeEpisodeId: "synthetic-change" },
68
+ summary: "Synthetic public behavior.",
69
+ capabilityEvidence: [{ kind: "test", id: "case", path: "case.test.mjs" }],
70
+ initialState: { commit: initialCommit },
71
+ referenceCommit,
72
+ targetBehavior: [{ id: "behavior", description: "Return one.", critical: true, evidence: [] }],
73
+ baselineObservations: [observation("baseline", "baseline", "pass")],
74
+ preChangeObservations: [observation("pre", "grade", "fail")],
75
+ postChangeObservations: [observation("post", "grade", "pass")],
76
+ candidateTestIds: ["case"],
77
+ environment: {
78
+ protectedControlPaths: ["control.json"],
79
+ trustedPreparationRecipes: [],
80
+ candidateValidationRecipes: [
81
+ {
82
+ id: "syntax",
83
+ kind: "check",
84
+ cwd: ".",
85
+ executable: "node",
86
+ args: ["--check", "case.test.mjs"],
87
+ timeoutMs: 5000
88
+ }
89
+ ],
90
+ baselineGradeRecipes: [{ ...grade, id: "baseline" }],
91
+ gradeRecipes: [grade]
92
+ },
93
+ confidence: "high",
94
+ risks: [],
95
+ rejectionReasons: []
96
+ };
97
+ const suite = {
98
+ version: 1,
99
+ caseId: "synthetic-case",
100
+ fixtures: ["good", "broken"].map((id) => ({
101
+ id,
102
+ description: `Frozen ${id} fixture.`,
103
+ expectedBehavior: "Return one.",
104
+ source: "generated",
105
+ testPath: "case.test.mjs",
106
+ kind: "metamorphic",
107
+ expectationMode: "preserved"
108
+ })),
109
+ overlays: [
110
+ { path: "case.test.mjs", content: goodCode, fixtureIds: ["good"] },
111
+ { path: "case.test.mjs", content: brokenCode, fixtureIds: ["broken"] }
112
+ ]
113
+ };
114
+ return { root, seed, suite };
115
+ }
116
+ function runner(data, options = {}) {
117
+ const calls = [];
118
+ const artifacts = [];
119
+ const events = [];
120
+ const repairAccounting = { attempts: 0, validatedCalls: 0 };
121
+ const effect = validateRepositoryFixturesV1({
122
+ repositoryRoot: data.root,
123
+ operationId: "fixture-test",
124
+ seed: options.seed ?? data.seed,
125
+ suite: options.suite ?? data.suite,
126
+ allowedTestPaths: new Set(["case.test.mjs"]),
127
+ context: {
128
+ visible: { title: "Frozen visible task" },
129
+ pinnedManifest: { apiVersion: "synthetic" }
130
+ },
131
+ modelPlan,
132
+ maximumRepairAttempts: options.maximumRepairAttempts ?? 1,
133
+ checkpointStore: options.checkpointStore,
134
+ onRepairAttempt: () => Effect.sync(() => {
135
+ repairAccounting.attempts += 1;
136
+ }),
137
+ onRepairCall: () => Effect.sync(() => {
138
+ repairAccounting.validatedCalls += 1;
139
+ })
140
+ }).pipe(Effect.provide(RepositoryFoundryLanguageModelLive), Effect.provideService(EvalAuthoringTransport, {
141
+ complete: (request) => Effect.sync(() => {
142
+ calls.push(request);
143
+ return JSON.stringify(options.reply?.(request) ?? {
144
+ overlays: [{ path: "case.test.mjs", content: goodCode, fixtureIds: ["broken"] }]
145
+ });
146
+ })
147
+ }), Effect.provide(RepositoryFoundryProgressLive((event) => Effect.sync(() => {
148
+ events.push(event);
149
+ }), (artifact) => Effect.sync(() => {
150
+ artifacts.push(artifact);
151
+ }))));
152
+ return { effect, calls, artifacts, events, repairAccounting };
153
+ }
154
+ test("fixture preflight repairs only failed code, replays the pinned reference, and retains private evidence without counting host model calls", async (t) => {
155
+ const data = await fixture(t);
156
+ const original = JSON.stringify(data.suite);
157
+ const run = runner(data);
158
+ const result = await Effect.runPromise(run.effect);
159
+ assert.equal(result.modelCalls.length, 1);
160
+ assert.equal(run.calls.length, 1);
161
+ assert.equal(run.calls[0].foundryRole, "hill-climb-planner");
162
+ assert.equal(run.calls[0].operationId, "fixture-test:fixture-repair:1");
163
+ const packet = JSON.parse(run.calls[0].input);
164
+ assert.deepEqual(packet.failedFixtures.map((entry) => entry.fixture.id), ["broken"]);
165
+ assert.equal(packet.failedFixtures[0].evidence.outcome, "unknown");
166
+ assert.equal(packet.failedFixtures[0].diagnostics[0].stage, "candidate-validation");
167
+ assert.match(packet.failedFixtures[0].diagnostics[0].stderr, /SyntaxError/u);
168
+ assert.equal(packet.context.pinnedManifest.apiVersion, "synthetic");
169
+ assert.deepEqual(result.suite.fixtures, data.suite.fixtures);
170
+ assert.deepEqual(result.suite.overlays[0], data.suite.overlays[0]);
171
+ assert.equal(result.suite.overlays[1].content, goodCode);
172
+ assert.equal(JSON.stringify(data.suite), original);
173
+ const host = run.artifacts.filter((artifact) => artifact.role === "fixture-validator");
174
+ assert.equal(host.length, 3, "the already-passing overlay is not replayed or rewritten by repair");
175
+ for (const artifact of host) {
176
+ const request = artifact.request.input;
177
+ assert.equal(request.replayInput.commit, data.seed.referenceCommit);
178
+ assert.equal(request.replayInput.contentOverlays.length, 1);
179
+ assert.equal(request.replayInput.repetitions, 1);
180
+ assert.equal(artifact.model, "local-replay");
181
+ const value = artifact.value;
182
+ assert.equal(value.admissionEvidence, false);
183
+ assert.ok(value.results.length > 0);
184
+ }
185
+ assert.equal(run.events.filter((event) => event.kind === "model-call" && event.phase === "complete").length, 1);
186
+ assert.ok(run.events
187
+ .filter((event) => event.role === "fixture-validator")
188
+ .every((event) => event.kind === "heartbeat"));
189
+ assert.ok(run.events.every((event) => !JSON.stringify(event).includes("SyntaxError")));
190
+ assert.equal(await readFile(join(data.root, "control.json"), "utf8"), "untrusted working tree");
191
+ });
192
+ test("passing reference fixtures require no repair or model calls", async (t) => {
193
+ const data = await fixture(t);
194
+ const suite = {
195
+ ...data.suite,
196
+ overlays: data.suite.overlays.map((overlay) => ({ ...overlay, content: goodCode }))
197
+ };
198
+ const run = runner(data, { suite, maximumRepairAttempts: 0 });
199
+ const result = await Effect.runPromise(run.effect);
200
+ assert.deepEqual(result.suite, suite);
201
+ assert.deepEqual(result.modelCalls, []);
202
+ assert.equal(run.calls.length, 0);
203
+ assert.equal(run.events.filter((event) => event.kind === "model-call").length, 0);
204
+ });
205
+ test("reference preflight does not overlap independent fixture command trees", async (t) => {
206
+ const data = await fixture(t);
207
+ const suite = {
208
+ ...data.suite,
209
+ overlays: data.suite.overlays.map((overlay) => ({ ...overlay, content: goodCode }))
210
+ };
211
+ let active = 0;
212
+ let peak = 0;
213
+ let executed = 0;
214
+ const run = runner(data, { suite, maximumRepairAttempts: 0 });
215
+ const result = await Effect.runPromise(run.effect.pipe(Effect.provideService(RepositoryCommandExecutionPort, {
216
+ run: (input) => Effect.tryPromise({
217
+ try: async () => {
218
+ active += 1;
219
+ peak = Math.max(peak, active);
220
+ executed += 1;
221
+ try {
222
+ // Allow a sibling replay to reach its first command if the
223
+ // preflight accidentally becomes parallel again.
224
+ await new Promise((resolve) => setTimeout(resolve, 1_000));
225
+ const { stdout, stderr } = await execute(input.executable, [...input.args], { cwd: input.cwd, env: input.environment, timeout: input.timeoutMs });
226
+ return { exitCode: 0, stdout, stderr, timedOut: false };
227
+ }
228
+ finally {
229
+ active -= 1;
230
+ }
231
+ },
232
+ catch: (cause) => new RepositoryFoundryError({
233
+ operation: "run-command",
234
+ detail: "reference preflight command failed",
235
+ cause
236
+ })
237
+ })
238
+ })));
239
+ assert.equal(result.modelCalls.length, 0);
240
+ assert.equal(executed, 4, "both fixtures must run validation and grading");
241
+ assert.equal(peak, 1, "one fixture's build and grade must finish before the next starts");
242
+ });
243
+ test("failed reference preflight returns concrete compiler evidence to the same author without copying overlay bodies", async (t) => {
244
+ const data = await fixture(t);
245
+ const run = runner(data, { maximumRepairAttempts: 0 });
246
+ const result = await Effect.runPromise(run.effect.pipe(Effect.result));
247
+ assert.equal(result._tag, "Failure");
248
+ if (result._tag !== "Failure")
249
+ return;
250
+ const feedback = repositoryFixturePreflightFeedbackV1(result.failure);
251
+ assert.match(feedback, /SyntaxError/);
252
+ assert.match(feedback, /candidate-validation/);
253
+ assert.match(feedback, /"gradeExecuted":false/);
254
+ assert.match(feedback, /case\.test\.mjs/);
255
+ assert.doesNotMatch(feedback, /\[object Object\]/);
256
+ assert.ok(!feedback.includes(goodCode));
257
+ assert.ok(feedback.length < 20_000);
258
+ });
259
+ test("fixture preflight retains completed overlays and invalidates only changed executable inputs", async (t) => {
260
+ const data = await fixture(t);
261
+ const checkpointStore = makeCaseCheckpointStoreV1({ caseDirectory: join(data.root, "preflight-work") });
262
+ const suite = {
263
+ ...data.suite,
264
+ overlays: data.suite.overlays.map((overlay) => ({ ...overlay, content: goodCode }))
265
+ };
266
+ await Effect.runPromise(runner(data, { suite, checkpointStore, maximumRepairAttempts: 0 }).effect);
267
+ const restored = runner(data, { suite, checkpointStore, maximumRepairAttempts: 0 });
268
+ await Effect.runPromise(restored.effect.pipe(Effect.provideService(RepositoryCommandExecutionPort, {
269
+ run: () => Effect.fail(new RepositoryFoundryError({
270
+ operation: "run-command", detail: "completed preflight must not execute again"
271
+ }))
272
+ })));
273
+ assert.ok(restored.artifacts.filter((artifact) => artifact.role === "fixture-validator")
274
+ .every((artifact) => artifact.value.restored));
275
+ const changed = runner(data, {
276
+ suite: { ...suite, overlays: suite.overlays.map((overlay, index) => index === 0 ? { ...overlay, content: `${goodCode}\n// distinct executable input\n` } : overlay) },
277
+ checkpointStore, maximumRepairAttempts: 0
278
+ });
279
+ await Effect.runPromise(changed.effect);
280
+ const flags = changed.artifacts.filter((artifact) => artifact.role === "fixture-validator")
281
+ .map((artifact) => artifact.value.restored).sort();
282
+ assert.deepEqual(flags, [false, true]);
283
+ });
284
+ test("failed reference preflight stops at its bounded repair allowance before downstream generation", async (t) => {
285
+ const data = await fixture(t);
286
+ for (const maximumRepairAttempts of [0, 2]) {
287
+ const run = runner(data, {
288
+ maximumRepairAttempts,
289
+ reply: () => ({ overlays: [data.suite.overlays[1]] })
290
+ });
291
+ await assert.rejects(Effect.runPromise(run.effect), /fixture preflight failed after/u);
292
+ assert.equal(run.calls.length, maximumRepairAttempts);
293
+ assert.ok(run.calls.every((call) => call.foundryRole === "hill-climb-planner"));
294
+ assert.equal(run.artifacts.filter((artifact) => artifact.role === "fixture-validator").length, 2 + maximumRepairAttempts);
295
+ }
296
+ });
297
+ test("repair cannot remove a failed fixture, alter its path or identity, or rewrite a passing overlay", async (t) => {
298
+ const data = await fixture(t);
299
+ for (const overlays of [
300
+ [],
301
+ [{ path: "other.test.mjs", content: goodCode, fixtureIds: ["broken"] }],
302
+ [{ path: "case.test.mjs", content: goodCode, fixtureIds: ["renamed"] }],
303
+ [{ path: "case.test.mjs", content: goodCode, fixtureIds: ["good"] }],
304
+ [{ path: "case.test.mjs", content: goodCode, fixtureIds: ["broken", "good"] }]
305
+ ]) {
306
+ const run = runner(data, { reply: () => ({ overlays }) });
307
+ await assert.rejects(Effect.runPromise(run.effect), /fixture repair changed frozen identity/u);
308
+ assert.equal(run.calls.length, 1);
309
+ assert.equal(run.artifacts.filter((artifact) => artifact.role === "fixture-validator").length, 2);
310
+ }
311
+ });
312
+ test("invalid fixture metadata and paths fail before any replay or model request", async (t) => {
313
+ const data = await fixture(t);
314
+ for (const suite of [
315
+ { ...data.suite, fixtures: [data.suite.fixtures[0], data.suite.fixtures[0]] },
316
+ { ...data.suite, overlays: [] },
317
+ {
318
+ ...data.suite,
319
+ fixtures: data.suite.fixtures.map((fixture) => ({
320
+ ...fixture,
321
+ testPath: "../case.test.mjs"
322
+ })),
323
+ overlays: data.suite.overlays.map((overlay) => ({ ...overlay, path: "../case.test.mjs" }))
324
+ },
325
+ {
326
+ ...data.suite,
327
+ fixtures: data.suite.fixtures.map((fixture) => ({ ...fixture, expectedBehavior: "" }))
328
+ }
329
+ ]) {
330
+ const run = runner(data, { suite });
331
+ await assert.rejects(Effect.runPromise(run.effect), /fixture preflight input failed validation/u);
332
+ assert.equal(run.calls.length, 0);
333
+ assert.equal(run.artifacts.length, 0);
334
+ }
335
+ });
336
+ test("a malformed model response still consumes its reserved fixture repair attempt", async (t) => {
337
+ const data = await fixture(t);
338
+ const run = runner(data, { reply: () => ({ unexpected: true }) });
339
+ await assert.rejects(Effect.runPromise(run.effect), /violated routekit_repository_fixture_overlay_repair_v1/u);
340
+ assert.equal(run.calls.length, 1);
341
+ assert.deepEqual(run.repairAccounting, { attempts: 1, validatedCalls: 0 });
342
+ assert.equal(run.events.filter((event) => event.phase === "complete").at(-1)?.modelCalls, 1);
343
+ });
344
+ test("runtime errors, failing setup hooks, and empty test discovery remain unknown and block preflight", async (t) => {
345
+ const data = await fixture(t);
346
+ for (const code of [
347
+ 'import test from "node:test"; test("contract", () => { throw new TypeError("runtime"); });',
348
+ 'import test,{beforeEach} from "node:test"; import assert from "node:assert/strict"; beforeEach(() => assert.fail("setup")); test("contract", () => {});',
349
+ "export const noTests = true;"
350
+ ]) {
351
+ const run = runner(data, {
352
+ maximumRepairAttempts: 0,
353
+ suite: {
354
+ ...data.suite,
355
+ overlays: data.suite.overlays.map((overlay) => ({ ...overlay, content: code }))
356
+ }
357
+ });
358
+ await assert.rejects(Effect.runPromise(run.effect), /fixture preflight failed after/u);
359
+ assert.equal(run.calls.length, 0);
360
+ assert.ok(run.artifacts.every((artifact) => artifact.value.evidence.outcome === "unknown"));
361
+ }
362
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,110 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { Effect, Layer } from "effect";
4
+ import { boundRepositoryFoundryIdleStallMsV1, formatRepositoryFoundryProgressLineV1, makeRepositoryFoundryProgress, REPOSITORY_FOUNDRY_DEFAULT_IDLE_STALL_MS, reportFoundryModelCallV1, reportFoundryStageV1, RepositoryFoundryIdleStallError, RepositoryFoundryProgress, withRepositoryFoundryIdleStall } from "../index.js";
5
+ test("foundry progress emits stage and model-call events", async () => {
6
+ const events = [];
7
+ const progress = await Effect.runPromise(makeRepositoryFoundryProgress((event) => Effect.sync(() => {
8
+ events.push(event);
9
+ })));
10
+ await Effect.runPromise(Effect.gen(function* () {
11
+ yield* reportFoundryStageV1("author-specification");
12
+ yield* reportFoundryModelCallV1({ role: "repository-analyst", phase: "start" });
13
+ yield* reportFoundryModelCallV1({
14
+ role: "repository-analyst",
15
+ phase: "complete",
16
+ callId: "call_1"
17
+ });
18
+ yield* reportFoundryStageV1("tournament");
19
+ const snap = yield* progress.snapshot;
20
+ assert.equal(snap.stage, "tournament");
21
+ assert.equal(snap.modelCalls, 1);
22
+ }).pipe(Effect.provideService(RepositoryFoundryProgress, progress)));
23
+ assert.equal(events.length, 4);
24
+ assert.equal(events[0]?.kind, "stage");
25
+ assert.equal(events[0]?.stage, "author-specification");
26
+ assert.equal(events[1]?.kind, "model-call");
27
+ assert.equal(events[1]?.phase, "start");
28
+ assert.equal(events[2]?.phase, "complete");
29
+ assert.equal(events[2]?.modelCalls, 1);
30
+ assert.match(formatRepositoryFoundryProgressLineV1(events[2]), /foundry progress kind=model-call stage=author-specification modelCalls=1 role=repository-analyst phase=complete callId=call_1/u);
31
+ });
32
+ test("idle stall fails closed before first model call when progress stays flat", async () => {
33
+ const progress = await Effect.runPromise(makeRepositoryFoundryProgress());
34
+ const startedAt = Date.now();
35
+ const error = await Effect.runPromise(withRepositoryFoundryIdleStall(Effect.gen(function* () {
36
+ yield* reportFoundryStageV1("execute-start");
37
+ // Silent post-turbo authoring: no further stage/modelCalls emissions.
38
+ yield* Effect.sleep(5_000);
39
+ return "should-not-reach";
40
+ }), {
41
+ idleStallMs: 80,
42
+ wallTimeMs: 10_000
43
+ }).pipe(Effect.provideService(RepositoryFoundryProgress, progress), Effect.flip));
44
+ assert.ok(error instanceof RepositoryFoundryIdleStallError);
45
+ assert.equal(error.stage, "execute-start");
46
+ assert.equal(error.modelCalls, 0);
47
+ assert.match(error.message, /stalled/u);
48
+ assert.match(error.message, /idleStallMs=80/u);
49
+ assert.ok(Date.now() - startedAt < 2_000);
50
+ });
51
+ test("idle stall fails closed after a hung model-call start with no completion", async () => {
52
+ const progress = await Effect.runPromise(makeRepositoryFoundryProgress());
53
+ const startedAt = Date.now();
54
+ const error = await Effect.runPromise(withRepositoryFoundryIdleStall(Effect.gen(function* () {
55
+ yield* reportFoundryStageV1("author-specification");
56
+ yield* reportFoundryModelCallV1({
57
+ role: "repository-analyst",
58
+ phase: "start"
59
+ });
60
+ // Hung provider call or stalled transport: start emitted, nothing else.
61
+ yield* Effect.sleep(5_000);
62
+ return "should-not-reach";
63
+ }), {
64
+ idleStallMs: 80,
65
+ wallTimeMs: 10_000
66
+ }).pipe(Effect.provideService(RepositoryFoundryProgress, progress), Effect.flip));
67
+ assert.ok(error instanceof RepositoryFoundryIdleStallError);
68
+ assert.equal(error.stage, "author-specification");
69
+ assert.equal(error.modelCalls, 0);
70
+ assert.match(error.message, /stalled/u);
71
+ assert.ok(Date.now() - startedAt < 2_000);
72
+ });
73
+ test("normal progress does not false-trigger idle stall", async () => {
74
+ const progress = await Effect.runPromise(makeRepositoryFoundryProgress());
75
+ const result = await Effect.runPromise(withRepositoryFoundryIdleStall(Effect.gen(function* () {
76
+ for (let index = 0; index < 5; index += 1) {
77
+ yield* Effect.sleep(40);
78
+ yield* reportFoundryModelCallV1({
79
+ role: "oracle-designer",
80
+ phase: index % 2 === 0 ? "start" : "complete"
81
+ });
82
+ }
83
+ return "ok";
84
+ }), {
85
+ idleStallMs: 120,
86
+ wallTimeMs: 10_000
87
+ }).pipe(Effect.provideService(RepositoryFoundryProgress, progress)));
88
+ assert.equal(result, "ok");
89
+ const snap = await Effect.runPromise(progress.snapshot);
90
+ assert.equal(snap.modelCalls, 2);
91
+ });
92
+ test("idle stall is capped by wall and defaults to twenty minutes", () => {
93
+ assert.equal(REPOSITORY_FOUNDRY_DEFAULT_IDLE_STALL_MS, 20 * 60_000);
94
+ assert.equal(boundRepositoryFoundryIdleStallMsV1(undefined, 4 * 60 * 60_000), 20 * 60_000);
95
+ assert.equal(boundRepositoryFoundryIdleStallMsV1(60_000, 30_000), 30_000);
96
+ });
97
+ test("progress helpers no-op without a progress service", async () => {
98
+ await Effect.runPromise(Effect.gen(function* () {
99
+ yield* reportFoundryStageV1("execute-start");
100
+ yield* reportFoundryModelCallV1({ role: "adversary", phase: "start" });
101
+ }));
102
+ });
103
+ test("RepositoryFoundryProgressLive layer wires emit", async () => {
104
+ const events = [];
105
+ const layer = Layer.effect(RepositoryFoundryProgress, makeRepositoryFoundryProgress((event) => Effect.sync(() => {
106
+ events.push(event.stage);
107
+ })));
108
+ await Effect.runPromise(reportFoundryStageV1("admit").pipe(Effect.provide(layer)));
109
+ assert.deepEqual(events, ["admit"]);
110
+ });
@@ -0,0 +1 @@
1
+ export {};