@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
@@ -0,0 +1,632 @@
1
+ import { createHash } from "node:crypto";
2
+ const MAXIMUM_JSON_BYTES = 16 * 1024 * 1024;
3
+ const digest = (text) => createHash("sha256").update(JSON.stringify(text), "utf8").digest("hex");
4
+ const bytes = (value) => Buffer.byteLength(JSON.stringify(value), "utf8");
5
+ const spliceContext = (base, prefix, suffix) => {
6
+ const end = base.length - suffix;
7
+ return {
8
+ startLine: base.slice(0, prefix).split("\n").length,
9
+ endLine: base.slice(0, end).split("\n").length,
10
+ immediatelyBefore: base.slice(Math.max(0, prefix - 120), prefix),
11
+ immediatelyAfter: base.slice(end, end + 120)
12
+ };
13
+ };
14
+ export const REPOSITORY_REVIEW_EVIDENCE_INSTRUCTIONS = `The input uses routekit-lossless-review-json-v1.
15
+ Decode evidence before reviewing it. Null, booleans, numbers, and strings represent themselves.
16
+ Every original object is ["object", [[key, encodedValue], ...]], and every original array is
17
+ ["array", [encodedValue, ...]]. ["text", digest] resolves a string from texts. A text entry is
18
+ ["literal", exactString] or ["splice", baseDigest, prefixChars, suffixChars, replacement, context].
19
+ For a splice, retain the first prefixChars and last suffixChars of the literal base string and
20
+ insert replacement between them. Character counts use JavaScript UTF-16 code units, not UTF-8 bytes.
21
+ The verified context gives one-based start/end lines in the base and up to 120 characters immediately
22
+ before and after the replaced range, so you can locate the changed code without counting characters.
23
+ Digests are SHA-256 of UTF-8 JSON.stringify(exactString). The host verified exact reconstruction.
24
+ All original fields, source, controls, and evidence are retained. Evidence-inventory paths address
25
+ the decoded original object; the encoding does not change those paths or their meaning.`;
26
+ /** Factor full-file variants without weakening or truncating the review evidence. */
27
+ export function encodeRepositoryReviewEvidenceV1(input, sourceBases) {
28
+ let size = 0;
29
+ const frequencies = new Map();
30
+ const addBytes = (count) => {
31
+ size += count;
32
+ if (size > MAXIMUM_JSON_BYTES)
33
+ throw new Error("review evidence exceeds the 16MiB encoding bound");
34
+ };
35
+ const normalize = (value, depth = 0) => {
36
+ if (depth > 128)
37
+ throw new Error("review evidence exceeds the encoding depth bound");
38
+ if (value === null || typeof value === "boolean" || typeof value === "number") {
39
+ const normalized = typeof value === "number" && !Number.isFinite(value) ? null : value;
40
+ addBytes(bytes(normalized));
41
+ return normalized;
42
+ }
43
+ if (typeof value === "string") {
44
+ const length = bytes(value);
45
+ addBytes(length);
46
+ if (length >= 256)
47
+ frequencies.set(value, (frequencies.get(value) ?? 0) + 1);
48
+ return value;
49
+ }
50
+ if (Array.isArray(value)) {
51
+ if (typeof value.toJSON === "function")
52
+ throw new Error("review evidence requires plain JSON arrays without toJSON transformations");
53
+ addBytes(2 + Math.max(0, value.length - 1));
54
+ return value.map((entry) => normalize(entry === undefined ? null : entry, depth + 1));
55
+ }
56
+ if (typeof value === "object" && value !== null) {
57
+ const prototype = Object.getPrototypeOf(value);
58
+ if ((prototype !== Object.prototype && prototype !== null) ||
59
+ typeof value.toJSON === "function")
60
+ throw new Error("review evidence requires plain JSON objects without toJSON transformations");
61
+ const entries = Object.entries(value).filter(([, entry]) => entry !== undefined);
62
+ addBytes(2 + Math.max(0, entries.length - 1));
63
+ return Object.fromEntries(entries.map(([key, entry]) => {
64
+ addBytes(bytes(key) + 1);
65
+ return [key, normalize(entry, depth + 1)];
66
+ }));
67
+ }
68
+ throw new Error("review evidence must be JSON serializable");
69
+ };
70
+ const original = normalize(input);
71
+ const originalJson = JSON.stringify(original);
72
+ if (originalJson !== JSON.stringify(input))
73
+ throw new Error("review evidence normalization changed its JSON serialization");
74
+ const bases = [...new Set(sourceBases)].map((content) => ({ content, key: digest(content) }));
75
+ if (bases.reduce((total, base) => total + Buffer.byteLength(base.content), 0) > MAXIMUM_JSON_BYTES)
76
+ throw new Error("review source bases exceed the 16MiB encoding bound");
77
+ const texts = Object.create(null);
78
+ const textKeys = new Map();
79
+ for (const [content, frequency] of frequencies) {
80
+ const key = digest(content);
81
+ const contentBytes = bytes(content);
82
+ let best;
83
+ for (const base of bases) {
84
+ let prefix = 0;
85
+ while (prefix < content.length &&
86
+ prefix < base.content.length &&
87
+ content.charCodeAt(prefix) === base.content.charCodeAt(prefix))
88
+ prefix += 1;
89
+ let suffix = 0;
90
+ while (suffix < content.length - prefix &&
91
+ suffix < base.content.length - prefix &&
92
+ content.charCodeAt(content.length - suffix - 1) ===
93
+ base.content.charCodeAt(base.content.length - suffix - 1))
94
+ suffix += 1;
95
+ const entry = [
96
+ "splice",
97
+ base.key,
98
+ prefix,
99
+ suffix,
100
+ content.slice(prefix, content.length - suffix),
101
+ spliceContext(base.content, prefix, suffix)
102
+ ];
103
+ const length = bytes(entry);
104
+ if (length + 160 < contentBytes && (best === undefined || length < best.size))
105
+ best = { base, entry, size: length };
106
+ }
107
+ if (best !== undefined) {
108
+ texts[best.base.key] = ["literal", best.base.content];
109
+ // A base must remain literal even if it also occurs in the evidence.
110
+ if (texts[key]?.[0] !== "literal")
111
+ texts[key] = best.entry;
112
+ textKeys.set(content, key);
113
+ }
114
+ else if (frequency > 1) {
115
+ texts[key] = ["literal", content];
116
+ textKeys.set(content, key);
117
+ }
118
+ }
119
+ const encode = (value) => {
120
+ if (typeof value === "string") {
121
+ const key = textKeys.get(value);
122
+ return key === undefined ? value : ["text", key];
123
+ }
124
+ if (Array.isArray(value))
125
+ return ["array", value.map(encode)];
126
+ if (typeof value === "object" && value !== null)
127
+ return ["object", Object.entries(value).map(([key, entry]) => [key, encode(entry)])];
128
+ return value;
129
+ };
130
+ const packet = {
131
+ encoding: "routekit-lossless-review-json-v1",
132
+ texts,
133
+ evidence: encode(original)
134
+ };
135
+ if (JSON.stringify(decodeRepositoryReviewEvidenceV1(packet)) !== originalJson)
136
+ throw new Error("review evidence did not reconstruct exactly");
137
+ return packet;
138
+ }
139
+ /** Host-side integrity check; the reviewer receives the same reconstruction rules. */
140
+ export function decodeRepositoryReviewEvidenceV1(packet) {
141
+ if (packet.encoding !== "routekit-lossless-review-json-v1")
142
+ throw new Error("unknown review evidence encoding");
143
+ const text = (key) => {
144
+ const entry = packet.texts[key];
145
+ if (entry === undefined)
146
+ throw new Error("review text reference is missing");
147
+ let value;
148
+ if (entry[0] === "literal")
149
+ value = entry[1];
150
+ else {
151
+ const [, baseKey, prefix, suffix, replacement, context] = entry;
152
+ const base = packet.texts[baseKey];
153
+ if (base?.[0] !== "literal" ||
154
+ digest(base[1]) !== baseKey ||
155
+ !Number.isSafeInteger(prefix) ||
156
+ !Number.isSafeInteger(suffix) ||
157
+ prefix < 0 ||
158
+ suffix < 0 ||
159
+ prefix + suffix > base[1].length)
160
+ throw new Error("review text splice has an invalid base or overlapping ranges");
161
+ if (JSON.stringify(context) !== JSON.stringify(spliceContext(base[1], prefix, suffix)))
162
+ throw new Error("review text splice context does not match its source range");
163
+ value = base[1].slice(0, prefix) + replacement + base[1].slice(base[1].length - suffix);
164
+ }
165
+ if (digest(value) !== key)
166
+ throw new Error("review text digest mismatch");
167
+ return value;
168
+ };
169
+ const decode = (node) => {
170
+ if (!Array.isArray(node))
171
+ return node;
172
+ const tagged = node;
173
+ switch (tagged[0]) {
174
+ case "text":
175
+ return text(tagged[1]);
176
+ case "array":
177
+ return tagged[1].map(decode);
178
+ case "object":
179
+ return Object.fromEntries(tagged[1].map(([key, entry]) => [key, decode(entry)]));
180
+ default:
181
+ throw new Error("unknown review evidence node");
182
+ }
183
+ };
184
+ return decode(packet.evidence);
185
+ }
186
+ export const REPOSITORY_REVIEW_EVIDENCE_V2_INSTRUCTIONS = `The input uses routekit-lossless-review-json-v2.
187
+ Decode evidence before reviewing it. Null, booleans, numbers, and strings represent themselves.
188
+ ["a", ...items] represents an original array of decoded items. ["r", shapeIndex, ...values]
189
+ represents an original object: zip shapes[shapeIndex] with the decoded values, in the given order.
190
+ For example, shapes[0]=["solutionId","outcome"] and ["r",0,"candidate-a","fail"] represents
191
+ {"solutionId":"candidate-a","outcome":"fail"}. Every original array or object has an explicit tag.
192
+ ["s", index] resolves exactly strings[index]. ["j", ...parts] concatenates decoded string
193
+ parts without adding or removing spaces or delimiters. These joins factor repetitive diagnostics and evidence paths;
194
+ the individual outcome, duration, error, and other evidence fields remain available.
195
+ ["n", index] resolves exactly nodes[index]. These shared arrays and objects avoid repeating
196
+ identical fixtures and control overlays across the proposal and executed evidence. A node may
197
+ refer only to earlier node entries. Every occurrence reconstructs the complete original subtree.
198
+ ["t", index] resolves texts[index], a [digest, entry] pair. An entry is ["literal", exactString]
199
+ or ["splice", baseDigest, prefixChars, suffixChars, replacement, context]. Locate the literal base
200
+ by its digest in texts. Retain its first prefixChars and last suffixChars, inserting replacement
201
+ between them. Counts use JavaScript UTF-16 code units. The verified context gives one-based start/end
202
+ lines and up to 120 characters immediately before and after the replacement.
203
+ A ["patch", baseDigest, hunks] entry applies separated edits to the exact resolved base string.
204
+ Each hunk is [startChars, endChars, exactReplacement, context]. Offsets are zero-based UTF-16,
205
+ end-exclusive, ordered, nonoverlapping ranges in the ORIGINAL base. Preserve all text between
206
+ ranges; insert each replacement once. Context verifies the original source lines and neighboring
207
+ text. A base may itself be encoded; text dependencies are acyclic and the host validates every digest.
208
+ Text digests are SHA-256
209
+ of UTF-8 JSON.stringify(exactString). originalDigest binds the complete decoded original JSON.
210
+ The host verified exact reconstruction. No source, control, observation, or evidence-inventory entry
211
+ was omitted. Evidence-inventory paths address the decoded original object, with unchanged meaning.`;
212
+ // Delimited execution diagnostics contain many stable fields and a few changing
213
+ // measurements. Preserve every delimiter and byte; never split multiline code.
214
+ const diagnosticParts = (value) => {
215
+ if (value.includes("\n"))
216
+ return [value];
217
+ if (value.length > 120 && (value.match(/;/gu)?.length ?? 0) >= 3)
218
+ return value.match(/[^;]*(?:;|$)/gu)?.filter((part) => part.length > 0) ?? [value];
219
+ const slash = value.lastIndexOf("/");
220
+ if (slash > 12 && /^[0-9]+$/u.test(value.slice(slash + 1)))
221
+ return [value.slice(0, slash + 1), value.slice(slash + 1)];
222
+ return [value];
223
+ };
224
+ /** Unique line anchors retain distant unchanged regions without synthesizing source. */
225
+ const sourceHunks = (base, changed) => {
226
+ const lines = (text) => [...text.matchAll(/[^\n]*\n|[^\n]+$/gu)].map((match) => ({
227
+ text: match[0],
228
+ start: match.index,
229
+ end: match.index + match[0].length
230
+ }));
231
+ const before = lines(base);
232
+ const after = lines(changed);
233
+ const unique = (values) => {
234
+ const indexes = new Map();
235
+ values.forEach((line, index) => {
236
+ if (line.text.trim().length >= 8)
237
+ indexes.set(line.text, indexes.has(line.text) ? -1 : index);
238
+ });
239
+ return indexes;
240
+ };
241
+ const beforeIndexes = unique(before);
242
+ const afterIndexes = unique(after);
243
+ const pairs = [];
244
+ for (const [text, afterIndex] of afterIndexes) {
245
+ const beforeIndex = beforeIndexes.get(text);
246
+ if (afterIndex >= 0 && beforeIndex !== undefined && beforeIndex >= 0)
247
+ pairs.push({ before: beforeIndex, after: afterIndex });
248
+ }
249
+ pairs.sort((left, right) => left.after - right.after);
250
+ const tails = [];
251
+ const previous = [];
252
+ pairs.forEach((pair, index) => {
253
+ let low = 0;
254
+ let high = tails.length;
255
+ while (low < high) {
256
+ const middle = (low + high) >>> 1;
257
+ if (pairs[tails[middle]].before < pair.before)
258
+ low = middle + 1;
259
+ else
260
+ high = middle;
261
+ }
262
+ previous[index] = low === 0 ? -1 : tails[low - 1];
263
+ tails[low] = index;
264
+ });
265
+ const anchors = [];
266
+ for (let index = tails.at(-1) ?? -1; index >= 0; index = previous[index])
267
+ anchors.push(pairs[index]);
268
+ anchors.reverse();
269
+ const hunks = [];
270
+ const add = (start, end, replacement) => {
271
+ const original = base.slice(start, end);
272
+ if (original === replacement)
273
+ return;
274
+ let prefix = 0;
275
+ while (prefix < original.length &&
276
+ prefix < replacement.length &&
277
+ original.charCodeAt(prefix) === replacement.charCodeAt(prefix))
278
+ prefix += 1;
279
+ let suffix = 0;
280
+ while (suffix < original.length - prefix &&
281
+ suffix < replacement.length - prefix &&
282
+ original.charCodeAt(original.length - suffix - 1) ===
283
+ replacement.charCodeAt(replacement.length - suffix - 1))
284
+ suffix += 1;
285
+ const hunk = [
286
+ start + prefix,
287
+ end - suffix,
288
+ replacement.slice(prefix, replacement.length - suffix),
289
+ spliceContext(base, start + prefix, base.length - end + suffix)
290
+ ];
291
+ const last = hunks.at(-1);
292
+ if (last !== undefined && hunk[0] - last[1] < 512) {
293
+ const joined = [
294
+ last[0],
295
+ hunk[1],
296
+ last[2] + base.slice(last[1], hunk[0]) + hunk[2],
297
+ spliceContext(base, last[0], base.length - hunk[1])
298
+ ];
299
+ if (bytes(joined) <= bytes(last) + bytes(hunk)) {
300
+ hunks[hunks.length - 1] = joined;
301
+ return;
302
+ }
303
+ }
304
+ hunks.push(hunk);
305
+ };
306
+ let baseStart = 0;
307
+ let changedStart = 0;
308
+ for (const anchor of anchors) {
309
+ const left = before[anchor.before];
310
+ const right = after[anchor.after];
311
+ add(baseStart, left.start, changed.slice(changedStart, right.start));
312
+ baseStart = left.end;
313
+ changedStart = right.end;
314
+ }
315
+ add(baseStart, base.length, changed.slice(changedStart));
316
+ return hunks;
317
+ };
318
+ /** Lossless row and string dictionaries keep full observed populations reviewable. */
319
+ export function encodeRepositoryReviewEvidenceV2(input, sourceBases) {
320
+ const original = encodeRepositoryReviewEvidenceV1(input, sourceBases);
321
+ const texts = Object.entries(original.texts);
322
+ const textIndexes = new Map(texts.map(([key], index) => [key, index]));
323
+ const sourceCandidates = [];
324
+ const resolvedOriginal = (key) => decodeRepositoryReviewEvidenceV1({
325
+ ...original,
326
+ evidence: ["text", key]
327
+ });
328
+ for (const [index, [key, entry]] of texts.entries()) {
329
+ const content = resolvedOriginal(key);
330
+ let best = entry;
331
+ if (content.includes("\n") && content.length >= 512) {
332
+ const candidates = entry[0] === "splice"
333
+ ? [
334
+ { key: entry[1], content: resolvedOriginal(entry[1]) },
335
+ ...sourceCandidates.filter((candidate) => candidate.key !== entry[1])
336
+ ]
337
+ : sourceCandidates;
338
+ for (const candidate of candidates) {
339
+ const patch = [
340
+ "patch",
341
+ candidate.key,
342
+ sourceHunks(candidate.content, content)
343
+ ];
344
+ if (bytes(patch) < bytes(best))
345
+ best = patch;
346
+ }
347
+ }
348
+ texts[index] = [key, best];
349
+ // Only original literals become bases, in their original order. Existing
350
+ // splices refer to those literals; new literal dependencies point backwards.
351
+ if (entry[0] === "literal" && content.includes("\n") && content.length >= 512)
352
+ sourceCandidates.push({ key, content });
353
+ }
354
+ const inlineTexts = new Map();
355
+ const factorInline = (node) => {
356
+ if (typeof node === "string" && node.includes("\n") && node.length >= 512) {
357
+ if (inlineTexts.has(node))
358
+ return;
359
+ const key = digest(node);
360
+ const existing = textIndexes.get(key);
361
+ if (existing !== undefined) {
362
+ inlineTexts.set(node, existing);
363
+ return;
364
+ }
365
+ let best;
366
+ for (const candidate of sourceCandidates) {
367
+ const patch = ["patch", candidate.key, sourceHunks(candidate.content, node)];
368
+ if (bytes(patch) + 100 < bytes(node) && (best === undefined || bytes(patch) < bytes(best)))
369
+ best = patch;
370
+ }
371
+ if (best !== undefined) {
372
+ inlineTexts.set(node, texts.length);
373
+ textIndexes.set(key, texts.length);
374
+ texts.push([key, best]);
375
+ }
376
+ }
377
+ else if (Array.isArray(node)) {
378
+ const tagged = node;
379
+ if (tagged[0] === "object")
380
+ for (const [, entry] of tagged[1])
381
+ factorInline(entry);
382
+ if (tagged[0] === "array")
383
+ for (const entry of tagged[1])
384
+ factorInline(entry);
385
+ }
386
+ };
387
+ factorInline(original.evidence);
388
+ const frequencies = new Map();
389
+ const count = (node) => {
390
+ if (typeof node === "string") {
391
+ for (const part of diagnosticParts(node))
392
+ frequencies.set(part, (frequencies.get(part) ?? 0) + 1);
393
+ }
394
+ else if (Array.isArray(node)) {
395
+ const tagged = node;
396
+ if (tagged[0] === "object")
397
+ for (const [, entry] of tagged[1])
398
+ count(entry);
399
+ if (tagged[0] === "array")
400
+ for (const entry of tagged[1])
401
+ count(entry);
402
+ }
403
+ };
404
+ count(original.evidence);
405
+ const strings = [...frequencies]
406
+ .filter(([text, frequency]) => frequency > 1 && text.length >= 12)
407
+ .map(([text]) => text);
408
+ const stringIndexes = new Map(strings.map((text, index) => [text, index]));
409
+ const shapes = [];
410
+ const shapeIndexes = new Map();
411
+ const encodeString = (value) => {
412
+ const index = stringIndexes.get(value);
413
+ return index === undefined ? value : ["s", index];
414
+ };
415
+ const encode = (node) => {
416
+ if (typeof node === "string") {
417
+ const textIndex = inlineTexts.get(node);
418
+ if (textIndex !== undefined)
419
+ return ["t", textIndex];
420
+ const literal = encodeString(node);
421
+ const parts = diagnosticParts(node);
422
+ if (parts.length === 1)
423
+ return literal;
424
+ const joined = ["j", ...parts.map(encodeString)];
425
+ return bytes(joined) < bytes(literal) ? joined : literal;
426
+ }
427
+ if (!Array.isArray(node))
428
+ return node;
429
+ const tagged = node;
430
+ if (tagged[0] === "text")
431
+ return ["t", textIndexes.get(tagged[1])];
432
+ if (tagged[0] === "array")
433
+ return ["a", ...tagged[1].map(encode)];
434
+ const keys = tagged[1].map(([key]) => key);
435
+ const signature = JSON.stringify(keys);
436
+ let index = shapeIndexes.get(signature);
437
+ if (index === undefined) {
438
+ index = shapes.length;
439
+ shapeIndexes.set(signature, index);
440
+ shapes.push(keys);
441
+ }
442
+ return ["r", index, ...tagged[1].map(([, entry]) => encode(entry))];
443
+ };
444
+ const expandedEvidence = encode(original.evidence);
445
+ const subtreeCounts = new Map();
446
+ const countSubtrees = (node) => {
447
+ if (!Array.isArray(node))
448
+ return;
449
+ const tagged = node;
450
+ const signature = JSON.stringify(tagged);
451
+ if (signature.length >= 96)
452
+ subtreeCounts.set(signature, (subtreeCounts.get(signature) ?? 0) + 1);
453
+ for (const child of tagged)
454
+ countSubtrees(child);
455
+ };
456
+ countSubtrees(expandedEvidence);
457
+ const nodes = [];
458
+ const nodeIndexes = new Map();
459
+ const share = (node) => {
460
+ if (!Array.isArray(node))
461
+ return node;
462
+ const tagged = node;
463
+ const signature = JSON.stringify(tagged);
464
+ const existing = nodeIndexes.get(signature);
465
+ if (existing !== undefined)
466
+ return ["n", existing];
467
+ const shared = tagged[0] === "r"
468
+ ? ["r", tagged[1], ...tagged.slice(2).map(share)]
469
+ : tagged[0] === "a"
470
+ ? ["a", ...tagged.slice(1).map(share)]
471
+ : tagged[0] === "j"
472
+ ? ["j", ...tagged.slice(1).map(share)]
473
+ : tagged;
474
+ if ((subtreeCounts.get(signature) ?? 0) > 1) {
475
+ const index = nodes.length;
476
+ nodes.push(shared);
477
+ nodeIndexes.set(signature, index);
478
+ return ["n", index];
479
+ }
480
+ return shared;
481
+ };
482
+ const evidence = share(expandedEvidence);
483
+ const packet = {
484
+ encoding: "routekit-lossless-review-json-v2",
485
+ originalDigest: digest(JSON.stringify(input)),
486
+ texts,
487
+ shapes,
488
+ strings,
489
+ nodes,
490
+ evidence
491
+ };
492
+ if (JSON.stringify(decodeRepositoryReviewEvidenceV2(packet)) !== JSON.stringify(input))
493
+ throw new Error("compact review evidence did not reconstruct exactly");
494
+ return packet;
495
+ }
496
+ /** Reject malformed tables and any change to the complete reconstructed evidence. */
497
+ export function decodeRepositoryReviewEvidenceV2(packet) {
498
+ if (packet.encoding !== "routekit-lossless-review-json-v2")
499
+ throw new Error("unknown compact review evidence encoding");
500
+ if (bytes(packet) > MAXIMUM_JSON_BYTES)
501
+ throw new Error("compact review evidence exceeds the 16MiB encoding bound");
502
+ const indexed = (table, index, name) => {
503
+ if (typeof index !== "number" ||
504
+ !Number.isSafeInteger(index) ||
505
+ index < 0 ||
506
+ index >= table.length)
507
+ throw new Error(`compact review ${name} reference is missing`);
508
+ return table[index];
509
+ };
510
+ if (new Set(packet.texts.map(([key]) => key)).size !== packet.texts.length)
511
+ throw new Error("compact review text keys must be unique");
512
+ const textTable = new Map(packet.texts);
513
+ const resolvedTexts = new Map();
514
+ const resolving = new Set();
515
+ const resolveText = (key, depth = 0) => {
516
+ const cached = resolvedTexts.get(key);
517
+ if (cached !== undefined)
518
+ return cached;
519
+ if (depth > 128 || resolving.has(key))
520
+ throw new Error("compact review text dependencies must be bounded and acyclic");
521
+ const entry = textTable.get(key);
522
+ if (entry === undefined)
523
+ throw new Error("compact review text base is missing");
524
+ resolving.add(key);
525
+ let value;
526
+ if (entry[0] === "literal")
527
+ value = entry[1];
528
+ else {
529
+ const base = resolveText(entry[1], depth + 1);
530
+ const hunks = entry[0] === "splice"
531
+ ? [[entry[2], base.length - entry[3], entry[4], entry[5]]]
532
+ : entry[0] === "patch"
533
+ ? entry[2]
534
+ : (() => {
535
+ throw new Error("unknown compact review text entry");
536
+ })();
537
+ let cursor = 0;
538
+ let expandedCharacters = 0;
539
+ const parts = [];
540
+ for (const [start, end, replacement, context] of hunks) {
541
+ if (!Number.isSafeInteger(start) ||
542
+ !Number.isSafeInteger(end) ||
543
+ start < cursor ||
544
+ end < start ||
545
+ end > base.length ||
546
+ typeof replacement !== "string" ||
547
+ JSON.stringify(context) !== JSON.stringify(spliceContext(base, start, base.length - end)))
548
+ throw new Error("compact review source edits have invalid ranges or source context");
549
+ expandedCharacters += start - cursor + replacement.length;
550
+ if (expandedCharacters > MAXIMUM_JSON_BYTES)
551
+ throw new Error("compact review source text exceeds the expanded size bound");
552
+ parts.push(base.slice(cursor, start), replacement);
553
+ cursor = end;
554
+ }
555
+ if (expandedCharacters + base.length - cursor > MAXIMUM_JSON_BYTES)
556
+ throw new Error("compact review source text exceeds the expanded size bound");
557
+ parts.push(base.slice(cursor));
558
+ value = parts.join("");
559
+ }
560
+ if (digest(value) !== key)
561
+ throw new Error("compact review text digest mismatch");
562
+ resolving.delete(key);
563
+ resolvedTexts.set(key, value);
564
+ return value;
565
+ };
566
+ const literalTexts = Object.fromEntries(packet.texts.map(([key]) => [key, ["literal", resolveText(key)]]));
567
+ let expandedNodes = 0;
568
+ const expand = (node, depth = 0, nodeCeiling = packet.nodes.length) => {
569
+ if (++expandedNodes > 1_000_000)
570
+ throw new Error("compact review evidence exceeds the expanded-node bound");
571
+ if (depth > 128)
572
+ throw new Error("compact review evidence exceeds the encoding depth bound");
573
+ if (!Array.isArray(node)) {
574
+ if (node !== null &&
575
+ typeof node !== "boolean" &&
576
+ typeof node !== "number" &&
577
+ typeof node !== "string")
578
+ throw new Error("compact review requires tagged objects and arrays");
579
+ return node;
580
+ }
581
+ const tagged = node;
582
+ switch (tagged[0]) {
583
+ case "a":
584
+ return ["array", tagged.slice(1).map((value) => expand(value, depth + 1, nodeCeiling))];
585
+ case "r": {
586
+ const keys = indexed(packet.shapes, tagged[1], "shape");
587
+ const values = tagged.slice(2);
588
+ if (keys.length !== values.length ||
589
+ keys.some((key) => typeof key !== "string") ||
590
+ new Set(keys).size !== keys.length)
591
+ throw new Error("compact review row does not match a unique object shape");
592
+ return [
593
+ "object",
594
+ keys.map((key, index) => [key, expand(values[index], depth + 1, nodeCeiling)])
595
+ ];
596
+ }
597
+ case "t":
598
+ if (tagged.length !== 2)
599
+ throw new Error("compact review text reference is malformed");
600
+ return ["text", indexed(packet.texts, tagged[1], "text")[0]];
601
+ case "s": {
602
+ if (tagged.length !== 2)
603
+ throw new Error("compact review string reference is malformed");
604
+ const value = indexed(packet.strings, tagged[1], "string");
605
+ if (typeof value !== "string")
606
+ throw new Error("compact review string must be literal");
607
+ return value;
608
+ }
609
+ case "n": {
610
+ if (tagged.length !== 2 || typeof tagged[1] !== "number" || tagged[1] >= nodeCeiling)
611
+ throw new Error("compact review node references must be acyclic and point backwards");
612
+ return expand(indexed(packet.nodes, tagged[1], "node"), depth, tagged[1]);
613
+ }
614
+ case "j": {
615
+ const parts = tagged.slice(1).map((part) => expand(part, depth + 1, nodeCeiling));
616
+ if (parts.some((part) => typeof part !== "string"))
617
+ throw new Error("compact review joins require only literal string parts");
618
+ return parts.join("");
619
+ }
620
+ default:
621
+ throw new Error("unknown compact review evidence node");
622
+ }
623
+ };
624
+ const value = decodeRepositoryReviewEvidenceV1({
625
+ encoding: "routekit-lossless-review-json-v1",
626
+ texts: literalTexts,
627
+ evidence: expand(packet.evidence)
628
+ });
629
+ if (digest(JSON.stringify(value)) !== packet.originalDigest)
630
+ throw new Error("compact review original evidence digest mismatch");
631
+ return value;
632
+ }
@@ -0,0 +1,7 @@
1
+ import type { RepositoryBehaviorMapV1, RepositoryChangeEpisodeV1 } from "../repository-behavior-protocol.js";
2
+ /** Retrieval heuristic only; executable qualification and dimension critics remain mandatory. */
3
+ export declare function rankRepositorySeedCandidatesV1(map: RepositoryBehaviorMapV1, requestedDimension: string): readonly {
4
+ readonly episode: RepositoryChangeEpisodeV1;
5
+ readonly relevance: number;
6
+ readonly matchedTerms: readonly string[];
7
+ }[];