@tangle-network/agent-eval 0.221.8 → 0.222.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 (579) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/dist/adapters/http.d.ts +3 -5
  3. package/dist/adapters/http.d.ts.map +1 -1
  4. package/dist/adapters/http.js +1 -2
  5. package/dist/{adversarial-smnADNFS.d.ts → adversarial-DnQQFqTR.d.ts} +1 -3
  6. package/dist/adversarial-DnQQFqTR.d.ts.map +1 -0
  7. package/dist/{agent-profile-CNmwfaqq.d.ts → agent-profile-CoD1Dotf.d.ts} +4 -10
  8. package/dist/agent-profile-CoD1Dotf.d.ts.map +1 -0
  9. package/dist/agent-profile-Dngk3LZ0.js +153 -0
  10. package/dist/agent-profile-Dngk3LZ0.js.map +1 -0
  11. package/dist/{agent-profile-cell-BcpFbNd5.d.ts → agent-profile-cell-3kYxUsK2.d.ts} +3 -5
  12. package/dist/agent-profile-cell-3kYxUsK2.d.ts.map +1 -0
  13. package/dist/{agent-profile-cell-B1V1gUZs.js → agent-profile-cell-CT5JYueM.js} +5 -7
  14. package/dist/{agent-profile-cell-B1V1gUZs.js.map → agent-profile-cell-CT5JYueM.js.map} +1 -1
  15. package/dist/{agreement-irr-BhAqjluA.js → agreement-irr-BTjDN0i6.js} +4 -5
  16. package/dist/{agreement-irr-BhAqjluA.js.map → agreement-irr-BTjDN0i6.js.map} +1 -1
  17. package/dist/analyst/index.d.ts +95 -159
  18. package/dist/analyst/index.d.ts.map +1 -1
  19. package/dist/analyst/index.js +28 -39
  20. package/dist/analyst/index.js.map +1 -1
  21. package/dist/{analyze-runs-DfX6dHP0.d.ts → analyze-runs-C-pP1sK9.d.ts} +7 -13
  22. package/dist/analyze-runs-C-pP1sK9.d.ts.map +1 -0
  23. package/dist/{analyze-runs-CHmsykNJ.js → analyze-runs-CTheASYV.js} +23 -32
  24. package/dist/{analyze-runs-CHmsykNJ.js.map → analyze-runs-CTheASYV.js.map} +1 -1
  25. package/dist/{attribute-vocabulary-CcXqHODT.d.ts → attribute-vocabulary-5oo8ykIx.d.ts} +2 -4
  26. package/dist/attribute-vocabulary-5oo8ykIx.d.ts.map +1 -0
  27. package/dist/authenticity/index.d.ts +0 -2
  28. package/dist/authenticity/index.d.ts.map +1 -1
  29. package/dist/authenticity/index.js +1 -2
  30. package/dist/{benchmark-command-Cnjfo0Zh.js → benchmark-command-jYWR2gya.js} +61 -94
  31. package/dist/benchmark-command-jYWR2gya.js.map +1 -0
  32. package/dist/benchmarks/index.d.ts +5 -15
  33. package/dist/benchmarks/index.d.ts.map +1 -1
  34. package/dist/benchmarks/index.js +27 -38
  35. package/dist/benchmarks/index.js.map +1 -1
  36. package/dist/{bounded-process-Cj9YjXbE.js → bounded-process-BZrWXIKW.js} +2 -3
  37. package/dist/{bounded-process-Cj9YjXbE.js.map → bounded-process-BZrWXIKW.js.map} +1 -1
  38. package/dist/builder-eval/index.d.ts +5 -14
  39. package/dist/builder-eval/index.d.ts.map +1 -1
  40. package/dist/builder-eval/index.js +11 -17
  41. package/dist/builder-eval/index.js.map +1 -1
  42. package/dist/{calibration-CTwxpJ-t.js → calibration-6usfVYYo.js} +4 -5
  43. package/dist/{calibration-CTwxpJ-t.js.map → calibration-6usfVYYo.js.map} +1 -1
  44. package/dist/campaign/index.d.ts +9 -9
  45. package/dist/campaign/index.js +15 -14
  46. package/dist/{campaign-uddTlFg5.js → campaign-ddr1N3yD.js} +61 -58
  47. package/dist/campaign-ddr1N3yD.js.map +1 -0
  48. package/dist/{campaign-evidence-DunzcJGv.js → campaign-evidence-DN8rWuBj.js} +20 -322
  49. package/dist/campaign-evidence-DN8rWuBj.js.map +1 -0
  50. package/dist/{canonical-Dq2hOQ8L.js → canonical-CicJlINA.js} +3 -4
  51. package/dist/{canonical-Dq2hOQ8L.js.map → canonical-CicJlINA.js.map} +1 -1
  52. package/dist/{canonical-CFpojCN5.d.ts → canonical-gLeHiqzd.d.ts} +2 -4
  53. package/dist/canonical-gLeHiqzd.d.ts.map +1 -0
  54. package/dist/{cell-spend-DEWR3nj-.js → cell-spend-zxmzg4GH.js} +3 -4
  55. package/dist/{cell-spend-DEWR3nj-.js.map → cell-spend-zxmzg4GH.js.map} +1 -1
  56. package/dist/{chat-client-BNATB3rJ.js → chat-client-CO3uB33i.js} +3 -4
  57. package/dist/{chat-client-BNATB3rJ.js.map → chat-client-CO3uB33i.js.map} +1 -1
  58. package/dist/{chat-json-call-BzWYp18J.js → chat-json-call-8yUv4LFO.js} +4 -5
  59. package/dist/{chat-json-call-BzWYp18J.js.map → chat-json-call-8yUv4LFO.js.map} +1 -1
  60. package/dist/{claim-BPVuyHuy.js → claim-Dod_mjk3.js} +5 -6
  61. package/dist/{claim-BPVuyHuy.js.map → claim-Dod_mjk3.js.map} +1 -1
  62. package/dist/cli.js +179 -23
  63. package/dist/cli.js.map +1 -1
  64. package/dist/{client-hwo3cJjR.d.ts → client-BIFwUg7I.d.ts} +6 -12
  65. package/dist/client-BIFwUg7I.d.ts.map +1 -0
  66. package/dist/{cluster-bootstrap-DEwwhl0C.js → cluster-bootstrap-SbaeM44s.js} +4 -5
  67. package/dist/{cluster-bootstrap-DEwwhl0C.js.map → cluster-bootstrap-SbaeM44s.js.map} +1 -1
  68. package/dist/completion-verifier-7KEfroqx.d.ts +168 -0
  69. package/dist/completion-verifier-7KEfroqx.d.ts.map +1 -0
  70. package/dist/{completion-verifier-asaV1nSj.js → completion-verifier-rqbMh5-4.js} +9 -160
  71. package/dist/completion-verifier-rqbMh5-4.js.map +1 -0
  72. package/dist/contract/index.d.ts +13 -13
  73. package/dist/contract/index.js +41 -60
  74. package/dist/contract/index.js.map +1 -1
  75. package/dist/{cost-ledger-BGZB6yY2.js → cost-ledger-CS8R3IZj.js} +10 -17
  76. package/dist/{cost-ledger-BGZB6yY2.js.map → cost-ledger-CS8R3IZj.js.map} +1 -1
  77. package/dist/{cost-ledger-C1W3ICmP.d.ts → cost-ledger-Czro9wmo.d.ts} +1 -5
  78. package/dist/cost-ledger-Czro9wmo.d.ts.map +1 -0
  79. package/dist/{dataset-DQqhOCPt.d.ts → dataset-DThC1S6G.d.ts} +1 -3
  80. package/dist/dataset-DThC1S6G.d.ts.map +1 -0
  81. package/dist/{decision-point-0nJubuoM.js → decision-point-lhMgODOR.js} +14 -18
  82. package/dist/{decision-point-0nJubuoM.js.map → decision-point-lhMgODOR.js.map} +1 -1
  83. package/dist/{deep-freeze-CurcOQg3.js → deep-freeze-CK8-2W7p.js} +2 -3
  84. package/dist/{deep-freeze-CurcOQg3.js.map → deep-freeze-CK8-2W7p.js.map} +1 -1
  85. package/dist/{default-registry-CLG5YqGS.d.ts → default-registry-B1DstPYg.d.ts} +53 -61
  86. package/dist/default-registry-B1DstPYg.d.ts.map +1 -0
  87. package/dist/{default-registry-BBTDgkDM.js → default-registry-C1tPEjZ4.js} +29 -45
  88. package/dist/{default-registry-BBTDgkDM.js.map → default-registry-C1tPEjZ4.js.map} +1 -1
  89. package/dist/{define-agent-eval-CCbT7Kfr.js → define-agent-eval-BLoP4Lf9.js} +15 -18
  90. package/dist/{define-agent-eval-CCbT7Kfr.js.map → define-agent-eval-BLoP4Lf9.js.map} +1 -1
  91. package/dist/{define-agent-eval-JKt3gMQr.d.ts → define-agent-eval-CAffiFbN.d.ts} +19 -27
  92. package/dist/define-agent-eval-CAffiFbN.d.ts.map +1 -0
  93. package/dist/{descriptive-CVNy48rR.js → descriptive-cPwITVfy.js} +30 -8
  94. package/dist/descriptive-cPwITVfy.js.map +1 -0
  95. package/dist/diagnosis/index.d.ts +5 -15
  96. package/dist/diagnosis/index.d.ts.map +1 -1
  97. package/dist/diagnosis/index.js +13 -19
  98. package/dist/diagnosis/index.js.map +1 -1
  99. package/dist/{dspy-rlm-engine-DN1p_5jx.js → dspy-rlm-engine-jDiWkul6.js} +7 -10
  100. package/dist/{dspy-rlm-engine-DN1p_5jx.js.map → dspy-rlm-engine-jDiWkul6.js.map} +1 -1
  101. package/dist/{emitter-DbMXUIVP.js → emitter-DhQ65mza.js} +3 -4
  102. package/dist/{emitter-DbMXUIVP.js.map → emitter-DhQ65mza.js.map} +1 -1
  103. package/dist/{emitter-DABYYTcH.d.ts → emitter-mAXC5PSN.d.ts} +3 -5
  104. package/dist/emitter-mAXC5PSN.d.ts.map +1 -0
  105. package/dist/{engine-dtRVeuQs.d.ts → engine-CaHaCc3W.d.ts} +10 -18
  106. package/dist/engine-CaHaCc3W.d.ts.map +1 -0
  107. package/dist/{equal-terms-DbPGcVtI.js → equal-terms-K11VHmR3.js} +3 -4
  108. package/dist/{equal-terms-DbPGcVtI.js.map → equal-terms-K11VHmR3.js.map} +1 -1
  109. package/dist/{errors-BcOs5MKW.js → errors-DeEEV9Vx.js} +2 -3
  110. package/dist/{errors-BcOs5MKW.js.map → errors-DeEEV9Vx.js.map} +1 -1
  111. package/dist/{errors-DEE6u6ot.d.ts → errors-E9I2hldP.d.ts} +1 -3
  112. package/dist/errors-E9I2hldP.d.ts.map +1 -0
  113. package/dist/{eval-campaign-DoX5vz3E.js → eval-campaign-Cgixrvf7.js} +8 -9
  114. package/dist/{eval-campaign-DoX5vz3E.js.map → eval-campaign-Cgixrvf7.js.map} +1 -1
  115. package/dist/{evaluation-wdGyZ7jV.js → evaluation-B8H3GYej.js} +4 -6
  116. package/dist/{evaluation-wdGyZ7jV.js.map → evaluation-B8H3GYej.js.map} +1 -1
  117. package/dist/{evaluation-DblGquCB.d.ts → evaluation-BPqUvZ66.d.ts} +4 -6
  118. package/dist/evaluation-BPqUvZ66.d.ts.map +1 -0
  119. package/dist/evaluation.d.ts +1 -1
  120. package/dist/evaluation.js +1 -2
  121. package/dist/{exact-types-Do63KoKn.d.ts → exact-types-D98BKpxo.d.ts} +8 -10
  122. package/dist/exact-types-D98BKpxo.d.ts.map +1 -0
  123. package/dist/{exec-CpbtOXVt.js → exec-C0_AkLUv.js} +3 -5
  124. package/dist/{exec-CpbtOXVt.js.map → exec-C0_AkLUv.js.map} +1 -1
  125. package/dist/{execution-tracks-CpgFPpS5.js → execution-tracks-DaDXYwAq.js} +2 -3
  126. package/dist/{execution-tracks-CpgFPpS5.js.map → execution-tracks-DaDXYwAq.js.map} +1 -1
  127. package/dist/experiment/index.d.ts +9 -37
  128. package/dist/experiment/index.d.ts.map +1 -1
  129. package/dist/experiment/index.js +29 -40
  130. package/dist/experiment/index.js.map +1 -1
  131. package/dist/{exporters-Dk3oEbK_.d.ts → exporters-B5Ze_RKh.d.ts} +4 -4
  132. package/dist/exporters-B5Ze_RKh.d.ts.map +1 -0
  133. package/dist/{exporters-DWvM16LE.js → exporters-ByLcILYU.js} +23 -5
  134. package/dist/exporters-ByLcILYU.js.map +1 -0
  135. package/dist/{external-optimizer-process-DEzJ2CGX.js → external-optimizer-process-BRVmaDFe.js} +5 -6
  136. package/dist/{external-optimizer-process-DEzJ2CGX.js.map → external-optimizer-process-BRVmaDFe.js.map} +1 -1
  137. package/dist/{external-optimizer-subprocess-B_ukPtRD.js → external-optimizer-subprocess-U616hV_l.js} +24 -37
  138. package/dist/{external-optimizer-subprocess-B_ukPtRD.js.map → external-optimizer-subprocess-U616hV_l.js.map} +1 -1
  139. package/dist/{extract-usage-BZLU01kR.js → extract-usage-ISFqhfDz.js} +2 -3
  140. package/dist/{extract-usage-BZLU01kR.js.map → extract-usage-ISFqhfDz.js.map} +1 -1
  141. package/dist/{failure-cluster-DN0t63Z0.d.ts → failure-cluster-DOoa7CBg.d.ts} +3 -7
  142. package/dist/failure-cluster-DOoa7CBg.d.ts.map +1 -0
  143. package/dist/{failure-taxonomy-Bx5oWqaW.js → failure-taxonomy-9eQfXKoW.js} +2 -3
  144. package/dist/{failure-taxonomy-Bx5oWqaW.js.map → failure-taxonomy-9eQfXKoW.js.map} +1 -1
  145. package/dist/{feedback-trajectory-CYVJXolG.d.ts → feedback-trajectory-SBGncrCP.d.ts} +7 -13
  146. package/dist/feedback-trajectory-SBGncrCP.d.ts.map +1 -0
  147. package/dist/{finding-composition-8n0fFgVI.js → finding-composition-DlvE1Qul.js} +4 -6
  148. package/dist/{finding-composition-8n0fFgVI.js.map → finding-composition-DlvE1Qul.js.map} +1 -1
  149. package/dist/{findings-store-Bg4sdS-e.js → findings-store-B75Dspaq.js} +11 -14
  150. package/dist/{findings-store-Bg4sdS-e.js.map → findings-store-B75Dspaq.js.map} +1 -1
  151. package/dist/fuzz.d.ts +3 -17
  152. package/dist/fuzz.d.ts.map +1 -1
  153. package/dist/fuzz.js +30 -29
  154. package/dist/fuzz.js.map +1 -1
  155. package/dist/{hf-dataset-CKxIJQba.js → hf-dataset-DPVQXW5n.js} +362 -21
  156. package/dist/hf-dataset-DPVQXW5n.js.map +1 -0
  157. package/dist/hosted/index.d.ts +2 -6
  158. package/dist/hosted/index.d.ts.map +1 -1
  159. package/dist/hosted/index.js +1 -2
  160. package/dist/{index-CalAsXMR.d.ts → index-B1Bm9oJA.d.ts} +3 -15
  161. package/dist/index-B1Bm9oJA.d.ts.map +1 -0
  162. package/dist/{index-CdEVr8-O.d.ts → index-B7v2QHlD.d.ts} +24 -299
  163. package/dist/index-B7v2QHlD.d.ts.map +1 -0
  164. package/dist/{index-CTIRz-AB.d.ts → index-CUjeTDPv.d.ts} +14 -36
  165. package/dist/index-CUjeTDPv.d.ts.map +1 -0
  166. package/dist/{index-CfJULcW5.d.ts → index-DAk2quYu.d.ts} +18 -38
  167. package/dist/index-DAk2quYu.d.ts.map +1 -0
  168. package/dist/{index-D7fmC-1K.d.ts → index-DUn0GNiZ.d.ts} +183 -36
  169. package/dist/index-DUn0GNiZ.d.ts.map +1 -0
  170. package/dist/{index-CHxwfW5g.d.ts → index-DwUGehqX.d.ts} +3 -9
  171. package/dist/index-DwUGehqX.d.ts.map +1 -0
  172. package/dist/{index-jnuFLxOs.d.ts → index-aDPVYBIM.d.ts} +11 -39
  173. package/dist/index-aDPVYBIM.d.ts.map +1 -0
  174. package/dist/index.d.ts +55 -188
  175. package/dist/index.d.ts.map +1 -1
  176. package/dist/index.js +122 -195
  177. package/dist/index.js.map +1 -1
  178. package/dist/{integrity-D-s2iHiT.js → integrity-B1V6klyO.js} +12 -363
  179. package/dist/integrity-B1V6klyO.js.map +1 -0
  180. package/dist/{integrity-D9lBnv_K.d.ts → integrity-BAdVzT8u.d.ts} +4 -6
  181. package/dist/integrity-BAdVzT8u.d.ts.map +1 -0
  182. package/dist/{integrity-W4CADcFc.js → integrity-DOHt1mwU.js} +3 -4
  183. package/dist/{integrity-W4CADcFc.js.map → integrity-DOHt1mwU.js.map} +1 -1
  184. package/dist/{internal-BTK91Bqt.js → internal-v6XfOeJW.js} +6 -8
  185. package/dist/{internal-BTK91Bqt.js.map → internal-v6XfOeJW.js.map} +1 -1
  186. package/dist/{interval-Dq9gt7jx.js → interval-Bd2f4CRT.js} +6 -8
  187. package/dist/{interval-Dq9gt7jx.js.map → interval-Bd2f4CRT.js.map} +1 -1
  188. package/dist/{interval-ohuOJurX.d.ts → interval-CWyxqDpE.d.ts} +1 -5
  189. package/dist/interval-CWyxqDpE.d.ts.map +1 -0
  190. package/dist/{journal-C7om8Gum.js → journal-C1uLJi0w.js} +115 -121
  191. package/dist/{journal-C7om8Gum.js.map → journal-C1uLJi0w.js.map} +1 -1
  192. package/dist/{json-BhdsJaOQ.js → json-DtvZNAU9.js} +4 -6
  193. package/dist/{json-BhdsJaOQ.js.map → json-DtvZNAU9.js.map} +1 -1
  194. package/dist/json-recovery-DK4MDm5r.js +296 -0
  195. package/dist/json-recovery-DK4MDm5r.js.map +1 -0
  196. package/dist/{judge-calibration-BkXMIWA4.js → judge-calibration-DGqlfWW8.js} +5 -6
  197. package/dist/{judge-calibration-BkXMIWA4.js.map → judge-calibration-DGqlfWW8.js.map} +1 -1
  198. package/dist/{judge-calibration-DFtEMlde.d.ts → judge-calibration-DnrbQaXI.d.ts} +1 -3
  199. package/dist/judge-calibration-DnrbQaXI.d.ts.map +1 -0
  200. package/dist/{judge-gate-BVvmP00P.js → judge-gate-C2BCOt-M.js} +8 -12
  201. package/dist/{judge-gate-BVvmP00P.js.map → judge-gate-C2BCOt-M.js.map} +1 -1
  202. package/dist/judges-BLxg5p8E.js +20 -0
  203. package/dist/judges-BLxg5p8E.js.map +1 -0
  204. package/dist/{kind-factory-Dl0PmNQL.js → kind-factory-VKysp1ds.js} +23 -39
  205. package/dist/{kind-factory-Dl0PmNQL.js.map → kind-factory-VKysp1ds.js.map} +1 -1
  206. package/dist/ledger-core/index.d.ts +2 -2
  207. package/dist/ledger-core/index.js +3 -3
  208. package/dist/ledger-core/lock-holder.d.ts +1 -1
  209. package/dist/ledger-core/lock-holder.js +1 -2
  210. package/dist/{ledger-core-CAxUdDk0.js → ledger-core-CfT-FzPf.js} +5 -6
  211. package/dist/{ledger-core-CAxUdDk0.js.map → ledger-core-CfT-FzPf.js.map} +1 -1
  212. package/dist/{llm-client-b1ysZVIU.js → llm-client-kJ9EOqjt.js} +22 -30
  213. package/dist/{llm-client-b1ysZVIU.js.map → llm-client-kJ9EOqjt.js.map} +1 -1
  214. package/dist/{llm-judge-Cybq29bL.js → llm-judge-cgbhTKQp.js} +108 -164
  215. package/dist/llm-judge-cgbhTKQp.js.map +1 -0
  216. package/dist/{lock-holder-DaJbfpci.d.ts → lock-holder-DoxlZFkQ.d.ts} +1 -3
  217. package/dist/lock-holder-DoxlZFkQ.d.ts.map +1 -0
  218. package/dist/matrix/index.d.ts +3 -3
  219. package/dist/matrix/index.js +2 -2
  220. package/dist/{matrix-DtkZLD_3.d.ts → matrix-CBUzIZs4.d.ts} +4 -12
  221. package/dist/matrix-CBUzIZs4.d.ts.map +1 -0
  222. package/dist/{matrix-B8l-Nsxd.js → matrix-CgpX8wdm.js} +8 -13
  223. package/dist/matrix-CgpX8wdm.js.map +1 -0
  224. package/dist/{mean-BbA_JCzW.js → mean-CdDYG-us.js} +6 -9
  225. package/dist/{mean-BbA_JCzW.js.map → mean-CdDYG-us.js.map} +1 -1
  226. package/dist/meta-eval/index.d.ts +3 -3
  227. package/dist/meta-eval/index.js +17 -21
  228. package/dist/meta-eval/index.js.map +1 -1
  229. package/dist/{metrics-BKaPBtIG.js → metrics-DNCAUtuB.js} +2 -3
  230. package/dist/{metrics-BKaPBtIG.js.map → metrics-DNCAUtuB.js.map} +1 -1
  231. package/dist/{mint-CbdwjTPW.js → mint-D9ZysYtY.js} +7 -8
  232. package/dist/{mint-CbdwjTPW.js.map → mint-D9ZysYtY.js.map} +1 -1
  233. package/dist/{multi-layer-verifier-DEgMUk6v.d.ts → multi-layer-verifier-lM4aVN78.d.ts} +2 -4
  234. package/dist/multi-layer-verifier-lM4aVN78.d.ts.map +1 -0
  235. package/dist/{multiplicity-Sg0U7h8j.js → multiplicity-DAd4xaDC.js} +3 -4
  236. package/dist/{multiplicity-Sg0U7h8j.js.map → multiplicity-DAd4xaDC.js.map} +1 -1
  237. package/dist/{multiplicity-DIWHvysC.d.ts → multiplicity-D_SEsc5j.d.ts} +1 -3
  238. package/dist/multiplicity-D_SEsc5j.d.ts.map +1 -0
  239. package/dist/multishot/golden/index.d.ts +1 -17
  240. package/dist/multishot/golden/index.d.ts.map +1 -1
  241. package/dist/multishot/golden/index.js +10 -17
  242. package/dist/multishot/golden/index.js.map +1 -1
  243. package/dist/multishot/index.d.ts +2 -10
  244. package/dist/multishot/index.d.ts.map +1 -1
  245. package/dist/multishot/index.js +11 -18
  246. package/dist/multishot/index.js.map +1 -1
  247. package/dist/{nonnegative-number-DvdMxg_f.js → nonnegative-number-lEYbOsuh.js} +2 -3
  248. package/dist/{nonnegative-number-DvdMxg_f.js.map → nonnegative-number-lEYbOsuh.js.map} +1 -1
  249. package/dist/openapi.json +1 -1
  250. package/dist/{otel-spans-64hmQqON.js → otel-spans-BsGzTWIK.js} +5 -6
  251. package/dist/{otel-spans-64hmQqON.js.map → otel-spans-BsGzTWIK.js.map} +1 -1
  252. package/dist/{otlp-attributes-D9ptWaIJ.js → otlp-attributes-Boeb7gtH.js} +2 -3
  253. package/dist/{otlp-attributes-D9ptWaIJ.js.map → otlp-attributes-Boeb7gtH.js.map} +1 -1
  254. package/dist/{outcome-observations-FLmRpgYa.js → outcome-observations-D4snOtUb.js} +4 -5
  255. package/dist/{outcome-observations-FLmRpgYa.js.map → outcome-observations-D4snOtUb.js.map} +1 -1
  256. package/dist/{outcome-store-DUcMj-3D.js → outcome-store-TarrcfHG.js} +2 -3
  257. package/dist/{outcome-store-DUcMj-3D.js.map → outcome-store-TarrcfHG.js.map} +1 -1
  258. package/dist/{package-version-D7lQHt_-.js → package-version-CJl_pY9W.js} +2 -3
  259. package/dist/{package-version-D7lQHt_-.js.map → package-version-CJl_pY9W.js.map} +1 -1
  260. package/dist/{paired-arms-B2ttLc0_.js → paired-arms-D-54hO-k.js} +10 -14
  261. package/dist/{paired-arms-B2ttLc0_.js.map → paired-arms-D-54hO-k.js.map} +1 -1
  262. package/dist/{paired-binary-B_nejA44.js → paired-binary-BR0nwHOA.js} +3 -4
  263. package/dist/{paired-binary-B_nejA44.js.map → paired-binary-BR0nwHOA.js.map} +1 -1
  264. package/dist/{paired-promotion-decision-CQMJ5xGN.d.ts → paired-promotion-decision-BDnqepZ1.d.ts} +1 -5
  265. package/dist/paired-promotion-decision-BDnqepZ1.d.ts.map +1 -0
  266. package/dist/{paired-promotion-decision-D0SHb-ZL.js → paired-promotion-decision-FGvHA4p_.js} +5 -7
  267. package/dist/{paired-promotion-decision-D0SHb-ZL.js.map → paired-promotion-decision-FGvHA4p_.js.map} +1 -1
  268. package/dist/{pareto-BiBnQXAE.js → pareto-B9udAt2i.js} +28 -50
  269. package/dist/pareto-B9udAt2i.js.map +1 -0
  270. package/dist/pipelines/index.d.ts +5 -11
  271. package/dist/pipelines/index.d.ts.map +1 -1
  272. package/dist/pipelines/index.js +6 -8
  273. package/dist/pipelines/index.js.map +1 -1
  274. package/dist/{power-and-mde-CQX-0weG.js → power-and-mde-ClI6RWw4.js} +4 -5
  275. package/dist/{power-and-mde-CQX-0weG.js.map → power-and-mde-ClI6RWw4.js.map} +1 -1
  276. package/dist/{predicate-FdKmElA_.js → predicate-BYHA4MBn.js} +2 -3
  277. package/dist/{predicate-FdKmElA_.js.map → predicate-BYHA4MBn.js.map} +1 -1
  278. package/dist/{prime-bridge-transport-6feEglLf.d.ts → prime-bridge-transport-Cfqir_Im.d.ts} +1 -3
  279. package/dist/prime-bridge-transport-Cfqir_Im.d.ts.map +1 -0
  280. package/dist/{prime-bridge-transport-Z3cpKGoV.js → prime-bridge-transport-Csd5SQg7.js} +2 -3
  281. package/dist/{prime-bridge-transport-Z3cpKGoV.js.map → prime-bridge-transport-Csd5SQg7.js.map} +1 -1
  282. package/dist/{prime-protocol-BGxjfhM4.d.ts → prime-protocol-COFkxas6.d.ts} +4 -8
  283. package/dist/prime-protocol-COFkxas6.d.ts.map +1 -0
  284. package/dist/{prime-protocol-BFgGrEMP.js → prime-protocol-CrhpXRz9.js} +4 -6
  285. package/dist/{prime-protocol-BFgGrEMP.js.map → prime-protocol-CrhpXRz9.js.map} +1 -1
  286. package/dist/profile-cell.d.ts +1 -1
  287. package/dist/profile-cell.js +1 -2
  288. package/dist/{promotion-gate-CkVZHagC.d.ts → promotion-gate-CixshGI8.d.ts} +5 -11
  289. package/dist/promotion-gate-CixshGI8.d.ts.map +1 -0
  290. package/dist/{promotion-policy-6A8osGr_.js → promotion-policy-CBYeD4zi.js} +5 -6
  291. package/dist/{promotion-policy-6A8osGr_.js.map → promotion-policy-CBYeD4zi.js.map} +1 -1
  292. package/dist/{proposal-findings-DqLUWsAG.js → proposal-findings-WFQrxnfe.js} +3 -4
  293. package/dist/{proposal-findings-DqLUWsAG.js.map → proposal-findings-WFQrxnfe.js.map} +1 -1
  294. package/dist/{quantile--0yb07pD.js → quantile-CncXP-Ss.js} +2 -3
  295. package/dist/{quantile--0yb07pD.js.map → quantile-CncXP-Ss.js.map} +1 -1
  296. package/dist/{query-B_RZ36an.js → query-CGXzO9d4.js} +5 -6
  297. package/dist/{query-B_RZ36an.js.map → query-CGXzO9d4.js.map} +1 -1
  298. package/dist/{query-Cmv_U8vf.d.ts → query-UD0B08Sb.d.ts} +4 -6
  299. package/dist/query-UD0B08Sb.d.ts.map +1 -0
  300. package/dist/{random-DGEyr3zG.d.ts → random-BN150Q_X.d.ts} +1 -5
  301. package/dist/random-BN150Q_X.d.ts.map +1 -0
  302. package/dist/{random-DDDcC7YU.js → random-DrzcgC7F.js} +3 -4
  303. package/dist/{random-DDDcC7YU.js.map → random-DrzcgC7F.js.map} +1 -1
  304. package/dist/{raw-provider-sink-75w4FWBj.js → raw-provider-sink-DDLkP_eF.js} +3 -4
  305. package/dist/{raw-provider-sink-75w4FWBj.js.map → raw-provider-sink-DDLkP_eF.js.map} +1 -1
  306. package/dist/{record-id-DUgsK5qp.js → record-id-CWZXFh58.js} +2 -3
  307. package/dist/{record-id-DUgsK5qp.js.map → record-id-CWZXFh58.js.map} +1 -1
  308. package/dist/{redact-DXdlFb_U.d.ts → redact-C_wzC4c_.d.ts} +1 -3
  309. package/dist/redact-C_wzC4c_.d.ts.map +1 -0
  310. package/dist/{redact-mtkTiJVk.js → redact-D6APJS1d.js} +3 -5
  311. package/dist/{redact-mtkTiJVk.js.map → redact-D6APJS1d.js.map} +1 -1
  312. package/dist/{registry-BcdJmyoU.d.ts → registry-dhdDoAV8.d.ts} +5 -11
  313. package/dist/registry-dhdDoAV8.d.ts.map +1 -0
  314. package/dist/{release-confidence-CYIFH-fp.js → release-confidence-CTUJz5mM.js} +10 -16
  315. package/dist/release-confidence-CTUJz5mM.js.map +1 -0
  316. package/dist/{render-BhJqXoBH.js → render-pfAZ7IR4.js} +266 -33
  317. package/dist/render-pfAZ7IR4.js.map +1 -0
  318. package/dist/{reporting-html-Kvlc8oMt.js → reporting-html-DMXIjATy.js} +2 -3
  319. package/dist/{reporting-html-Kvlc8oMt.js.map → reporting-html-DMXIjATy.js.map} +1 -1
  320. package/dist/reporting.d.ts +6 -6
  321. package/dist/reporting.js +7 -7
  322. package/dist/{researcher-DKWtoMWk.d.ts → researcher-CLnNJ7Or.d.ts} +8 -12
  323. package/dist/researcher-CLnNJ7Or.d.ts.map +1 -0
  324. package/dist/{reward-nw2xZGZG.js → reward-P0VD_Aft.js} +2 -3
  325. package/dist/{reward-nw2xZGZG.js.map → reward-P0VD_Aft.js.map} +1 -1
  326. package/dist/{reward-BeUgVVC_.d.ts → reward-ST4PXNXF.d.ts} +2 -4
  327. package/dist/reward-ST4PXNXF.d.ts.map +1 -0
  328. package/dist/{reward-hacking-WTxUbtbb.d.ts → reward-hacking-C9hPVT0Q.d.ts} +4 -8
  329. package/dist/reward-hacking-C9hPVT0Q.d.ts.map +1 -0
  330. package/dist/{reward-hacking-ByuETaIb.js → reward-hacking-DZzHZlS1.js} +5 -7
  331. package/dist/{reward-hacking-ByuETaIb.js.map → reward-hacking-DZzHZlS1.js.map} +1 -1
  332. package/dist/rl.d.ts +26 -63
  333. package/dist/rl.d.ts.map +1 -1
  334. package/dist/rl.js +35 -52
  335. package/dist/rl.js.map +1 -1
  336. package/dist/{rolldown-runtime-8H4AJuhK.js → rolldown-runtime-BJohB4LM.js} +1 -2
  337. package/dist/rollout/index.d.ts +6 -6
  338. package/dist/rollout/index.js +7 -7
  339. package/dist/{rollout-Dd1ucT_M.js → rollout-BhkMpAJT.js} +279 -16
  340. package/dist/rollout-BhkMpAJT.js.map +1 -0
  341. package/dist/{terminal-record-CB9BFtjS.js → rollout-nodes-BHR9Q5jP.js} +351 -11
  342. package/dist/rollout-nodes-BHR9Q5jP.js.map +1 -0
  343. package/dist/{round-decimal-COrKglMh.js → round-decimal-ZmjAQPo1.js} +2 -3
  344. package/dist/{round-decimal-COrKglMh.js.map → round-decimal-ZmjAQPo1.js.map} +1 -1
  345. package/dist/{rubric-predictive-validity-Cd5SCtAf.d.ts → rubric-predictive-validity-B3RzbwOx.d.ts} +2 -8
  346. package/dist/rubric-predictive-validity-B3RzbwOx.d.ts.map +1 -0
  347. package/dist/{rubric-predictive-validity-CeKW2GQN.js → rubric-predictive-validity-CQp_M0vy.js} +3 -4
  348. package/dist/{rubric-predictive-validity-CeKW2GQN.js.map → rubric-predictive-validity-CQp_M0vy.js.map} +1 -1
  349. package/dist/{run-record-CysKLB93.js → run-record-CZy4-TnZ.js} +4 -5
  350. package/dist/{run-record-CysKLB93.js.map → run-record-CZy4-TnZ.js.map} +1 -1
  351. package/dist/{run-record-C3awiXPf.d.ts → run-record-D2BFMPGl.d.ts} +5 -7
  352. package/dist/run-record-D2BFMPGl.d.ts.map +1 -0
  353. package/dist/{run-record-DhEJgoPz.js → run-record-DEjx43cI.js} +6 -7
  354. package/dist/{run-record-DhEJgoPz.js.map → run-record-DEjx43cI.js.map} +1 -1
  355. package/dist/{sandbox-harness-BlSOu4LX.d.ts → sandbox-harness-B3Kx1fOA.d.ts} +1 -3
  356. package/dist/sandbox-harness-B3Kx1fOA.d.ts.map +1 -0
  357. package/dist/{schema-D6EVKzTB.d.ts → schema-CkIvnmLU.d.ts} +2 -43
  358. package/dist/schema-CkIvnmLU.d.ts.map +1 -0
  359. package/dist/{schema-Bt2vLFm3.js → schema-D-xu3MU_.js} +2 -3
  360. package/dist/{schema-Bt2vLFm3.js.map → schema-D-xu3MU_.js.map} +1 -1
  361. package/dist/{schema-C-ziyJD7.d.ts → schema-DkFJr3Y8.d.ts} +111 -48
  362. package/dist/schema-DkFJr3Y8.d.ts.map +1 -0
  363. package/dist/{schema-CvhfLjtZ.js → schema-YUIXT8iW.js} +37 -7
  364. package/dist/schema-YUIXT8iW.js.map +1 -0
  365. package/dist/search/index.d.ts +3 -35
  366. package/dist/search/index.d.ts.map +1 -1
  367. package/dist/search/index.js +4 -5
  368. package/dist/{search-kernel-CctpiDd2.d.ts → search-kernel-CBdwFZ05.d.ts} +10 -36
  369. package/dist/search-kernel-CBdwFZ05.d.ts.map +1 -0
  370. package/dist/{search-ledger-CZRqtFbW.js → search-ledger-BsVi-Ngv.js} +17 -26
  371. package/dist/{search-ledger-CZRqtFbW.js.map → search-ledger-BsVi-Ngv.js.map} +1 -1
  372. package/dist/{search-ledger-file-Bd5Tioq6.js → search-ledger-file-DTBD6X-y.js} +6 -8
  373. package/dist/{search-ledger-file-Bd5Tioq6.js.map → search-ledger-file-DTBD6X-y.js.map} +1 -1
  374. package/dist/{search-ledger-types-p2xKfiDJ.d.ts → search-ledger-types-qiYRUo_N.d.ts} +5 -9
  375. package/dist/search-ledger-types-qiYRUo_N.d.ts.map +1 -0
  376. package/dist/{search-shipper-Dn3NLsuH.js → search-shipper-pdg4viK7.js} +8 -13
  377. package/dist/{search-shipper-Dn3NLsuH.js.map → search-shipper-pdg4viK7.js.map} +1 -1
  378. package/dist/{search-summary-D4bwYnAE.js → search-summary-Ct7SrmVc.js} +6 -7
  379. package/dist/{search-summary-D4bwYnAE.js.map → search-summary-Ct7SrmVc.js.map} +1 -1
  380. package/dist/{sequential-CimQrbjv.js → sequential-B1I0tRfL.js} +6 -7
  381. package/dist/{sequential-CimQrbjv.js.map → sequential-B1I0tRfL.js.map} +1 -1
  382. package/dist/{sequential-KwGspfeR.d.ts → sequential-Bb_pdTqG.d.ts} +1 -3
  383. package/dist/sequential-Bb_pdTqG.d.ts.map +1 -0
  384. package/dist/{sequential-BVv1sjsw.js → sequential-Bjs5roiK.js} +2 -3
  385. package/dist/{sequential-BVv1sjsw.js.map → sequential-Bjs5roiK.js.map} +1 -1
  386. package/dist/{sequential-eprocess-DodI6RoF.js → sequential-eprocess-C1YLwFaz.js} +3 -4
  387. package/dist/{sequential-eprocess-DodI6RoF.js.map → sequential-eprocess-C1YLwFaz.js.map} +1 -1
  388. package/dist/{server-ChhXPCgX.js → server-DA6h3co5.js} +11 -17
  389. package/dist/{server-ChhXPCgX.js.map → server-DA6h3co5.js.map} +1 -1
  390. package/dist/{single-run-lock-Dekd8_Wv.js → single-run-lock-BGlW3OSk.js} +3 -4
  391. package/dist/{single-run-lock-Dekd8_Wv.js.map → single-run-lock-BGlW3OSk.js.map} +1 -1
  392. package/dist/{skillopt-optimization-method-sB_-yi1G.js → skillopt-optimization-method-qB1M554K.js} +38 -57
  393. package/dist/{skillopt-optimization-method-sB_-yi1G.js.map → skillopt-optimization-method-qB1M554K.js.map} +1 -1
  394. package/dist/{spans-CVngGij3.d.ts → spans-vZoW__3q.d.ts} +2 -4
  395. package/dist/spans-vZoW__3q.d.ts.map +1 -0
  396. package/dist/{statistical-heldout-BjzSOmLH.d.ts → statistical-heldout-Cei036nE.d.ts} +9 -37
  397. package/dist/statistical-heldout-Cei036nE.d.ts.map +1 -0
  398. package/dist/{statistical-heldout-Bksv92Th.js → statistical-heldout-TP6ndL0B.js} +4 -5
  399. package/dist/{statistical-heldout-Bksv92Th.js.map → statistical-heldout-TP6ndL0B.js.map} +1 -1
  400. package/dist/{steps-DlepJPwD.d.ts → steps-B8fYY_Vo.d.ts} +1 -3
  401. package/dist/steps-B8fYY_Vo.d.ts.map +1 -0
  402. package/dist/{store-B3nWRy3B.d.ts → store-CMs5wGXP.d.ts} +2 -4
  403. package/dist/store-CMs5wGXP.d.ts.map +1 -0
  404. package/dist/{store-BhNuLdJw.js → store-ZykIyQmy.js} +2 -3
  405. package/dist/{store-BhNuLdJw.js.map → store-ZykIyQmy.js.map} +1 -1
  406. package/dist/{store-otlp-CFf27E8_.js → store-otlp-DmLm65XW.js} +8 -13
  407. package/dist/{store-otlp-CFf27E8_.js.map → store-otlp-DmLm65XW.js.map} +1 -1
  408. package/dist/{store-tool-spans-DxsFwtdr.d.ts → store-tool-spans-B3i3fl0A.d.ts} +11 -29
  409. package/dist/store-tool-spans-B3i3fl0A.d.ts.map +1 -0
  410. package/dist/{store-tool-spans-BK_8FjGG.js → store-tool-spans-C2g8UYm-.js} +17 -41
  411. package/dist/{store-tool-spans-BK_8FjGG.js.map → store-tool-spans-C2g8UYm-.js.map} +1 -1
  412. package/dist/storyboard/index.d.ts +1 -5
  413. package/dist/storyboard/index.d.ts.map +1 -1
  414. package/dist/storyboard/index.js +3 -5
  415. package/dist/storyboard/index.js.map +1 -1
  416. package/dist/{summary-report-C8V49Jt3.d.ts → summary-report-0La5vejY.d.ts} +5 -13
  417. package/dist/summary-report-0La5vejY.d.ts.map +1 -0
  418. package/dist/{summary-report-DHDWxe6p.js → summary-report-CPfsrLac.js} +21 -30
  419. package/dist/summary-report-CPfsrLac.js.map +1 -0
  420. package/dist/supervisor-run/index.d.ts +30 -29
  421. package/dist/supervisor-run/index.d.ts.map +1 -1
  422. package/dist/supervisor-run/index.js +6 -7
  423. package/dist/{systemone-CHnqwmYg.d.ts → systemone-Cw2txK5m.d.ts} +12 -24
  424. package/dist/systemone-Cw2txK5m.d.ts.map +1 -0
  425. package/dist/{systemone-protocol-Bl2EI2KQ.d.ts → systemone-protocol-C4t7JH4Y.d.ts} +1 -3
  426. package/dist/systemone-protocol-C4t7JH4Y.d.ts.map +1 -0
  427. package/dist/systemone-protocol.d.ts +1 -1
  428. package/dist/systemone-protocol.js +2 -3
  429. package/dist/{systemone-review-cQ9acAsb.d.ts → systemone-review-BLgxt-4Q.d.ts} +8 -10
  430. package/dist/systemone-review-BLgxt-4Q.d.ts.map +1 -0
  431. package/dist/{systemone-review-DFGtIUcf.js → systemone-review-S49gsy_y.js} +5 -6
  432. package/dist/{systemone-review-DFGtIUcf.js.map → systemone-review-S49gsy_y.js.map} +1 -1
  433. package/dist/systemone.d.ts +4 -4
  434. package/dist/systemone.js +3 -3
  435. package/dist/{task-failure-attributes-oIK3BhCR.js → task-failure-attributes-CC6VuIpk.js} +7 -10
  436. package/dist/{task-failure-attributes-oIK3BhCR.js.map → task-failure-attributes-CC6VuIpk.js.map} +1 -1
  437. package/dist/{tool-groups-b3oU_D88.d.ts → tool-groups-C3K-d3gd.d.ts} +3 -5
  438. package/dist/tool-groups-C3K-d3gd.d.ts.map +1 -0
  439. package/dist/{tool-waste-CkjzWmeY.d.ts → tool-waste-BFG1vwTV.d.ts} +4 -16
  440. package/dist/tool-waste-BFG1vwTV.d.ts.map +1 -0
  441. package/dist/{tool-waste-DLsjS_p-.js → tool-waste-CLJ46AbT.js} +10 -26
  442. package/dist/{tool-waste-DLsjS_p-.js.map → tool-waste-CLJ46AbT.js.map} +1 -1
  443. package/dist/trace-attributes.d.ts +1 -1
  444. package/dist/trace-attributes.js +1 -2
  445. package/dist/{trace-questions-BmT8M6UQ.d.ts → trace-questions-ej5AEJ5X.d.ts} +4 -6
  446. package/dist/trace-questions-ej5AEJ5X.d.ts.map +1 -0
  447. package/dist/trace-repair/index.d.ts +46 -92
  448. package/dist/trace-repair/index.d.ts.map +1 -1
  449. package/dist/trace-repair/index.js +32 -54
  450. package/dist/trace-repair/index.js.map +1 -1
  451. package/dist/traces.d.ts +13 -29
  452. package/dist/traces.d.ts.map +1 -1
  453. package/dist/traces.js +18 -22
  454. package/dist/traces.js.map +1 -1
  455. package/dist/{trajectory-D_7rLrvE.js → trajectory-O3GDHmev.js} +2 -3
  456. package/dist/{trajectory-D_7rLrvE.js.map → trajectory-O3GDHmev.js.map} +1 -1
  457. package/dist/trajectory-replay/index.d.ts +2 -22
  458. package/dist/trajectory-replay/index.d.ts.map +1 -1
  459. package/dist/trajectory-replay/index.js +19 -30
  460. package/dist/trajectory-replay/index.js.map +1 -1
  461. package/dist/{tree-DSqwJpL9.js → tree-DrIChF4a.js} +39 -68
  462. package/dist/{tree-DSqwJpL9.js.map → tree-DrIChF4a.js.map} +1 -1
  463. package/dist/{types-B_IFcKp5.d.ts → types-0KglnQ9o.d.ts} +3 -15
  464. package/dist/types-0KglnQ9o.d.ts.map +1 -0
  465. package/dist/{types-DZ0mYVw9.d.ts → types-0oMg7zee.d.ts} +3 -5
  466. package/dist/types-0oMg7zee.d.ts.map +1 -0
  467. package/dist/{types-CnWmj8NW.js → types-BK0blWhe.js} +3 -4
  468. package/dist/{types-CnWmj8NW.js.map → types-BK0blWhe.js.map} +1 -1
  469. package/dist/{types-CmXY0PQf.d.ts → types-C-aOqgt2.d.ts} +2 -5
  470. package/dist/types-C-aOqgt2.d.ts.map +1 -0
  471. package/dist/{types-M6eF9m-r.d.ts → types-C54Uk_a1.d.ts} +84 -24
  472. package/dist/types-C54Uk_a1.d.ts.map +1 -0
  473. package/dist/{types-BXgASBCL.js → types-DK4vNv5q.js} +2 -3
  474. package/dist/{types-BXgASBCL.js.map → types-DK4vNv5q.js.map} +1 -1
  475. package/dist/{types-6Lfdlshp.d.ts → types-DzCO-S1m.d.ts} +50 -62
  476. package/dist/types-DzCO-S1m.d.ts.map +1 -0
  477. package/dist/{verdict-BGQmxQ8A.js → verdict-C8TcdwfD.js} +3 -4
  478. package/dist/{verdict-BGQmxQ8A.js.map → verdict-C8TcdwfD.js.map} +1 -1
  479. package/dist/{verdict-C24NELtN.d.ts → verdict-D_qiBQ6_.d.ts} +1 -5
  480. package/dist/verdict-D_qiBQ6_.d.ts.map +1 -0
  481. package/dist/{verdict-cache-CL_7tePD.js → verdict-cache-BVH-fl18.js} +3 -4
  482. package/dist/{verdict-cache-CL_7tePD.js.map → verdict-cache-BVH-fl18.js.map} +1 -1
  483. package/dist/wire/index.d.ts +43 -51
  484. package/dist/wire/index.d.ts.map +1 -1
  485. package/dist/wire/index.js +1 -2
  486. package/docs/eval-surface-map.md +15 -0
  487. package/docs/rollout.md +132 -6
  488. package/package.json +18 -18
  489. package/dist/adversarial-smnADNFS.d.ts.map +0 -1
  490. package/dist/agent-profile-CNmwfaqq.d.ts.map +0 -1
  491. package/dist/agent-profile-cell-BcpFbNd5.d.ts.map +0 -1
  492. package/dist/analyze-runs-DfX6dHP0.d.ts.map +0 -1
  493. package/dist/attribute-vocabulary-CcXqHODT.d.ts.map +0 -1
  494. package/dist/benchmark-command-Cnjfo0Zh.js.map +0 -1
  495. package/dist/campaign-evidence-DunzcJGv.js.map +0 -1
  496. package/dist/campaign-uddTlFg5.js.map +0 -1
  497. package/dist/canonical-CFpojCN5.d.ts.map +0 -1
  498. package/dist/client-hwo3cJjR.d.ts.map +0 -1
  499. package/dist/completion-verifier-asaV1nSj.js.map +0 -1
  500. package/dist/cost-ledger-C1W3ICmP.d.ts.map +0 -1
  501. package/dist/dataset-DQqhOCPt.d.ts.map +0 -1
  502. package/dist/default-registry-CLG5YqGS.d.ts.map +0 -1
  503. package/dist/define-agent-eval-JKt3gMQr.d.ts.map +0 -1
  504. package/dist/descriptive-B2iPaT9J.d.ts +0 -89
  505. package/dist/descriptive-B2iPaT9J.d.ts.map +0 -1
  506. package/dist/descriptive-CVNy48rR.js.map +0 -1
  507. package/dist/emitter-DABYYTcH.d.ts.map +0 -1
  508. package/dist/engine-dtRVeuQs.d.ts.map +0 -1
  509. package/dist/errors-DEE6u6ot.d.ts.map +0 -1
  510. package/dist/evaluation-DblGquCB.d.ts.map +0 -1
  511. package/dist/exact-types-Do63KoKn.d.ts.map +0 -1
  512. package/dist/exporters-DWvM16LE.js.map +0 -1
  513. package/dist/exporters-Dk3oEbK_.d.ts.map +0 -1
  514. package/dist/failure-cluster-DN0t63Z0.d.ts.map +0 -1
  515. package/dist/feedback-trajectory-CYVJXolG.d.ts.map +0 -1
  516. package/dist/hf-dataset-CKxIJQba.js.map +0 -1
  517. package/dist/index-CHxwfW5g.d.ts.map +0 -1
  518. package/dist/index-CTIRz-AB.d.ts.map +0 -1
  519. package/dist/index-CalAsXMR.d.ts.map +0 -1
  520. package/dist/index-CdEVr8-O.d.ts.map +0 -1
  521. package/dist/index-CfJULcW5.d.ts.map +0 -1
  522. package/dist/index-D7fmC-1K.d.ts.map +0 -1
  523. package/dist/index-jnuFLxOs.d.ts.map +0 -1
  524. package/dist/integrity-D-s2iHiT.js.map +0 -1
  525. package/dist/integrity-D9lBnv_K.d.ts.map +0 -1
  526. package/dist/interval-ohuOJurX.d.ts.map +0 -1
  527. package/dist/judge-calibration-DFtEMlde.d.ts.map +0 -1
  528. package/dist/llm-judge-Cybq29bL.js.map +0 -1
  529. package/dist/lock-holder-DaJbfpci.d.ts.map +0 -1
  530. package/dist/matrix-B8l-Nsxd.js.map +0 -1
  531. package/dist/matrix-DtkZLD_3.d.ts.map +0 -1
  532. package/dist/mint-CkzpVPdz.d.ts +0 -81
  533. package/dist/mint-CkzpVPdz.d.ts.map +0 -1
  534. package/dist/multi-layer-verifier-DEgMUk6v.d.ts.map +0 -1
  535. package/dist/multiplicity-DIWHvysC.d.ts.map +0 -1
  536. package/dist/paired-promotion-decision-CQMJ5xGN.d.ts.map +0 -1
  537. package/dist/pareto-BiBnQXAE.js.map +0 -1
  538. package/dist/prime-bridge-transport-6feEglLf.d.ts.map +0 -1
  539. package/dist/prime-protocol-BGxjfhM4.d.ts.map +0 -1
  540. package/dist/promotion-gate-CkVZHagC.d.ts.map +0 -1
  541. package/dist/query-Cmv_U8vf.d.ts.map +0 -1
  542. package/dist/random-DGEyr3zG.d.ts.map +0 -1
  543. package/dist/redact-DXdlFb_U.d.ts.map +0 -1
  544. package/dist/registry-BcdJmyoU.d.ts.map +0 -1
  545. package/dist/release-confidence-CYIFH-fp.js.map +0 -1
  546. package/dist/render-BhJqXoBH.js.map +0 -1
  547. package/dist/researcher-DKWtoMWk.d.ts.map +0 -1
  548. package/dist/reward-BeUgVVC_.d.ts.map +0 -1
  549. package/dist/reward-hacking-WTxUbtbb.d.ts.map +0 -1
  550. package/dist/rollout-Dd1ucT_M.js.map +0 -1
  551. package/dist/rubric-predictive-validity-Cd5SCtAf.d.ts.map +0 -1
  552. package/dist/run-record-C3awiXPf.d.ts.map +0 -1
  553. package/dist/sandbox-harness-BlSOu4LX.d.ts.map +0 -1
  554. package/dist/schema-C-ziyJD7.d.ts.map +0 -1
  555. package/dist/schema-CvhfLjtZ.js.map +0 -1
  556. package/dist/schema-D6EVKzTB.d.ts.map +0 -1
  557. package/dist/search-kernel-CctpiDd2.d.ts.map +0 -1
  558. package/dist/search-ledger-types-p2xKfiDJ.d.ts.map +0 -1
  559. package/dist/sequential-KwGspfeR.d.ts.map +0 -1
  560. package/dist/spans-CVngGij3.d.ts.map +0 -1
  561. package/dist/statistical-heldout-BjzSOmLH.d.ts.map +0 -1
  562. package/dist/steps-DlepJPwD.d.ts.map +0 -1
  563. package/dist/store-B3nWRy3B.d.ts.map +0 -1
  564. package/dist/store-tool-spans-DxsFwtdr.d.ts.map +0 -1
  565. package/dist/summary-report-C8V49Jt3.d.ts.map +0 -1
  566. package/dist/summary-report-DHDWxe6p.js.map +0 -1
  567. package/dist/systemone-CHnqwmYg.d.ts.map +0 -1
  568. package/dist/systemone-protocol-Bl2EI2KQ.d.ts.map +0 -1
  569. package/dist/systemone-review-cQ9acAsb.d.ts.map +0 -1
  570. package/dist/terminal-record-CB9BFtjS.js.map +0 -1
  571. package/dist/tool-groups-b3oU_D88.d.ts.map +0 -1
  572. package/dist/tool-waste-CkjzWmeY.d.ts.map +0 -1
  573. package/dist/trace-questions-BmT8M6UQ.d.ts.map +0 -1
  574. package/dist/types-6Lfdlshp.d.ts.map +0 -1
  575. package/dist/types-B_IFcKp5.d.ts.map +0 -1
  576. package/dist/types-CmXY0PQf.d.ts.map +0 -1
  577. package/dist/types-DZ0mYVw9.d.ts.map +0 -1
  578. package/dist/types-M6eF9m-r.d.ts.map +0 -1
  579. package/dist/verdict-C24NELtN.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/pipelines/first-divergence.ts","../../src/pipelines/stuck-loop.ts"],"sourcesContent":["/**\n * Step diff between two runs, with the first divergence marked.\n *\n * Steps pair in three passes, each over the steps still unpaired:\n * 1. `id`: the same step id in both runs, e.g. a forked run that kept its\n * parent's span ids.\n * 2. `position`: the same index with the same name and kind.\n * 3. `name`: the same name and kind anywhere, first unpaired step in order.\n * A step left unpaired exists in only one run. The first divergence is the\n * first index at which the two runs stop agreeing step for step, and it says\n * how: a paired step changed, one run replaced, added or removed a step, or the\n * runs ran the same steps in a different order.\n *\n * `diffSteps` reads plain `DiffStep` lists, so the same diff serves any step\n * source, including flat OTLP spans (`diffStepsFromSpans`). Use it to\n * attribute \"why is variant B better?\" to a step, and to compare sibling or\n * parent and child runs of a search tree.\n */\n\nimport type { DiagnosisSpan } from '../diagnosis/spans'\nimport type { TrajectoryStep } from '../trajectory'\n\n/** One step of a run, as the diff reads it. */\nexport interface DiffStep {\n /** The step's id within its run. */\n id: string\n name: string\n kind: string\n /** Fields compared once two steps pair, such as status, tool or model. */\n fields: Readonly<Record<string, string | number | boolean | null>>\n}\n\nexport type StepPairing = 'id' | 'position' | 'name'\n\nexport interface FieldDifference {\n field: string\n a: string | number | boolean | null\n b: string | number | boolean | null\n}\n\nexport interface StepPair {\n /** Index in run A. */\n a: number\n /** Index in run B. */\n b: number\n pairedBy: StepPairing\n /** Empty when the paired steps agree on name, kind and every field. */\n differences: FieldDifference[]\n}\n\nexport type StepDivergenceKind = 'changed' | 'replaced' | 'only-in-a' | 'only-in-b' | 'reordered'\n\nexport interface StepDivergence {\n /** The first index at which the runs stop agreeing; equals `commonPrefixLen`. */\n index: number\n kind: StepDivergenceKind\n /** Index of the step at `index` in each run, or null when that run has ended. */\n a: number | null\n b: number | null\n /** Set when `kind` is `changed`. */\n differences: FieldDifference[]\n reason: string\n}\n\nexport interface StepDiff {\n /** Paired steps in run A order. */\n pairs: StepPair[]\n /** Indexes of run A steps with no partner in run B. */\n onlyInA: number[]\n /** Indexes of run B steps with no partner in run A. */\n onlyInB: number[]\n /** Leading steps paired index for index with no difference. */\n commonPrefixLen: number\n /** Null when the runs agree step for step. */\n firstDivergence: StepDivergence | null\n}\n\nexport function diffSteps(a: readonly DiffStep[], b: readonly DiffStep[]): StepDiff {\n const partnerOfA = new Map<number, { b: number; pairedBy: StepPairing }>()\n const pairedB = new Set<number>()\n const pair = (i: number, j: number, pairedBy: StepPairing) => {\n partnerOfA.set(i, { b: j, pairedBy })\n pairedB.add(j)\n }\n\n const bById = new Map<string, number[]>()\n b.forEach((step, j) => {\n const list = bById.get(step.id)\n if (list) list.push(j)\n else bById.set(step.id, [j])\n })\n a.forEach((step, i) => {\n const j = bById.get(step.id)?.find((candidate) => !pairedB.has(candidate))\n if (j !== undefined) pair(i, j, 'id')\n })\n a.forEach((step, i) => {\n if (partnerOfA.has(i) || i >= b.length || pairedB.has(i)) return\n if (sameShape(step, b[i]!)) pair(i, i, 'position')\n })\n a.forEach((step, i) => {\n if (partnerOfA.has(i)) return\n const j = b.findIndex((candidate, index) => !pairedB.has(index) && sameShape(step, candidate))\n if (j >= 0) pair(i, j, 'name')\n })\n\n const pairs: StepPair[] = [...partnerOfA.entries()]\n .sort(([x], [y]) => x - y)\n .map(([i, partner]) => ({\n a: i,\n b: partner.b,\n pairedBy: partner.pairedBy,\n differences: differencesBetween(a[i]!, b[partner.b]!),\n }))\n const pairByA = new Map(pairs.map((entry) => [entry.a, entry]))\n const partnerOfB = new Map(pairs.map((entry) => [entry.b, entry.a]))\n\n let prefix = 0\n while (prefix < a.length && prefix < b.length) {\n const entry = pairByA.get(prefix)\n if (!entry || entry.b !== prefix || entry.differences.length > 0) break\n prefix += 1\n }\n\n return {\n pairs,\n onlyInA: a.map((_, i) => i).filter((i) => !partnerOfA.has(i)),\n onlyInB: b.map((_, j) => j).filter((j) => !pairedB.has(j)),\n commonPrefixLen: prefix,\n firstDivergence:\n prefix === a.length && prefix === b.length\n ? null\n : divergenceAt(prefix, a, b, pairByA.get(prefix), partnerOfB),\n }\n}\n\nfunction divergenceAt(\n index: number,\n a: readonly DiffStep[],\n b: readonly DiffStep[],\n pairOfA: StepPair | undefined,\n partnerOfB: ReadonlyMap<number, number>,\n): StepDivergence {\n const stepA = a[index]\n const stepB = b[index]\n const base = {\n index,\n a: stepA ? index : null,\n b: stepB ? index : null,\n differences: [] as FieldDifference[],\n }\n if (stepA && stepB && pairOfA?.b === index) {\n return {\n ...base,\n kind: 'changed',\n differences: pairOfA.differences,\n reason: `at index ${index}, ${describe(stepA)} changed: ${pairOfA.differences\n .map((d) => `${d.field} ${String(d.a)} vs ${String(d.b)}`)\n .join('; ')}`,\n }\n }\n const aUnpaired = stepA !== undefined && pairOfA === undefined\n const bUnpaired = stepB !== undefined && !partnerOfB.has(index)\n if (stepA && stepB && aUnpaired && bUnpaired) {\n return {\n ...base,\n kind: 'replaced',\n reason: `at index ${index}, A ran ${describe(stepA)} and B ran ${describe(stepB)}`,\n }\n }\n if (stepA && aUnpaired) {\n return {\n ...base,\n kind: 'only-in-a',\n reason: `at index ${index}, only A has ${describe(stepA)}`,\n }\n }\n if (stepB && bUnpaired) {\n return {\n ...base,\n kind: 'only-in-b',\n reason: `at index ${index}, only B has ${describe(stepB)}`,\n }\n }\n return {\n ...base,\n kind: 'reordered',\n reason: `at index ${index}, A ran ${describe(stepA!)} and B ran ${describe(stepB!)}; both steps occur in the other run at a different position`,\n }\n}\n\nfunction sameShape(x: DiffStep, y: DiffStep): boolean {\n return x.name === y.name && x.kind === y.kind\n}\n\nfunction differencesBetween(x: DiffStep, y: DiffStep): FieldDifference[] {\n const differences: FieldDifference[] = []\n if (x.kind !== y.kind) differences.push({ field: 'kind', a: x.kind, b: y.kind })\n if (x.name !== y.name) differences.push({ field: 'name', a: x.name, b: y.name })\n const fields = [...new Set([...Object.keys(x.fields), ...Object.keys(y.fields)])].sort()\n for (const field of fields) {\n const left = x.fields[field] ?? null\n const right = y.fields[field] ?? null\n if (left !== right) differences.push({ field, a: left, b: right })\n }\n return differences\n}\n\nfunction describe(step: DiffStep): string {\n return `${step.kind} \"${step.name}\"`\n}\n\n// ── agent-eval trace store ────────────────────────────────────────────\n\nexport interface DivergenceReport {\n runA: string\n runB: string\n /** Null when the runs agree step for step. */\n firstDivergenceIndex: number | null\n aStep?: TrajectoryStep\n bStep?: TrajectoryStep\n reason?: string\n commonPrefixLen: number\n /** The step diff behind the first divergence, over trajectory step indexes. */\n diff: StepDiff\n}\n\n// ── flat OTLP spans ───────────────────────────────────────────────────\n\n/**\n * One run's spans as diff steps, in containment order: depth first, siblings\n * by start time, the same order `buildTrajectory` gives a trace store run.\n * Spans whose parent is absent, or whose parents form a cycle, start their own\n * subtree, so every span appears exactly once.\n */\nexport function diffStepsFromSpans(spans: readonly DiagnosisSpan[]): DiffStep[] {\n const ids = new Set(spans.map((span) => span.spanId))\n const children = new Map<string | null, DiagnosisSpan[]>()\n for (const span of spans) {\n const parent =\n span.parentSpanId !== null && ids.has(span.parentSpanId) ? span.parentSpanId : null\n const list = children.get(parent)\n if (list) list.push(span)\n else children.set(parent, [span])\n }\n // Span ids are random per run, so two runs of the same logical trace can carry\n // different ids for \"the same\" span. Siblings that share a start time (a common\n // case: parallel steps a driver starts together) must still sort the same way\n // in both runs, or the diff below reports a false `reordered` divergence purely\n // from spanId noise. End time, kind and name are content, not per-run identity,\n // so they break the tie before spanId, which is the last resort.\n const byStart = (x: DiagnosisSpan, y: DiagnosisSpan) =>\n (x.startMs ?? 0) - (y.startMs ?? 0) ||\n (x.endMs ?? 0) - (y.endMs ?? 0) ||\n x.kind.localeCompare(y.kind) ||\n x.name.localeCompare(y.name) ||\n x.spanId.localeCompare(y.spanId)\n for (const list of children.values()) list.sort(byStart)\n const ordered: DiffStep[] = []\n const visited = new Set<string>()\n const visit = (span: DiagnosisSpan) => {\n if (visited.has(span.spanId)) return\n visited.add(span.spanId)\n ordered.push({\n id: span.spanId,\n name: span.name,\n kind: span.kind,\n fields: { status: span.status, tool: span.toolName, model: span.model },\n })\n for (const child of children.get(span.spanId) ?? []) visit(child)\n }\n for (const root of children.get(null) ?? []) visit(root)\n for (const span of [...spans].sort(byStart)) visit(span)\n return ordered\n}\n","/**\n * StuckLoopView — detects when an agent calls the same tool with the\n * same (or structurally similar) arguments ≥ N times in a short window.\n *\n * Rationale: agents that loop are the number-one production failure\n * mode on long-horizon flows. The view returns (runId, toolName,\n * argHash, occurrences, windowMs) for each detected loop plus a\n * fraction of runs affected.\n */\n\nimport { executionTrackByLane } from '../trace/execution-tracks'\nimport { argHash, hasCapturedToolArgs } from '../trace/query'\nimport { isToolSpan, type Span, type ToolSpan } from '../trace/schema'\nimport type { TraceStore } from '../trace/store'\n\nconst DEFAULT_MAX_WINDOW_MS = 60_000\nconst DEFAULT_MAX_INTERVENING_TOOL_CALLS = 0\n\ninterface ScopedToolCall {\n span: ToolSpan\n scopeSpanId: string | null\n laneSpanId: string | null\n}\n\ninterface IndexedToolCall extends ScopedToolCall {\n toolCallIndex: number\n trackId: string\n}\n\nexport interface StuckLoopFinding {\n runId: string\n toolName: string\n argHash: string\n /** Calls in this episode's densest qualifying interval, not the whole-run total. */\n occurrences: number\n spanIds: string[]\n /** Nearest agent ancestor, or the direct parent when ancestry is incomplete. */\n scopeSpanId?: string\n /** Milliseconds between first and last call in the loop. */\n windowMs: number\n}\n\nexport interface StuckLoopReport {\n findings: StuckLoopFinding[]\n affectedRunRatio: number\n totalRuns: number\n}\n\nexport interface StuckLoopOptions {\n /** Minimum call count to flag a loop (default 3). */\n minOccurrences?: number\n /** Maximum time between the first and last repeated call (default 60 seconds). */\n maxWindowMs?: number\n /**\n * Maximum other tool calls allowed between adjacent repeats (default 0).\n * Set to 1 to detect alternating patterns such as A,B,A,B,A.\n */\n maxInterveningToolCalls?: number\n /** Filter to a specific runId; omit to scan the entire corpus. */\n runId?: string\n}\n\nexport async function stuckLoopView(\n store: TraceStore,\n options: StuckLoopOptions = {},\n): Promise<StuckLoopReport> {\n const minOccurrences = options.minOccurrences ?? 3\n const maxWindowMs = options.maxWindowMs ?? DEFAULT_MAX_WINDOW_MS\n const maxInterveningToolCalls =\n options.maxInterveningToolCalls ?? DEFAULT_MAX_INTERVENING_TOOL_CALLS\n if (!Number.isInteger(minOccurrences) || minOccurrences < 1) {\n throw new RangeError('minOccurrences must be a positive integer')\n }\n if (!Number.isFinite(maxWindowMs) || maxWindowMs < 0) {\n throw new RangeError('maxWindowMs must be a finite non-negative number')\n }\n if (!Number.isInteger(maxInterveningToolCalls) || maxInterveningToolCalls < 0) {\n throw new RangeError('maxInterveningToolCalls must be a non-negative integer')\n }\n const runs = options.runId\n ? [{ runId: options.runId }]\n : (await store.listRuns()).map((r) => ({ runId: r.runId }))\n\n const findings: StuckLoopFinding[] = []\n for (const { runId } of runs) {\n const spans = await store.spans({ runId })\n const spansById = new Map(spans.map((span) => [span.spanId, span]))\n const scopedTools: ScopedToolCall[] = spans\n .filter(isToolSpan)\n .map((span, sourceIndex) => ({ span, sourceIndex }))\n .sort((a, b) => a.span.startedAt - b.span.startedAt || a.sourceIndex - b.sourceIndex)\n .map(({ span }) => ({ span, ...executionScope(span, spansById) }))\n const trackByLane = executionTrackByLane(\n scopedTools.map((call) => {\n const direct = call.laneSpanId === null || call.laneSpanId === call.scopeSpanId\n const timed = direct\n ? call.span\n : call.laneSpanId\n ? spansById.get(call.laneSpanId)\n : undefined\n return {\n key: executionKey(call),\n scopeKey: JSON.stringify(call.scopeSpanId),\n start: timed?.startedAt ?? null,\n end: timed?.endedAt ?? null,\n }\n }),\n )\n const nextToolIndexByTrack = new Map<string, number>()\n const orderedTools: IndexedToolCall[] = scopedTools.map((call) => {\n const trackId = trackByLane.get(executionKey(call))!\n const toolCallIndex = nextToolIndexByTrack.get(trackId) ?? 0\n nextToolIndexByTrack.set(trackId, toolCallIndex + 1)\n return { ...call, toolCallIndex, trackId }\n })\n const byKey = new Map<\n string,\n {\n calls: IndexedToolCall[]\n argHash: string\n toolName: string\n scopeSpanId: string | null\n }\n >()\n for (const call of orderedTools) {\n if (!hasCapturedToolArgs(call.span)) continue\n const h = argHash(call.span.args)\n const key = JSON.stringify([call.trackId, call.span.toolName, h])\n const bucket = byKey.get(key) ?? {\n calls: [],\n argHash: h,\n toolName: call.span.toolName,\n scopeSpanId: call.scopeSpanId,\n }\n bucket.calls.push(call)\n byKey.set(key, bucket)\n }\n for (const { calls, argHash: h, toolName, scopeSpanId } of byKey.values()) {\n if (calls.length < minOccurrences) continue\n let episodeStart = 0\n for (let episodeEnd = 1; episodeEnd <= calls.length; episodeEnd += 1) {\n const previous = calls[episodeEnd - 1]!\n const next = calls[episodeEnd]\n const episodeEnded =\n next === undefined ||\n next.span.startedAt - previous.span.startedAt > maxWindowMs ||\n next.toolCallIndex - previous.toolCallIndex - 1 > maxInterveningToolCalls ||\n !callsAreSerial(previous, next)\n if (!episodeEnded) continue\n\n const episode = calls.slice(episodeStart, episodeEnd)\n let left = 0\n let bestStart = 0\n let bestEnd = -1\n for (let right = 0; right < episode.length; right += 1) {\n while (episode[right]!.span.startedAt - episode[left]!.span.startedAt > maxWindowMs) {\n left += 1\n }\n if (right - left > bestEnd - bestStart) {\n bestStart = left\n bestEnd = right\n }\n }\n if (bestEnd - bestStart + 1 >= minOccurrences) {\n const loop = episode.slice(bestStart, bestEnd + 1)\n const first = loop[0]!.span.startedAt\n const last = loop[loop.length - 1]!.span.startedAt\n findings.push({\n runId,\n toolName,\n argHash: h,\n occurrences: loop.length,\n spanIds: loop.map((call) => call.span.spanId),\n ...(scopeSpanId ? { scopeSpanId } : {}),\n windowMs: last - first,\n })\n }\n episodeStart = episodeEnd\n }\n }\n }\n\n const affectedRuns = new Set(findings.map((f) => f.runId))\n return {\n findings,\n affectedRunRatio: runs.length > 0 ? affectedRuns.size / runs.length : 0,\n totalRuns: runs.length,\n }\n}\n\nfunction laneKey(call: Pick<ScopedToolCall, 'scopeSpanId' | 'laneSpanId'>): string {\n return JSON.stringify([call.scopeSpanId, call.laneSpanId])\n}\n\nfunction executionKey(call: ScopedToolCall): string {\n return call.laneSpanId === null || call.laneSpanId === call.scopeSpanId\n ? JSON.stringify([call.scopeSpanId, call.span.spanId])\n : laneKey(call)\n}\n\nfunction executionScope(\n span: ToolSpan,\n spansById: ReadonlyMap<string, Span>,\n): { scopeSpanId: string | null; laneSpanId: string | null } {\n const directParent = span.parentSpanId\n if (!directParent) return { scopeSpanId: null, laneSpanId: null }\n\n let currentId: string | undefined = directParent\n let laneSpanId: string | null = null\n const seen = new Set<string>()\n while (currentId && !seen.has(currentId)) {\n seen.add(currentId)\n const current = spansById.get(currentId)\n if (!current) return { scopeSpanId: directParent, laneSpanId: directParent }\n if (current.kind === 'agent') {\n return { scopeSpanId: current.spanId, laneSpanId: laneSpanId ?? current.spanId }\n }\n laneSpanId = current.spanId\n currentId = current.parentSpanId\n }\n return { scopeSpanId: directParent, laneSpanId: directParent }\n}\n\nfunction callsAreSerial(previous: IndexedToolCall, next: IndexedToolCall): boolean {\n return previous.span.endedAt !== undefined && previous.span.endedAt <= next.span.startedAt\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/pipelines/first-divergence.ts","../../src/pipelines/stuck-loop.ts"],"sourcesContent":["/**\n * Step diff between two runs, with the first divergence marked.\n *\n * Steps pair in three passes, each over the steps still unpaired:\n * 1. `id`: the same step id in both runs, e.g. a forked run that kept its\n * parent's span ids.\n * 2. `position`: the same index with the same name and kind.\n * 3. `name`: the same name and kind anywhere, first unpaired step in order.\n * A step left unpaired exists in only one run. The first divergence is the\n * first index at which the two runs stop agreeing step for step, and it says\n * how: a paired step changed, one run replaced, added or removed a step, or the\n * runs ran the same steps in a different order.\n *\n * `diffSteps` reads plain `DiffStep` lists, so the same diff serves any step\n * source, including flat OTLP spans (`diffStepsFromSpans`). Use it to\n * attribute \"why is variant B better?\" to a step, and to compare sibling or\n * parent and child runs of a search tree.\n */\n\nimport type { DiagnosisSpan } from '../diagnosis/spans'\nimport type { TrajectoryStep } from '../trajectory'\n\n/** One step of a run, as the diff reads it. */\nexport interface DiffStep {\n /** The step's id within its run. */\n id: string\n name: string\n kind: string\n /** Fields compared once two steps pair, such as status, tool or model. */\n fields: Readonly<Record<string, string | number | boolean | null>>\n}\n\nexport type StepPairing = 'id' | 'position' | 'name'\n\nexport interface FieldDifference {\n field: string\n a: string | number | boolean | null\n b: string | number | boolean | null\n}\n\nexport interface StepPair {\n /** Index in run A. */\n a: number\n /** Index in run B. */\n b: number\n pairedBy: StepPairing\n /** Empty when the paired steps agree on name, kind and every field. */\n differences: FieldDifference[]\n}\n\nexport type StepDivergenceKind = 'changed' | 'replaced' | 'only-in-a' | 'only-in-b' | 'reordered'\n\nexport interface StepDivergence {\n /** The first index at which the runs stop agreeing; equals `commonPrefixLen`. */\n index: number\n kind: StepDivergenceKind\n /** Index of the step at `index` in each run, or null when that run has ended. */\n a: number | null\n b: number | null\n /** Set when `kind` is `changed`. */\n differences: FieldDifference[]\n reason: string\n}\n\nexport interface StepDiff {\n /** Paired steps in run A order. */\n pairs: StepPair[]\n /** Indexes of run A steps with no partner in run B. */\n onlyInA: number[]\n /** Indexes of run B steps with no partner in run A. */\n onlyInB: number[]\n /** Leading steps paired index for index with no difference. */\n commonPrefixLen: number\n /** Null when the runs agree step for step. */\n firstDivergence: StepDivergence | null\n}\n\nexport function diffSteps(a: readonly DiffStep[], b: readonly DiffStep[]): StepDiff {\n const partnerOfA = new Map<number, { b: number; pairedBy: StepPairing }>()\n const pairedB = new Set<number>()\n const pair = (i: number, j: number, pairedBy: StepPairing) => {\n partnerOfA.set(i, { b: j, pairedBy })\n pairedB.add(j)\n }\n\n const bById = new Map<string, number[]>()\n b.forEach((step, j) => {\n const list = bById.get(step.id)\n if (list) list.push(j)\n else bById.set(step.id, [j])\n })\n a.forEach((step, i) => {\n const j = bById.get(step.id)?.find((candidate) => !pairedB.has(candidate))\n if (j !== undefined) pair(i, j, 'id')\n })\n a.forEach((step, i) => {\n if (partnerOfA.has(i) || i >= b.length || pairedB.has(i)) return\n if (sameShape(step, b[i]!)) pair(i, i, 'position')\n })\n a.forEach((step, i) => {\n if (partnerOfA.has(i)) return\n const j = b.findIndex((candidate, index) => !pairedB.has(index) && sameShape(step, candidate))\n if (j >= 0) pair(i, j, 'name')\n })\n\n const pairs: StepPair[] = [...partnerOfA.entries()]\n .sort(([x], [y]) => x - y)\n .map(([i, partner]) => ({\n a: i,\n b: partner.b,\n pairedBy: partner.pairedBy,\n differences: differencesBetween(a[i]!, b[partner.b]!),\n }))\n const pairByA = new Map(pairs.map((entry) => [entry.a, entry]))\n const partnerOfB = new Map(pairs.map((entry) => [entry.b, entry.a]))\n\n let prefix = 0\n while (prefix < a.length && prefix < b.length) {\n const entry = pairByA.get(prefix)\n if (!entry || entry.b !== prefix || entry.differences.length > 0) break\n prefix += 1\n }\n\n return {\n pairs,\n onlyInA: a.map((_, i) => i).filter((i) => !partnerOfA.has(i)),\n onlyInB: b.map((_, j) => j).filter((j) => !pairedB.has(j)),\n commonPrefixLen: prefix,\n firstDivergence:\n prefix === a.length && prefix === b.length\n ? null\n : divergenceAt(prefix, a, b, pairByA.get(prefix), partnerOfB),\n }\n}\n\nfunction divergenceAt(\n index: number,\n a: readonly DiffStep[],\n b: readonly DiffStep[],\n pairOfA: StepPair | undefined,\n partnerOfB: ReadonlyMap<number, number>,\n): StepDivergence {\n const stepA = a[index]\n const stepB = b[index]\n const base = {\n index,\n a: stepA ? index : null,\n b: stepB ? index : null,\n differences: [] as FieldDifference[],\n }\n if (stepA && stepB && pairOfA?.b === index) {\n return {\n ...base,\n kind: 'changed',\n differences: pairOfA.differences,\n reason: `at index ${index}, ${describe(stepA)} changed: ${pairOfA.differences\n .map((d) => `${d.field} ${String(d.a)} vs ${String(d.b)}`)\n .join('; ')}`,\n }\n }\n const aUnpaired = stepA !== undefined && pairOfA === undefined\n const bUnpaired = stepB !== undefined && !partnerOfB.has(index)\n if (stepA && stepB && aUnpaired && bUnpaired) {\n return {\n ...base,\n kind: 'replaced',\n reason: `at index ${index}, A ran ${describe(stepA)} and B ran ${describe(stepB)}`,\n }\n }\n if (stepA && aUnpaired) {\n return {\n ...base,\n kind: 'only-in-a',\n reason: `at index ${index}, only A has ${describe(stepA)}`,\n }\n }\n if (stepB && bUnpaired) {\n return {\n ...base,\n kind: 'only-in-b',\n reason: `at index ${index}, only B has ${describe(stepB)}`,\n }\n }\n return {\n ...base,\n kind: 'reordered',\n reason: `at index ${index}, A ran ${describe(stepA!)} and B ran ${describe(stepB!)}; both steps occur in the other run at a different position`,\n }\n}\n\nfunction sameShape(x: DiffStep, y: DiffStep): boolean {\n return x.name === y.name && x.kind === y.kind\n}\n\nfunction differencesBetween(x: DiffStep, y: DiffStep): FieldDifference[] {\n const differences: FieldDifference[] = []\n if (x.kind !== y.kind) differences.push({ field: 'kind', a: x.kind, b: y.kind })\n if (x.name !== y.name) differences.push({ field: 'name', a: x.name, b: y.name })\n const fields = [...new Set([...Object.keys(x.fields), ...Object.keys(y.fields)])].sort()\n for (const field of fields) {\n const left = x.fields[field] ?? null\n const right = y.fields[field] ?? null\n if (left !== right) differences.push({ field, a: left, b: right })\n }\n return differences\n}\n\nfunction describe(step: DiffStep): string {\n return `${step.kind} \"${step.name}\"`\n}\n\n// ── agent-eval trace store ────────────────────────────────────────────\n\nexport interface DivergenceReport {\n runA: string\n runB: string\n /** Null when the runs agree step for step. */\n firstDivergenceIndex: number | null\n aStep?: TrajectoryStep\n bStep?: TrajectoryStep\n reason?: string\n commonPrefixLen: number\n /** The step diff behind the first divergence, over trajectory step indexes. */\n diff: StepDiff\n}\n\n// ── flat OTLP spans ───────────────────────────────────────────────────\n\n/**\n * One run's spans as diff steps, in containment order: depth first, siblings\n * by start time, the same order `buildTrajectory` gives a trace store run.\n * Spans whose parent is absent, or whose parents form a cycle, start their own\n * subtree, so every span appears exactly once.\n */\nexport function diffStepsFromSpans(spans: readonly DiagnosisSpan[]): DiffStep[] {\n const ids = new Set(spans.map((span) => span.spanId))\n const children = new Map<string | null, DiagnosisSpan[]>()\n for (const span of spans) {\n const parent =\n span.parentSpanId !== null && ids.has(span.parentSpanId) ? span.parentSpanId : null\n const list = children.get(parent)\n if (list) list.push(span)\n else children.set(parent, [span])\n }\n // Span ids are random per run, so two runs of the same logical trace can carry\n // different ids for \"the same\" span. Siblings that share a start time (a common\n // case: parallel steps a driver starts together) must still sort the same way\n // in both runs, or the diff below reports a false `reordered` divergence purely\n // from spanId noise. End time, kind and name are content, not per-run identity,\n // so they break the tie before spanId, which is the last resort.\n const byStart = (x: DiagnosisSpan, y: DiagnosisSpan) =>\n (x.startMs ?? 0) - (y.startMs ?? 0) ||\n (x.endMs ?? 0) - (y.endMs ?? 0) ||\n x.kind.localeCompare(y.kind) ||\n x.name.localeCompare(y.name) ||\n x.spanId.localeCompare(y.spanId)\n for (const list of children.values()) list.sort(byStart)\n const ordered: DiffStep[] = []\n const visited = new Set<string>()\n const visit = (span: DiagnosisSpan) => {\n if (visited.has(span.spanId)) return\n visited.add(span.spanId)\n ordered.push({\n id: span.spanId,\n name: span.name,\n kind: span.kind,\n fields: { status: span.status, tool: span.toolName, model: span.model },\n })\n for (const child of children.get(span.spanId) ?? []) visit(child)\n }\n for (const root of children.get(null) ?? []) visit(root)\n for (const span of [...spans].sort(byStart)) visit(span)\n return ordered\n}\n","/**\n * StuckLoopView — detects when an agent calls the same tool with the\n * same (or structurally similar) arguments ≥ N times in a short window.\n *\n * Rationale: agents that loop are the number-one production failure\n * mode on long-horizon flows. The view returns (runId, toolName,\n * argHash, occurrences, windowMs) for each detected loop plus a\n * fraction of runs affected.\n */\n\nimport { executionTrackByLane } from '../trace/execution-tracks'\nimport { argHash, hasCapturedToolArgs } from '../trace/query'\nimport { isToolSpan, type Span, type ToolSpan } from '../trace/schema'\nimport type { TraceStore } from '../trace/store'\n\nconst DEFAULT_MAX_WINDOW_MS = 60_000\nconst DEFAULT_MAX_INTERVENING_TOOL_CALLS = 0\n\ninterface ScopedToolCall {\n span: ToolSpan\n scopeSpanId: string | null\n laneSpanId: string | null\n}\n\ninterface IndexedToolCall extends ScopedToolCall {\n toolCallIndex: number\n trackId: string\n}\n\nexport interface StuckLoopFinding {\n runId: string\n toolName: string\n argHash: string\n /** Calls in this episode's densest qualifying interval, not the whole-run total. */\n occurrences: number\n spanIds: string[]\n /** Nearest agent ancestor, or the direct parent when ancestry is incomplete. */\n scopeSpanId?: string\n /** Milliseconds between first and last call in the loop. */\n windowMs: number\n}\n\nexport interface StuckLoopReport {\n findings: StuckLoopFinding[]\n affectedRunRatio: number\n totalRuns: number\n}\n\nexport interface StuckLoopOptions {\n /** Minimum call count to flag a loop (default 3). */\n minOccurrences?: number\n /** Maximum time between the first and last repeated call (default 60 seconds). */\n maxWindowMs?: number\n /**\n * Maximum other tool calls allowed between adjacent repeats (default 0).\n * Set to 1 to detect alternating patterns such as A,B,A,B,A.\n */\n maxInterveningToolCalls?: number\n /** Filter to a specific runId; omit to scan the entire corpus. */\n runId?: string\n}\n\nexport async function stuckLoopView(\n store: TraceStore,\n options: StuckLoopOptions = {},\n): Promise<StuckLoopReport> {\n const minOccurrences = options.minOccurrences ?? 3\n const maxWindowMs = options.maxWindowMs ?? DEFAULT_MAX_WINDOW_MS\n const maxInterveningToolCalls =\n options.maxInterveningToolCalls ?? DEFAULT_MAX_INTERVENING_TOOL_CALLS\n if (!Number.isInteger(minOccurrences) || minOccurrences < 1) {\n throw new RangeError('minOccurrences must be a positive integer')\n }\n if (!Number.isFinite(maxWindowMs) || maxWindowMs < 0) {\n throw new RangeError('maxWindowMs must be a finite non-negative number')\n }\n if (!Number.isInteger(maxInterveningToolCalls) || maxInterveningToolCalls < 0) {\n throw new RangeError('maxInterveningToolCalls must be a non-negative integer')\n }\n const runs = options.runId\n ? [{ runId: options.runId }]\n : (await store.listRuns()).map((r) => ({ runId: r.runId }))\n\n const findings: StuckLoopFinding[] = []\n for (const { runId } of runs) {\n const spans = await store.spans({ runId })\n const spansById = new Map(spans.map((span) => [span.spanId, span]))\n const scopedTools: ScopedToolCall[] = spans\n .filter(isToolSpan)\n .map((span, sourceIndex) => ({ span, sourceIndex }))\n .sort((a, b) => a.span.startedAt - b.span.startedAt || a.sourceIndex - b.sourceIndex)\n .map(({ span }) => ({ span, ...executionScope(span, spansById) }))\n const trackByLane = executionTrackByLane(\n scopedTools.map((call) => {\n const direct = call.laneSpanId === null || call.laneSpanId === call.scopeSpanId\n const timed = direct\n ? call.span\n : call.laneSpanId\n ? spansById.get(call.laneSpanId)\n : undefined\n return {\n key: executionKey(call),\n scopeKey: JSON.stringify(call.scopeSpanId),\n start: timed?.startedAt ?? null,\n end: timed?.endedAt ?? null,\n }\n }),\n )\n const nextToolIndexByTrack = new Map<string, number>()\n const orderedTools: IndexedToolCall[] = scopedTools.map((call) => {\n const trackId = trackByLane.get(executionKey(call))!\n const toolCallIndex = nextToolIndexByTrack.get(trackId) ?? 0\n nextToolIndexByTrack.set(trackId, toolCallIndex + 1)\n return { ...call, toolCallIndex, trackId }\n })\n const byKey = new Map<\n string,\n {\n calls: IndexedToolCall[]\n argHash: string\n toolName: string\n scopeSpanId: string | null\n }\n >()\n for (const call of orderedTools) {\n if (!hasCapturedToolArgs(call.span)) continue\n const h = argHash(call.span.args)\n const key = JSON.stringify([call.trackId, call.span.toolName, h])\n const bucket = byKey.get(key) ?? {\n calls: [],\n argHash: h,\n toolName: call.span.toolName,\n scopeSpanId: call.scopeSpanId,\n }\n bucket.calls.push(call)\n byKey.set(key, bucket)\n }\n for (const { calls, argHash: h, toolName, scopeSpanId } of byKey.values()) {\n if (calls.length < minOccurrences) continue\n let episodeStart = 0\n for (let episodeEnd = 1; episodeEnd <= calls.length; episodeEnd += 1) {\n const previous = calls[episodeEnd - 1]!\n const next = calls[episodeEnd]\n const episodeEnded =\n next === undefined ||\n next.span.startedAt - previous.span.startedAt > maxWindowMs ||\n next.toolCallIndex - previous.toolCallIndex - 1 > maxInterveningToolCalls ||\n !callsAreSerial(previous, next)\n if (!episodeEnded) continue\n\n const episode = calls.slice(episodeStart, episodeEnd)\n let left = 0\n let bestStart = 0\n let bestEnd = -1\n for (let right = 0; right < episode.length; right += 1) {\n while (episode[right]!.span.startedAt - episode[left]!.span.startedAt > maxWindowMs) {\n left += 1\n }\n if (right - left > bestEnd - bestStart) {\n bestStart = left\n bestEnd = right\n }\n }\n if (bestEnd - bestStart + 1 >= minOccurrences) {\n const loop = episode.slice(bestStart, bestEnd + 1)\n const first = loop[0]!.span.startedAt\n const last = loop[loop.length - 1]!.span.startedAt\n findings.push({\n runId,\n toolName,\n argHash: h,\n occurrences: loop.length,\n spanIds: loop.map((call) => call.span.spanId),\n ...(scopeSpanId ? { scopeSpanId } : {}),\n windowMs: last - first,\n })\n }\n episodeStart = episodeEnd\n }\n }\n }\n\n const affectedRuns = new Set(findings.map((f) => f.runId))\n return {\n findings,\n affectedRunRatio: runs.length > 0 ? affectedRuns.size / runs.length : 0,\n totalRuns: runs.length,\n }\n}\n\nfunction laneKey(call: Pick<ScopedToolCall, 'scopeSpanId' | 'laneSpanId'>): string {\n return JSON.stringify([call.scopeSpanId, call.laneSpanId])\n}\n\nfunction executionKey(call: ScopedToolCall): string {\n return call.laneSpanId === null || call.laneSpanId === call.scopeSpanId\n ? JSON.stringify([call.scopeSpanId, call.span.spanId])\n : laneKey(call)\n}\n\nfunction executionScope(\n span: ToolSpan,\n spansById: ReadonlyMap<string, Span>,\n): { scopeSpanId: string | null; laneSpanId: string | null } {\n const directParent = span.parentSpanId\n if (!directParent) return { scopeSpanId: null, laneSpanId: null }\n\n let currentId: string | undefined = directParent\n let laneSpanId: string | null = null\n const seen = new Set<string>()\n while (currentId && !seen.has(currentId)) {\n seen.add(currentId)\n const current = spansById.get(currentId)\n if (!current) return { scopeSpanId: directParent, laneSpanId: directParent }\n if (current.kind === 'agent') {\n return { scopeSpanId: current.spanId, laneSpanId: laneSpanId ?? current.spanId }\n }\n laneSpanId = current.spanId\n currentId = current.parentSpanId\n }\n return { scopeSpanId: directParent, laneSpanId: directParent }\n}\n\nfunction callsAreSerial(previous: IndexedToolCall, next: IndexedToolCall): boolean {\n return previous.span.endedAt !== undefined && previous.span.endedAt <= next.span.startedAt\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { o as normalCdf } from "./paired-arms-B2ttLc0_.js";
2
- import { s as zQuantile } from "./internal-BTK91Bqt.js";
3
- //#region src/statistics/power-and-mde.ts
1
+ import { o as normalCdf } from "./paired-arms-D-54hO-k.js";
2
+ import { s as zQuantile } from "./internal-v6XfOeJW.js";
3
+ // src/statistics/power-and-mde.ts
4
4
  /**
5
5
  * Required N per arm for a two-sample comparison at target effect size,
6
6
  * alpha, and power. Normal-approximation formula:
@@ -94,7 +94,6 @@ function mcnemarPower(opts) {
94
94
  const zBeta = (Math.sqrt(nPairs) * Math.abs(delta) - zAlpha * Math.sqrt(pDisc)) / denom;
95
95
  return Math.min(1, Math.max(0, normalCdf(zBeta)));
96
96
  }
97
- //#endregion
98
97
  export { requiredSampleSize as a, requiredPairedSampleSize as i, mcnemarRequiredN as n, pairedMde as r, mcnemarPower as t };
99
98
 
100
- //# sourceMappingURL=power-and-mde-CQX-0weG.js.map
99
+ //# sourceMappingURL=power-and-mde-ClI6RWw4.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"power-and-mde-CQX-0weG.js","names":[],"sources":["../src/statistics/power-and-mde.ts"],"sourcesContent":["import { normalCdf } from '../math/normal'\nimport { zQuantile } from './internal'\n\n// ── Power analysis + minimum detectable effect ───────────────────────\n\n/**\n * Required N per arm for a two-sample comparison at target effect size,\n * alpha, and power. Normal-approximation formula:\n * n = 2 * ( (z_{1-α/2} + z_{1-β}) / d )^2\n * where d is Cohen's d. Returns Infinity for effect ≤ 0.\n */\nexport function requiredSampleSize(opts: {\n effect: number\n alpha?: number\n power?: number\n twoSided?: boolean\n}): number {\n const effect = opts.effect\n if (!Number.isFinite(effect) || effect <= 0) return Infinity\n const alpha = opts.alpha ?? 0.05\n const power = opts.power ?? 0.8\n const twoSided = opts.twoSided ?? true\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const zBeta = zQuantile(power)\n const n = 2 * ((zAlpha + zBeta) / effect) ** 2\n return Math.ceil(n)\n}\n\n/**\n * Required number of paired observations for a target Cohen's dz.\n * Unlike the independent-groups formula, this has no two-arm factor of two.\n *\n * Normal quantiles with no t correction, so treat the result as a LOWER bound:\n * it returns 32 where the exact t-based answer is 34 at dz = 0.5, and 13 where\n * it is 15 at dz = 0.8 — a 6–13 % shortfall precisely in the range a caller\n * consults to decide whether 3–10 repetitions suffice.\n */\nexport function requiredPairedSampleSize(opts: {\n effect: number\n alpha?: number\n power?: number\n twoSided?: boolean\n}): number {\n const effect = opts.effect\n if (!Number.isFinite(effect) || effect <= 0) return Infinity\n const alpha = opts.alpha ?? 0.05\n const power = opts.power ?? 0.8\n const twoSided = opts.twoSided ?? true\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const zBeta = zQuantile(power)\n return Math.ceil(((zAlpha + zBeta) / effect) ** 2)\n}\n\n/**\n * Minimum detectable paired effect (standardised units) for a target paired\n * sample size: d_min = (z_{1-α/2} + z_β) / sqrt(n_paired). Multiply by\n * sd(deltas) for score units; treat as a lower bound — Wilcoxon and bootstrap\n * have asymptotic relative efficiency below 1 vs the t-test on heavy tails.\n */\nexport function pairedMde(opts: {\n nPaired: number\n alpha?: number\n power?: number\n twoSided?: boolean\n}): number {\n if (!Number.isFinite(opts.nPaired) || opts.nPaired <= 0) return Infinity\n const alpha = opts.alpha ?? 0.05\n const power = opts.power ?? 0.8\n const twoSided = opts.twoSided ?? true\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const zBeta = zQuantile(power)\n return (zAlpha + zBeta) / Math.sqrt(opts.nPaired)\n}\n\n/**\n * Number of paired observations needed for a McNemar test to reach a target\n * power — the pre-registration companion to {@link mcnemar}. Parametrised by the\n * expected discordant-cell probabilities `p10` (P[treatment wins on a pair]) and\n * `p01` (P[control wins]); concordant pairs carry no information, so the count\n * is driven entirely by the discordant rate. Lachin's (1992) asymptotic normal\n * approximation: with discordant rate `pDisc = p10 + p01` and marginal effect\n * `δ = p10 − p01`,\n * n = ( z_{1-α/2}·√pDisc + z_{1-β}·√(pDisc − δ²) )² / δ².\n * Returns Infinity when there is no effect (p10 === p01). Asymptotic — at the\n * tiny discordant counts where the exact {@link mcnemar} differs from the normal\n * approximation, treat the result as a lower bound and prefer the discordant-pair\n * floor.\n */\nexport function mcnemarRequiredN(opts: {\n p10: number\n p01: number\n alpha?: number\n power?: number\n twoSided?: boolean\n}): number {\n const { p10, p01 } = opts\n if (p10 < 0 || p01 < 0 || p10 + p01 > 1) {\n throw new Error(`mcnemarRequiredN: require p10,p01 ≥ 0 and p10+p01 ≤ 1 (got ${p10}, ${p01})`)\n }\n const delta = p10 - p01\n if (delta === 0) return Infinity\n const alpha = opts.alpha ?? 0.05\n const power = opts.power ?? 0.8\n const twoSided = opts.twoSided ?? true\n const pDisc = p10 + p01\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const zBeta = zQuantile(power)\n const n =\n (zAlpha * Math.sqrt(pDisc) + zBeta * Math.sqrt(Math.max(0, pDisc - delta * delta))) ** 2 /\n (delta * delta)\n return Math.ceil(n)\n}\n\n/**\n * Power of a McNemar test at a given number of paired observations, the inverse\n * of {@link mcnemarRequiredN} (same Lachin asymptotic model, same parameters).\n * Returns a value in [0, 1]; equals `alpha` when there is no effect.\n */\nexport function mcnemarPower(opts: {\n p10: number\n p01: number\n nPairs: number\n alpha?: number\n twoSided?: boolean\n}): number {\n const { p10, p01, nPairs } = opts\n if (p10 < 0 || p01 < 0 || p10 + p01 > 1) {\n throw new Error(`mcnemarPower: require p10,p01 ≥ 0 and p10+p01 ≤ 1 (got ${p10}, ${p01})`)\n }\n const alpha = opts.alpha ?? 0.05\n const twoSided = opts.twoSided ?? true\n const delta = p10 - p01\n if (delta === 0 || nPairs <= 0) return alpha\n const pDisc = p10 + p01\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const denom = Math.sqrt(Math.max(1e-12, pDisc - delta * delta))\n const zBeta = (Math.sqrt(nPairs) * Math.abs(delta) - zAlpha * Math.sqrt(pDisc)) / denom\n return Math.min(1, Math.max(0, normalCdf(zBeta)))\n}\n"],"mappings":";;;;;;;;;AAWA,SAAgB,mBAAmB,MAKxB;CACT,MAAM,SAAS,KAAK;CACpB,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,GAAG,OAAO;CACpD,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,KAAK,YAAY;CAGlC,MAAM,IAAI,MAFK,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAEnC,IADP,UAAU,KACK,KAAK,WAAW;CAC7C,OAAO,KAAK,KAAK,CAAC;AACpB;;;;;;;;;;AAWA,SAAgB,yBAAyB,MAK9B;CACT,MAAM,SAAS,KAAK;CACpB,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,GAAG,OAAO;CACpD,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,SAAS,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAAK;CAC7D,MAAM,QAAQ,UAAU,KAAK;CAC7B,OAAO,KAAK,OAAO,SAAS,SAAS,WAAW,CAAC;AACnD;;;;;;;AAQA,SAAgB,UAAU,MAKf;CACT,IAAI,CAAC,OAAO,SAAS,KAAK,OAAO,KAAK,KAAK,WAAW,GAAG,OAAO;CAChE,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,KAAK,YAAY;CAGlC,QAFe,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAE3C,IADC,UAAU,KACH,KAAK,KAAK,KAAK,KAAK,OAAO;AAClD;;;;;;;;;;;;;;;AAgBA,SAAgB,iBAAiB,MAMtB;CACT,MAAM,EAAE,KAAK,QAAQ;CACrB,IAAI,MAAM,KAAK,MAAM,KAAK,MAAM,MAAM,GACpC,MAAM,IAAI,MAAM,8DAA8D,IAAI,IAAI,IAAI,EAAE;CAE9F,MAAM,QAAQ,MAAM;CACpB,IAAI,UAAU,GAAG,OAAO;CACxB,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAAK;CAC7D,MAAM,QAAQ,UAAU,KAAK;CAC7B,MAAM,KACH,SAAS,KAAK,KAAK,KAAK,IAAI,QAAQ,KAAK,KAAK,KAAK,IAAI,GAAG,QAAQ,QAAQ,KAAK,CAAC,MAAM,KACtF,QAAQ;CACX,OAAO,KAAK,KAAK,CAAC;AACpB;;;;;;AAOA,SAAgB,aAAa,MAMlB;CACT,MAAM,EAAE,KAAK,KAAK,WAAW;CAC7B,IAAI,MAAM,KAAK,MAAM,KAAK,MAAM,MAAM,GACpC,MAAM,IAAI,MAAM,0DAA0D,IAAI,IAAI,IAAI,EAAE;CAE1F,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,QAAQ,MAAM;CACpB,IAAI,UAAU,KAAK,UAAU,GAAG,OAAO;CACvC,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAAK;CAC7D,MAAM,QAAQ,KAAK,KAAK,KAAK,IAAI,OAAO,QAAQ,QAAQ,KAAK,CAAC;CAC9D,MAAM,SAAS,KAAK,KAAK,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,SAAS,KAAK,KAAK,KAAK,KAAK;CAClF,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,KAAK,CAAC,CAAC;AAClD"}
1
+ {"version":3,"file":"power-and-mde-ClI6RWw4.js","names":[],"sources":["../src/statistics/power-and-mde.ts"],"sourcesContent":["import { normalCdf } from '../math/normal'\nimport { zQuantile } from './internal'\n\n// ── Power analysis + minimum detectable effect ───────────────────────\n\n/**\n * Required N per arm for a two-sample comparison at target effect size,\n * alpha, and power. Normal-approximation formula:\n * n = 2 * ( (z_{1-α/2} + z_{1-β}) / d )^2\n * where d is Cohen's d. Returns Infinity for effect ≤ 0.\n */\nexport function requiredSampleSize(opts: {\n effect: number\n alpha?: number\n power?: number\n twoSided?: boolean\n}): number {\n const effect = opts.effect\n if (!Number.isFinite(effect) || effect <= 0) return Infinity\n const alpha = opts.alpha ?? 0.05\n const power = opts.power ?? 0.8\n const twoSided = opts.twoSided ?? true\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const zBeta = zQuantile(power)\n const n = 2 * ((zAlpha + zBeta) / effect) ** 2\n return Math.ceil(n)\n}\n\n/**\n * Required number of paired observations for a target Cohen's dz.\n * Unlike the independent-groups formula, this has no two-arm factor of two.\n *\n * Normal quantiles with no t correction, so treat the result as a LOWER bound:\n * it returns 32 where the exact t-based answer is 34 at dz = 0.5, and 13 where\n * it is 15 at dz = 0.8 — a 6–13 % shortfall precisely in the range a caller\n * consults to decide whether 3–10 repetitions suffice.\n */\nexport function requiredPairedSampleSize(opts: {\n effect: number\n alpha?: number\n power?: number\n twoSided?: boolean\n}): number {\n const effect = opts.effect\n if (!Number.isFinite(effect) || effect <= 0) return Infinity\n const alpha = opts.alpha ?? 0.05\n const power = opts.power ?? 0.8\n const twoSided = opts.twoSided ?? true\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const zBeta = zQuantile(power)\n return Math.ceil(((zAlpha + zBeta) / effect) ** 2)\n}\n\n/**\n * Minimum detectable paired effect (standardised units) for a target paired\n * sample size: d_min = (z_{1-α/2} + z_β) / sqrt(n_paired). Multiply by\n * sd(deltas) for score units; treat as a lower bound — Wilcoxon and bootstrap\n * have asymptotic relative efficiency below 1 vs the t-test on heavy tails.\n */\nexport function pairedMde(opts: {\n nPaired: number\n alpha?: number\n power?: number\n twoSided?: boolean\n}): number {\n if (!Number.isFinite(opts.nPaired) || opts.nPaired <= 0) return Infinity\n const alpha = opts.alpha ?? 0.05\n const power = opts.power ?? 0.8\n const twoSided = opts.twoSided ?? true\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const zBeta = zQuantile(power)\n return (zAlpha + zBeta) / Math.sqrt(opts.nPaired)\n}\n\n/**\n * Number of paired observations needed for a McNemar test to reach a target\n * power — the pre-registration companion to {@link mcnemar}. Parametrised by the\n * expected discordant-cell probabilities `p10` (P[treatment wins on a pair]) and\n * `p01` (P[control wins]); concordant pairs carry no information, so the count\n * is driven entirely by the discordant rate. Lachin's (1992) asymptotic normal\n * approximation: with discordant rate `pDisc = p10 + p01` and marginal effect\n * `δ = p10 − p01`,\n * n = ( z_{1-α/2}·√pDisc + z_{1-β}·√(pDisc − δ²) )² / δ².\n * Returns Infinity when there is no effect (p10 === p01). Asymptotic — at the\n * tiny discordant counts where the exact {@link mcnemar} differs from the normal\n * approximation, treat the result as a lower bound and prefer the discordant-pair\n * floor.\n */\nexport function mcnemarRequiredN(opts: {\n p10: number\n p01: number\n alpha?: number\n power?: number\n twoSided?: boolean\n}): number {\n const { p10, p01 } = opts\n if (p10 < 0 || p01 < 0 || p10 + p01 > 1) {\n throw new Error(`mcnemarRequiredN: require p10,p01 ≥ 0 and p10+p01 ≤ 1 (got ${p10}, ${p01})`)\n }\n const delta = p10 - p01\n if (delta === 0) return Infinity\n const alpha = opts.alpha ?? 0.05\n const power = opts.power ?? 0.8\n const twoSided = opts.twoSided ?? true\n const pDisc = p10 + p01\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const zBeta = zQuantile(power)\n const n =\n (zAlpha * Math.sqrt(pDisc) + zBeta * Math.sqrt(Math.max(0, pDisc - delta * delta))) ** 2 /\n (delta * delta)\n return Math.ceil(n)\n}\n\n/**\n * Power of a McNemar test at a given number of paired observations, the inverse\n * of {@link mcnemarRequiredN} (same Lachin asymptotic model, same parameters).\n * Returns a value in [0, 1]; equals `alpha` when there is no effect.\n */\nexport function mcnemarPower(opts: {\n p10: number\n p01: number\n nPairs: number\n alpha?: number\n twoSided?: boolean\n}): number {\n const { p10, p01, nPairs } = opts\n if (p10 < 0 || p01 < 0 || p10 + p01 > 1) {\n throw new Error(`mcnemarPower: require p10,p01 ≥ 0 and p10+p01 ≤ 1 (got ${p10}, ${p01})`)\n }\n const alpha = opts.alpha ?? 0.05\n const twoSided = opts.twoSided ?? true\n const delta = p10 - p01\n if (delta === 0 || nPairs <= 0) return alpha\n const pDisc = p10 + p01\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const denom = Math.sqrt(Math.max(1e-12, pDisc - delta * delta))\n const zBeta = (Math.sqrt(nPairs) * Math.abs(delta) - zAlpha * Math.sqrt(pDisc)) / denom\n return Math.min(1, Math.max(0, normalCdf(zBeta)))\n}\n"],"mappings":";;;;;;;;;AAWA,SAAgB,mBAAmB,MAKxB;CACT,MAAM,SAAS,KAAK;CACpB,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,GAAG,OAAO;CACpD,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,KAAK,YAAY;CAGlC,MAAM,IAAI,MAFK,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAEnC,IADP,UAAU,KACK,KAAK,WAAW;CAC7C,OAAO,KAAK,KAAK,CAAC;AACpB;;;;;;;;;;AAWA,SAAgB,yBAAyB,MAK9B;CACT,MAAM,SAAS,KAAK;CACpB,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,GAAG,OAAO;CACpD,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,SAAS,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAAK;CAC7D,MAAM,QAAQ,UAAU,KAAK;CAC7B,OAAO,KAAK,OAAO,SAAS,SAAS,WAAW,CAAC;AACnD;;;;;;;AAQA,SAAgB,UAAU,MAKf;CACT,IAAI,CAAC,OAAO,SAAS,KAAK,OAAO,KAAK,KAAK,WAAW,GAAG,OAAO;CAChE,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,KAAK,YAAY;CAGlC,QAFe,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAE3C,IADC,UAAU,KACH,KAAK,KAAK,KAAK,KAAK,OAAO;AAClD;;;;;;;;;;;;;;;AAgBA,SAAgB,iBAAiB,MAMtB;CACT,MAAM,EAAE,KAAK,QAAQ;CACrB,IAAI,MAAM,KAAK,MAAM,KAAK,MAAM,MAAM,GACpC,MAAM,IAAI,MAAM,8DAA8D,IAAI,IAAI,IAAI,EAAE;CAE9F,MAAM,QAAQ,MAAM;CACpB,IAAI,UAAU,GAAG,OAAO;CACxB,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAAK;CAC7D,MAAM,QAAQ,UAAU,KAAK;CAC7B,MAAM,KACH,SAAS,KAAK,KAAK,KAAK,IAAI,QAAQ,KAAK,KAAK,KAAK,IAAI,GAAG,QAAQ,QAAQ,KAAK,CAAC,MAAM,KACtF,QAAQ;CACX,OAAO,KAAK,KAAK,CAAC;AACpB;;;;;;AAOA,SAAgB,aAAa,MAMlB;CACT,MAAM,EAAE,KAAK,KAAK,WAAW;CAC7B,IAAI,MAAM,KAAK,MAAM,KAAK,MAAM,MAAM,GACpC,MAAM,IAAI,MAAM,0DAA0D,IAAI,IAAI,IAAI,EAAE;CAE1F,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,QAAQ,MAAM;CACpB,IAAI,UAAU,KAAK,UAAU,GAAG,OAAO;CACvC,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,UAAU,WAAW,IAAI,QAAQ,IAAI,IAAI,KAAK;CAC7D,MAAM,QAAQ,KAAK,KAAK,KAAK,IAAI,OAAO,QAAQ,QAAQ,KAAK,CAAC;CAC9D,MAAM,SAAS,KAAK,KAAK,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,SAAS,KAAK,KAAK,KAAK,KAAK;CAClF,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,KAAK,CAAC,CAAC;AAClD"}
@@ -1,4 +1,4 @@
1
- //#region src/experiment/ast/predicate.ts
1
+ // src/experiment/ast/predicate.ts
2
2
  /** Read a dot-separated field path. Missing segments yield `undefined`. */
3
3
  function readField(record, path) {
4
4
  let current = record;
@@ -32,7 +32,6 @@ function compareValues(value, op, target) {
32
32
  case "gte": return left >= right;
33
33
  }
34
34
  }
35
- //#endregion
36
35
  export { evaluatePredicate as n, readField as r, compareValues as t };
37
36
 
38
- //# sourceMappingURL=predicate-FdKmElA_.js.map
37
+ //# sourceMappingURL=predicate-BYHA4MBn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"predicate-FdKmElA_.js","names":[],"sources":["../src/experiment/ast/predicate.ts"],"sourcesContent":["import type { EvidenceRecord, JsonValue } from './evidence'\n\n// ── Predicate ────────────────────────────────────────────────────────\n\n/**\n * Closed-key comparison over a declared record schema. The only leaf node.\n * `field` is a dot-separated path into an evidence record.\n */\nexport type Predicate =\n | {\n kind: 'compare'\n field: string\n op: 'eq' | 'ne' | 'lt' | 'lte' | 'gt' | 'gte'\n value: JsonValue\n }\n | { kind: 'in'; field: string; values: JsonValue[] }\n | { kind: 'all'; of: Predicate[] }\n | { kind: 'any'; of: Predicate[] }\n | { kind: 'not'; of: Predicate }\n\n/** Read a dot-separated field path. Missing segments yield `undefined`. */\nexport function readField(record: EvidenceRecord, path: string): unknown {\n let current: unknown = record\n for (const key of path.split('.')) {\n if (current === null || typeof current !== 'object') return undefined\n current = (current as Record<string, unknown>)[key]\n }\n return current\n}\n\n/** Evaluate a predicate against one evidence record. */\nexport function evaluatePredicate(predicate: Predicate, record: EvidenceRecord): boolean {\n switch (predicate.kind) {\n case 'compare':\n return compareValues(readField(record, predicate.field), predicate.op, predicate.value)\n case 'in':\n return predicate.values.includes(readField(record, predicate.field) as JsonValue)\n case 'all':\n return predicate.of.every((p) => evaluatePredicate(p, record))\n case 'any':\n return predicate.of.some((p) => evaluatePredicate(p, record))\n case 'not':\n return !evaluatePredicate(predicate.of, record)\n }\n}\n\n/** Numbers compare numerically; everything else compares as strings. */\nexport function compareValues(\n value: unknown,\n op: 'eq' | 'ne' | 'lt' | 'lte' | 'gt' | 'gte',\n target: JsonValue,\n): boolean {\n if (op === 'eq') return value === target\n if (op === 'ne') return value !== target\n const numeric = typeof value === 'number' && typeof target === 'number'\n const left = numeric ? (value as number) : String(value)\n const right = numeric ? (target as number) : String(target)\n switch (op) {\n case 'lt':\n return left < right\n case 'lte':\n return left <= right\n case 'gt':\n return left > right\n case 'gte':\n return left >= right\n }\n}\n"],"mappings":";;AAqBA,SAAgB,UAAU,QAAwB,MAAuB;CACvE,IAAI,UAAmB;CACvB,KAAK,MAAM,OAAO,KAAK,MAAM,GAAG,GAAG;EACjC,IAAI,YAAY,QAAQ,OAAO,YAAY,UAAU,OAAO,KAAA;EAC5D,UAAW,QAAoC;CACjD;CACA,OAAO;AACT;;AAGA,SAAgB,kBAAkB,WAAsB,QAAiC;CACvF,QAAQ,UAAU,MAAlB;EACE,KAAK,WACH,OAAO,cAAc,UAAU,QAAQ,UAAU,KAAK,GAAG,UAAU,IAAI,UAAU,KAAK;EACxF,KAAK,MACH,OAAO,UAAU,OAAO,SAAS,UAAU,QAAQ,UAAU,KAAK,CAAc;EAClF,KAAK,OACH,OAAO,UAAU,GAAG,OAAO,MAAM,kBAAkB,GAAG,MAAM,CAAC;EAC/D,KAAK,OACH,OAAO,UAAU,GAAG,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC;EAC9D,KAAK,OACH,OAAO,CAAC,kBAAkB,UAAU,IAAI,MAAM;CAClD;AACF;;AAGA,SAAgB,cACd,OACA,IACA,QACS;CACT,IAAI,OAAO,MAAM,OAAO,UAAU;CAClC,IAAI,OAAO,MAAM,OAAO,UAAU;CAClC,MAAM,UAAU,OAAO,UAAU,YAAY,OAAO,WAAW;CAC/D,MAAM,OAAO,UAAW,QAAmB,OAAO,KAAK;CACvD,MAAM,QAAQ,UAAW,SAAoB,OAAO,MAAM;CAC1D,QAAQ,IAAR;EACE,KAAK,MACH,OAAO,OAAO;EAChB,KAAK,OACH,OAAO,QAAQ;EACjB,KAAK,MACH,OAAO,OAAO;EAChB,KAAK,OACH,OAAO,QAAQ;CACnB;AACF"}
1
+ {"version":3,"file":"predicate-BYHA4MBn.js","names":[],"sources":["../src/experiment/ast/predicate.ts"],"sourcesContent":["import type { EvidenceRecord, JsonValue } from './evidence'\n\n// ── Predicate ────────────────────────────────────────────────────────\n\n/**\n * Closed-key comparison over a declared record schema. The only leaf node.\n * `field` is a dot-separated path into an evidence record.\n */\nexport type Predicate =\n | {\n kind: 'compare'\n field: string\n op: 'eq' | 'ne' | 'lt' | 'lte' | 'gt' | 'gte'\n value: JsonValue\n }\n | { kind: 'in'; field: string; values: JsonValue[] }\n | { kind: 'all'; of: Predicate[] }\n | { kind: 'any'; of: Predicate[] }\n | { kind: 'not'; of: Predicate }\n\n/** Read a dot-separated field path. Missing segments yield `undefined`. */\nexport function readField(record: EvidenceRecord, path: string): unknown {\n let current: unknown = record\n for (const key of path.split('.')) {\n if (current === null || typeof current !== 'object') return undefined\n current = (current as Record<string, unknown>)[key]\n }\n return current\n}\n\n/** Evaluate a predicate against one evidence record. */\nexport function evaluatePredicate(predicate: Predicate, record: EvidenceRecord): boolean {\n switch (predicate.kind) {\n case 'compare':\n return compareValues(readField(record, predicate.field), predicate.op, predicate.value)\n case 'in':\n return predicate.values.includes(readField(record, predicate.field) as JsonValue)\n case 'all':\n return predicate.of.every((p) => evaluatePredicate(p, record))\n case 'any':\n return predicate.of.some((p) => evaluatePredicate(p, record))\n case 'not':\n return !evaluatePredicate(predicate.of, record)\n }\n}\n\n/** Numbers compare numerically; everything else compares as strings. */\nexport function compareValues(\n value: unknown,\n op: 'eq' | 'ne' | 'lt' | 'lte' | 'gt' | 'gte',\n target: JsonValue,\n): boolean {\n if (op === 'eq') return value === target\n if (op === 'ne') return value !== target\n const numeric = typeof value === 'number' && typeof target === 'number'\n const left = numeric ? (value as number) : String(value)\n const right = numeric ? (target as number) : String(target)\n switch (op) {\n case 'lt':\n return left < right\n case 'lte':\n return left <= right\n case 'gt':\n return left > right\n case 'gte':\n return left >= right\n }\n}\n"],"mappings":";;AAqBA,SAAgB,UAAU,QAAwB,MAAuB;CACvE,IAAI,UAAmB;CACvB,KAAK,MAAM,OAAO,KAAK,MAAM,GAAG,GAAG;EACjC,IAAI,YAAY,QAAQ,OAAO,YAAY,UAAU,OAAO,KAAA;EAC5D,UAAW,QAAoC;CACjD;CACA,OAAO;AACT;;AAGA,SAAgB,kBAAkB,WAAsB,QAAiC;CACvF,QAAQ,UAAU,MAAlB;EACE,KAAK,WACH,OAAO,cAAc,UAAU,QAAQ,UAAU,KAAK,GAAG,UAAU,IAAI,UAAU,KAAK;EACxF,KAAK,MACH,OAAO,UAAU,OAAO,SAAS,UAAU,QAAQ,UAAU,KAAK,CAAc;EAClF,KAAK,OACH,OAAO,UAAU,GAAG,OAAO,MAAM,kBAAkB,GAAG,MAAM,CAAC;EAC/D,KAAK,OACH,OAAO,UAAU,GAAG,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC;EAC9D,KAAK,OACH,OAAO,CAAC,kBAAkB,UAAU,IAAI,MAAM;CAClD;AACF;;AAGA,SAAgB,cACd,OACA,IACA,QACS;CACT,IAAI,OAAO,MAAM,OAAO,UAAU;CAClC,IAAI,OAAO,MAAM,OAAO,UAAU;CAClC,MAAM,UAAU,OAAO,UAAU,YAAY,OAAO,WAAW;CAC/D,MAAM,OAAO,UAAW,QAAmB,OAAO,KAAK;CACvD,MAAM,QAAQ,UAAW,SAAoB,OAAO,MAAM;CAC1D,QAAQ,IAAR;EACE,KAAK,MACH,OAAO,OAAO;EAChB,KAAK,OACH,OAAO,QAAQ;EACjB,KAAK,MACH,OAAO,OAAO;EAChB,KAAK,OACH,OAAO,QAAQ;CACnB;AACF"}
@@ -1,4 +1,3 @@
1
- //#region src/analyst/prime-bridge-transport.d.ts
2
1
  /**
3
2
  * The bridge seam for the prime analyst protocol: one POST to an
4
3
  * OpenAI-compatible `/v1/chat/completions` endpoint, returning the raw status
@@ -44,6 +43,5 @@ type PrimeBridgeTransport = (request: PrimeBridgeTransportRequest) => Promise<Pr
44
43
  * minutes, so the request's AbortSignal is the only deadline.
45
44
  */
46
45
  declare function nodeHttpPrimeBridgeTransport(): PrimeBridgeTransport;
47
- //#endregion
48
46
  export { nodeHttpPrimeBridgeTransport as i, PrimeBridgeTransportRequest as n, PrimeBridgeTransportResult as r, PrimeBridgeTransport as t };
49
- //# sourceMappingURL=prime-bridge-transport-6feEglLf.d.ts.map
47
+ //# sourceMappingURL=prime-bridge-transport-Cfqir_Im.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prime-bridge-transport-Cfqir_Im.d.ts","names":[],"sources":["../src/analyst/prime-bridge-transport.ts"],"mappings":";;;;;;;;;;;;;;;;;UAoBiB;EACf;EACA;IACE;IACA,UAAU;MAAQ;MAAc;;;;;;;;EAOlC,QAAQ;;UAGO;EACf;EACA;;;KAIU,wBACV,SAAS,gCACN,QAAQ;;;;;;iBAOG,gCAAgC"}
@@ -1,6 +1,6 @@
1
1
  import { request } from "node:http";
2
2
  import { request as request$1 } from "node:https";
3
- //#region src/analyst/prime-bridge-transport.ts
3
+ // src/analyst/prime-bridge-transport.ts
4
4
  /**
5
5
  * Default transport on node:http/node:https rather than fetch: undici's fixed
6
6
  * response-header timeout kills prime calls that legitimately run past five
@@ -37,7 +37,6 @@ function nodeHttpPrimeBridgeTransport() {
37
37
  });
38
38
  };
39
39
  }
40
- //#endregion
41
40
  export { nodeHttpPrimeBridgeTransport as t };
42
41
 
43
- //# sourceMappingURL=prime-bridge-transport-Z3cpKGoV.js.map
42
+ //# sourceMappingURL=prime-bridge-transport-Csd5SQg7.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prime-bridge-transport-Z3cpKGoV.js","names":["httpsRequest","httpRequest"],"sources":["../src/analyst/prime-bridge-transport.ts"],"sourcesContent":["import { request as httpRequest } from 'node:http'\nimport { request as httpsRequest } from 'node:https'\n\n/**\n * The bridge seam for the prime analyst protocol: one POST to an\n * OpenAI-compatible `/v1/chat/completions` endpoint, returning the raw status\n * and body text.\n *\n * Deliberately NOT `callLlm` from `../llm-client`, which serves a different\n * contract:\n * - it retries transient failures, and a prime turn holds a single model seat\n * for minutes — a silent second attempt doubles the seat time and the spend;\n * - it normalizes usage, while the protocol's receipt depends on the bridge's\n * non-standard `model_requests` and `estimated` fields;\n * - it composes sampling and response-format options the bridge's CLI backends\n * reject;\n * - it collapses HTTP status, unparseable body, and empty content into two\n * error classes, while the protocol classifies them as three distinct\n * terminal reasons.\n */\nexport interface PrimeBridgeTransportRequest {\n url: string\n body: {\n model: string\n messages: Array<{ role: 'user'; content: string }>\n }\n /**\n * The call's only deadline. The protocol aborts it on the per-call timeout\n * and on the caller's cancellation, so a transport that imposes a second\n * deadline of its own competes with this one.\n */\n signal: AbortSignal\n}\n\nexport interface PrimeBridgeTransportResult {\n status: number\n text: string\n}\n\n/** One POST to the bridge. Injectable so tests run against a fake bridge. */\nexport type PrimeBridgeTransport = (\n request: PrimeBridgeTransportRequest,\n) => Promise<PrimeBridgeTransportResult>\n\n/**\n * Default transport on node:http/node:https rather than fetch: undici's fixed\n * response-header timeout kills prime calls that legitimately run past five\n * minutes, so the request's AbortSignal is the only deadline.\n */\nexport function nodeHttpPrimeBridgeTransport(): PrimeBridgeTransport {\n return ({ url, body, signal }) => {\n const target = new URL(url)\n if (target.protocol !== 'http:' && target.protocol !== 'https:') {\n throw new TypeError(`bridge URL must be http: or https:, got ${target.protocol}`)\n }\n const send = target.protocol === 'https:' ? httpsRequest : httpRequest\n const encoded = JSON.stringify(body)\n return new Promise((resolvePromise, rejectPromise) => {\n const req = send(\n {\n hostname: target.hostname,\n port: target.port,\n // The query string is part of the caller's URL; dropping it would\n // send the request somewhere other than where the caller pointed.\n path: `${target.pathname}${target.search}`,\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(encoded),\n },\n signal,\n },\n (res) => {\n const chunks: Buffer[] = []\n res.on('data', (chunk: Buffer) => chunks.push(chunk))\n res.on('end', () =>\n resolvePromise({\n status: res.statusCode ?? 0,\n text: Buffer.concat(chunks).toString('utf8'),\n }),\n )\n res.on('error', rejectPromise)\n },\n )\n req.on('error', rejectPromise)\n req.end(encoded)\n })\n }\n}\n"],"mappings":";;;;;;;;AAiDA,SAAgB,+BAAqD;CACnE,QAAQ,EAAE,KAAK,MAAM,aAAa;EAChC,MAAM,SAAS,IAAI,IAAI,GAAG;EAC1B,IAAI,OAAO,aAAa,WAAW,OAAO,aAAa,UACrD,MAAM,IAAI,UAAU,2CAA2C,OAAO,UAAU;EAElF,MAAM,OAAO,OAAO,aAAa,WAAWA,YAAeC;EAC3D,MAAM,UAAU,KAAK,UAAU,IAAI;EACnC,OAAO,IAAI,SAAS,gBAAgB,kBAAkB;GACpD,MAAM,MAAM,KACV;IACE,UAAU,OAAO;IACjB,MAAM,OAAO;IAGb,MAAM,GAAG,OAAO,WAAW,OAAO;IAClC,QAAQ;IACR,SAAS;KACP,gBAAgB;KAChB,kBAAkB,OAAO,WAAW,OAAO;IAC7C;IACA;GACF,IACC,QAAQ;IACP,MAAM,SAAmB,CAAC;IAC1B,IAAI,GAAG,SAAS,UAAkB,OAAO,KAAK,KAAK,CAAC;IACpD,IAAI,GAAG,aACL,eAAe;KACb,QAAQ,IAAI,cAAc;KAC1B,MAAM,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,MAAM;IAC7C,CAAC,CACH;IACA,IAAI,GAAG,SAAS,aAAa;GAC/B,CACF;GACA,IAAI,GAAG,SAAS,aAAa;GAC7B,IAAI,IAAI,OAAO;EACjB,CAAC;CACH;AACF"}
1
+ {"version":3,"file":"prime-bridge-transport-Csd5SQg7.js","names":["httpsRequest","httpRequest"],"sources":["../src/analyst/prime-bridge-transport.ts"],"sourcesContent":["import { request as httpRequest } from 'node:http'\nimport { request as httpsRequest } from 'node:https'\n\n/**\n * The bridge seam for the prime analyst protocol: one POST to an\n * OpenAI-compatible `/v1/chat/completions` endpoint, returning the raw status\n * and body text.\n *\n * Deliberately NOT `callLlm` from `../llm-client`, which serves a different\n * contract:\n * - it retries transient failures, and a prime turn holds a single model seat\n * for minutes — a silent second attempt doubles the seat time and the spend;\n * - it normalizes usage, while the protocol's receipt depends on the bridge's\n * non-standard `model_requests` and `estimated` fields;\n * - it composes sampling and response-format options the bridge's CLI backends\n * reject;\n * - it collapses HTTP status, unparseable body, and empty content into two\n * error classes, while the protocol classifies them as three distinct\n * terminal reasons.\n */\nexport interface PrimeBridgeTransportRequest {\n url: string\n body: {\n model: string\n messages: Array<{ role: 'user'; content: string }>\n }\n /**\n * The call's only deadline. The protocol aborts it on the per-call timeout\n * and on the caller's cancellation, so a transport that imposes a second\n * deadline of its own competes with this one.\n */\n signal: AbortSignal\n}\n\nexport interface PrimeBridgeTransportResult {\n status: number\n text: string\n}\n\n/** One POST to the bridge. Injectable so tests run against a fake bridge. */\nexport type PrimeBridgeTransport = (\n request: PrimeBridgeTransportRequest,\n) => Promise<PrimeBridgeTransportResult>\n\n/**\n * Default transport on node:http/node:https rather than fetch: undici's fixed\n * response-header timeout kills prime calls that legitimately run past five\n * minutes, so the request's AbortSignal is the only deadline.\n */\nexport function nodeHttpPrimeBridgeTransport(): PrimeBridgeTransport {\n return ({ url, body, signal }) => {\n const target = new URL(url)\n if (target.protocol !== 'http:' && target.protocol !== 'https:') {\n throw new TypeError(`bridge URL must be http: or https:, got ${target.protocol}`)\n }\n const send = target.protocol === 'https:' ? httpsRequest : httpRequest\n const encoded = JSON.stringify(body)\n return new Promise((resolvePromise, rejectPromise) => {\n const req = send(\n {\n hostname: target.hostname,\n port: target.port,\n // The query string is part of the caller's URL; dropping it would\n // send the request somewhere other than where the caller pointed.\n path: `${target.pathname}${target.search}`,\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(encoded),\n },\n signal,\n },\n (res) => {\n const chunks: Buffer[] = []\n res.on('data', (chunk: Buffer) => chunks.push(chunk))\n res.on('end', () =>\n resolvePromise({\n status: res.statusCode ?? 0,\n text: Buffer.concat(chunks).toString('utf8'),\n }),\n )\n res.on('error', rejectPromise)\n },\n )\n req.on('error', rejectPromise)\n req.end(encoded)\n })\n }\n}\n"],"mappings":";;;;;;;;AAiDA,SAAgB,+BAAqD;CACnE,QAAQ,EAAE,KAAK,MAAM,aAAa;EAChC,MAAM,SAAS,IAAI,IAAI,GAAG;EAC1B,IAAI,OAAO,aAAa,WAAW,OAAO,aAAa,UACrD,MAAM,IAAI,UAAU,2CAA2C,OAAO,UAAU;EAElF,MAAM,OAAO,OAAO,aAAa,WAAWA,YAAeC;EAC3D,MAAM,UAAU,KAAK,UAAU,IAAI;EACnC,OAAO,IAAI,SAAS,gBAAgB,kBAAkB;GACpD,MAAM,MAAM,KACV;IACE,UAAU,OAAO;IACjB,MAAM,OAAO;IAGb,MAAM,GAAG,OAAO,WAAW,OAAO;IAClC,QAAQ;IACR,SAAS;KACP,gBAAgB;KAChB,kBAAkB,OAAO,WAAW,OAAO;IAC7C;IACA;GACF,IACC,QAAQ;IACP,MAAM,SAAmB,CAAC;IAC1B,IAAI,GAAG,SAAS,UAAkB,OAAO,KAAK,KAAK,CAAC;IACpD,IAAI,GAAG,aACL,eAAe;KACb,QAAQ,IAAI,cAAc;KAC1B,MAAM,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,MAAM;IAC7C,CAAC,CACH;IACA,IAAI,GAAG,SAAS,aAAa;GAC/B,CACF;GACA,IAAI,GAAG,SAAS,aAAa;GAC7B,IAAI,IAAI,OAAO;EACjB,CAAC;CACH;AACF"}
@@ -1,7 +1,6 @@
1
- import { m as CustomTokenPricing } from "./cost-ledger-C1W3ICmP.js";
2
- import { p as AnalystUsageReceipt } from "./types-6Lfdlshp.js";
3
- import { t as PrimeBridgeTransport } from "./prime-bridge-transport-6feEglLf.js";
4
- //#region src/analyst/reply-contract.d.ts
1
+ import { m as CustomTokenPricing } from "./cost-ledger-Czro9wmo.js";
2
+ import { p as AnalystUsageReceipt } from "./types-DzCO-S1m.js";
3
+ import { t as PrimeBridgeTransport } from "./prime-bridge-transport-Cfqir_Im.js";
5
4
  /**
6
5
  * The reply grammar an analyst arm holds a model to, independent of transport.
7
6
  *
@@ -80,8 +79,6 @@ interface DecodedReply<TRow> {
80
79
  /** Valid rows dropped by `maxRows`. */
81
80
  overflow: number;
82
81
  }
83
- //#endregion
84
- //#region src/analyst/prime-protocol.d.ts
85
82
  /**
86
83
  * The prime analyst protocol: a one-shot RLM reached through an
87
84
  * OpenAI-compatible bridge, given the whole trajectory inline because it has no
@@ -308,6 +305,5 @@ interface PrimeProtocolIdentity {
308
305
  * claim rather than a label.
309
306
  */
310
307
  declare function primeProtocolSha256(identity: PrimeProtocolIdentity): string;
311
- //#endregion
312
308
  export { runPrimeExchange as C, ReplyRowDecoded as D, ReplyEnvelope as E, ReplyRowRejection as O, projectPrimeTrajectory as S, ReplyContract as T, buildPrimePrompt as _, PrimeProjectionOutcome as a, normalizePrimeUsage as b, PrimeProtocolIdentity as c, PrimeRepairPromptSpec as d, PrimeRepairState as f, analystUsageReceiptFromPrimeUsage as g, PrimeTurnRecord as h, PrimeProjectionDelivery as i, PrimeRawUsage as l, PrimeRowDecoded as m, PrimeExchangeOutcome as n, PrimeProjectionSource as o, PrimeReplyContract as p, PrimeFailure as r, PrimePromptSpec as s, PrimeExchangeOptions as t, PrimeRejectedRow as u, buildPrimeRepairPrompt as v, DecodedReply as w, primeProtocolSha256 as x, mergePrimeRawUsage as y };
313
- //# sourceMappingURL=prime-protocol-BGxjfhM4.d.ts.map
309
+ //# sourceMappingURL=prime-protocol-COFkxas6.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prime-protocol-COFkxas6.d.ts","names":[],"sources":["../src/analyst/reply-contract.ts","../src/analyst/prime-protocol.ts"],"mappings":";;;;;;;;;;;;;KAaY,gBAAgB;EAAU;EAAU,KAAK;;EAAW;EAAW;;;UAG1D;EACf;;EAEA,QAAQ;;UAGO,cAAc;;EAE7B;;EAEA;;;;;EAKA;;;;;;EAMA,UAAU,cAAc,gBAAgB,gBAAgB;;;;;;EAMxD;;;;;;EAMA,eAAe,iBAAiB;;;;;;EAMhC;;;;;EAKA;;;UAIe;EACf;EACA;;UAGe,aAAa;EAC5B,MAAM;;EAEN,QAAQ;EACR,UAAU;;EAEV;;EAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;KC3CU,gBAAgB,QAAQ,gBAAgB;KAExC,mBAAmB,QAAQ,cAAc;UAIpC;EACf;;EAEA;EACA;;EAEA;EACA;;EAEA;;iBAGc,iBAAiB,MAAM;UAatB;EACf;EACA;EACA;;;iBAIc,uBAAuB,MAAM;;;;;;UAoE5B;;;;;;EAMf;;EAEA;;EAEA;;;;;;;EAOA;;;iBAQc,oBAAoB,eAAe;;;;;;iBAgBnC,mBAAmB,GAAG,eAAe,GAAG,gBAAgB;;;;;;;;;;;;;iBA6BxD,kCACd,OAAO,eACP,SAAS,qBACR;;;;;;;;KAqCS;EAEN;EACA;;EAEA;EAAqB;EAAiB;EAAgB;;EACtD;EAAiB;EAAiB;;UAEvB;EACf;;EAEA;;;UAIe;EACf;EACA,OAAO;;EAEP;;UAGe;EACf;EACA;;KAGU,qBAAqB;EAE3B;;EAEA;EACA,MAAM;EACN,UAAU;;EAEV;;EAEA;EACA,OAAO;EACP,OAAO;EACP,QAAQ;EACR;;EAGA;EACA,SAAS;EACT,OAAO;EACP,OAAO;EACP,QAAQ;;EAER;;UAGW,qBAAqB;EACpC,UAAU,mBAAmB;EAC7B;EACA,WAAW;;EAEX;EACA;;EAEA;;EAEA;EACA,SAAS;;;;;;;iBAQW,iBAAiB,MACrC,SAAS,qBAAqB,QAC7B,QAAQ,qBAAqB;;;;;;UAyLf,sBAAsB;;EAErC,QAAQ,iBAAiB;;EAEzB,UAAU,iBAAiB;;EAE3B;;UAGe;EACf;EACA;EACA;;KAGU,uBAAuB;EAE7B;EACA,gBAAgB;EAChB;EACA,UAAU;;EAEV;EAAW;EAAgB;;;;;;;;;iBASX,uBAAuB,OAC3C,QAAQ,sBAAsB,QAC9B;EAAU;IACT,QAAQ,uBAAuB;UA8BjB;EACf;EACA;EACA;EACA;;EAEA,QAAQ,SAAS;;;;;;;;;;;;iBAaH,oBAAoB,UAAU"}
@@ -1,6 +1,6 @@
1
- import { s as ValidationError } from "./errors-BcOs5MKW.js";
1
+ import { s as ValidationError } from "./errors-DeEEV9Vx.js";
2
2
  import { createHash } from "node:crypto";
3
- //#region src/analyst/reply-contract.ts
3
+ // src/analyst/reply-contract.ts
4
4
  /**
5
5
  * The reply grammar an analyst arm holds a model to, independent of transport.
6
6
  *
@@ -67,8 +67,7 @@ function decodeReplyRows(contract, value) {
67
67
  overflow
68
68
  };
69
69
  }
70
- //#endregion
71
- //#region src/analyst/prime-protocol.ts
70
+ // src/analyst/prime-protocol.ts
72
71
  function buildPrimePrompt(spec) {
73
72
  return [
74
73
  `QUESTION: ${spec.question}`,
@@ -477,7 +476,6 @@ function primeProtocolSha256(identity) {
477
476
  limits: identity.limits
478
477
  })).digest("hex");
479
478
  }
480
- //#endregion
481
479
  export { normalizePrimeUsage as a, runPrimeExchange as c, mergePrimeRawUsage as i, decodeReplyRows as l, buildPrimePrompt as n, primeProtocolSha256 as o, buildPrimeRepairPrompt as r, projectPrimeTrajectory as s, analystUsageReceiptFromPrimeUsage as t };
482
480
 
483
- //# sourceMappingURL=prime-protocol-BFgGrEMP.js.map
481
+ //# sourceMappingURL=prime-protocol-CrhpXRz9.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prime-protocol-BFgGrEMP.js","names":[],"sources":["../src/analyst/reply-contract.ts","../src/analyst/prime-protocol.ts"],"sourcesContent":["/**\n * The reply grammar an analyst arm holds a model to, independent of transport.\n *\n * One contract serves every arm shape: the inline bridge protocol\n * (`runPrimeExchange`) reads the base fields, and one-shot JSON arms\n * additionally use the strict-envelope and all-rejected knobs. `PrimeReplyContract`\n * in ./prime-protocol is a type alias of this contract, so a consumer written\n * against the prime protocol names the same grammar object.\n */\n\nimport { ValidationError } from '../errors'\n\n/** Verdict of decoding one raw reply row. */\nexport type ReplyRowDecoded<TRow> = { ok: true; row: TRow } | { ok: false; reason: string }\n\n/** A strictly parsed reply envelope: the row array plus retained extras. */\nexport interface ReplyEnvelope {\n rows: readonly unknown[]\n /** Envelope fields beside the rows the arm retains (e.g. a `report` string). */\n extras: Record<string, unknown>\n}\n\nexport interface ReplyContract<TRow> {\n /** Name of the reply's row array, e.g. `blocks` or `findings`. */\n rowsField: string\n /** Row-grammar lines spliced into the first-turn prompt. */\n contractLines: readonly string[]\n /**\n * The same grammar restated for the repair turn, which never carries the\n * evidence. Empty when the arm declares zero repair turns.\n */\n repairContractLines: readonly string[]\n /**\n * Validate and convert one raw row in a single pass. One function rather than\n * a separate validator and constructor, so the two can never disagree about\n * what a valid row is.\n */\n decodeRow(row: unknown, index: number): ReplyRowDecoded<TRow>\n /**\n * Cap on ACCEPTED rows. The cap is applied after decoding, so malformed rows\n * never consume an accepted slot; the surplus is reported as `overflow`.\n * Omit when the consumer's own expansion owns the cap and records the drop.\n */\n maxRows?: number\n /**\n * Strict envelope parse for one-shot JSON arms. Throws on an envelope defect\n * (missing report, unknown key, over-cap row count). When absent, rows are\n * read from `rowsField` on the parsed reply object.\n */\n parseEnvelope?(value: unknown): ReplyEnvelope\n /**\n * What a reply whose EVERY reported row was rejected means. `fail` throws a\n * validation error carrying each rejection; `accept-empty` (the default)\n * keeps the honest empty result beside the recorded rejections.\n */\n whenAllRowsRejected?: 'fail' | 'accept-empty'\n /**\n * Message prefix for the `fail` case, in the contract's own row vocabulary\n * (e.g. \"every reported failure block was malformed\").\n */\n allRejectedMessage?: string\n}\n\n/** One rejected row, indexed as the model reported it. */\nexport interface ReplyRowRejection {\n index: number\n reason: string\n}\n\nexport interface DecodedReply<TRow> {\n rows: TRow[]\n /** Envelope fields beside the rows (empty when the contract has no envelope). */\n extras: Record<string, unknown>\n rejected: ReplyRowRejection[]\n /** Rows the model reported, before decoding or the count cap. */\n reportedRows: number\n /** Valid rows dropped by `maxRows`. */\n overflow: number\n}\n\n/**\n * The per-row half of a decode: validate each raw row under the contract's\n * grammar and cap ACCEPTED rows. Shape before count — a malformed row never\n * consumes an accepted slot. Shared by every consumer of a `ReplyContract`\n * row array, whatever envelope handling surrounds it.\n */\nexport function decodeContractRows<TRow>(\n contract: Pick<ReplyContract<TRow>, 'decodeRow' | 'maxRows'>,\n rawRows: readonly unknown[],\n): { rows: TRow[]; rejected: ReplyRowRejection[]; overflow: number } {\n const rows: TRow[] = []\n const rejected: ReplyRowRejection[] = []\n let overflow = 0\n rawRows.forEach((row, index) => {\n const decoded = contract.decodeRow(row, index)\n if (!decoded.ok) {\n rejected.push({ index, reason: decoded.reason })\n return\n }\n if (contract.maxRows !== undefined && rows.length >= contract.maxRows) {\n overflow += 1\n return\n }\n rows.push(decoded.row)\n })\n return { rows, rejected, overflow }\n}\n\n/**\n * Decode a parsed reply value under a contract: strict envelope when declared,\n * then per-row decoding, then the all-rejected policy.\n */\nexport function decodeReplyRows<TRow>(\n contract: ReplyContract<TRow>,\n value: unknown,\n): DecodedReply<TRow> {\n let rawRows: readonly unknown[]\n let extras: Record<string, unknown> = {}\n if (contract.parseEnvelope) {\n const envelope = contract.parseEnvelope(value)\n rawRows = envelope.rows\n extras = envelope.extras\n } else {\n const record =\n typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined\n const field = record?.[contract.rowsField]\n if (!Array.isArray(field)) {\n throw new ValidationError(`reply has no \"${contract.rowsField}\" array`)\n }\n rawRows = field\n }\n const { rows, rejected, overflow } = decodeContractRows(contract, rawRows)\n if (rows.length === 0 && rawRows.length > 0 && contract.whenAllRowsRejected === 'fail') {\n throw new ValidationError(\n `${contract.allRejectedMessage ?? 'every reported row was malformed'}: ${rejected\n .map((entry) => entry.reason)\n .join(' | ')}`,\n )\n }\n return { rows, extras, rejected, reportedRows: rawRows.length, overflow }\n}\n","import { createHash } from 'node:crypto'\nimport type { CustomTokenPricing } from '../cost-ledger'\nimport type { PrimeBridgeTransport, PrimeBridgeTransportResult } from './prime-bridge-transport'\nimport { decodeContractRows, type ReplyContract, type ReplyRowDecoded } from './reply-contract'\nimport type { AnalystUsageReceipt } from './types'\n\n/**\n * The prime analyst protocol: a one-shot RLM reached through an\n * OpenAI-compatible bridge, given the whole trajectory inline because it has no\n * REPL and no trace tools, answering in one fenced JSON block of short strings.\n *\n * This module owns every part of that protocol that does not depend on what the\n * rows MEAN: prompt and contract composition, the bounded repair turn, reply\n * extraction, row decoding order, the render-measure-fall-back-fail-loud\n * projection ladder, usage normalization, and the protocol identity digest.\n *\n * The cut: the core speaks RAW ROWS and never names a finding type. It knows a\n * prime reply carries an `answer` string plus an array of rows under a named\n * field, and that each row is decoded by a caller-supplied function. Consumers\n * — the CodeTraceBench benchmark runner here, a span-grounded trace analyzer\n * elsewhere — map decoded rows into their own finding shape on the way out. So\n * nothing in this file may import a block type, a finding type, or a trace\n * store, and no consumer needs another copy of the protocol.\n */\n\n// ── Reply contract ───────────────────────────────────────────────────\n\n/**\n * The prime reply grammar is the general analyst reply contract: these aliases\n * keep every prime-protocol consumer compiling against the shared type in\n * ./reply-contract. The exchange below reads the base fields (`rowsField`,\n * contract lines, `decodeRow`, `maxRows`); the strict-envelope knobs serve\n * one-shot JSON arms and are inert here.\n */\nexport type PrimeRowDecoded<TRow> = ReplyRowDecoded<TRow>\n\nexport type PrimeReplyContract<TRow> = ReplyContract<TRow>\n\n// ── Prompt composition ───────────────────────────────────────────────\n\nexport interface PrimePromptSpec {\n question: string\n /** Task definition spliced under a `TASK DEFINITION:` heading. Omit when the question is the whole task. */\n taskDefinition?: string\n contractLines: readonly string[]\n /** Line introducing the trajectory, e.g. `TRAJECTORY (trace_id X; 12 assistant step spans; ...):`. */\n trajectoryHeader: string\n renderedTrajectory: string\n /** Material appended after the trajectory, e.g. the final-verification spans. */\n trailer?: string\n}\n\nexport function buildPrimePrompt(spec: PrimePromptSpec): string {\n return [\n `QUESTION: ${spec.question}`,\n '',\n ...(spec.taskDefinition === undefined ? [] : ['TASK DEFINITION:', spec.taskDefinition, '']),\n ...spec.contractLines,\n '',\n spec.trajectoryHeader,\n spec.renderedTrajectory,\n ...(spec.trailer === undefined ? [] : ['', spec.trailer]),\n ].join('\\n')\n}\n\nexport interface PrimeRepairPromptSpec {\n defect: string\n previousReply: string\n repairContractLines: readonly string[]\n}\n\n/** Carries the malformed reply and the contract — never the trajectory. */\nexport function buildPrimeRepairPrompt(spec: PrimeRepairPromptSpec): string {\n return [\n 'Your previous reply to a trace-analysis task was structurally malformed and could not be parsed',\n `(${spec.defect}). Below is your previous reply verbatim. Re-emit ONLY the corrected JSON — one`,\n 'fenced ```json block, no other text, no tools. The JSON object has exactly two fields:',\n ...spec.repairContractLines,\n '',\n 'PREVIOUS REPLY:',\n spec.previousReply,\n ].join('\\n')\n}\n\n// ── Reply extraction ─────────────────────────────────────────────────\n\n/**\n * Recover the reply's JSON object.\n *\n * Distinct from `extractJsonPayload` in ../llm-client, which serves a response\n * that DECLARES a JSON root and therefore must not scan onward. A prime reply\n * is prose plus a fenced block, and when the model emits several fences the\n * last one is its answer — so fences are scanned in reverse, and only then is a\n * brace-to-brace slice tried.\n */\nfunction extractPrimeJsonObject(text: string): Record<string, unknown> | null {\n const direct = parsePrimeJsonObject(text)\n if (direct) return direct\n const fenced = [...text.matchAll(/```(?:json)?\\s*\\n?([\\s\\S]*?)```/g)]\n for (let index = fenced.length - 1; index >= 0; index -= 1) {\n const candidate = parsePrimeJsonObject(fenced[index]![1]!)\n if (candidate) return candidate\n }\n const start = text.indexOf('{')\n const end = text.lastIndexOf('}')\n if (start >= 0 && end > start) {\n const candidate = parsePrimeJsonObject(text.slice(start, end + 1))\n if (candidate) return candidate\n }\n return null\n}\n\n/** Why the reply cannot be read as a prime answer, or null when it can. */\nfunction primeReplyDefect(\n parsed: Record<string, unknown> | null,\n rowsField: string,\n): string | null {\n if (parsed === null) return 'no parseable JSON object'\n if (!Array.isArray(parsed[rowsField])) return `JSON has no \"${rowsField}\" array`\n return null\n}\n\nfunction parsePrimeJsonObject(text: string): Record<string, unknown> | null {\n try {\n const value: unknown = JSON.parse(text.trim())\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null\n } catch {\n return null\n }\n}\n\n// ── Usage ────────────────────────────────────────────────────────────\n\n/**\n * Token accounting exactly as the bridge reported it. Lossless on purpose: a\n * side the bridge did not report stays null rather than becoming a zero, and a\n * side it DID report survives even when its partner is missing.\n */\nexport interface PrimeRawUsage {\n /**\n * Model-usage records the bridge observed. NOT a count of bridge round trips:\n * one prime turn routes several internal model calls, so a single turn\n * typically reports 3-5.\n */\n calls: number | null\n /** Prompt tokens the bridge reported; null when it reported none. */\n inputTokens: number | null\n /** Completion tokens the bridge reported; null when it reported none. */\n outputTokens: number | null\n /**\n * True when the bridge DERIVED the counts (from character lengths) because\n * the backend reported no usage of its own. Pricing derived counts produces a\n * guess about a guess, which a reader must be able to tell apart from a\n * rate-estimated cost over exact tokens.\n */\n bridgeEstimated: boolean\n}\n\nfunction emptyPrimeRawUsage(): PrimeRawUsage {\n return { calls: null, inputTokens: null, outputTokens: null, bridgeEstimated: false }\n}\n\n/** Read the bridge's OpenAI-shaped `usage` object. */\nexport function normalizePrimeUsage(raw: unknown): PrimeRawUsage {\n if (typeof raw !== 'object' || raw === null) return emptyPrimeRawUsage()\n const record = raw as Record<string, unknown>\n return {\n calls: tokenCountOrNull(record.model_requests),\n inputTokens: tokenCountOrNull(record.prompt_tokens),\n outputTokens: tokenCountOrNull(record.completion_tokens),\n bridgeEstimated: record.estimated === true,\n }\n}\n\n/**\n * Sum two turns. Each side poisons independently: two turns that both report\n * input and neither report output yield a real input total beside a null\n * output, because discarding a measured count is as wrong as inventing one.\n */\nexport function mergePrimeRawUsage(a: PrimeRawUsage, b: PrimeRawUsage): PrimeRawUsage {\n return {\n calls: sumOrNull(a.calls, b.calls),\n inputTokens: sumOrNull(a.inputTokens, b.inputTokens),\n outputTokens: sumOrNull(a.outputTokens, b.outputTokens),\n bridgeEstimated: a.bridgeEstimated || b.bridgeEstimated,\n }\n}\n\nfunction sumOrNull(a: number | null, b: number | null): number | null {\n return a !== null && b !== null ? a + b : null\n}\n\nfunction tokenCountOrNull(value: unknown): number | null {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : null\n}\n\n/**\n * Bind raw prime usage to agent-eval's typed receipt.\n *\n * `RunTokenUsage.input` and `.output` are non-nullable, so a one-sided count\n * cannot round-trip through `tokens` without writing a zero nobody measured.\n * The complete-accounting field therefore stays null, the reported side is\n * carried verbatim in `partialTokens`, and its price becomes the receipt's\n * `knownCostUsd` lower bound.\n *\n * Only agent-eval calls this; consumers with no pricing table read\n * `PrimeRawUsage` directly.\n */\nexport function analystUsageReceiptFromPrimeUsage(\n usage: PrimeRawUsage,\n pricing: CustomTokenPricing,\n): AnalystUsageReceipt {\n const { calls, inputTokens, outputTokens, bridgeEstimated } = usage\n const estimatedTokens = bridgeEstimated ? { tokensEstimated: true } : {}\n if (inputTokens !== null && outputTokens !== null) {\n return {\n calls,\n tokens: { input: inputTokens, output: outputTokens },\n cost: { kind: 'estimated', usd: priceTokens(inputTokens, outputTokens, pricing) },\n ...estimatedTokens,\n }\n }\n if (inputTokens === null && outputTokens === null) {\n return { calls, tokens: null, cost: { kind: 'uncaptured', usd: null }, ...estimatedTokens }\n }\n return {\n calls,\n tokens: null,\n partialTokens: { input: inputTokens, output: outputTokens },\n cost: { kind: 'uncaptured', usd: null },\n knownCostUsd: priceTokens(inputTokens ?? 0, outputTokens ?? 0, pricing),\n ...estimatedTokens,\n }\n}\n\nfunction priceTokens(input: number, output: number, pricing: CustomTokenPricing): number {\n return (input * pricing.inputUsdPerMillion + output * pricing.outputUsdPerMillion) / 1_000_000\n}\n\n// ── Two-turn exchange ────────────────────────────────────────────────\n\n/**\n * Why an exchange ended without a readable reply. `deadline` and `aborted` are\n * separate members from `transport` on purpose: a model that ran past its\n * deadline, a caller who cancelled, and a bridge that refused the connection\n * demand three different responses, and a record that conflates them cannot be\n * acted on.\n */\nexport type PrimeFailure =\n | {\n kind: 'transport' | 'unparseable-json' | 'no-content' | 'deadline' | 'malformed-reply'\n message: string\n }\n | { kind: 'http-status'; message: string; status: number; bodySnippet: string }\n | { kind: 'aborted'; message: string; cause: unknown }\n\nexport interface PrimeRepairState {\n attempted: boolean\n /** Null when no repair turn ran, or when the repair turn never returned a reply. */\n succeeded: boolean | null\n}\n\n/** One completed bridge turn. A turn that failed produces no record. */\nexport interface PrimeTurnRecord {\n turn: 'first' | 'repair'\n usage: PrimeRawUsage\n /** The reply's `usage` object verbatim; null when the bridge sent none. */\n rawUsage: unknown\n}\n\nexport interface PrimeRejectedRow {\n index: number\n reason: string\n}\n\nexport type PrimeExchangeOutcome<TRow> =\n | {\n ok: true\n /** The reply's `answer` field; null when absent or not a string. */\n answer: string | null\n rows: TRow[]\n rejected: PrimeRejectedRow[]\n /** Rows the model reported, before decoding or the count cap. */\n reportedRows: number\n /** Valid rows dropped by `contract.maxRows`. */\n overflow: number\n usage: PrimeRawUsage\n turns: PrimeTurnRecord[]\n repair: PrimeRepairState\n reply: string\n }\n | {\n ok: false\n failure: PrimeFailure\n usage: PrimeRawUsage\n turns: PrimeTurnRecord[]\n repair: PrimeRepairState\n /** The last reply received, when one arrived — the diagnostic artifact for a malformed case. */\n reply?: string\n }\n\nexport interface PrimeExchangeOptions<TRow> {\n contract: PrimeReplyContract<TRow>\n prompt: string\n transport: PrimeBridgeTransport\n /** Full endpoint, e.g. `http://localhost:4181/v1/chat/completions`. */\n url: string\n model: string\n /** Deadline for ONE turn. Prime analyses routinely exceed five minutes. */\n timeoutMs: number\n /** Whether a structurally malformed reply gets one bounded repair turn. */\n repair: boolean\n signal?: AbortSignal\n}\n\n/**\n * Run the protocol: one call, one bounded repair turn on a structurally\n * malformed reply, then decode. Zero valid rows from a well-formed reply is an\n * honest null, not a failure.\n */\nexport async function runPrimeExchange<TRow>(\n options: PrimeExchangeOptions<TRow>,\n): Promise<PrimeExchangeOutcome<TRow>> {\n const { contract } = options\n const turns: PrimeTurnRecord[] = []\n const repair: PrimeRepairState = { attempted: false, succeeded: null }\n\n const first = await callPrimeTurn(options, options.prompt)\n if (!first.ok) {\n return { ok: false, failure: first.failure, usage: mergeTurns(turns), turns, repair }\n }\n turns.push({ turn: 'first', usage: first.usage, rawUsage: first.rawUsage })\n\n let reply = first.content\n let parsed = extractPrimeJsonObject(reply)\n let defect = primeReplyDefect(parsed, contract.rowsField)\n\n if (defect !== null && options.repair) {\n repair.attempted = true\n const second = await callPrimeTurn(\n options,\n buildPrimeRepairPrompt({\n defect,\n previousReply: reply,\n repairContractLines: contract.repairContractLines,\n }),\n )\n if (!second.ok) {\n return { ok: false, failure: second.failure, usage: mergeTurns(turns), turns, repair, reply }\n }\n turns.push({ turn: 'repair', usage: second.usage, rawUsage: second.rawUsage })\n reply = second.content\n parsed = extractPrimeJsonObject(reply)\n defect = primeReplyDefect(parsed, contract.rowsField)\n repair.succeeded = defect === null\n }\n\n const usage = mergeTurns(turns)\n if (defect !== null) {\n return {\n ok: false,\n failure: {\n kind: 'malformed-reply',\n message: `${defect} in prime reply${repair.attempted ? ' even after the bounded repair turn' : ''}`,\n },\n usage,\n turns,\n repair,\n reply,\n }\n }\n\n const rawRows = parsed![contract.rowsField] as unknown[]\n const { rows, rejected, overflow } = decodeContractRows(contract, rawRows)\n const answer = parsed!.answer\n return {\n ok: true,\n answer: typeof answer === 'string' ? answer : null,\n rows,\n rejected,\n reportedRows: rawRows.length,\n overflow,\n usage,\n turns,\n repair,\n reply,\n }\n}\n\ntype PrimeTurnOutcome =\n | { ok: true; content: string; usage: PrimeRawUsage; rawUsage: unknown }\n | { ok: false; failure: PrimeFailure }\n\nasync function callPrimeTurn<TRow>(\n options: PrimeExchangeOptions<TRow>,\n content: string,\n): Promise<PrimeTurnOutcome> {\n const { transport, url, model, timeoutMs, signal } = options\n const controller = new AbortController()\n const forwardAbort = () => controller.abort(signal?.reason)\n if (signal?.aborted) controller.abort(signal.reason)\n else signal?.addEventListener('abort', forwardAbort, { once: true })\n const deadline = setTimeout(() => controller.abort(), timeoutMs)\n let result: PrimeBridgeTransportResult\n try {\n result = await transport({\n url,\n body: { model, messages: [{ role: 'user', content }] },\n signal: controller.signal,\n })\n } catch (error) {\n if (signal?.aborted) {\n return {\n ok: false,\n failure: {\n kind: 'aborted',\n message: 'prime exchange cancelled by the caller',\n cause: error,\n },\n }\n }\n if (controller.signal.aborted) {\n return {\n ok: false,\n failure: { kind: 'deadline', message: `bridge call exceeded ${timeoutMs}ms` },\n }\n }\n return {\n ok: false,\n failure: {\n kind: 'transport',\n message: `bridge transport failure: ${error instanceof Error ? error.message : String(error)}`,\n },\n }\n } finally {\n clearTimeout(deadline)\n signal?.removeEventListener('abort', forwardAbort)\n }\n\n if (result.status !== 200) {\n const bodySnippet = result.text.slice(0, 500)\n return {\n ok: false,\n failure: {\n kind: 'http-status',\n message: `bridge HTTP ${result.status}: ${bodySnippet}`,\n status: result.status,\n bodySnippet,\n },\n }\n }\n let response: unknown\n try {\n response = JSON.parse(result.text)\n } catch {\n return {\n ok: false,\n failure: {\n kind: 'unparseable-json',\n message: `bridge returned unparseable JSON (${result.text.length} bytes)`,\n },\n }\n }\n const replyContent = primeReplyContent(response)\n if (replyContent === null) {\n return {\n ok: false,\n failure: { kind: 'no-content', message: 'bridge reply carries no message content' },\n }\n }\n const rawUsage = primeReplyUsage(response)\n return { ok: true, content: replyContent, usage: normalizePrimeUsage(rawUsage), rawUsage }\n}\n\n/**\n * Fold from the FIRST turn, never from an empty receipt: an all-null identity\n * would poison every side it merged with and erase counts the bridge reported.\n */\nfunction mergeTurns(turns: readonly PrimeTurnRecord[]): PrimeRawUsage {\n if (turns.length === 0) return emptyPrimeRawUsage()\n return turns\n .slice(1)\n .reduce<PrimeRawUsage>((total, turn) => mergePrimeRawUsage(total, turn.usage), turns[0]!.usage)\n}\n\nfunction primeReplyContent(response: unknown): string | null {\n if (typeof response !== 'object' || response === null) return null\n const choices = (response as { choices?: unknown }).choices\n if (!Array.isArray(choices) || choices.length === 0) return null\n const message = (choices[0] as { message?: unknown })?.message\n if (typeof message !== 'object' || message === null) return null\n const content = (message as { content?: unknown }).content\n return typeof content === 'string' && content.length > 0 ? content : null\n}\n\nfunction primeReplyUsage(response: unknown): unknown {\n if (typeof response !== 'object' || response === null) return null\n return (response as { usage?: unknown }).usage ?? null\n}\n\n// ── Trajectory projection ────────────────────────────────────────────\n\n/**\n * Where the inlined trajectory comes from. The protocol needs only two moves —\n * fetch it all, or fetch a reduced version — so no store, artifact path, or\n * span type enters the shared signature.\n */\nexport interface PrimeProjectionSource<TItem> {\n /** The full projection, or null when the source declares itself oversized. */\n full(): Promise<readonly TItem[] | null>\n /** A reduced projection of the same material. */\n capped(): Promise<readonly TItem[]>\n /** How `capped` reduces, named for the failure message, e.g. `per-attribute cap 1200`. */\n cappedDescription: string\n}\n\nexport interface PrimeProjectionDelivery {\n mode: 'inline-json'\n fetch: 'full' | 'capped'\n renderedChars: number\n}\n\nexport type PrimeProjectionOutcome<TItem> =\n | {\n ok: true\n items: readonly TItem[]\n rendered: string\n delivery: PrimeProjectionDelivery\n }\n | { ok: false; reason: string; renderedChars: number }\n\n/**\n * Render, measure, fall back to the capped projection, re-measure, fail loud.\n *\n * Inline is the only delivery prime has, so an oversized trajectory is a\n * refusal rather than a silent truncation: dropping spans would understate the\n * trajectory and the analyst would answer a question about a different run.\n */\nexport async function projectPrimeTrajectory<TItem>(\n source: PrimeProjectionSource<TItem>,\n limits: { maxInlineChars: number },\n): Promise<PrimeProjectionOutcome<TItem>> {\n let fetch: PrimeProjectionDelivery['fetch'] = 'full'\n let items = await source.full()\n if (items === null) {\n fetch = 'capped'\n items = await source.capped()\n }\n let rendered = JSON.stringify(items)\n if (rendered.length > limits.maxInlineChars && fetch === 'full') {\n fetch = 'capped'\n items = await source.capped()\n rendered = JSON.stringify(items)\n }\n if (rendered.length > limits.maxInlineChars) {\n return {\n ok: false,\n reason: `trajectory renders to ${rendered.length} chars even at ${source.cappedDescription}; inline delivery impossible`,\n renderedChars: rendered.length,\n }\n }\n return {\n ok: true,\n items,\n rendered,\n delivery: { mode: 'inline-json', fetch, renderedChars: rendered.length },\n }\n}\n\n// ── Protocol identity ────────────────────────────────────────────────\n\nexport interface PrimeProtocolIdentity {\n question: string\n taskDefinition?: string\n contractLines: readonly string[]\n repairContractLines: readonly string[]\n /** Numeric limits the contract states, e.g. row and width caps. */\n limits: Readonly<Record<string, number>>\n}\n\n/**\n * Digest of everything a consumer can send to the bridge under the prime\n * protocol, recorded per observation so a prime result names the exact contract\n * that produced it.\n *\n * Computed over the ACTUALLY composed contract, so two consumers that both\n * stamp `analyst_id: 'prime'` while asking materially different questions get\n * different digests by construction. That is what makes 'prime' a reproducible\n * claim rather than a label.\n */\nexport function primeProtocolSha256(identity: PrimeProtocolIdentity): string {\n return createHash('sha256')\n .update(\n JSON.stringify({\n kind: 'prime-analyst-protocol',\n question: identity.question,\n taskPrompt: identity.taskDefinition ?? null,\n outputContract: identity.contractLines,\n repairContract: buildPrimeRepairPrompt({\n defect: '<defect>',\n previousReply: '<previous-reply>',\n repairContractLines: identity.repairContractLines,\n }),\n limits: identity.limits,\n }),\n )\n .digest('hex')\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"prime-protocol-CrhpXRz9.js","names":[],"sources":["../src/analyst/reply-contract.ts","../src/analyst/prime-protocol.ts"],"sourcesContent":["/**\n * The reply grammar an analyst arm holds a model to, independent of transport.\n *\n * One contract serves every arm shape: the inline bridge protocol\n * (`runPrimeExchange`) reads the base fields, and one-shot JSON arms\n * additionally use the strict-envelope and all-rejected knobs. `PrimeReplyContract`\n * in ./prime-protocol is a type alias of this contract, so a consumer written\n * against the prime protocol names the same grammar object.\n */\n\nimport { ValidationError } from '../errors'\n\n/** Verdict of decoding one raw reply row. */\nexport type ReplyRowDecoded<TRow> = { ok: true; row: TRow } | { ok: false; reason: string }\n\n/** A strictly parsed reply envelope: the row array plus retained extras. */\nexport interface ReplyEnvelope {\n rows: readonly unknown[]\n /** Envelope fields beside the rows the arm retains (e.g. a `report` string). */\n extras: Record<string, unknown>\n}\n\nexport interface ReplyContract<TRow> {\n /** Name of the reply's row array, e.g. `blocks` or `findings`. */\n rowsField: string\n /** Row-grammar lines spliced into the first-turn prompt. */\n contractLines: readonly string[]\n /**\n * The same grammar restated for the repair turn, which never carries the\n * evidence. Empty when the arm declares zero repair turns.\n */\n repairContractLines: readonly string[]\n /**\n * Validate and convert one raw row in a single pass. One function rather than\n * a separate validator and constructor, so the two can never disagree about\n * what a valid row is.\n */\n decodeRow(row: unknown, index: number): ReplyRowDecoded<TRow>\n /**\n * Cap on ACCEPTED rows. The cap is applied after decoding, so malformed rows\n * never consume an accepted slot; the surplus is reported as `overflow`.\n * Omit when the consumer's own expansion owns the cap and records the drop.\n */\n maxRows?: number\n /**\n * Strict envelope parse for one-shot JSON arms. Throws on an envelope defect\n * (missing report, unknown key, over-cap row count). When absent, rows are\n * read from `rowsField` on the parsed reply object.\n */\n parseEnvelope?(value: unknown): ReplyEnvelope\n /**\n * What a reply whose EVERY reported row was rejected means. `fail` throws a\n * validation error carrying each rejection; `accept-empty` (the default)\n * keeps the honest empty result beside the recorded rejections.\n */\n whenAllRowsRejected?: 'fail' | 'accept-empty'\n /**\n * Message prefix for the `fail` case, in the contract's own row vocabulary\n * (e.g. \"every reported failure block was malformed\").\n */\n allRejectedMessage?: string\n}\n\n/** One rejected row, indexed as the model reported it. */\nexport interface ReplyRowRejection {\n index: number\n reason: string\n}\n\nexport interface DecodedReply<TRow> {\n rows: TRow[]\n /** Envelope fields beside the rows (empty when the contract has no envelope). */\n extras: Record<string, unknown>\n rejected: ReplyRowRejection[]\n /** Rows the model reported, before decoding or the count cap. */\n reportedRows: number\n /** Valid rows dropped by `maxRows`. */\n overflow: number\n}\n\n/**\n * The per-row half of a decode: validate each raw row under the contract's\n * grammar and cap ACCEPTED rows. Shape before count — a malformed row never\n * consumes an accepted slot. Shared by every consumer of a `ReplyContract`\n * row array, whatever envelope handling surrounds it.\n */\nexport function decodeContractRows<TRow>(\n contract: Pick<ReplyContract<TRow>, 'decodeRow' | 'maxRows'>,\n rawRows: readonly unknown[],\n): { rows: TRow[]; rejected: ReplyRowRejection[]; overflow: number } {\n const rows: TRow[] = []\n const rejected: ReplyRowRejection[] = []\n let overflow = 0\n rawRows.forEach((row, index) => {\n const decoded = contract.decodeRow(row, index)\n if (!decoded.ok) {\n rejected.push({ index, reason: decoded.reason })\n return\n }\n if (contract.maxRows !== undefined && rows.length >= contract.maxRows) {\n overflow += 1\n return\n }\n rows.push(decoded.row)\n })\n return { rows, rejected, overflow }\n}\n\n/**\n * Decode a parsed reply value under a contract: strict envelope when declared,\n * then per-row decoding, then the all-rejected policy.\n */\nexport function decodeReplyRows<TRow>(\n contract: ReplyContract<TRow>,\n value: unknown,\n): DecodedReply<TRow> {\n let rawRows: readonly unknown[]\n let extras: Record<string, unknown> = {}\n if (contract.parseEnvelope) {\n const envelope = contract.parseEnvelope(value)\n rawRows = envelope.rows\n extras = envelope.extras\n } else {\n const record =\n typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined\n const field = record?.[contract.rowsField]\n if (!Array.isArray(field)) {\n throw new ValidationError(`reply has no \"${contract.rowsField}\" array`)\n }\n rawRows = field\n }\n const { rows, rejected, overflow } = decodeContractRows(contract, rawRows)\n if (rows.length === 0 && rawRows.length > 0 && contract.whenAllRowsRejected === 'fail') {\n throw new ValidationError(\n `${contract.allRejectedMessage ?? 'every reported row was malformed'}: ${rejected\n .map((entry) => entry.reason)\n .join(' | ')}`,\n )\n }\n return { rows, extras, rejected, reportedRows: rawRows.length, overflow }\n}\n","import { createHash } from 'node:crypto'\nimport type { CustomTokenPricing } from '../cost-ledger'\nimport type { PrimeBridgeTransport, PrimeBridgeTransportResult } from './prime-bridge-transport'\nimport { decodeContractRows, type ReplyContract, type ReplyRowDecoded } from './reply-contract'\nimport type { AnalystUsageReceipt } from './types'\n\n/**\n * The prime analyst protocol: a one-shot RLM reached through an\n * OpenAI-compatible bridge, given the whole trajectory inline because it has no\n * REPL and no trace tools, answering in one fenced JSON block of short strings.\n *\n * This module owns every part of that protocol that does not depend on what the\n * rows MEAN: prompt and contract composition, the bounded repair turn, reply\n * extraction, row decoding order, the render-measure-fall-back-fail-loud\n * projection ladder, usage normalization, and the protocol identity digest.\n *\n * The cut: the core speaks RAW ROWS and never names a finding type. It knows a\n * prime reply carries an `answer` string plus an array of rows under a named\n * field, and that each row is decoded by a caller-supplied function. Consumers\n * — the CodeTraceBench benchmark runner here, a span-grounded trace analyzer\n * elsewhere — map decoded rows into their own finding shape on the way out. So\n * nothing in this file may import a block type, a finding type, or a trace\n * store, and no consumer needs another copy of the protocol.\n */\n\n// ── Reply contract ───────────────────────────────────────────────────\n\n/**\n * The prime reply grammar is the general analyst reply contract: these aliases\n * keep every prime-protocol consumer compiling against the shared type in\n * ./reply-contract. The exchange below reads the base fields (`rowsField`,\n * contract lines, `decodeRow`, `maxRows`); the strict-envelope knobs serve\n * one-shot JSON arms and are inert here.\n */\nexport type PrimeRowDecoded<TRow> = ReplyRowDecoded<TRow>\n\nexport type PrimeReplyContract<TRow> = ReplyContract<TRow>\n\n// ── Prompt composition ───────────────────────────────────────────────\n\nexport interface PrimePromptSpec {\n question: string\n /** Task definition spliced under a `TASK DEFINITION:` heading. Omit when the question is the whole task. */\n taskDefinition?: string\n contractLines: readonly string[]\n /** Line introducing the trajectory, e.g. `TRAJECTORY (trace_id X; 12 assistant step spans; ...):`. */\n trajectoryHeader: string\n renderedTrajectory: string\n /** Material appended after the trajectory, e.g. the final-verification spans. */\n trailer?: string\n}\n\nexport function buildPrimePrompt(spec: PrimePromptSpec): string {\n return [\n `QUESTION: ${spec.question}`,\n '',\n ...(spec.taskDefinition === undefined ? [] : ['TASK DEFINITION:', spec.taskDefinition, '']),\n ...spec.contractLines,\n '',\n spec.trajectoryHeader,\n spec.renderedTrajectory,\n ...(spec.trailer === undefined ? [] : ['', spec.trailer]),\n ].join('\\n')\n}\n\nexport interface PrimeRepairPromptSpec {\n defect: string\n previousReply: string\n repairContractLines: readonly string[]\n}\n\n/** Carries the malformed reply and the contract — never the trajectory. */\nexport function buildPrimeRepairPrompt(spec: PrimeRepairPromptSpec): string {\n return [\n 'Your previous reply to a trace-analysis task was structurally malformed and could not be parsed',\n `(${spec.defect}). Below is your previous reply verbatim. Re-emit ONLY the corrected JSON — one`,\n 'fenced ```json block, no other text, no tools. The JSON object has exactly two fields:',\n ...spec.repairContractLines,\n '',\n 'PREVIOUS REPLY:',\n spec.previousReply,\n ].join('\\n')\n}\n\n// ── Reply extraction ─────────────────────────────────────────────────\n\n/**\n * Recover the reply's JSON object.\n *\n * Distinct from `extractJsonPayload` in ../llm-client, which serves a response\n * that DECLARES a JSON root and therefore must not scan onward. A prime reply\n * is prose plus a fenced block, and when the model emits several fences the\n * last one is its answer — so fences are scanned in reverse, and only then is a\n * brace-to-brace slice tried.\n */\nfunction extractPrimeJsonObject(text: string): Record<string, unknown> | null {\n const direct = parsePrimeJsonObject(text)\n if (direct) return direct\n const fenced = [...text.matchAll(/```(?:json)?\\s*\\n?([\\s\\S]*?)```/g)]\n for (let index = fenced.length - 1; index >= 0; index -= 1) {\n const candidate = parsePrimeJsonObject(fenced[index]![1]!)\n if (candidate) return candidate\n }\n const start = text.indexOf('{')\n const end = text.lastIndexOf('}')\n if (start >= 0 && end > start) {\n const candidate = parsePrimeJsonObject(text.slice(start, end + 1))\n if (candidate) return candidate\n }\n return null\n}\n\n/** Why the reply cannot be read as a prime answer, or null when it can. */\nfunction primeReplyDefect(\n parsed: Record<string, unknown> | null,\n rowsField: string,\n): string | null {\n if (parsed === null) return 'no parseable JSON object'\n if (!Array.isArray(parsed[rowsField])) return `JSON has no \"${rowsField}\" array`\n return null\n}\n\nfunction parsePrimeJsonObject(text: string): Record<string, unknown> | null {\n try {\n const value: unknown = JSON.parse(text.trim())\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null\n } catch {\n return null\n }\n}\n\n// ── Usage ────────────────────────────────────────────────────────────\n\n/**\n * Token accounting exactly as the bridge reported it. Lossless on purpose: a\n * side the bridge did not report stays null rather than becoming a zero, and a\n * side it DID report survives even when its partner is missing.\n */\nexport interface PrimeRawUsage {\n /**\n * Model-usage records the bridge observed. NOT a count of bridge round trips:\n * one prime turn routes several internal model calls, so a single turn\n * typically reports 3-5.\n */\n calls: number | null\n /** Prompt tokens the bridge reported; null when it reported none. */\n inputTokens: number | null\n /** Completion tokens the bridge reported; null when it reported none. */\n outputTokens: number | null\n /**\n * True when the bridge DERIVED the counts (from character lengths) because\n * the backend reported no usage of its own. Pricing derived counts produces a\n * guess about a guess, which a reader must be able to tell apart from a\n * rate-estimated cost over exact tokens.\n */\n bridgeEstimated: boolean\n}\n\nfunction emptyPrimeRawUsage(): PrimeRawUsage {\n return { calls: null, inputTokens: null, outputTokens: null, bridgeEstimated: false }\n}\n\n/** Read the bridge's OpenAI-shaped `usage` object. */\nexport function normalizePrimeUsage(raw: unknown): PrimeRawUsage {\n if (typeof raw !== 'object' || raw === null) return emptyPrimeRawUsage()\n const record = raw as Record<string, unknown>\n return {\n calls: tokenCountOrNull(record.model_requests),\n inputTokens: tokenCountOrNull(record.prompt_tokens),\n outputTokens: tokenCountOrNull(record.completion_tokens),\n bridgeEstimated: record.estimated === true,\n }\n}\n\n/**\n * Sum two turns. Each side poisons independently: two turns that both report\n * input and neither report output yield a real input total beside a null\n * output, because discarding a measured count is as wrong as inventing one.\n */\nexport function mergePrimeRawUsage(a: PrimeRawUsage, b: PrimeRawUsage): PrimeRawUsage {\n return {\n calls: sumOrNull(a.calls, b.calls),\n inputTokens: sumOrNull(a.inputTokens, b.inputTokens),\n outputTokens: sumOrNull(a.outputTokens, b.outputTokens),\n bridgeEstimated: a.bridgeEstimated || b.bridgeEstimated,\n }\n}\n\nfunction sumOrNull(a: number | null, b: number | null): number | null {\n return a !== null && b !== null ? a + b : null\n}\n\nfunction tokenCountOrNull(value: unknown): number | null {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : null\n}\n\n/**\n * Bind raw prime usage to agent-eval's typed receipt.\n *\n * `RunTokenUsage.input` and `.output` are non-nullable, so a one-sided count\n * cannot round-trip through `tokens` without writing a zero nobody measured.\n * The complete-accounting field therefore stays null, the reported side is\n * carried verbatim in `partialTokens`, and its price becomes the receipt's\n * `knownCostUsd` lower bound.\n *\n * Only agent-eval calls this; consumers with no pricing table read\n * `PrimeRawUsage` directly.\n */\nexport function analystUsageReceiptFromPrimeUsage(\n usage: PrimeRawUsage,\n pricing: CustomTokenPricing,\n): AnalystUsageReceipt {\n const { calls, inputTokens, outputTokens, bridgeEstimated } = usage\n const estimatedTokens = bridgeEstimated ? { tokensEstimated: true } : {}\n if (inputTokens !== null && outputTokens !== null) {\n return {\n calls,\n tokens: { input: inputTokens, output: outputTokens },\n cost: { kind: 'estimated', usd: priceTokens(inputTokens, outputTokens, pricing) },\n ...estimatedTokens,\n }\n }\n if (inputTokens === null && outputTokens === null) {\n return { calls, tokens: null, cost: { kind: 'uncaptured', usd: null }, ...estimatedTokens }\n }\n return {\n calls,\n tokens: null,\n partialTokens: { input: inputTokens, output: outputTokens },\n cost: { kind: 'uncaptured', usd: null },\n knownCostUsd: priceTokens(inputTokens ?? 0, outputTokens ?? 0, pricing),\n ...estimatedTokens,\n }\n}\n\nfunction priceTokens(input: number, output: number, pricing: CustomTokenPricing): number {\n return (input * pricing.inputUsdPerMillion + output * pricing.outputUsdPerMillion) / 1_000_000\n}\n\n// ── Two-turn exchange ────────────────────────────────────────────────\n\n/**\n * Why an exchange ended without a readable reply. `deadline` and `aborted` are\n * separate members from `transport` on purpose: a model that ran past its\n * deadline, a caller who cancelled, and a bridge that refused the connection\n * demand three different responses, and a record that conflates them cannot be\n * acted on.\n */\nexport type PrimeFailure =\n | {\n kind: 'transport' | 'unparseable-json' | 'no-content' | 'deadline' | 'malformed-reply'\n message: string\n }\n | { kind: 'http-status'; message: string; status: number; bodySnippet: string }\n | { kind: 'aborted'; message: string; cause: unknown }\n\nexport interface PrimeRepairState {\n attempted: boolean\n /** Null when no repair turn ran, or when the repair turn never returned a reply. */\n succeeded: boolean | null\n}\n\n/** One completed bridge turn. A turn that failed produces no record. */\nexport interface PrimeTurnRecord {\n turn: 'first' | 'repair'\n usage: PrimeRawUsage\n /** The reply's `usage` object verbatim; null when the bridge sent none. */\n rawUsage: unknown\n}\n\nexport interface PrimeRejectedRow {\n index: number\n reason: string\n}\n\nexport type PrimeExchangeOutcome<TRow> =\n | {\n ok: true\n /** The reply's `answer` field; null when absent or not a string. */\n answer: string | null\n rows: TRow[]\n rejected: PrimeRejectedRow[]\n /** Rows the model reported, before decoding or the count cap. */\n reportedRows: number\n /** Valid rows dropped by `contract.maxRows`. */\n overflow: number\n usage: PrimeRawUsage\n turns: PrimeTurnRecord[]\n repair: PrimeRepairState\n reply: string\n }\n | {\n ok: false\n failure: PrimeFailure\n usage: PrimeRawUsage\n turns: PrimeTurnRecord[]\n repair: PrimeRepairState\n /** The last reply received, when one arrived — the diagnostic artifact for a malformed case. */\n reply?: string\n }\n\nexport interface PrimeExchangeOptions<TRow> {\n contract: PrimeReplyContract<TRow>\n prompt: string\n transport: PrimeBridgeTransport\n /** Full endpoint, e.g. `http://localhost:4181/v1/chat/completions`. */\n url: string\n model: string\n /** Deadline for ONE turn. Prime analyses routinely exceed five minutes. */\n timeoutMs: number\n /** Whether a structurally malformed reply gets one bounded repair turn. */\n repair: boolean\n signal?: AbortSignal\n}\n\n/**\n * Run the protocol: one call, one bounded repair turn on a structurally\n * malformed reply, then decode. Zero valid rows from a well-formed reply is an\n * honest null, not a failure.\n */\nexport async function runPrimeExchange<TRow>(\n options: PrimeExchangeOptions<TRow>,\n): Promise<PrimeExchangeOutcome<TRow>> {\n const { contract } = options\n const turns: PrimeTurnRecord[] = []\n const repair: PrimeRepairState = { attempted: false, succeeded: null }\n\n const first = await callPrimeTurn(options, options.prompt)\n if (!first.ok) {\n return { ok: false, failure: first.failure, usage: mergeTurns(turns), turns, repair }\n }\n turns.push({ turn: 'first', usage: first.usage, rawUsage: first.rawUsage })\n\n let reply = first.content\n let parsed = extractPrimeJsonObject(reply)\n let defect = primeReplyDefect(parsed, contract.rowsField)\n\n if (defect !== null && options.repair) {\n repair.attempted = true\n const second = await callPrimeTurn(\n options,\n buildPrimeRepairPrompt({\n defect,\n previousReply: reply,\n repairContractLines: contract.repairContractLines,\n }),\n )\n if (!second.ok) {\n return { ok: false, failure: second.failure, usage: mergeTurns(turns), turns, repair, reply }\n }\n turns.push({ turn: 'repair', usage: second.usage, rawUsage: second.rawUsage })\n reply = second.content\n parsed = extractPrimeJsonObject(reply)\n defect = primeReplyDefect(parsed, contract.rowsField)\n repair.succeeded = defect === null\n }\n\n const usage = mergeTurns(turns)\n if (defect !== null) {\n return {\n ok: false,\n failure: {\n kind: 'malformed-reply',\n message: `${defect} in prime reply${repair.attempted ? ' even after the bounded repair turn' : ''}`,\n },\n usage,\n turns,\n repair,\n reply,\n }\n }\n\n const rawRows = parsed![contract.rowsField] as unknown[]\n const { rows, rejected, overflow } = decodeContractRows(contract, rawRows)\n const answer = parsed!.answer\n return {\n ok: true,\n answer: typeof answer === 'string' ? answer : null,\n rows,\n rejected,\n reportedRows: rawRows.length,\n overflow,\n usage,\n turns,\n repair,\n reply,\n }\n}\n\ntype PrimeTurnOutcome =\n | { ok: true; content: string; usage: PrimeRawUsage; rawUsage: unknown }\n | { ok: false; failure: PrimeFailure }\n\nasync function callPrimeTurn<TRow>(\n options: PrimeExchangeOptions<TRow>,\n content: string,\n): Promise<PrimeTurnOutcome> {\n const { transport, url, model, timeoutMs, signal } = options\n const controller = new AbortController()\n const forwardAbort = () => controller.abort(signal?.reason)\n if (signal?.aborted) controller.abort(signal.reason)\n else signal?.addEventListener('abort', forwardAbort, { once: true })\n const deadline = setTimeout(() => controller.abort(), timeoutMs)\n let result: PrimeBridgeTransportResult\n try {\n result = await transport({\n url,\n body: { model, messages: [{ role: 'user', content }] },\n signal: controller.signal,\n })\n } catch (error) {\n if (signal?.aborted) {\n return {\n ok: false,\n failure: {\n kind: 'aborted',\n message: 'prime exchange cancelled by the caller',\n cause: error,\n },\n }\n }\n if (controller.signal.aborted) {\n return {\n ok: false,\n failure: { kind: 'deadline', message: `bridge call exceeded ${timeoutMs}ms` },\n }\n }\n return {\n ok: false,\n failure: {\n kind: 'transport',\n message: `bridge transport failure: ${error instanceof Error ? error.message : String(error)}`,\n },\n }\n } finally {\n clearTimeout(deadline)\n signal?.removeEventListener('abort', forwardAbort)\n }\n\n if (result.status !== 200) {\n const bodySnippet = result.text.slice(0, 500)\n return {\n ok: false,\n failure: {\n kind: 'http-status',\n message: `bridge HTTP ${result.status}: ${bodySnippet}`,\n status: result.status,\n bodySnippet,\n },\n }\n }\n let response: unknown\n try {\n response = JSON.parse(result.text)\n } catch {\n return {\n ok: false,\n failure: {\n kind: 'unparseable-json',\n message: `bridge returned unparseable JSON (${result.text.length} bytes)`,\n },\n }\n }\n const replyContent = primeReplyContent(response)\n if (replyContent === null) {\n return {\n ok: false,\n failure: { kind: 'no-content', message: 'bridge reply carries no message content' },\n }\n }\n const rawUsage = primeReplyUsage(response)\n return { ok: true, content: replyContent, usage: normalizePrimeUsage(rawUsage), rawUsage }\n}\n\n/**\n * Fold from the FIRST turn, never from an empty receipt: an all-null identity\n * would poison every side it merged with and erase counts the bridge reported.\n */\nfunction mergeTurns(turns: readonly PrimeTurnRecord[]): PrimeRawUsage {\n if (turns.length === 0) return emptyPrimeRawUsage()\n return turns\n .slice(1)\n .reduce<PrimeRawUsage>((total, turn) => mergePrimeRawUsage(total, turn.usage), turns[0]!.usage)\n}\n\nfunction primeReplyContent(response: unknown): string | null {\n if (typeof response !== 'object' || response === null) return null\n const choices = (response as { choices?: unknown }).choices\n if (!Array.isArray(choices) || choices.length === 0) return null\n const message = (choices[0] as { message?: unknown })?.message\n if (typeof message !== 'object' || message === null) return null\n const content = (message as { content?: unknown }).content\n return typeof content === 'string' && content.length > 0 ? content : null\n}\n\nfunction primeReplyUsage(response: unknown): unknown {\n if (typeof response !== 'object' || response === null) return null\n return (response as { usage?: unknown }).usage ?? null\n}\n\n// ── Trajectory projection ────────────────────────────────────────────\n\n/**\n * Where the inlined trajectory comes from. The protocol needs only two moves —\n * fetch it all, or fetch a reduced version — so no store, artifact path, or\n * span type enters the shared signature.\n */\nexport interface PrimeProjectionSource<TItem> {\n /** The full projection, or null when the source declares itself oversized. */\n full(): Promise<readonly TItem[] | null>\n /** A reduced projection of the same material. */\n capped(): Promise<readonly TItem[]>\n /** How `capped` reduces, named for the failure message, e.g. `per-attribute cap 1200`. */\n cappedDescription: string\n}\n\nexport interface PrimeProjectionDelivery {\n mode: 'inline-json'\n fetch: 'full' | 'capped'\n renderedChars: number\n}\n\nexport type PrimeProjectionOutcome<TItem> =\n | {\n ok: true\n items: readonly TItem[]\n rendered: string\n delivery: PrimeProjectionDelivery\n }\n | { ok: false; reason: string; renderedChars: number }\n\n/**\n * Render, measure, fall back to the capped projection, re-measure, fail loud.\n *\n * Inline is the only delivery prime has, so an oversized trajectory is a\n * refusal rather than a silent truncation: dropping spans would understate the\n * trajectory and the analyst would answer a question about a different run.\n */\nexport async function projectPrimeTrajectory<TItem>(\n source: PrimeProjectionSource<TItem>,\n limits: { maxInlineChars: number },\n): Promise<PrimeProjectionOutcome<TItem>> {\n let fetch: PrimeProjectionDelivery['fetch'] = 'full'\n let items = await source.full()\n if (items === null) {\n fetch = 'capped'\n items = await source.capped()\n }\n let rendered = JSON.stringify(items)\n if (rendered.length > limits.maxInlineChars && fetch === 'full') {\n fetch = 'capped'\n items = await source.capped()\n rendered = JSON.stringify(items)\n }\n if (rendered.length > limits.maxInlineChars) {\n return {\n ok: false,\n reason: `trajectory renders to ${rendered.length} chars even at ${source.cappedDescription}; inline delivery impossible`,\n renderedChars: rendered.length,\n }\n }\n return {\n ok: true,\n items,\n rendered,\n delivery: { mode: 'inline-json', fetch, renderedChars: rendered.length },\n }\n}\n\n// ── Protocol identity ────────────────────────────────────────────────\n\nexport interface PrimeProtocolIdentity {\n question: string\n taskDefinition?: string\n contractLines: readonly string[]\n repairContractLines: readonly string[]\n /** Numeric limits the contract states, e.g. row and width caps. */\n limits: Readonly<Record<string, number>>\n}\n\n/**\n * Digest of everything a consumer can send to the bridge under the prime\n * protocol, recorded per observation so a prime result names the exact contract\n * that produced it.\n *\n * Computed over the ACTUALLY composed contract, so two consumers that both\n * stamp `analyst_id: 'prime'` while asking materially different questions get\n * different digests by construction. That is what makes 'prime' a reproducible\n * claim rather than a label.\n */\nexport function primeProtocolSha256(identity: PrimeProtocolIdentity): string {\n return createHash('sha256')\n .update(\n JSON.stringify({\n kind: 'prime-analyst-protocol',\n question: identity.question,\n taskPrompt: identity.taskDefinition ?? null,\n outputContract: identity.contractLines,\n repairContract: buildPrimeRepairPrompt({\n defect: '<defect>',\n previousReply: '<previous-reply>',\n repairContractLines: identity.repairContractLines,\n }),\n limits: identity.limits,\n }),\n )\n .digest('hex')\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { _ as toAgentProfileJson, a as AgentProfileCellSchemaVersion, c as AgentProfileHarness, d as AgentProfileKind, f as AgentProfileSource, g as groupRunsByAgentProfileCell, h as buildAgentProfileCell, i as AgentProfileCellInput, l as AgentProfileJson, m as agentProfileCellKey, n as AgentInterfaceProfileLike, o as AgentProfileCellValidationError, p as AgentProfileSourceInput, r as AgentProfileCell, s as AgentProfileDimensionValue, t as AGENT_PROFILE_KINDS, u as AgentProfileJsonObject, v as validateAgentProfileCell, y as verifyAgentProfileCell } from "./agent-profile-cell-BcpFbNd5.js";
1
+ import { _ as toAgentProfileJson, a as AgentProfileCellSchemaVersion, c as AgentProfileHarness, d as AgentProfileKind, f as AgentProfileSource, g as groupRunsByAgentProfileCell, h as buildAgentProfileCell, i as AgentProfileCellInput, l as AgentProfileJson, m as agentProfileCellKey, n as AgentInterfaceProfileLike, o as AgentProfileCellValidationError, p as AgentProfileSourceInput, r as AgentProfileCell, s as AgentProfileDimensionValue, t as AGENT_PROFILE_KINDS, u as AgentProfileJsonObject, v as validateAgentProfileCell, y as verifyAgentProfileCell } from "./agent-profile-cell-3kYxUsK2.js";
2
2
  export { AGENT_PROFILE_KINDS, AgentInterfaceProfileLike, AgentProfileCell, AgentProfileCellInput, AgentProfileCellSchemaVersion, AgentProfileCellValidationError, AgentProfileDimensionValue, AgentProfileHarness, AgentProfileJson, AgentProfileJsonObject, AgentProfileKind, AgentProfileSource, AgentProfileSourceInput, agentProfileCellKey, buildAgentProfileCell, groupRunsByAgentProfileCell, toAgentProfileJson, validateAgentProfileCell, verifyAgentProfileCell };
@@ -1,2 +1 @@
1
- import { a as groupRunsByAgentProfileCell, c as verifyAgentProfileCell, i as buildAgentProfileCell, n as AgentProfileCellValidationError, o as toAgentProfileJson, r as agentProfileCellKey, s as validateAgentProfileCell, t as AGENT_PROFILE_KINDS } from "./agent-profile-cell-B1V1gUZs.js";
2
- export { AGENT_PROFILE_KINDS, AgentProfileCellValidationError, agentProfileCellKey, buildAgentProfileCell, groupRunsByAgentProfileCell, toAgentProfileJson, validateAgentProfileCell, verifyAgentProfileCell };
1
+ export { t as AGENT_PROFILE_KINDS, n as AgentProfileCellValidationError, r as agentProfileCellKey, i as buildAgentProfileCell, a as groupRunsByAgentProfileCell, o as toAgentProfileJson, s as validateAgentProfileCell, c as verifyAgentProfileCell } from "./agent-profile-cell-CT5JYueM.js";
@@ -1,8 +1,7 @@
1
- import { o as FailureClass } from "./schema-D6EVKzTB.js";
2
- import { a as RunRecord, c as RunSplitTag } from "./run-record-C3awiXPf.js";
3
- import { i as DatasetSplit, n as DatasetManifest, r as DatasetScenario } from "./dataset-DQqhOCPt.js";
4
- import { S as HeldOutGateDecision } from "./summary-report-C8V49Jt3.js";
5
- //#region src/statistics/rank-tests.d.ts
1
+ import { o as FailureClass } from "./schema-CkIvnmLU.js";
2
+ import { a as RunRecord, c as RunSplitTag } from "./run-record-D2BFMPGl.js";
3
+ import { i as DatasetSplit, n as DatasetManifest, r as DatasetScenario } from "./dataset-DThC1S6G.js";
4
+ import { S as HeldOutGateDecision } from "./summary-report-0La5vejY.js";
6
5
  /** How a rank test's p-value was actually computed. */
7
6
  type RankTestMethod = 'exact' | 'permutation' | 'asymptotic';
8
7
  /**
@@ -71,8 +70,6 @@ interface WilcoxonSignedRankResult {
71
70
  * `pFloor` states rather than leaving `p = 1` to be read as a measured null.
72
71
  */
73
72
  declare function wilcoxonSignedRank(before: number[], after: number[], opts?: RankTestOptions): WilcoxonSignedRankResult;
74
- //#endregion
75
- //#region src/release-confidence.d.ts
76
73
  /** Severity of an actionable finding attached to a run/trace. */
77
74
  type AsiSeverity = 'info' | 'warning' | 'error' | 'critical';
78
75
  /** Actionable side-info — a diagnosed finding the loop can act on. */
@@ -201,8 +198,6 @@ interface ReleaseConfidenceScorecard {
201
198
  summary: string;
202
199
  }
203
200
  declare function evaluateReleaseConfidence(input: ReleaseConfidenceInput): ReleaseConfidenceScorecard;
204
- //#endregion
205
- //#region src/promotion-gate.d.ts
206
201
  /**
207
202
  * Bootstrap-CI promotion gate.
208
203
  *
@@ -299,6 +294,5 @@ declare function judgeReplayGate<TOutput>(args: JudgeReplayGateArgs<TOutput>): P
299
294
  baselineSamples: number;
300
295
  candidateSamples: number;
301
296
  }>;
302
- //#endregion
303
297
  export { mannWhitneyU as C, WilcoxonSignedRankResult as S, evaluateReleaseConfidence as _, bootstrapCi as a, RankTestMethodRequest as b, ReleaseConfidenceAxis as c, ReleaseConfidenceIssue as d, ReleaseConfidenceMetrics as f, ReleaseTraceEvidence as g, ReleaseConfidenceThresholds as h, Verdict as i, ReleaseConfidenceAxisName as l, ReleaseConfidenceStatus as m, BootstrapResult as n, judgeReplayGate as o, ReleaseConfidenceScorecard as p, JudgeReplayGateArgs as r, ActionableSideInfo as s, BootstrapOptions as t, ReleaseConfidenceInput as u, MannWhitneyResult as v, wilcoxonSignedRank as w, RankTestOptions as x, RankTestMethod as y };
304
- //# sourceMappingURL=promotion-gate-CkVZHagC.d.ts.map
298
+ //# sourceMappingURL=promotion-gate-CixshGI8.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion-gate-CixshGI8.d.ts","names":[],"sources":["../src/statistics/rank-tests.ts","../src/release-confidence.ts","../src/promotion-gate.ts"],"mappings":";;;;;KAiCY;;;;;KAMA;UAEK;;EAEf,SAAS;;EAET;;;EAGA;;UAYe;;EAEf;;EAEA;;EAEA;;EAEA,QAAQ;;EAER;;;;;;;;;;;;;;iBAec,aACd,aACA,aACA,OAAM,kBACL;UAuFc;;;EAGf;;EAEA;;EAEA,QAAQ;;EAER;;EAEA;;;;;;;;;;;;;;;iBAgBc,mBACd,kBACA,iBACA,OAAM,kBACL;;KCxLE;;UAGY;;EAEf;;EAEA;EACA,WAAW;;EAEX;;EAEA;;EAEA;;EAEA;EACA,WAAW;;KAGD;KACA;UAQK;EACf;EACA;EACA,QAAQ;EACR;EACA;EACA;EACA;EACA;;EAEA,eAAe;EACf,MAAM;EACN,WAAW;;UAGI;;EAEf;EACA;EACA;EACA;;EAEA;EACA;EACA;;EAEA;EACA;EACA;;EAEA;;EAEA;;UAGe;EACf;EACA;EACA;EACA,UAAU;EACV,qBAAqB;EACrB,gBAAgB;EAChB,kBAAkB;EAClB,eAAe;EACf,aAAa;;UAGE;EACf,MAAM;EACN,QAAQ;EACR;EACA;;UAGe;EACf,MAAM;EACN;EACA;EACA;;UAGe;EACf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aAAa,OAAO;EACpB,cAAc;EACd,oBAAoB,QAAQ,OAAO;EACnC,0BAA0B;;;;;;;EAO1B;;UAGe;EACf;EACA;EACA;EACA,QAAQ;EACR;EACA,MAAM;EACN,QAAQ;EACR,SAAS;EACT,SAAS;EACT,cAAc;EACd;;iBAkBc,0BACd,OAAO,yBACN;;;;;;;;;;;;;;;;;;;;;;;;;KC3JS;UAEK;EACf;EACA;;EAEA;;EAEA;;EAEA;;EAEA;EACA;EACA,SAAS;;UAGM;;EAEf;;EAEA;;;;;;EAMA;;;EAGA;;;;;;;;;iBAUc,YACd,oBACA,qBACA,UAAS,mBACR;;;;;;;;;;;;;;;;UA0Gc,oBAAoB;EACnC,iBAAiB;EACjB,kBAAkB;;EAElB,QAAQ,QAAQ,YAAY;EAC5B;EACA;;EAEA;;EAEA;;;;;iBAMoB,gBAAgB,SACpC,MAAM,oBAAoB,WACzB,QAAQ;EAAoB;EAAyB"}