@tangle-network/agent-eval 0.216.1 → 0.218.1

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 (532) hide show
  1. package/CHANGELOG.md +137 -57
  2. package/README.md +2 -2
  3. package/dist/adapters/http.d.ts +2 -2
  4. package/dist/{agent-profile-VFcQncbW.d.ts → agent-profile-DTt8uGP9.d.ts} +4 -17
  5. package/dist/agent-profile-DTt8uGP9.d.ts.map +1 -0
  6. package/dist/{agent-profile-cell-BK8mlqlq.js → agent-profile-cell-B1V1gUZs.js} +4 -53
  7. package/dist/agent-profile-cell-B1V1gUZs.js.map +1 -0
  8. package/dist/{agent-profile-cell-BNp-Js9F.d.ts → agent-profile-cell-BcpFbNd5.d.ts} +2 -22
  9. package/dist/agent-profile-cell-BcpFbNd5.d.ts.map +1 -0
  10. package/dist/{agreement-irr-BEWLIF3_.js → agreement-irr-BhAqjluA.js} +5 -5
  11. package/dist/agreement-irr-BhAqjluA.js.map +1 -0
  12. package/dist/analyst/index.d.ts +36 -169
  13. package/dist/analyst/index.d.ts.map +1 -1
  14. package/dist/analyst/index.js +17 -192
  15. package/dist/analyst/index.js.map +1 -1
  16. package/dist/{analyze-runs-D68fd-su.d.ts → analyze-runs-DjlZOVXx.d.ts} +5 -5
  17. package/dist/{analyze-runs-D68fd-su.d.ts.map → analyze-runs-DjlZOVXx.d.ts.map} +1 -1
  18. package/dist/{analyze-runs-C84irm4i.js → analyze-runs-DqPJaJ4X.js} +225 -21
  19. package/dist/analyze-runs-DqPJaJ4X.js.map +1 -0
  20. package/dist/authenticity/index.d.ts +0 -23
  21. package/dist/authenticity/index.d.ts.map +1 -1
  22. package/dist/authenticity/index.js +1 -34
  23. package/dist/authenticity/index.js.map +1 -1
  24. package/dist/{benchmark-command-By0vh8q7.js → benchmark-command-BupdHRyf.js} +1225 -661
  25. package/dist/benchmark-command-BupdHRyf.js.map +1 -0
  26. package/dist/benchmarks/index.d.ts +5 -6
  27. package/dist/benchmarks/index.d.ts.map +1 -1
  28. package/dist/benchmarks/index.js +4 -4
  29. package/dist/benchmarks/index.js.map +1 -1
  30. package/dist/builder-eval/index.d.ts +3 -3
  31. package/dist/builder-eval/index.js +2 -2
  32. package/dist/builder-eval/index.js.map +1 -1
  33. package/dist/campaign/index.d.ts +7 -7
  34. package/dist/campaign/index.js +15 -15
  35. package/dist/{campaign-BudZ70zo.js → campaign-CGvUTnmc.js} +324 -800
  36. package/dist/campaign-CGvUTnmc.js.map +1 -0
  37. package/dist/{campaign-evidence-Clrn4hBV.js → campaign-evidence-DunzcJGv.js} +10 -18
  38. package/dist/{campaign-evidence-Clrn4hBV.js.map → campaign-evidence-DunzcJGv.js.map} +1 -1
  39. package/dist/{canonical-B2RqLofv.js → canonical-Dq2hOQ8L.js} +2 -2
  40. package/dist/{canonical-B2RqLofv.js.map → canonical-Dq2hOQ8L.js.map} +1 -1
  41. package/dist/cell-spend-DEWR3nj-.js +90 -0
  42. package/dist/cell-spend-DEWR3nj-.js.map +1 -0
  43. package/dist/{chat-client-l-MVDlDk.js → chat-client-B2pXlPdx.js} +2 -2
  44. package/dist/{chat-client-l-MVDlDk.js.map → chat-client-B2pXlPdx.js.map} +1 -1
  45. package/dist/{chat-json-call-puMArmtW.js → chat-json-call-Dm9c-b41.js} +3 -2
  46. package/dist/chat-json-call-Dm9c-b41.js.map +1 -0
  47. package/dist/{claim-q4HQhK1G.js → claim-BPVuyHuy.js} +3 -3
  48. package/dist/{claim-q4HQhK1G.js.map → claim-BPVuyHuy.js.map} +1 -1
  49. package/dist/cli.js +113 -12
  50. package/dist/cli.js.map +1 -1
  51. package/dist/{client-BzL9niqi.d.ts → client-hwo3cJjR.d.ts} +3 -16
  52. package/dist/client-hwo3cJjR.d.ts.map +1 -0
  53. package/dist/{cluster-bootstrap-qcUWYFl-.js → cluster-bootstrap-DEwwhl0C.js} +3 -3
  54. package/dist/{cluster-bootstrap-qcUWYFl-.js.map → cluster-bootstrap-DEwwhl0C.js.map} +1 -1
  55. package/dist/{produced-state-BsDmnwxc.js → completion-verifier-DbLVf3i8.js} +9 -64
  56. package/dist/completion-verifier-DbLVf3i8.js.map +1 -0
  57. package/dist/contract/index.d.ts +12 -12
  58. package/dist/contract/index.js +107 -403
  59. package/dist/contract/index.js.map +1 -1
  60. package/dist/{cost-ledger-BP8V4kUQ.js → cost-ledger-D0352Z4d.js} +4 -8
  61. package/dist/cost-ledger-D0352Z4d.js.map +1 -0
  62. package/dist/dataset-DQqhOCPt.d.ts.map +1 -1
  63. package/dist/{default-registry-COhk9g36.js → default-registry-BJ-Pq6yL.js} +314 -285
  64. package/dist/default-registry-BJ-Pq6yL.js.map +1 -0
  65. package/dist/{default-registry-DzHiGruW.d.ts → default-registry-DXgLmoDI.d.ts} +7 -50
  66. package/dist/default-registry-DXgLmoDI.d.ts.map +1 -0
  67. package/dist/{define-agent-eval-CNTPzIkp.js → define-agent-eval-BGdFKlrc.js} +170 -110
  68. package/dist/define-agent-eval-BGdFKlrc.js.map +1 -0
  69. package/dist/{define-agent-eval-WSck0CZJ.d.ts → define-agent-eval-BlH10zEw.d.ts} +8 -8
  70. package/dist/define-agent-eval-BlH10zEw.d.ts.map +1 -0
  71. package/dist/{descriptive-DboxPZrG.js → descriptive-CVNy48rR.js} +2 -2
  72. package/dist/{descriptive-DboxPZrG.js.map → descriptive-CVNy48rR.js.map} +1 -1
  73. package/dist/diagnosis/index.d.ts +4 -14
  74. package/dist/diagnosis/index.d.ts.map +1 -1
  75. package/dist/diagnosis/index.js +67 -28
  76. package/dist/diagnosis/index.js.map +1 -1
  77. package/dist/{dspy-rlm-engine-LRCu61m5.js → dspy-rlm-engine-CSMwudLO.js} +5 -10
  78. package/dist/dspy-rlm-engine-CSMwudLO.js.map +1 -0
  79. package/dist/{emitter-HcCmFQl_.d.ts → emitter-DABYYTcH.d.ts} +5 -5
  80. package/dist/emitter-DABYYTcH.d.ts.map +1 -0
  81. package/dist/emitter-DbMXUIVP.js.map +1 -1
  82. package/dist/{engine-3A_4jOlI.d.ts → engine-BvZ0R-36.d.ts} +17 -21
  83. package/dist/engine-BvZ0R-36.d.ts.map +1 -0
  84. package/dist/{equal-terms-BtdXayCJ.js → equal-terms-DbPGcVtI.js} +2 -2
  85. package/dist/equal-terms-DbPGcVtI.js.map +1 -0
  86. package/dist/{errors-DVZiqS7K.js → errors-BcOs5MKW.js} +2 -8
  87. package/dist/{errors-DVZiqS7K.js.map → errors-BcOs5MKW.js.map} +1 -1
  88. package/dist/eval-campaign-BUMIxKTE.js +393 -0
  89. package/dist/eval-campaign-BUMIxKTE.js.map +1 -0
  90. package/dist/{evaluation-6Yoi74gM.d.ts → evaluation-BOZ38vOH.d.ts} +7 -7
  91. package/dist/evaluation-BOZ38vOH.d.ts.map +1 -0
  92. package/dist/evaluation.d.ts +2 -2
  93. package/dist/evaluation.js +1 -1
  94. package/dist/evaluation.js.map +1 -1
  95. package/dist/{exact-types-ClugMJfI.d.ts → exact-types-CflbJ9f3.d.ts} +2 -2
  96. package/dist/{exact-types-ClugMJfI.d.ts.map → exact-types-CflbJ9f3.d.ts.map} +1 -1
  97. package/dist/{exec-ChJ6d5if.js → exec-CpbtOXVt.js} +2 -24
  98. package/dist/{exec-ChJ6d5if.js.map → exec-CpbtOXVt.js.map} +1 -1
  99. package/dist/execution-tracks-CpgFPpS5.js.map +1 -1
  100. package/dist/experiment/index.d.ts +9 -112
  101. package/dist/experiment/index.d.ts.map +1 -1
  102. package/dist/experiment/index.js +258 -311
  103. package/dist/experiment/index.js.map +1 -1
  104. package/dist/{exporters-X4xwla8A.js → exporters-DWvM16LE.js} +3 -3
  105. package/dist/exporters-DWvM16LE.js.map +1 -0
  106. package/dist/{exporters-ChTnR90l.d.ts → exporters-Dk3oEbK_.d.ts} +2 -4
  107. package/dist/{exporters-ChTnR90l.d.ts.map → exporters-Dk3oEbK_.d.ts.map} +1 -1
  108. package/dist/{external-optimizer-process-BjMGUuds.js → external-optimizer-process-C3Wm7Vhn.js} +4 -3
  109. package/dist/external-optimizer-process-C3Wm7Vhn.js.map +1 -0
  110. package/dist/{external-optimizer-subprocess-BqW0hHcI.js → external-optimizer-subprocess-B5gdLRZv.js} +9 -11
  111. package/dist/external-optimizer-subprocess-B5gdLRZv.js.map +1 -0
  112. package/dist/{extract-usage-BrnzRJ6H.js → extract-usage-BZLU01kR.js} +2 -23
  113. package/dist/{extract-usage-BrnzRJ6H.js.map → extract-usage-BZLU01kR.js.map} +1 -1
  114. package/dist/{failure-cluster-CbgEDcFJ.d.ts → failure-cluster-DN0t63Z0.d.ts} +4 -43
  115. package/dist/failure-cluster-DN0t63Z0.d.ts.map +1 -0
  116. package/dist/{failure-taxonomy-CjabTATj.js → failure-taxonomy-Bx5oWqaW.js} +2 -19
  117. package/dist/{failure-taxonomy-CjabTATj.js.map → failure-taxonomy-Bx5oWqaW.js.map} +1 -1
  118. package/dist/{feedback-trajectory-C4EG0nNH.d.ts → feedback-trajectory-BWmhRBGu.d.ts} +7 -9
  119. package/dist/feedback-trajectory-BWmhRBGu.d.ts.map +1 -0
  120. package/dist/{semantic-concept-judge-BQF8te0T.js → findings-store-BtTzPL0d.js} +9 -249
  121. package/dist/findings-store-BtTzPL0d.js.map +1 -0
  122. package/dist/fuzz.d.ts +19 -62
  123. package/dist/fuzz.d.ts.map +1 -1
  124. package/dist/fuzz.js +62 -108
  125. package/dist/fuzz.js.map +1 -1
  126. package/dist/{hf-dataset-BR2yhuNn.js → hf-dataset-CKxIJQba.js} +4 -24
  127. package/dist/hf-dataset-CKxIJQba.js.map +1 -0
  128. package/dist/hosted/index.d.ts +2 -2
  129. package/dist/hosted/index.js +2 -2
  130. package/dist/{index-CyszSg4O.d.ts → index-B16FNdW5.d.ts} +145 -360
  131. package/dist/index-B16FNdW5.d.ts.map +1 -0
  132. package/dist/{index-DV-jSzxF.d.ts → index-BLGqZ81N.d.ts} +10 -15
  133. package/dist/{index-DV-jSzxF.d.ts.map → index-BLGqZ81N.d.ts.map} +1 -1
  134. package/dist/{index-BO41eGj5.d.ts → index-CX-GAUpw.d.ts} +3 -7
  135. package/dist/index-CX-GAUpw.d.ts.map +1 -0
  136. package/dist/{index-DHKEAv3s.d.ts → index-CalAsXMR.d.ts} +8 -68
  137. package/dist/index-CalAsXMR.d.ts.map +1 -0
  138. package/dist/{index-BFRO6chs.d.ts → index-CiRwLv2R.d.ts} +5 -69
  139. package/dist/index-CiRwLv2R.d.ts.map +1 -0
  140. package/dist/{index-DPcngtwt.d.ts → index-DbMOXYnP.d.ts} +11 -36
  141. package/dist/index-DbMOXYnP.d.ts.map +1 -0
  142. package/dist/index.d.ts +211 -218
  143. package/dist/index.d.ts.map +1 -1
  144. package/dist/index.js +999 -1714
  145. package/dist/index.js.map +1 -1
  146. package/dist/{integrity-dLiDe2kD.js → integrity-C8oUeB0g.js} +326 -203
  147. package/dist/integrity-C8oUeB0g.js.map +1 -0
  148. package/dist/{integrity-BXOsAb3i.js → integrity-W4CADcFc.js} +3 -7
  149. package/dist/{integrity-BXOsAb3i.js.map → integrity-W4CADcFc.js.map} +1 -1
  150. package/dist/{integrity-DAMEDFaC.d.ts → integrity-_qgZLA5p.d.ts} +4 -6
  151. package/dist/{integrity-DAMEDFaC.d.ts.map → integrity-_qgZLA5p.d.ts.map} +1 -1
  152. package/dist/{internal-Epl-YBZW.js → internal-BTK91Bqt.js} +3 -3
  153. package/dist/{internal-Epl-YBZW.js.map → internal-BTK91Bqt.js.map} +1 -1
  154. package/dist/{interval-CELpye1n.js → interval-Dq9gt7jx.js} +3 -3
  155. package/dist/{interval-CELpye1n.js.map → interval-Dq9gt7jx.js.map} +1 -1
  156. package/dist/{journal-DfRz9kps.js → journal-C7om8Gum.js} +157 -147
  157. package/dist/journal-C7om8Gum.js.map +1 -0
  158. package/dist/json-BhdsJaOQ.js +111 -0
  159. package/dist/json-BhdsJaOQ.js.map +1 -0
  160. package/dist/{judge-calibration-BpCy5XQl.js → judge-calibration-BkXMIWA4.js} +3 -3
  161. package/dist/{judge-calibration-BpCy5XQl.js.map → judge-calibration-BkXMIWA4.js.map} +1 -1
  162. package/dist/{judge-gate-iY9s4L44.js → judge-gate-Co5tuh57.js} +4 -27
  163. package/dist/{judge-gate-iY9s4L44.js.map → judge-gate-Co5tuh57.js.map} +1 -1
  164. package/dist/{judge-gate-CE7CQAgt.d.ts → judge-gate-DsL0yFcb.d.ts} +8 -9
  165. package/dist/judge-gate-DsL0yFcb.d.ts.map +1 -0
  166. package/dist/{kind-factory-BobI5Jy3.js → kind-factory-Gy4fXixd.js} +88 -17
  167. package/dist/kind-factory-Gy4fXixd.js.map +1 -0
  168. package/dist/ledger-core/index.d.ts +2 -2
  169. package/dist/ledger-core/index.js +4 -4
  170. package/dist/ledger-core/lock-holder.d.ts +2 -0
  171. package/dist/ledger-core/lock-holder.js +181 -0
  172. package/dist/ledger-core/lock-holder.js.map +1 -0
  173. package/dist/{ledger-core-Gq7yp8lP.js → ledger-core-CAxUdDk0.js} +5 -84
  174. package/dist/ledger-core-CAxUdDk0.js.map +1 -0
  175. package/dist/{llm-client-CyBAoYiX.js → llm-client-_Y6ic-tf.js} +243 -355
  176. package/dist/llm-client-_Y6ic-tf.js.map +1 -0
  177. package/dist/{llm-judge-CG12SQJq.js → llm-judge-Djxh-Uhs.js} +662 -482
  178. package/dist/llm-judge-Djxh-Uhs.js.map +1 -0
  179. package/dist/lock-holder-DaJbfpci.d.ts +86 -0
  180. package/dist/lock-holder-DaJbfpci.d.ts.map +1 -0
  181. package/dist/matrix/index.d.ts +3 -3
  182. package/dist/matrix/index.js +3 -2
  183. package/dist/{matrix-Dm0BQW7U.js → matrix-B8l-Nsxd.js} +3 -88
  184. package/dist/matrix-B8l-Nsxd.js.map +1 -0
  185. package/dist/{matrix-DSrSxjjy.d.ts → matrix-CCSBna4q.d.ts} +9 -18
  186. package/dist/matrix-CCSBna4q.d.ts.map +1 -0
  187. package/dist/{mean-DHoMiudD.js → mean-BbA_JCzW.js} +39 -5
  188. package/dist/mean-BbA_JCzW.js.map +1 -0
  189. package/dist/meta-eval/index.d.ts +5 -5
  190. package/dist/meta-eval/index.js +10 -10
  191. package/dist/metrics-BKaPBtIG.js.map +1 -1
  192. package/dist/{mint-DNU8QPG4.d.ts → mint-BRZXuwRi.d.ts} +4 -4
  193. package/dist/{mint-DNU8QPG4.d.ts.map → mint-BRZXuwRi.d.ts.map} +1 -1
  194. package/dist/{mint-QaD5cA0u.js → mint-CbdwjTPW.js} +4 -4
  195. package/dist/{mint-QaD5cA0u.js.map → mint-CbdwjTPW.js.map} +1 -1
  196. package/dist/{multi-layer-verifier-BUaQ4C17.d.ts → multi-layer-verifier-DEgMUk6v.d.ts} +2 -2
  197. package/dist/{multi-layer-verifier-BUaQ4C17.d.ts.map → multi-layer-verifier-DEgMUk6v.d.ts.map} +1 -1
  198. package/dist/{multiplicity-DQUFcbW4.js → multiplicity-Sg0U7h8j.js} +2 -2
  199. package/dist/{multiplicity-DQUFcbW4.js.map → multiplicity-Sg0U7h8j.js.map} +1 -1
  200. package/dist/multishot/golden/index.d.ts +1 -23
  201. package/dist/multishot/golden/index.d.ts.map +1 -1
  202. package/dist/multishot/golden/index.js +3 -3
  203. package/dist/multishot/golden/index.js.map +1 -1
  204. package/dist/multishot/index.d.ts +3 -12
  205. package/dist/multishot/index.d.ts.map +1 -1
  206. package/dist/multishot/index.js +4 -3
  207. package/dist/multishot/index.js.map +1 -1
  208. package/dist/openapi.json +114 -10
  209. package/dist/{otel-spans-B9tUXRHF.js → otel-spans-CdN909k1.js} +3 -3
  210. package/dist/{otel-spans-B9tUXRHF.js.map → otel-spans-CdN909k1.js.map} +1 -1
  211. package/dist/{paired-arms-CwMGJsrS.js → paired-arms-Ct4LTKc1.js} +32 -9
  212. package/dist/paired-arms-Ct4LTKc1.js.map +1 -0
  213. package/dist/{paired-binary-CvpFHfKZ.js → paired-binary-B_nejA44.js} +3 -36
  214. package/dist/paired-binary-B_nejA44.js.map +1 -0
  215. package/dist/{paired-promotion-decision-DPKz8ZnF.d.ts → paired-promotion-decision-CQMJ5xGN.d.ts} +2 -34
  216. package/dist/paired-promotion-decision-CQMJ5xGN.d.ts.map +1 -0
  217. package/dist/{paired-promotion-decision-DsAPYGCm.js → paired-promotion-decision-D0SHb-ZL.js} +3 -3
  218. package/dist/{paired-promotion-decision-DsAPYGCm.js.map → paired-promotion-decision-D0SHb-ZL.js.map} +1 -1
  219. package/dist/{pareto-Cm6ndrWN.js → pareto-CTv8vozZ.js} +11 -11
  220. package/dist/pareto-CTv8vozZ.js.map +1 -0
  221. package/dist/pipelines/index.d.ts +16 -19
  222. package/dist/pipelines/index.d.ts.map +1 -1
  223. package/dist/pipelines/index.js +4 -68
  224. package/dist/pipelines/index.js.map +1 -1
  225. package/dist/{power-and-mde-Hj2ubb4B.js → power-and-mde-N5nU4_Ly.js} +3 -3
  226. package/dist/{power-and-mde-Hj2ubb4B.js.map → power-and-mde-N5nU4_Ly.js.map} +1 -1
  227. package/dist/{prime-protocol-CHKgA3a6.js → prime-protocol-BFgGrEMP.js} +3 -3
  228. package/dist/prime-protocol-BFgGrEMP.js.map +1 -0
  229. package/dist/{prime-protocol-HiB9HX7E.d.ts → prime-protocol-BWG2DQIk.d.ts} +3 -21
  230. package/dist/prime-protocol-BWG2DQIk.d.ts.map +1 -0
  231. package/dist/profile-cell.d.ts +2 -2
  232. package/dist/profile-cell.js +2 -2
  233. package/dist/{promotion-gate-BawrdPYr.d.ts → promotion-gate-CxEHRsZW.d.ts} +7 -8
  234. package/dist/{promotion-gate-BawrdPYr.d.ts.map → promotion-gate-CxEHRsZW.d.ts.map} +1 -1
  235. package/dist/{promotion-policy-KO57gbyV.js → promotion-policy-6A8osGr_.js} +4 -4
  236. package/dist/{promotion-policy-KO57gbyV.js.map → promotion-policy-6A8osGr_.js.map} +1 -1
  237. package/dist/{proposal-findings-CY1xKn_a.js → proposal-findings-n-5WBbEx.js} +3 -3
  238. package/dist/proposal-findings-n-5WBbEx.js.map +1 -0
  239. package/dist/{query-BUCZCK7F.js → query-B_RZ36an.js} +5 -5
  240. package/dist/query-B_RZ36an.js.map +1 -0
  241. package/dist/{query-DK1nWcmp.d.ts → query-Cmv_U8vf.d.ts} +4 -24
  242. package/dist/{query-DK1nWcmp.d.ts.map → query-Cmv_U8vf.d.ts.map} +1 -1
  243. package/dist/{random-ByUSnV9w.js → random-DDDcC7YU.js} +2 -2
  244. package/dist/{random-ByUSnV9w.js.map → random-DDDcC7YU.js.map} +1 -1
  245. package/dist/{raw-provider-sink-DoHz4JNG.js → raw-provider-sink-75w4FWBj.js} +2 -2
  246. package/dist/{raw-provider-sink-DoHz4JNG.js.map → raw-provider-sink-75w4FWBj.js.map} +1 -1
  247. package/dist/{redact-mtCCcT8z.d.ts → redact-DXdlFb_U.d.ts} +2 -3
  248. package/dist/redact-DXdlFb_U.d.ts.map +1 -0
  249. package/dist/{redact-B5xXKqQ3.js → redact-mtkTiJVk.js} +2 -7
  250. package/dist/{redact-B5xXKqQ3.js.map → redact-mtkTiJVk.js.map} +1 -1
  251. package/dist/{registry-D7_hm2fK.d.ts → registry-ssNoHzwD.d.ts} +4 -4
  252. package/dist/{registry-D7_hm2fK.d.ts.map → registry-ssNoHzwD.d.ts.map} +1 -1
  253. package/dist/{release-confidence-CpuP65S5.js → release-confidence-CYIFH-fp.js} +6 -11
  254. package/dist/release-confidence-CYIFH-fp.js.map +1 -0
  255. package/dist/{report-command-SC9nqb4M.js → render-Cs34y0iX.js} +625 -587
  256. package/dist/render-Cs34y0iX.js.map +1 -0
  257. package/dist/reporting.d.ts +6 -6
  258. package/dist/reporting.js +8 -8
  259. package/dist/{researcher-CEcfku-T.d.ts → researcher-GU1tV4dn.d.ts} +9 -9
  260. package/dist/{researcher-CEcfku-T.d.ts.map → researcher-GU1tV4dn.d.ts.map} +1 -1
  261. package/dist/{reward-CpCmAM8L.d.ts → reward-DrZ71vnf.d.ts} +3 -26
  262. package/dist/reward-DrZ71vnf.d.ts.map +1 -0
  263. package/dist/{reward-hacking-E0d-WVcP.js → reward-hacking-ByuETaIb.js} +3 -3
  264. package/dist/{reward-hacking-E0d-WVcP.js.map → reward-hacking-ByuETaIb.js.map} +1 -1
  265. package/dist/{reward-hacking-RVdZ6Kkt.d.ts → reward-hacking-E52wq86n.d.ts} +5 -18
  266. package/dist/reward-hacking-E52wq86n.d.ts.map +1 -0
  267. package/dist/reward-nw2xZGZG.js.map +1 -1
  268. package/dist/rl.d.ts +117 -295
  269. package/dist/rl.d.ts.map +1 -1
  270. package/dist/rl.js +27 -747
  271. package/dist/rl.js.map +1 -1
  272. package/dist/rollout/index.d.ts +5 -5
  273. package/dist/rollout/index.js +7 -8
  274. package/dist/{rollout-DZV1t2Wg.js → rollout-Dd1ucT_M.js} +88 -13
  275. package/dist/rollout-Dd1ucT_M.js.map +1 -0
  276. package/dist/{rubric-predictive-validity-DaFW70y9.js → rubric-predictive-validity-D3_oI72N.js} +3 -3
  277. package/dist/{rubric-predictive-validity-DaFW70y9.js.map → rubric-predictive-validity-D3_oI72N.js.map} +1 -1
  278. package/dist/{rubric-predictive-validity-C03EC7ZE.d.ts → rubric-predictive-validity-DiwT8PbL.d.ts} +2 -2
  279. package/dist/{rubric-predictive-validity-C03EC7ZE.d.ts.map → rubric-predictive-validity-DiwT8PbL.d.ts.map} +1 -1
  280. package/dist/{run-record-C1E24G2A.d.ts → run-record-CaxbLq6Y.d.ts} +4 -10
  281. package/dist/run-record-CaxbLq6Y.d.ts.map +1 -0
  282. package/dist/{run-record-C5e7FjhJ.js → run-record-CysKLB93.js} +3 -3
  283. package/dist/run-record-CysKLB93.js.map +1 -0
  284. package/dist/{run-record-Boc5IUTp.js → run-record-DhEJgoPz.js} +4 -4
  285. package/dist/{run-record-Boc5IUTp.js.map → run-record-DhEJgoPz.js.map} +1 -1
  286. package/dist/sandbox-harness-BlSOu4LX.d.ts.map +1 -1
  287. package/dist/{schema-CSf6qWgZ.js → schema-Bt2vLFm3.js} +2 -14
  288. package/dist/schema-Bt2vLFm3.js.map +1 -0
  289. package/dist/schema-C-ziyJD7.d.ts.map +1 -1
  290. package/dist/{schema-BuiujZ-g.js → schema-CvhfLjtZ.js} +78 -48
  291. package/dist/schema-CvhfLjtZ.js.map +1 -0
  292. package/dist/{schema-2g7trUwH.d.ts → schema-D6EVKzTB.d.ts} +4 -5
  293. package/dist/schema-D6EVKzTB.d.ts.map +1 -0
  294. package/dist/search/index.d.ts +3 -31
  295. package/dist/search/index.d.ts.map +1 -1
  296. package/dist/search/index.js +4 -4
  297. package/dist/{search-kernel-DyNEa6IU.d.ts → search-kernel-p9JB3SmL.d.ts} +10 -27
  298. package/dist/search-kernel-p9JB3SmL.d.ts.map +1 -0
  299. package/dist/{search-ledger-CVUGLDZp.js → search-ledger-ClpN4I3e.js} +7 -7
  300. package/dist/{search-ledger-CVUGLDZp.js.map → search-ledger-ClpN4I3e.js.map} +1 -1
  301. package/dist/{search-ledger-file-DDQUgvCg.js → search-ledger-file-Bd5Tioq6.js} +4 -4
  302. package/dist/search-ledger-file-Bd5Tioq6.js.map +1 -0
  303. package/dist/{search-shipper-BOSD46qv.js → search-shipper-Bg2HW3Uv.js} +4 -4
  304. package/dist/search-shipper-Bg2HW3Uv.js.map +1 -0
  305. package/dist/{search-summary-BQCSWf1g.js → search-summary-CrBuvVnf.js} +5 -5
  306. package/dist/{search-summary-BQCSWf1g.js.map → search-summary-CrBuvVnf.js.map} +1 -1
  307. package/dist/{sequential-CzK5DarL.js → sequential-BVv1sjsw.js} +2 -32
  308. package/dist/{sequential-CzK5DarL.js.map → sequential-BVv1sjsw.js.map} +1 -1
  309. package/dist/{sequential-Bf_pbE50.js → sequential-CimQrbjv.js} +5 -5
  310. package/dist/sequential-CimQrbjv.js.map +1 -0
  311. package/dist/{sequential-BhsrMupG.d.ts → sequential-KwGspfeR.d.ts} +2 -9
  312. package/dist/{sequential-BhsrMupG.d.ts.map → sequential-KwGspfeR.d.ts.map} +1 -1
  313. package/dist/{sequential-eprocess-DM_qENCl.js → sequential-eprocess-DodI6RoF.js} +2 -2
  314. package/dist/{sequential-eprocess-DM_qENCl.js.map → sequential-eprocess-DodI6RoF.js.map} +1 -1
  315. package/dist/{server-e9oWO_bN.js → server-C6M0qR8h.js} +101 -101
  316. package/dist/server-C6M0qR8h.js.map +1 -0
  317. package/dist/{single-run-lock-CV9Eyd_q.js → single-run-lock-Dekd8_Wv.js} +7 -7
  318. package/dist/single-run-lock-Dekd8_Wv.js.map +1 -0
  319. package/dist/{skillopt-optimization-method-BiwA8nfX.js → skillopt-optimization-method-5dlex7MJ.js} +1386 -1184
  320. package/dist/skillopt-optimization-method-5dlex7MJ.js.map +1 -0
  321. package/dist/{spans-BHAUXMGN.d.ts → spans-CVngGij3.d.ts} +2 -2
  322. package/dist/{spans-BHAUXMGN.d.ts.map → spans-CVngGij3.d.ts.map} +1 -1
  323. package/dist/{statistical-heldout-CYpGaoDH.d.ts → statistical-heldout-BHfLZHrm.d.ts} +8 -67
  324. package/dist/statistical-heldout-BHfLZHrm.d.ts.map +1 -0
  325. package/dist/{statistical-heldout-42NlCNDe.js → statistical-heldout-Bksv92Th.js} +3 -3
  326. package/dist/statistical-heldout-Bksv92Th.js.map +1 -0
  327. package/dist/{steps-Bg5-KVx1.d.ts → steps-DlepJPwD.d.ts} +2 -56
  328. package/dist/steps-DlepJPwD.d.ts.map +1 -0
  329. package/dist/{store-C4avFjIi.d.ts → store-B3nWRy3B.d.ts} +2 -2
  330. package/dist/{store-C4avFjIi.d.ts.map → store-B3nWRy3B.d.ts.map} +1 -1
  331. package/dist/{store-otlp-DJ9dtA5x.js → store-otlp-BteDAbHK.js} +3 -3
  332. package/dist/{store-otlp-DJ9dtA5x.js.map → store-otlp-BteDAbHK.js.map} +1 -1
  333. package/dist/{store-tool-spans-CIX5arAG.js → store-tool-spans-D5l_OfTJ.js} +8 -8
  334. package/dist/store-tool-spans-D5l_OfTJ.js.map +1 -0
  335. package/dist/{store-tool-spans-DdCSPa7C.d.ts → store-tool-spans-DZS0HWVf.d.ts} +9 -18
  336. package/dist/store-tool-spans-DZS0HWVf.d.ts.map +1 -0
  337. package/dist/storyboard/index.d.ts +4 -11
  338. package/dist/storyboard/index.d.ts.map +1 -1
  339. package/dist/storyboard/index.js +1 -16
  340. package/dist/storyboard/index.js.map +1 -1
  341. package/dist/{summary-report-V_JACR4Y.js → summary-report-BsXJoYX5.js} +88 -10
  342. package/dist/summary-report-BsXJoYX5.js.map +1 -0
  343. package/dist/{summary-report-bdFDXq0b.d.ts → summary-report-CkbRcSuu.d.ts} +25 -19
  344. package/dist/summary-report-CkbRcSuu.d.ts.map +1 -0
  345. package/dist/supervisor-run/index.d.ts +60 -28
  346. package/dist/supervisor-run/index.d.ts.map +1 -1
  347. package/dist/supervisor-run/index.js +4 -458
  348. package/dist/supervisor-run/index.js.map +1 -1
  349. package/dist/{systemone-BomhHr2c.d.ts → systemone-BMzDJb1i.d.ts} +5 -5
  350. package/dist/{systemone-BomhHr2c.d.ts.map → systemone-BMzDJb1i.d.ts.map} +1 -1
  351. package/dist/systemone-protocol.js +1 -1
  352. package/dist/{systemone-review-CUVcQJu6.d.ts → systemone-review-CwE6JGIp.d.ts} +2 -2
  353. package/dist/{systemone-review-CUVcQJu6.d.ts.map → systemone-review-CwE6JGIp.d.ts.map} +1 -1
  354. package/dist/{systemone-review-D7sXwsqq.js → systemone-review-DzdOJ8I6.js} +3 -3
  355. package/dist/{systemone-review-D7sXwsqq.js.map → systemone-review-DzdOJ8I6.js.map} +1 -1
  356. package/dist/systemone.d.ts +5 -5
  357. package/dist/systemone.js +5 -5
  358. package/dist/systemone.js.map +1 -1
  359. package/dist/{task-failure-attributes-hEmASjix.js → task-failure-attributes-BMsblaDh.js} +3 -3
  360. package/dist/task-failure-attributes-BMsblaDh.js.map +1 -0
  361. package/dist/{terminal-record-DZyQZ3pz.js → terminal-record-D4Rv-j1W.js} +244 -196
  362. package/dist/terminal-record-D4Rv-j1W.js.map +1 -0
  363. package/dist/{tool-groups-C3NEcdCM.d.ts → tool-groups-DyNz2JZ_.d.ts} +3 -3
  364. package/dist/tool-groups-DyNz2JZ_.d.ts.map +1 -0
  365. package/dist/{tool-waste-BKgvd-TP.d.ts → tool-waste-CkjzWmeY.d.ts} +25 -28
  366. package/dist/tool-waste-CkjzWmeY.d.ts.map +1 -0
  367. package/dist/{tool-waste-BlesqTqW.js → tool-waste-DLsjS_p-.js} +5 -5
  368. package/dist/{tool-waste-BlesqTqW.js.map → tool-waste-DLsjS_p-.js.map} +1 -1
  369. package/dist/{trace-questions-CM2CAocU.d.ts → trace-questions-xxwgsuMi.d.ts} +4 -9
  370. package/dist/{trace-questions-CM2CAocU.d.ts.map → trace-questions-xxwgsuMi.d.ts.map} +1 -1
  371. package/dist/trace-repair/index.d.ts +14 -211
  372. package/dist/trace-repair/index.d.ts.map +1 -1
  373. package/dist/trace-repair/index.js +865 -981
  374. package/dist/trace-repair/index.js.map +1 -1
  375. package/dist/traces.d.ts +18 -46
  376. package/dist/traces.d.ts.map +1 -1
  377. package/dist/traces.js +13 -13
  378. package/dist/traces.js.map +1 -1
  379. package/dist/trajectory-replay/index.d.ts +7 -118
  380. package/dist/trajectory-replay/index.d.ts.map +1 -1
  381. package/dist/trajectory-replay/index.js +921 -869
  382. package/dist/trajectory-replay/index.js.map +1 -1
  383. package/dist/{tree-C1XYeXvy.js → tree-B5e1uAeL.js} +132 -21
  384. package/dist/tree-B5e1uAeL.js.map +1 -0
  385. package/dist/{types-Cbe2fWBa.d.ts → types-BKCzzmit.d.ts} +3 -3
  386. package/dist/{types-Cbe2fWBa.d.ts.map → types-BKCzzmit.d.ts.map} +1 -1
  387. package/dist/{types-B3jzCp0p.js → types-BXgASBCL.js} +2 -2
  388. package/dist/{types-B3jzCp0p.js.map → types-BXgASBCL.js.map} +1 -1
  389. package/dist/{types-C1tnkEgM.d.ts → types-CW8ewATZ.d.ts} +4 -113
  390. package/dist/types-CW8ewATZ.d.ts.map +1 -0
  391. package/dist/{types-BqkVmHfv.d.ts → types-CmXY0PQf.d.ts} +2 -4
  392. package/dist/types-CmXY0PQf.d.ts.map +1 -0
  393. package/dist/{types-C02qtnG8.d.ts → types-D-mgRzlh.d.ts} +7 -28
  394. package/dist/types-D-mgRzlh.d.ts.map +1 -0
  395. package/dist/{types-IXD2HJzu.js → types-DqFMNTgK.js} +2 -4
  396. package/dist/types-DqFMNTgK.js.map +1 -0
  397. package/dist/{types-Cq8mSbq8.d.ts → types-DtkO1G9L.d.ts} +7 -9
  398. package/dist/{types-Cq8mSbq8.d.ts.map → types-DtkO1G9L.d.ts.map} +1 -1
  399. package/dist/{verdict-Dl0tiT1X.js → verdict-BGQmxQ8A.js} +3 -3
  400. package/dist/verdict-BGQmxQ8A.js.map +1 -0
  401. package/dist/{verdict-E4eRNf7-.d.ts → verdict-C24NELtN.d.ts} +2 -15
  402. package/dist/{verdict-E4eRNf7-.d.ts.map → verdict-C24NELtN.d.ts.map} +1 -1
  403. package/dist/{verdict-cache-Bm8EKL2s.js → verdict-cache-CL_7tePD.js} +2 -2
  404. package/dist/verdict-cache-CL_7tePD.js.map +1 -0
  405. package/dist/wire/index.d.ts +31 -410
  406. package/dist/wire/index.d.ts.map +1 -1
  407. package/dist/wire/index.js +2 -2
  408. package/docs/changes/jev-evidence-review.md +1 -1
  409. package/docs/changes/jev-product-adoption.md +1 -1
  410. package/docs/changes/jev-recorded-evidence.md +1 -1
  411. package/docs/design/statistics-decisions.md +18 -18
  412. package/docs/design.md +1 -1
  413. package/docs/eval-surface-map.md +1 -0
  414. package/docs/evaluation-integrity.md +1 -1
  415. package/docs/profile-json-identity.md +1 -2
  416. package/docs/proofs/campaign-attempt-retention-20261001/README.md +2 -2
  417. package/docs/public-api.md +158 -538
  418. package/docs/rollout.md +1 -1
  419. package/docs/trace-repair-admission.md +1 -1
  420. package/docs/wire-protocol.md +1 -1
  421. package/package.json +7 -2
  422. package/dist/active-curriculum-B_Lc9kfO.js +0 -61
  423. package/dist/active-curriculum-B_Lc9kfO.js.map +0 -1
  424. package/dist/agent-profile-VFcQncbW.d.ts.map +0 -1
  425. package/dist/agent-profile-cell-BK8mlqlq.js.map +0 -1
  426. package/dist/agent-profile-cell-BNp-Js9F.d.ts.map +0 -1
  427. package/dist/agreement-irr-BEWLIF3_.js.map +0 -1
  428. package/dist/analyze-runs-C84irm4i.js.map +0 -1
  429. package/dist/baseline-Udi_PLuT.js +0 -259
  430. package/dist/baseline-Udi_PLuT.js.map +0 -1
  431. package/dist/benchmark-CXmVVHH2.js +0 -562
  432. package/dist/benchmark-CXmVVHH2.js.map +0 -1
  433. package/dist/benchmark-command-By0vh8q7.js.map +0 -1
  434. package/dist/campaign-BudZ70zo.js.map +0 -1
  435. package/dist/chat-json-call-puMArmtW.js.map +0 -1
  436. package/dist/claude-jsonl-dZir12m6.js +0 -86
  437. package/dist/claude-jsonl-dZir12m6.js.map +0 -1
  438. package/dist/client-BzL9niqi.d.ts.map +0 -1
  439. package/dist/cost-ledger-BP8V4kUQ.js.map +0 -1
  440. package/dist/counterfactual-CPaWN99-.d.ts +0 -60
  441. package/dist/counterfactual-CPaWN99-.d.ts.map +0 -1
  442. package/dist/counterfactual-Dn3veueY.js +0 -98
  443. package/dist/counterfactual-Dn3veueY.js.map +0 -1
  444. package/dist/default-registry-COhk9g36.js.map +0 -1
  445. package/dist/default-registry-DzHiGruW.d.ts.map +0 -1
  446. package/dist/define-agent-eval-CNTPzIkp.js.map +0 -1
  447. package/dist/define-agent-eval-WSck0CZJ.d.ts.map +0 -1
  448. package/dist/dspy-rlm-engine-LRCu61m5.js.map +0 -1
  449. package/dist/effect-sizes-BhzEpXMc.js +0 -82
  450. package/dist/effect-sizes-BhzEpXMc.js.map +0 -1
  451. package/dist/emitter-HcCmFQl_.d.ts.map +0 -1
  452. package/dist/engine-3A_4jOlI.d.ts.map +0 -1
  453. package/dist/equal-terms-BtdXayCJ.js.map +0 -1
  454. package/dist/eval-campaign-90jeaCAI.js +0 -343
  455. package/dist/eval-campaign-90jeaCAI.js.map +0 -1
  456. package/dist/evaluation-6Yoi74gM.d.ts.map +0 -1
  457. package/dist/exporters-X4xwla8A.js.map +0 -1
  458. package/dist/external-optimizer-process-BjMGUuds.js.map +0 -1
  459. package/dist/external-optimizer-subprocess-BqW0hHcI.js.map +0 -1
  460. package/dist/failure-cluster-CbgEDcFJ.d.ts.map +0 -1
  461. package/dist/feedback-trajectory-C4EG0nNH.d.ts.map +0 -1
  462. package/dist/hf-dataset-BR2yhuNn.js.map +0 -1
  463. package/dist/index-BFRO6chs.d.ts.map +0 -1
  464. package/dist/index-BO41eGj5.d.ts.map +0 -1
  465. package/dist/index-CyszSg4O.d.ts.map +0 -1
  466. package/dist/index-DHKEAv3s.d.ts.map +0 -1
  467. package/dist/index-DPcngtwt.d.ts.map +0 -1
  468. package/dist/integrity-dLiDe2kD.js.map +0 -1
  469. package/dist/journal-DfRz9kps.js.map +0 -1
  470. package/dist/judge-gate-CE7CQAgt.d.ts.map +0 -1
  471. package/dist/kind-factory-BobI5Jy3.js.map +0 -1
  472. package/dist/ledger-core-Gq7yp8lP.js.map +0 -1
  473. package/dist/llm-client-CyBAoYiX.js.map +0 -1
  474. package/dist/llm-judge-CG12SQJq.js.map +0 -1
  475. package/dist/matrix-DSrSxjjy.d.ts.map +0 -1
  476. package/dist/matrix-Dm0BQW7U.js.map +0 -1
  477. package/dist/mean-DHoMiudD.js.map +0 -1
  478. package/dist/normal-DsJZtrJc.js +0 -25
  479. package/dist/normal-DsJZtrJc.js.map +0 -1
  480. package/dist/paired-arms-CwMGJsrS.js.map +0 -1
  481. package/dist/paired-binary-CvpFHfKZ.js.map +0 -1
  482. package/dist/paired-promotion-decision-DPKz8ZnF.d.ts.map +0 -1
  483. package/dist/pareto-Cm6ndrWN.js.map +0 -1
  484. package/dist/prime-protocol-CHKgA3a6.js.map +0 -1
  485. package/dist/prime-protocol-HiB9HX7E.d.ts.map +0 -1
  486. package/dist/produced-state-BsDmnwxc.js.map +0 -1
  487. package/dist/proposal-findings-CY1xKn_a.js.map +0 -1
  488. package/dist/query-BUCZCK7F.js.map +0 -1
  489. package/dist/redact-mtCCcT8z.d.ts.map +0 -1
  490. package/dist/release-confidence-CpuP65S5.js.map +0 -1
  491. package/dist/report-command-SC9nqb4M.js.map +0 -1
  492. package/dist/reward-CpCmAM8L.d.ts.map +0 -1
  493. package/dist/reward-hacking-RVdZ6Kkt.d.ts.map +0 -1
  494. package/dist/rollout-DZV1t2Wg.js.map +0 -1
  495. package/dist/run-record-C1E24G2A.d.ts.map +0 -1
  496. package/dist/run-record-C5e7FjhJ.js.map +0 -1
  497. package/dist/schema-2g7trUwH.d.ts.map +0 -1
  498. package/dist/schema-BuiujZ-g.js.map +0 -1
  499. package/dist/schema-CSf6qWgZ.js.map +0 -1
  500. package/dist/search-kernel-DyNEa6IU.d.ts.map +0 -1
  501. package/dist/search-ledger-file-DDQUgvCg.js.map +0 -1
  502. package/dist/search-shipper-BOSD46qv.js.map +0 -1
  503. package/dist/semantic-concept-judge-BQF8te0T.js.map +0 -1
  504. package/dist/sequential-Bf_pbE50.js.map +0 -1
  505. package/dist/server-e9oWO_bN.js.map +0 -1
  506. package/dist/single-run-lock-CV9Eyd_q.js.map +0 -1
  507. package/dist/skillopt-optimization-method-BiwA8nfX.js.map +0 -1
  508. package/dist/statistical-heldout-42NlCNDe.js.map +0 -1
  509. package/dist/statistical-heldout-CYpGaoDH.d.ts.map +0 -1
  510. package/dist/steps-Bg5-KVx1.d.ts.map +0 -1
  511. package/dist/store-tool-spans-CIX5arAG.js.map +0 -1
  512. package/dist/store-tool-spans-DdCSPa7C.d.ts.map +0 -1
  513. package/dist/student-t-DVPW7CdL.js +0 -39
  514. package/dist/student-t-DVPW7CdL.js.map +0 -1
  515. package/dist/summary-report-V_JACR4Y.js.map +0 -1
  516. package/dist/summary-report-bdFDXq0b.d.ts.map +0 -1
  517. package/dist/task-failure-attributes-hEmASjix.js.map +0 -1
  518. package/dist/terminal-record-DZyQZ3pz.js.map +0 -1
  519. package/dist/tool-groups-C3NEcdCM.d.ts.map +0 -1
  520. package/dist/tool-waste-BKgvd-TP.d.ts.map +0 -1
  521. package/dist/trajectory-Y1fmdlw7.d.ts +0 -24
  522. package/dist/trajectory-Y1fmdlw7.d.ts.map +0 -1
  523. package/dist/tree-C1XYeXvy.js.map +0 -1
  524. package/dist/types-BqkVmHfv.d.ts.map +0 -1
  525. package/dist/types-C02qtnG8.d.ts.map +0 -1
  526. package/dist/types-C1tnkEgM.d.ts.map +0 -1
  527. package/dist/types-IXD2HJzu.js.map +0 -1
  528. package/dist/usage-receipt-Cx3xNeyB.js +0 -76
  529. package/dist/usage-receipt-Cx3xNeyB.js.map +0 -1
  530. package/dist/verdict-Dl0tiT1X.js.map +0 -1
  531. package/dist/verdict-cache-Bm8EKL2s.js.map +0 -1
  532. package/docs/design/self-improvement-evidence-audit.md +0 -263
@@ -1 +1 @@
1
- {"version":3,"file":"promotion-policy-KO57gbyV.js","names":[],"sources":["../src/campaign/gates/promotion-policy.ts"],"sourcesContent":["/**\n * Build paired evidence for each objective and apply a promotion policy.\n * The default policy requires at least one gain and every regression floor to\n * clear. A floor can fail because a larger loss remains plausible; that does\n * not demonstrate an observed regression. Missing evidence stays unresolved.\n * Confidence intervals apply to each axis, without a multiplicity adjustment.\n *\n * Cost and latency remain aggregate constraints because GateContext does not\n * supply paired observations for them. Compose a budget gate when needed.\n */\n\nimport {\n decidePairedPromotion,\n type PairedDecisionMethod,\n type PairedDecisionStatistic,\n type PairedMcNemarEvidence,\n} from '../../paired-promotion-decision'\nimport type { Direction } from '../../pareto'\nimport {\n DECISION_PAIRED_DELTA_STATISTIC,\n type PairedBootstrapResult,\n pairedBootstrap,\n} from '../../statistics'\nimport type { Gate, GateContext, GateDecision, GateResult, JudgeScore, Scenario } from '../types'\nimport { detectScale, pairHoldout } from './statistical-heldout'\n\n/** Where an objective's per-cell scalar comes from. `composite` reads the\n * judge's composite; `dimension` reads a named per-dimension score. */\nexport type ObjectiveSource = { kind: 'composite' } | { kind: 'dimension'; dimension: string }\n\nexport interface PromotionObjective {\n /** Stable label used in reports + `contributingGates`. */\n name: string\n source: ObjectiveSource\n /** 'maximize' (quality dims) or 'minimize' (error/risk/length dims). Orients\n * the paired delta so a positive bootstrap always means \"candidate better\". */\n direction: Direction\n /** Declared binary support {0, binaryScale}, including zero-only observations.\n * Must be finite and positive; paired cell scores must be 0 or this scale.\n * Uses the risk-difference mean and rejects the 'median' statistic. */\n binaryScale?: number\n /** The good-direction paired-delta CI lower bound must EXCEED this to count\n * as a significant gain on this axis. Interpreted in the judge's native\n * scale. Default 0 (⇒ \"confidently better\"). */\n gainThreshold?: number\n /** A floor breach (regression) is declared when the good-direction CI lower\n * bound is below −floorTolerance, or when the exact small-sample test proves\n * a drop past it. Defaults to 0.05 times the declared binary scale, or\n * auto-scales off observed magnitudes (0.05 on [0,1], 5 on 0-100). */\n floorTolerance?: number\n}\n\n/** Per-axis verdict from the shared paired decision rule.\n * 'regressed' includes uncertainty that prevents clearing the regression floor. */\nexport type AxisVerdict = 'improved' | 'regressed' | 'flat' | 'few_runs' | 'indeterminate'\n\nexport interface AxisEvidence {\n name: string\n source: ObjectiveSource\n direction: Direction\n /** Paired bootstrap on the GOOD-DIRECTION delta (oriented by `direction`):\n * a positive value means the candidate is better on this axis.\n *\n * DIAGNOSTIC on a pass/fail axis: there the verdict is decided on Tango's\n * score interval instead, because a percentile bootstrap over a three-atom\n * delta lattice is not a valid interval at the nonzero margin `floorTolerance`\n * and `gainThreshold` create. `ci` carries the interval that decided. */\n bootstrap: PairedBootstrapResult\n /** Which paired statistic `bootstrap.low`/`.high` bracket. `'mean'` unless the\n * caller asked for the median — on a pass/fail axis the median and its whole\n * CI are pinned at 0 by tie domination and can see neither a gain nor a\n * regression. `bootstrap.median` still carries the median point estimate. */\n bootstrapStatistic: 'median' | 'mean'\n /** The interval the axis verdict was actually decided on, good-direction and\n * in the axis's native units. */\n ci: { low: number; high: number }\n /** Which estimator produced `ci`. */\n decisionStatistic: PairedDecisionStatistic\n /** McNemar's exact evidence on a pass/fail axis; null otherwise. */\n mcnemar: PairedMcNemarEvidence | null\n /** `ci` has zero width or non-finite bounds. It cannot establish a gain or\n * clear a regression floor, regardless of the point estimate. */\n indeterminate: boolean\n /** Paired observations contributing to this axis. */\n n: number\n minimumRequired: number\n decisionMethod: PairedDecisionMethod\n gainThreshold: number\n floorTolerance: number\n verdict: AxisVerdict\n}\n\nexport interface EvidenceVector {\n /** One entry per objective — NOTHING averaged across axes. */\n axes: AxisEvidence[]\n /** Smallest paired n across axes that produced observations — the binding\n * evidence-sufficiency constraint. 0 when no axis produced observations. */\n minN: number\n /** Aggregate per-side cost from the gate context (a constraint input, not a\n * CI axis — see the module header). */\n cost: { candidate: number; baseline: number }\n}\n\n/** A promotion strategy: a pure function from the evidence vector to a verdict.\n * Many policies can run over the same `EvidenceVector` and disagree — that's\n * the point (competing strategies, shared evidence). */\nexport type PromotionPolicy = (ev: EvidenceVector) => GateResult\n\nexport interface BuildEvidenceVectorOptions {\n /** Minimum paired observations before an axis can claim significance; below\n * it the axis is `few_runs`. The exact small-sample test may require more\n * observations at the selected confidence. */\n minProductiveRuns?: number\n /** Confidence level for every axis bootstrap. Default 0.95. */\n confidence?: number\n /** Bootstrap resamples. Default 2000. */\n resamples?: number\n /** Fixed bootstrap seed for a deterministic, reproducible verdict. Default 1337. */\n seed?: number\n /** Paired statistic every axis CI is computed on. Default `'mean'` — see\n * {@link DECISION_PAIRED_DELTA_STATISTIC} for why the median is not. */\n statistic?: 'mean' | 'median'\n}\n\n/**\n * The Evidence Bus. For each objective, pair candidate vs baseline by full\n * cellId and bootstrap a CI on the good-direction paired delta. Reuses the\n * exact `pairHoldout` + `pairedBootstrap` machinery the held-out gate uses, so\n * a single source of truth governs pairing granularity + scale handling.\n */\nexport function buildEvidenceVector<TArtifact, TScenario extends Scenario>(\n ctx: GateContext<TArtifact, TScenario>,\n objectives: PromotionObjective[],\n opts: BuildEvidenceVectorOptions = {},\n): EvidenceVector {\n if (objectives.length === 0) {\n throw new Error('buildEvidenceVector: at least 1 objective required')\n }\n const confidence = opts.confidence ?? 0.95\n const resamples = opts.resamples ?? 2000\n const seed = opts.seed ?? 1337\n const baseline = ctx.baselineJudgeScores ?? ctx.judgeScores\n const scenarioIds = new Set(ctx.scenarios.map((s) => s.id))\n\n const axes: AxisEvidence[] = []\n for (const obj of objectives) {\n let select: (s: JudgeScore) => number | undefined\n if (obj.source.kind === 'composite') {\n select = (s) => s.composite\n } else {\n const dim = obj.source.dimension\n select = (s) => s.dimensions[dim]\n }\n const paired = pairHoldout(ctx.judgeScores, baseline, scenarioIds, select)\n // Orient to the good direction: maximize ⇒ bootstrap (candidate − baseline);\n // minimize ⇒ bootstrap (baseline − candidate) by swapping args, so a\n // positive bootstrap always reads as \"candidate better on this axis\".\n const before = obj.direction === 'maximize' ? paired.before : paired.after\n const after = obj.direction === 'maximize' ? paired.after : paired.before\n const n = paired.before.length\n const binaryScale = obj.binaryScale\n const floorTolerance =\n obj.floorTolerance ?? 0.05 * (binaryScale ?? detectScale([...paired.before, ...paired.after]))\n const gainThreshold = obj.gainThreshold ?? 0\n // Axes are decided on the MEAN paired delta — which for a pass/fail axis is\n // exactly the change in success rate. The median is structurally blind on\n // the shapes eval data lands in: with most pairs tied its bootstrap CI\n // collapses to [0,0] and the axis reads 'flat', hiding real gains AND real\n // regressions — pass/fail axes on ANY encoding ({0,1} and the 0-100 one\n // `detectScale` exists for), and low-cardinality axes even below half ties.\n // Orthogonal to `pairedDeltaTest`'s own small-sample switch: that picks the\n // TEST (bootstrap CI at n ≥ 20, exact sign test below), this picks the\n // ESTIMATOR the test is applied to. Both are needed — an exact sign test on\n // a tie-pinned median is still blind.\n const bootstrapStatistic = opts.statistic ?? DECISION_PAIRED_DELTA_STATISTIC\n // Both burdens of proof route through the ONE shared rule\n // (`decidePairedPromotion`), so a pass/fail axis is judged on Tango's score\n // interval — the only paired-binary construction valid at the nonzero\n // margins `gainThreshold` / `floorTolerance` create — and a zero-width\n // interval cannot buy a verdict in either direction.\n const improvement = decidePairedPromotion(before, after, {\n confidence,\n resamples,\n statistic: bootstrapStatistic,\n seed,\n threshold: gainThreshold,\n minPairs: opts.minProductiveRuns,\n binaryScale,\n })\n const regression = decidePairedPromotion(after, before, {\n confidence,\n resamples,\n statistic: bootstrapStatistic,\n seed,\n threshold: floorTolerance,\n minPairs: opts.minProductiveRuns,\n binaryScale,\n })\n const bootstrap =\n improvement.bootstrap ??\n pairedBootstrap(before, after, {\n confidence,\n resamples,\n statistic: bootstrapStatistic,\n seed,\n })\n // A floor breach fires on EITHER burden of proof, because they cover\n // different failures and the floor is the anti-Goodhart guard:\n // - `improvement.low < -floorTolerance` — the CREDIBLE WORST CASE exceeds\n // the tolerance. This is the contract `AxisEvidence.floorTolerance` and\n // `paretoPolicy`'s own reason string state, and it is the conservative\n // posture a safety axis needs: block unless the data can rule the\n // breach out, rather than waiting for the breach to be proven. Read off\n // the DECIDING interval, so a pass/fail axis is not screened by a\n // bootstrap that is pinned wherever ties dominate.\n // - `regression.promote` — a PROVEN drop past the tolerance. Adds the\n // small-sample path, where the decision is an exact sign test because\n // the bootstrap interval is descriptive only.\n // A tied binary axis still has uncertainty about unseen discordant pairs.\n // Its diagnostic bootstrap collapses to zero, so only the deciding score\n // interval can establish that a regression stays within the declared floor.\n const floorBreached = improvement.low < -floorTolerance || regression.promote\n // Floor check precedes the gain check: a credible regression must never be\n // masked as \"improved\". With the defaults (gainThreshold 0, positive floor)\n // the regions are disjoint and order is moot, but a consumer who sets a\n // negative gainThreshold (\"accept small dips\") could otherwise have a real\n // floor breach classified as a gain — anti-Goodhart wins the tie.\n const verdict: AxisVerdict = !improvement.sufficient\n ? 'few_runs'\n : improvement.indeterminate\n ? 'indeterminate'\n : floorBreached\n ? 'regressed'\n : improvement.promote\n ? 'improved'\n : 'flat'\n axes.push({\n name: obj.name,\n source: obj.source,\n direction: obj.direction,\n bootstrap,\n bootstrapStatistic,\n ci: { low: improvement.low, high: improvement.high },\n decisionStatistic: improvement.statistic,\n mcnemar: improvement.mcnemar,\n indeterminate: improvement.indeterminate,\n n,\n minimumRequired: improvement.minimumPairs,\n decisionMethod: improvement.method,\n gainThreshold,\n floorTolerance,\n verdict,\n })\n }\n const ns = axes.map((a) => a.n).filter((n) => n > 0)\n const minN = ns.length > 0 ? Math.min(...ns) : 0\n return { axes, minN, cost: { candidate: ctx.cost.candidate, baseline: ctx.cost.baseline } }\n}\n\n/**\n * Require a supported gain and every configured regression floor to clear.\n * A failed floor holds the candidate, including when uncertainty permits a loss.\n * Missing or indeterminate evidence requires more work; no gain holds release.\n */\nexport const paretoPolicy: PromotionPolicy = (ev) => {\n const contributingGates = ev.axes.map((ax) => ({\n name: `objective:${ax.name}`,\n status:\n ax.verdict === 'regressed'\n ? ('fail' as const)\n : ax.verdict === 'few_runs' || ax.verdict === 'indeterminate'\n ? ('not_evaluated' as const)\n : ('pass' as const),\n detail: {\n direction: ax.direction,\n source: ax.source,\n verdict: ax.verdict,\n n: ax.n,\n deltaMedian: ax.bootstrap.median,\n ciLow: ax.ci.low,\n ciHigh: ax.ci.high,\n decisionStatistic: ax.decisionStatistic,\n decisionMethod: ax.decisionMethod,\n mcnemar: ax.mcnemar,\n indeterminate: ax.indeterminate,\n bootstrapCiLow: ax.bootstrap.low,\n bootstrapCiHigh: ax.bootstrap.high,\n confidence: ax.bootstrap.confidence,\n gainThreshold: ax.gainThreshold,\n floorTolerance: ax.floorTolerance,\n },\n }))\n\n const regressed = ev.axes.filter((a) => a.verdict === 'regressed')\n const insufficient = ev.axes.filter(\n (a) => a.verdict === 'few_runs' || a.verdict === 'indeterminate',\n )\n const improved = ev.axes.filter((a) => a.verdict === 'improved')\n\n let decision: GateDecision\n const reasons: string[] = []\n if (regressed.length > 0) {\n // A gain on another axis cannot excuse an unresolved regression floor.\n decision = 'hold'\n for (const a of regressed) {\n reasons.push(\n `objective '${a.name}' did not clear its regression floor -${a.floorTolerance}: good-direction CI [${a.ci.low.toFixed(3)}, ${a.ci.high.toFixed(3)}] (n=${a.n})`,\n )\n }\n } else if (insufficient.length > 0) {\n // An unresolved axis cannot establish either a gain or a safe floor.\n decision = 'need_more_work'\n for (const a of insufficient) {\n reasons.push(\n a.verdict === 'few_runs'\n ? `objective '${a.name}' has only n=${a.n} paired runs — insufficient evidence to claim significance`\n : `objective '${a.name}' has an indeterminate deciding CI [${a.ci.low}, ${a.ci.high}] — insufficient evidence to clear its regression floor (n=${a.n})`,\n )\n }\n } else if (improved.length > 0) {\n decision = 'ship'\n reasons.push(\n `Supported objective gain: ${improved\n .map(\n (a) =>\n `'${a.name}' +${a.ci.low > 0 ? a.ci.low.toFixed(3) : a.bootstrap.mean.toFixed(3)} (CI.low ${a.ci.low.toFixed(3)})`,\n )\n .join(', ')}; every regression floor cleared`,\n )\n } else {\n // Every floor cleared, but no objective demonstrated a significant gain.\n decision = 'hold'\n reasons.push(\n 'no Pareto improvement: no objective shows a significant gain; every regression floor cleared',\n )\n }\n\n // `delta` surfaces the composite axis if present, else the first axis — a\n // single convenience scalar; the vector lives in `contributingGates`.\n const composite = ev.axes.find((a) => a.source.kind === 'composite') ?? ev.axes[0]\n return { decision, reasons, contributingGates, delta: composite?.bootstrap.median }\n}\n\nexport interface ParetoSignificanceGateOptions extends BuildEvidenceVectorOptions {\n /** The objective vector. Every axis is both a gain source and a safety floor. */\n objectives: PromotionObjective[]\n /** Strategy applied to the evidence vector. Default `paretoPolicy`. Override\n * to run a stricter/looser strategy over the SAME bus (competing policies). */\n policy?: PromotionPolicy\n /** Override the gate name in reports. */\n name?: string\n}\n\n/**\n * Wrap the bus + a policy as a `Gate`. Plugs into the existing\n * `runImprovementLoop({ gate })` slot and composes via `composeGate`; default\n * loop behavior is unchanged because consumers opt in by passing this gate.\n */\nexport function paretoSignificanceGate<TArtifact = unknown, TScenario extends Scenario = Scenario>(\n options: ParetoSignificanceGateOptions,\n): Gate<TArtifact, TScenario> {\n if (options.objectives.length === 0) {\n throw new Error('paretoSignificanceGate: at least 1 objective required')\n }\n const policy = options.policy ?? paretoPolicy\n return {\n name: options.name ?? 'paretoSignificanceGate',\n async decide(ctx: GateContext<TArtifact, TScenario>): Promise<GateResult> {\n const ev = buildEvidenceVector(ctx, options.objectives, options)\n return policy(ev)\n },\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"promotion-policy-6A8osGr_.js","names":[],"sources":["../src/campaign/gates/promotion-policy.ts"],"sourcesContent":["/**\n * Build paired evidence for each objective and apply a promotion policy.\n * The default policy requires at least one gain and every regression floor to\n * clear. A floor can fail because a larger loss remains plausible; that does\n * not demonstrate an observed regression. Missing evidence stays unresolved.\n * Confidence intervals apply to each axis, without a multiplicity adjustment.\n *\n * Cost and latency remain aggregate constraints because GateContext does not\n * supply paired observations for them. Compose a budget gate when needed.\n */\n\nimport {\n decidePairedPromotion,\n type PairedDecisionMethod,\n type PairedDecisionStatistic,\n type PairedMcNemarEvidence,\n} from '../../paired-promotion-decision'\nimport type { Direction } from '../../pareto'\nimport {\n DECISION_PAIRED_DELTA_STATISTIC,\n type PairedBootstrapResult,\n pairedBootstrap,\n} from '../../statistics'\nimport type { Gate, GateContext, GateDecision, GateResult, JudgeScore, Scenario } from '../types'\nimport { detectScale, pairHoldout } from './statistical-heldout'\n\n/** Where an objective's per-cell scalar comes from. `composite` reads the\n * judge's composite; `dimension` reads a named per-dimension score. */\nexport type ObjectiveSource = { kind: 'composite' } | { kind: 'dimension'; dimension: string }\n\nexport interface PromotionObjective {\n /** Stable label used in reports + `contributingGates`. */\n name: string\n source: ObjectiveSource\n /** 'maximize' (quality dims) or 'minimize' (error/risk/length dims). Orients\n * the paired delta so a positive bootstrap always means \"candidate better\". */\n direction: Direction\n /** Declared binary support {0, binaryScale}, including zero-only observations.\n * Must be finite and positive; paired cell scores must be 0 or this scale.\n * Uses the risk-difference mean and rejects the 'median' statistic. */\n binaryScale?: number\n /** The good-direction paired-delta CI lower bound must EXCEED this to count\n * as a significant gain on this axis. Interpreted in the judge's native\n * scale. Default 0 (⇒ \"confidently better\"). */\n gainThreshold?: number\n /** A floor breach (regression) is declared when the good-direction CI lower\n * bound is below −floorTolerance, or when the exact small-sample test proves\n * a drop past it. Defaults to 0.05 times the declared binary scale, or\n * auto-scales off observed magnitudes (0.05 on [0,1], 5 on 0-100). */\n floorTolerance?: number\n}\n\n/** Per-axis verdict from the shared paired decision rule.\n * 'regressed' includes uncertainty that prevents clearing the regression floor. */\nexport type AxisVerdict = 'improved' | 'regressed' | 'flat' | 'few_runs' | 'indeterminate'\n\nexport interface AxisEvidence {\n name: string\n source: ObjectiveSource\n direction: Direction\n /** Paired bootstrap on the GOOD-DIRECTION delta (oriented by `direction`):\n * a positive value means the candidate is better on this axis.\n *\n * DIAGNOSTIC on a pass/fail axis: there the verdict is decided on Tango's\n * score interval instead, because a percentile bootstrap over a three-atom\n * delta lattice is not a valid interval at the nonzero margin `floorTolerance`\n * and `gainThreshold` create. `ci` carries the interval that decided. */\n bootstrap: PairedBootstrapResult\n /** Which paired statistic `bootstrap.low`/`.high` bracket. `'mean'` unless the\n * caller asked for the median — on a pass/fail axis the median and its whole\n * CI are pinned at 0 by tie domination and can see neither a gain nor a\n * regression. `bootstrap.median` still carries the median point estimate. */\n bootstrapStatistic: 'median' | 'mean'\n /** The interval the axis verdict was actually decided on, good-direction and\n * in the axis's native units. */\n ci: { low: number; high: number }\n /** Which estimator produced `ci`. */\n decisionStatistic: PairedDecisionStatistic\n /** McNemar's exact evidence on a pass/fail axis; null otherwise. */\n mcnemar: PairedMcNemarEvidence | null\n /** `ci` has zero width or non-finite bounds. It cannot establish a gain or\n * clear a regression floor, regardless of the point estimate. */\n indeterminate: boolean\n /** Paired observations contributing to this axis. */\n n: number\n minimumRequired: number\n decisionMethod: PairedDecisionMethod\n gainThreshold: number\n floorTolerance: number\n verdict: AxisVerdict\n}\n\nexport interface EvidenceVector {\n /** One entry per objective — NOTHING averaged across axes. */\n axes: AxisEvidence[]\n /** Smallest paired n across axes that produced observations — the binding\n * evidence-sufficiency constraint. 0 when no axis produced observations. */\n minN: number\n /** Aggregate per-side cost from the gate context (a constraint input, not a\n * CI axis — see the module header). */\n cost: { candidate: number; baseline: number }\n}\n\n/** A promotion strategy: a pure function from the evidence vector to a verdict.\n * Many policies can run over the same `EvidenceVector` and disagree — that's\n * the point (competing strategies, shared evidence). */\nexport type PromotionPolicy = (ev: EvidenceVector) => GateResult\n\nexport interface BuildEvidenceVectorOptions {\n /** Minimum paired observations before an axis can claim significance; below\n * it the axis is `few_runs`. The exact small-sample test may require more\n * observations at the selected confidence. */\n minProductiveRuns?: number\n /** Confidence level for every axis bootstrap. Default 0.95. */\n confidence?: number\n /** Bootstrap resamples. Default 2000. */\n resamples?: number\n /** Fixed bootstrap seed for a deterministic, reproducible verdict. Default 1337. */\n seed?: number\n /** Paired statistic every axis CI is computed on. Default `'mean'` — see\n * {@link DECISION_PAIRED_DELTA_STATISTIC} for why the median is not. */\n statistic?: 'mean' | 'median'\n}\n\n/**\n * The Evidence Bus. For each objective, pair candidate vs baseline by full\n * cellId and bootstrap a CI on the good-direction paired delta. Reuses the\n * exact `pairHoldout` + `pairedBootstrap` machinery the held-out gate uses, so\n * a single source of truth governs pairing granularity + scale handling.\n */\nexport function buildEvidenceVector<TArtifact, TScenario extends Scenario>(\n ctx: GateContext<TArtifact, TScenario>,\n objectives: PromotionObjective[],\n opts: BuildEvidenceVectorOptions = {},\n): EvidenceVector {\n if (objectives.length === 0) {\n throw new Error('buildEvidenceVector: at least 1 objective required')\n }\n const confidence = opts.confidence ?? 0.95\n const resamples = opts.resamples ?? 2000\n const seed = opts.seed ?? 1337\n const baseline = ctx.baselineJudgeScores ?? ctx.judgeScores\n const scenarioIds = new Set(ctx.scenarios.map((s) => s.id))\n\n const axes: AxisEvidence[] = []\n for (const obj of objectives) {\n let select: (s: JudgeScore) => number | undefined\n if (obj.source.kind === 'composite') {\n select = (s) => s.composite\n } else {\n const dim = obj.source.dimension\n select = (s) => s.dimensions[dim]\n }\n const paired = pairHoldout(ctx.judgeScores, baseline, scenarioIds, select)\n // Orient to the good direction: maximize ⇒ bootstrap (candidate − baseline);\n // minimize ⇒ bootstrap (baseline − candidate) by swapping args, so a\n // positive bootstrap always reads as \"candidate better on this axis\".\n const before = obj.direction === 'maximize' ? paired.before : paired.after\n const after = obj.direction === 'maximize' ? paired.after : paired.before\n const n = paired.before.length\n const binaryScale = obj.binaryScale\n const floorTolerance =\n obj.floorTolerance ?? 0.05 * (binaryScale ?? detectScale([...paired.before, ...paired.after]))\n const gainThreshold = obj.gainThreshold ?? 0\n // Axes are decided on the MEAN paired delta — which for a pass/fail axis is\n // exactly the change in success rate. The median is structurally blind on\n // the shapes eval data lands in: with most pairs tied its bootstrap CI\n // collapses to [0,0] and the axis reads 'flat', hiding real gains AND real\n // regressions — pass/fail axes on ANY encoding ({0,1} and the 0-100 one\n // `detectScale` exists for), and low-cardinality axes even below half ties.\n // Orthogonal to `pairedDeltaTest`'s own small-sample switch: that picks the\n // TEST (bootstrap CI at n ≥ 20, exact sign test below), this picks the\n // ESTIMATOR the test is applied to. Both are needed — an exact sign test on\n // a tie-pinned median is still blind.\n const bootstrapStatistic = opts.statistic ?? DECISION_PAIRED_DELTA_STATISTIC\n // Both burdens of proof route through the ONE shared rule\n // (`decidePairedPromotion`), so a pass/fail axis is judged on Tango's score\n // interval — the only paired-binary construction valid at the nonzero\n // margins `gainThreshold` / `floorTolerance` create — and a zero-width\n // interval cannot buy a verdict in either direction.\n const improvement = decidePairedPromotion(before, after, {\n confidence,\n resamples,\n statistic: bootstrapStatistic,\n seed,\n threshold: gainThreshold,\n minPairs: opts.minProductiveRuns,\n binaryScale,\n })\n const regression = decidePairedPromotion(after, before, {\n confidence,\n resamples,\n statistic: bootstrapStatistic,\n seed,\n threshold: floorTolerance,\n minPairs: opts.minProductiveRuns,\n binaryScale,\n })\n const bootstrap =\n improvement.bootstrap ??\n pairedBootstrap(before, after, {\n confidence,\n resamples,\n statistic: bootstrapStatistic,\n seed,\n })\n // A floor breach fires on EITHER burden of proof, because they cover\n // different failures and the floor is the anti-Goodhart guard:\n // - `improvement.low < -floorTolerance` — the CREDIBLE WORST CASE exceeds\n // the tolerance. This is the contract `AxisEvidence.floorTolerance` and\n // `paretoPolicy`'s own reason string state, and it is the conservative\n // posture a safety axis needs: block unless the data can rule the\n // breach out, rather than waiting for the breach to be proven. Read off\n // the DECIDING interval, so a pass/fail axis is not screened by a\n // bootstrap that is pinned wherever ties dominate.\n // - `regression.promote` — a PROVEN drop past the tolerance. Adds the\n // small-sample path, where the decision is an exact sign test because\n // the bootstrap interval is descriptive only.\n // A tied binary axis still has uncertainty about unseen discordant pairs.\n // Its diagnostic bootstrap collapses to zero, so only the deciding score\n // interval can establish that a regression stays within the declared floor.\n const floorBreached = improvement.low < -floorTolerance || regression.promote\n // Floor check precedes the gain check: a credible regression must never be\n // masked as \"improved\". With the defaults (gainThreshold 0, positive floor)\n // the regions are disjoint and order is moot, but a consumer who sets a\n // negative gainThreshold (\"accept small dips\") could otherwise have a real\n // floor breach classified as a gain — anti-Goodhart wins the tie.\n const verdict: AxisVerdict = !improvement.sufficient\n ? 'few_runs'\n : improvement.indeterminate\n ? 'indeterminate'\n : floorBreached\n ? 'regressed'\n : improvement.promote\n ? 'improved'\n : 'flat'\n axes.push({\n name: obj.name,\n source: obj.source,\n direction: obj.direction,\n bootstrap,\n bootstrapStatistic,\n ci: { low: improvement.low, high: improvement.high },\n decisionStatistic: improvement.statistic,\n mcnemar: improvement.mcnemar,\n indeterminate: improvement.indeterminate,\n n,\n minimumRequired: improvement.minimumPairs,\n decisionMethod: improvement.method,\n gainThreshold,\n floorTolerance,\n verdict,\n })\n }\n const ns = axes.map((a) => a.n).filter((n) => n > 0)\n const minN = ns.length > 0 ? Math.min(...ns) : 0\n return { axes, minN, cost: { candidate: ctx.cost.candidate, baseline: ctx.cost.baseline } }\n}\n\n/**\n * Require a supported gain and every configured regression floor to clear.\n * A failed floor holds the candidate, including when uncertainty permits a loss.\n * Missing or indeterminate evidence requires more work; no gain holds release.\n */\nexport const paretoPolicy: PromotionPolicy = (ev) => {\n const contributingGates = ev.axes.map((ax) => ({\n name: `objective:${ax.name}`,\n status:\n ax.verdict === 'regressed'\n ? ('fail' as const)\n : ax.verdict === 'few_runs' || ax.verdict === 'indeterminate'\n ? ('not_evaluated' as const)\n : ('pass' as const),\n detail: {\n direction: ax.direction,\n source: ax.source,\n verdict: ax.verdict,\n n: ax.n,\n deltaMedian: ax.bootstrap.median,\n ciLow: ax.ci.low,\n ciHigh: ax.ci.high,\n decisionStatistic: ax.decisionStatistic,\n decisionMethod: ax.decisionMethod,\n mcnemar: ax.mcnemar,\n indeterminate: ax.indeterminate,\n bootstrapCiLow: ax.bootstrap.low,\n bootstrapCiHigh: ax.bootstrap.high,\n confidence: ax.bootstrap.confidence,\n gainThreshold: ax.gainThreshold,\n floorTolerance: ax.floorTolerance,\n },\n }))\n\n const regressed = ev.axes.filter((a) => a.verdict === 'regressed')\n const insufficient = ev.axes.filter(\n (a) => a.verdict === 'few_runs' || a.verdict === 'indeterminate',\n )\n const improved = ev.axes.filter((a) => a.verdict === 'improved')\n\n let decision: GateDecision\n const reasons: string[] = []\n if (regressed.length > 0) {\n // A gain on another axis cannot excuse an unresolved regression floor.\n decision = 'hold'\n for (const a of regressed) {\n reasons.push(\n `objective '${a.name}' did not clear its regression floor -${a.floorTolerance}: good-direction CI [${a.ci.low.toFixed(3)}, ${a.ci.high.toFixed(3)}] (n=${a.n})`,\n )\n }\n } else if (insufficient.length > 0) {\n // An unresolved axis cannot establish either a gain or a safe floor.\n decision = 'need_more_work'\n for (const a of insufficient) {\n reasons.push(\n a.verdict === 'few_runs'\n ? `objective '${a.name}' has only n=${a.n} paired runs — insufficient evidence to claim significance`\n : `objective '${a.name}' has an indeterminate deciding CI [${a.ci.low}, ${a.ci.high}] — insufficient evidence to clear its regression floor (n=${a.n})`,\n )\n }\n } else if (improved.length > 0) {\n decision = 'ship'\n reasons.push(\n `Supported objective gain: ${improved\n .map(\n (a) =>\n `'${a.name}' +${a.ci.low > 0 ? a.ci.low.toFixed(3) : a.bootstrap.mean.toFixed(3)} (CI.low ${a.ci.low.toFixed(3)})`,\n )\n .join(', ')}; every regression floor cleared`,\n )\n } else {\n // Every floor cleared, but no objective demonstrated a significant gain.\n decision = 'hold'\n reasons.push(\n 'no Pareto improvement: no objective shows a significant gain; every regression floor cleared',\n )\n }\n\n // `delta` surfaces the composite axis if present, else the first axis — a\n // single convenience scalar; the vector lives in `contributingGates`.\n const composite = ev.axes.find((a) => a.source.kind === 'composite') ?? ev.axes[0]\n return { decision, reasons, contributingGates, delta: composite?.bootstrap.median }\n}\n\nexport interface ParetoSignificanceGateOptions extends BuildEvidenceVectorOptions {\n /** The objective vector. Every axis is both a gain source and a safety floor. */\n objectives: PromotionObjective[]\n /** Strategy applied to the evidence vector. Default `paretoPolicy`. Override\n * to run a stricter/looser strategy over the SAME bus (competing policies). */\n policy?: PromotionPolicy\n /** Override the gate name in reports. */\n name?: string\n}\n\n/**\n * Wrap the bus + a policy as a `Gate`. Plugs into the existing\n * `runImprovementLoop({ gate })` slot and composes via `composeGate`; default\n * loop behavior is unchanged because consumers opt in by passing this gate.\n */\nexport function paretoSignificanceGate<TArtifact = unknown, TScenario extends Scenario = Scenario>(\n options: ParetoSignificanceGateOptions,\n): Gate<TArtifact, TScenario> {\n if (options.objectives.length === 0) {\n throw new Error('paretoSignificanceGate: at least 1 objective required')\n }\n const policy = options.policy ?? paretoPolicy\n return {\n name: options.name ?? 'paretoSignificanceGate',\n async decide(ctx: GateContext<TArtifact, TScenario>): Promise<GateResult> {\n const ev = buildEvidenceVector(ctx, options.objectives, options)\n return policy(ev)\n },\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { C as ProposalFindingSchema } from "./external-optimizer-subprocess-BqW0hHcI.js";
1
+ import { S as ProposalFindingSchema } from "./external-optimizer-subprocess-B5gdLRZv.js";
2
2
  //#region src/analyst/proposal-findings.ts
3
3
  /** True when a finding names a source candidate generation may learn from. */
4
4
  function isProposalFinding(finding) {
@@ -21,6 +21,6 @@ function findingLabel(finding, index) {
21
21
  return typeof id === "string" && id.length > 0 ? id : `index ${index}`;
22
22
  }
23
23
  //#endregion
24
- export { isProposalFinding as n, assertProposalFindings as t };
24
+ export { assertProposalFindings as t };
25
25
 
26
- //# sourceMappingURL=proposal-findings-CY1xKn_a.js.map
26
+ //# sourceMappingURL=proposal-findings-n-5WBbEx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proposal-findings-n-5WBbEx.js","names":[],"sources":["../src/analyst/proposal-findings.ts"],"sourcesContent":["import { ProposalFindingSchema } from './finding-scope'\nimport type { ProposalFinding } from './types'\n\n/** True when a finding names a source candidate generation may learn from. */\nfunction isProposalFinding(finding: unknown): finding is ProposalFinding {\n return ProposalFindingSchema.safeParse(finding).success\n}\n\n/**\n * Reject findings whose source has not been explicitly admitted for candidate\n * generation. Search feedback and observed production behavior are allowed;\n * final evaluation data has no allowed origin.\n */\nexport function assertProposalFindings(\n findings: unknown,\n context = 'proposal findings',\n): ReadonlyArray<ProposalFinding> {\n if (!Array.isArray(findings)) {\n throw new TypeError(`${context}: expected an array`)\n }\n const rejected = findings.flatMap((finding, index) =>\n isProposalFinding(finding) ? [] : [findingLabel(finding, index)],\n )\n if (rejected.length > 0) {\n throw new Error(\n `${context}: every finding must match AnalystFinding and declare ` +\n `proposal_origin as search or production. ` +\n `Rejected findings: [${rejected.join(', ')}].`,\n )\n }\n return findings as ReadonlyArray<ProposalFinding>\n}\n\nfunction findingLabel(finding: unknown, index: number): string {\n if (typeof finding !== 'object' || finding === null) return `index ${index}`\n const id = (finding as { finding_id?: unknown }).finding_id\n return typeof id === 'string' && id.length > 0 ? id : `index ${index}`\n}\n"],"mappings":";;;AAIA,SAAS,kBAAkB,SAA8C;CACvE,OAAO,sBAAsB,UAAU,OAAO,CAAC,CAAC;AAClD;;;;;;AAOA,SAAgB,uBACd,UACA,UAAU,qBACsB;CAChC,IAAI,CAAC,MAAM,QAAQ,QAAQ,GACzB,MAAM,IAAI,UAAU,GAAG,QAAQ,oBAAoB;CAErD,MAAM,WAAW,SAAS,SAAS,SAAS,UAC1C,kBAAkB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,SAAS,KAAK,CAAC,CACjE;CACA,IAAI,SAAS,SAAS,GACpB,MAAM,IAAI,MACR,GAAG,QAAQ,qHAEc,SAAS,KAAK,IAAI,EAAE,GAC/C;CAEF,OAAO;AACT;AAEA,SAAS,aAAa,SAAkB,OAAuB;CAC7D,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM,OAAO,SAAS;CACrE,MAAM,KAAM,QAAqC;CACjD,OAAO,OAAO,OAAO,YAAY,GAAG,SAAS,IAAI,KAAK,SAAS;AACjE"}
@@ -1,6 +1,6 @@
1
- import { s as ValidationError } from "./errors-DVZiqS7K.js";
2
- import { r as canonicalString } from "./canonical-B2RqLofv.js";
3
- import { a as isToolSpan, i as isLlmSpan, r as isJudgeSpan } from "./schema-CSf6qWgZ.js";
1
+ import { s as ValidationError } from "./errors-BcOs5MKW.js";
2
+ import { r as canonicalString } from "./canonical-Dq2hOQ8L.js";
3
+ import { i as isToolSpan, n as isJudgeSpan, r as isLlmSpan } from "./schema-Bt2vLFm3.js";
4
4
  //#region src/trace/query.ts
5
5
  /**
6
6
  * Typed query helpers over TraceStore.
@@ -129,6 +129,6 @@ function runMetricExtractor(metric) {
129
129
  };
130
130
  }
131
131
  //#endregion
132
- export { hasCapturedToolArgs as a, runFailureClass as c, toolSpans as d, groupBy as i, runMetricExtractor as l, aggregateLlm as n, judgeSpans as o, argHash as r, llmSpans as s, RUN_METRICS as t, runsForScenario as u };
132
+ export { llmSpans as a, runsForScenario as c, judgeSpans as i, toolSpans as l, groupBy as n, runFailureClass as o, hasCapturedToolArgs as r, runMetricExtractor as s, argHash as t };
133
133
 
134
- //# sourceMappingURL=query-BUCZCK7F.js.map
134
+ //# sourceMappingURL=query-B_RZ36an.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-B_RZ36an.js","names":[],"sources":["../src/trace/query.ts"],"sourcesContent":["/**\n * Typed query helpers over TraceStore.\n *\n * Not a full SQL engine — a minimal, composable set of operators that\n * cover the canned-pipeline use cases. For ad-hoc analytics, persist to\n * NDJSON and point DuckDB at it; the schema is stable so external SQL\n * tooling works out of the box.\n */\n\nimport { ValidationError } from '../errors'\nimport { canonicalString } from '../ledger-core/canonical'\nimport type { FailureClass, JudgeSpan, LlmSpan, Run, ToolSpan } from './schema'\nimport { isJudgeSpan, isLlmSpan, isToolSpan } from './schema'\nimport type { TraceStore } from './store'\n\nexport async function runsForScenario(store: TraceStore, scenarioId: string): Promise<Run[]> {\n return store.listRuns({ scenarioId })\n}\n\nexport async function llmSpans(store: TraceStore, runId?: string): Promise<LlmSpan[]> {\n const spans = await store.spans({ runId, kind: 'llm' })\n return spans.filter(isLlmSpan)\n}\n\nexport async function toolSpans(\n store: TraceStore,\n runId?: string,\n toolName?: string,\n): Promise<ToolSpan[]> {\n const spans = await store.spans({ runId, kind: 'tool', toolName })\n return spans.filter(isToolSpan)\n}\n\n/** Query judge-kind spans from the trace store, optionally scoped to a single run. */\nexport async function judgeSpans(store: TraceStore, runId?: string): Promise<JudgeSpan[]> {\n const spans = await store.spans({ runId, kind: 'judge' })\n return spans.filter(isJudgeSpan)\n}\n\n/** Group spans by any key selector. */\nexport function groupBy<T, K extends string | number>(items: T[], key: (t: T) => K): Map<K, T[]> {\n const map = new Map<K, T[]>()\n for (const item of items) {\n const k = key(item)\n let bucket = map.get(k)\n if (!bucket) {\n bucket = []\n map.set(k, bucket)\n }\n bucket.push(item)\n }\n return map\n}\n\n/**\n * Key tool arguments for de-duplication: RFC 8785 canonical JSON, so key\n * order cannot split one call into two keys. Uncaptured args (`undefined`)\n * key to the string `'undefined'` so every call still keys to a string; an\n * args value with no canonical JSON form (a nested `undefined`, a function, a\n * non-finite number) throws `LedgerCanonicalizationError`.\n */\nexport function argHash(args: unknown): string {\n if (args === undefined) return 'undefined'\n return canonicalString(args)\n}\n\n/** Whether argument-based comparisons are valid for this tool call. */\nexport function hasCapturedToolArgs(span: ToolSpan): boolean {\n return span.argsCaptured !== false\n}\n\n/** Sum an LLM-span array into aggregate token + cost. */\nfunction aggregateLlm(spans: LlmSpan[]): {\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n cacheWriteTokens: number\n reasoningTokens: number\n costUsd: number\n} {\n return spans.reduce(\n (acc, s) => ({\n inputTokens: acc.inputTokens + (s.inputTokens ?? 0),\n outputTokens: acc.outputTokens + (s.outputTokens ?? 0),\n cachedTokens: acc.cachedTokens + (s.cachedTokens ?? 0),\n cacheWriteTokens: acc.cacheWriteTokens + (s.cacheWriteTokens ?? 0),\n reasoningTokens: acc.reasoningTokens + (s.reasoningTokens ?? 0),\n costUsd: acc.costUsd + (s.costUsd ?? 0),\n }),\n {\n inputTokens: 0,\n outputTokens: 0,\n cachedTokens: 0,\n cacheWriteTokens: 0,\n reasoningTokens: 0,\n costUsd: 0,\n },\n )\n}\n\n/** Pick the outcome's failure class when present, else derive 'success' from run status. */\nexport function runFailureClass(run: Run): FailureClass {\n if (run.outcome?.failureClass) return run.outcome.failureClass\n if (run.status === 'completed' && run.outcome?.pass !== false) return 'success'\n if (run.status === 'aborted') return 'budget_exceeded'\n return 'unknown'\n}\n\n/**\n * Metrics `regressionView`, `correlationStudy`, and `calibrationCurve` can\n * read from a run without a caller-supplied extractor. The type derives from\n * this array, so a new metric cannot be declared without an extractor arm.\n */\nconst RUN_METRICS = [\n 'score',\n 'overallScore',\n 'pass',\n 'durationMs',\n 'costUsd',\n 'inputTokens',\n 'outputTokens',\n 'failureClass',\n] as const\n\nexport type RunMetric = (typeof RUN_METRICS)[number]\n\nfunction isRunMetric(metric: string): metric is RunMetric {\n return (RUN_METRICS as readonly string[]).includes(metric)\n}\n\n/**\n * The extractor for one built-in metric. `null` means this run carries no\n * value for the metric — the caller drops that run from the sample.\n *\n * Throws `ValidationError` on a metric name this package does not define:\n * an unrecognized name would otherwise read as \"every run is missing this\n * value\" and produce an empty study instead of a refusal.\n */\nexport function runMetricExtractor(\n metric: string,\n): (run: Run, store: TraceStore) => Promise<number | null> {\n if (!isRunMetric(metric)) {\n throw new ValidationError(\n `unknown run metric '${metric}' — pass an \\`extract\\` function or use one of: ${RUN_METRICS.join(', ')}`,\n )\n }\n return async (run, store) => {\n switch (metric) {\n case 'score':\n case 'overallScore':\n return run.outcome?.score ?? null\n case 'pass':\n return run.outcome?.pass === true ? 1 : 0\n case 'durationMs':\n return run.endedAt && run.startedAt ? run.endedAt - run.startedAt : null\n case 'costUsd':\n return aggregateLlm(await llmSpans(store, run.runId)).costUsd\n case 'inputTokens':\n return aggregateLlm(await llmSpans(store, run.runId)).inputTokens\n case 'outputTokens':\n return aggregateLlm(await llmSpans(store, run.runId)).outputTokens\n case 'failureClass':\n return runFailureClass(run) === 'success' ? 1 : 0\n }\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { C as ToolSpan, c as JudgeSpan, f as Run, l as LlmSpan, o as FailureClass } from "./schema-2g7trUwH.js";
2
- import { s as TraceStore } from "./store-C4avFjIi.js";
1
+ import { c as JudgeSpan, f as Run, l as LlmSpan, o as FailureClass, x as ToolSpan } from "./schema-D6EVKzTB.js";
2
+ import { s as TraceStore } from "./store-B3nWRy3B.js";
3
3
  //#region src/trace/query.d.ts
4
4
  declare function runsForScenario(store: TraceStore, scenarioId: string): Promise<Run[]>;
5
5
  declare function llmSpans(store: TraceStore, runId?: string): Promise<LlmSpan[]>;
@@ -16,17 +16,6 @@ declare function groupBy<T, K extends string | number>(items: T[], key: (t: T) =
16
16
  * non-finite number) throws `LedgerCanonicalizationError`.
17
17
  */
18
18
  declare function argHash(args: unknown): string;
19
- /** Whether argument-based comparisons are valid for this tool call. */
20
- declare function hasCapturedToolArgs(span: ToolSpan): boolean;
21
- /** Sum an LLM-span array into aggregate token + cost. */
22
- declare function aggregateLlm(spans: LlmSpan[]): {
23
- inputTokens: number;
24
- outputTokens: number;
25
- cachedTokens: number;
26
- cacheWriteTokens: number;
27
- reasoningTokens: number;
28
- costUsd: number;
29
- };
30
19
  /** Pick the outcome's failure class when present, else derive 'success' from run status. */
31
20
  declare function runFailureClass(run: Run): FailureClass;
32
21
  /**
@@ -36,15 +25,6 @@ declare function runFailureClass(run: Run): FailureClass;
36
25
  */
37
26
  declare const RUN_METRICS: readonly ['score', 'overallScore', 'pass', 'durationMs', 'costUsd', 'inputTokens', 'outputTokens', 'failureClass'];
38
27
  type RunMetric = (typeof RUN_METRICS)[number];
39
- /**
40
- * The extractor for one built-in metric. `null` means this run carries no
41
- * value for the metric — the caller drops that run from the sample.
42
- *
43
- * Throws `ValidationError` on a metric name this package does not define:
44
- * an unrecognized name would otherwise read as "every run is missing this
45
- * value" and produce an empty study instead of a refusal.
46
- */
47
- declare function runMetricExtractor(metric: string): (run: Run, store: TraceStore) => Promise<number | null>;
48
28
  //#endregion
49
- export { groupBy as a, llmSpans as c, runsForScenario as d, toolSpans as f, argHash as i, runFailureClass as l, RunMetric as n, hasCapturedToolArgs as o, aggregateLlm as r, judgeSpans as s, RUN_METRICS as t, runMetricExtractor as u };
50
- //# sourceMappingURL=query-DK1nWcmp.d.ts.map
29
+ export { llmSpans as a, toolSpans as c, judgeSpans as i, argHash as n, runFailureClass as o, groupBy as r, runsForScenario as s, RunMetric as t };
30
+ //# sourceMappingURL=query-Cmv_U8vf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-DK1nWcmp.d.ts","names":[],"sources":["../src/trace/query.ts"],"mappings":";;;iBAesB,gBAAgB,OAAO,YAAY,qBAAqB,QAAQ;iBAIhE,SAAS,OAAO,YAAY,iBAAiB,QAAQ;iBAKrD,UACpB,OAAO,YACP,gBACA,oBACC,QAAQ;;iBAMW,WAAW,OAAO,YAAY,iBAAiB,QAAQ;;iBAM7D,QAAQ,GAAG,2BAA2B,OAAO,KAAK,MAAM,GAAG,MAAM,IAAI,IAAI,GAAG;;;;;;;;iBAqB5E,QAAQ;;iBAMR,oBAAoB,MAAM;;iBAK1B,aAAa,OAAO;EAClC;EACA;EACA;EACA;EACA;EACA;;;iBAuBc,gBAAgB,KAAK,MAAM;;;;;;cAY9B;KAWD,oBAAoB;;;;;;;;;iBAchB,mBACd,kBACE,KAAK,KAAK,OAAO,eAAe"}
1
+ {"version":3,"file":"query-Cmv_U8vf.d.ts","names":[],"sources":["../src/trace/query.ts"],"mappings":";;;iBAesB,gBAAgB,OAAO,YAAY,qBAAqB,QAAQ;iBAIhE,SAAS,OAAO,YAAY,iBAAiB,QAAQ;iBAKrD,UACpB,OAAO,YACP,gBACA,oBACC,QAAQ;;iBAMW,WAAW,OAAO,YAAY,iBAAiB,QAAQ;;iBAM7D,QAAQ,GAAG,2BAA2B,OAAO,KAAK,MAAM,GAAG,MAAM,IAAI,IAAI,GAAG;;;;;;;;iBAqB5E,QAAQ;;iBAwCR,gBAAgB,KAAK,MAAM;;;;;;cAYrC;KAWM,oBAAoB"}
@@ -1,4 +1,4 @@
1
- import { s as ValidationError } from "./errors-DVZiqS7K.js";
1
+ import { s as ValidationError } from "./errors-BcOs5MKW.js";
2
2
  //#region src/statistics/random.ts
3
3
  /** Tiny seedable PRNG (mulberry32) — deterministic resampling/shuffling, not
4
4
  * cryptographic. Exported so e-process shuffles and bootstrap resampling
@@ -18,4 +18,4 @@ function mulberry32(seed) {
18
18
  //#endregion
19
19
  export { mulberry32 as t };
20
20
 
21
- //# sourceMappingURL=random-ByUSnV9w.js.map
21
+ //# sourceMappingURL=random-DDDcC7YU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"random-ByUSnV9w.js","names":[],"sources":["../src/statistics/random.ts"],"sourcesContent":["import { ValidationError } from '../errors'\n\n/** Tiny seedable PRNG (mulberry32) — deterministic resampling/shuffling, not\n * cryptographic. Exported so e-process shuffles and bootstrap resampling\n * share ONE PRNG implementation. Every distinct 32-bit seed gives a distinct\n * stream, including 0. */\nexport function mulberry32(seed: number): () => number {\n if (!Number.isFinite(seed)) {\n throw new ValidationError(`mulberry32: seed must be a finite number, got ${seed}`)\n }\n let s = seed | 0\n return () => {\n s = (s + 0x6d2b79f5) | 0\n let t = s\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n"],"mappings":";;;;;;AAMA,SAAgB,WAAW,MAA4B;CACrD,IAAI,CAAC,OAAO,SAAS,IAAI,GACvB,MAAM,IAAI,gBAAgB,iDAAiD,MAAM;CAEnF,IAAI,IAAI,OAAO;CACf,aAAa;EACX,IAAK,IAAI,aAAc;EACvB,IAAI,IAAI;EACR,IAAI,KAAK,KAAK,IAAK,MAAM,IAAK,IAAI,CAAC;EACnC,KAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,IAAI,EAAE;EACxC,SAAS,IAAK,MAAM,QAAS,KAAK;CACpC;AACF"}
1
+ {"version":3,"file":"random-DDDcC7YU.js","names":[],"sources":["../src/statistics/random.ts"],"sourcesContent":["import { ValidationError } from '../errors'\n\n/** Tiny seedable PRNG (mulberry32) — deterministic resampling/shuffling, not\n * cryptographic. Exported so e-process shuffles and bootstrap resampling\n * share ONE PRNG implementation. Every distinct 32-bit seed gives a distinct\n * stream, including 0. */\nexport function mulberry32(seed: number): () => number {\n if (!Number.isFinite(seed)) {\n throw new ValidationError(`mulberry32: seed must be a finite number, got ${seed}`)\n }\n let s = seed | 0\n return () => {\n s = (s + 0x6d2b79f5) | 0\n let t = s\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n"],"mappings":";;;;;;AAMA,SAAgB,WAAW,MAA4B;CACrD,IAAI,CAAC,OAAO,SAAS,IAAI,GACvB,MAAM,IAAI,gBAAgB,iDAAiD,MAAM;CAEnF,IAAI,IAAI,OAAO;CACf,aAAa;EACX,IAAK,IAAI,aAAc;EACvB,IAAI,IAAI;EACR,IAAI,KAAK,KAAK,IAAK,MAAM,IAAK,IAAI,CAAC;EACnC,KAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,IAAI,EAAE;EACxC,SAAS,IAAK,MAAM,QAAS,KAAK;CACpC;AACF"}
@@ -1,4 +1,4 @@
1
- import { o as redact } from "./redact-B5xXKqQ3.js";
1
+ import { a as redact } from "./redact-mtkTiJVk.js";
2
2
  import { promises } from "node:fs";
3
3
  import * as path from "node:path";
4
4
  //#region src/trace/raw-provider-sink.ts
@@ -161,4 +161,4 @@ function providerFromBaseUrl(baseUrl) {
161
161
  //#endregion
162
162
  export { providerFromBaseUrl as a, defaultProviderRedactor as i, InMemoryRawProviderSink as n, NoopRawProviderSink as r, FileSystemRawProviderSink as t };
163
163
 
164
- //# sourceMappingURL=raw-provider-sink-DoHz4JNG.js.map
164
+ //# sourceMappingURL=raw-provider-sink-75w4FWBj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"raw-provider-sink-DoHz4JNG.js","names":["fs"],"sources":["../src/trace/raw-provider-sink.ts"],"sourcesContent":["/**\n * RawProviderSink — first-class persistence for the actual HTTP-level\n * request/response bodies of every LLM provider call.\n *\n * Why this is a separate sink from the structured `LlmSpan`:\n *\n * - `LlmSpan` records the *intent* — model name, messages, output text,\n * usage. It's what dashboards read; it's NOT enough for forensics.\n * - When a downstream consumer reports \"the verifier used the wrong route\"\n * or \"tokens look right but reasoning was missing,\" the only way to\n * answer is the raw HTTP body. Span fields can lie (a proxy can echo\n * a different `model` value than what actually answered); the raw\n * response is ground truth.\n *\n * Default behaviour: opt-in. Pass `rawSink` to `LlmClientOptions` (or the\n * matrix runner / BuilderSession sets it up automatically) and every\n * request, response, and error is recorded — including retries, with the\n * attempt index attached so a flaky call's full event chain is recoverable.\n *\n * Redaction is enforced at sink time. The default redactor runs the redaction\n * core (`./redact`, default profile) over headers, bodies and the error\n * message: credential headers and fields are replaced by name, credential and\n * personal-data values by shape. Override via the sink constructor or the\n * per-call `redactor`. The `redactedFields` array on the persisted event lets\n * a reviewer see what was replaced without exposing the values.\n */\n\nimport { promises as fs } from 'node:fs'\nimport * as path from 'node:path'\nimport { redact } from './redact'\n\nexport type RawProviderDirection = 'request' | 'response' | 'error'\n\nexport interface RawProviderEvent {\n /** Stable id. Generated by the sink if omitted. */\n eventId: string\n /** Trace context populated by `LlmClient` when the call is wrapped in a span. */\n runId?: string\n spanId?: string\n /**\n * Logical provider name. Free-form so callers can use whatever id matches\n * their topology (`'openai'`, `'anthropic'`, `'tangle-router'`, …). When\n * omitted, derived from `baseUrl` in `LlmClientOptions`.\n */\n provider: string\n model: string\n /** Endpoint path, e.g. `'/v1/chat/completions'`. */\n endpoint: string\n /** Base URL used for the call (already-normalised — no trailing slash). */\n baseUrl: string\n /** 0-indexed retry attempt. The first attempt is 0; a retried call gets 1, 2, … */\n attemptIndex: number\n direction: RawProviderDirection\n /** Unix ms. */\n timestamp: number\n /** Wall-clock duration of the call leg. Set on `response` and `error` events; null on `request`. */\n durationMs?: number\n statusCode?: number\n requestHeaders?: Record<string, string>\n requestBody?: unknown\n responseHeaders?: Record<string, string>\n responseBody?: unknown\n /** Set on `direction: 'error'` events. */\n errorMessage?: string\n /** JSON Pointers of the fields the redactor replaced ('/requestHeaders/Authorization', '/requestBody/apiKey', …). */\n redactedFields: string[]\n}\n\nexport interface RawProviderSinkFilter {\n runId?: string\n spanId?: string\n direction?: RawProviderDirection\n attemptIndex?: number\n}\n\nexport interface RawProviderSink {\n record(event: RawProviderEvent): Promise<void>\n /** Optional listing — implementations that durably persist (file, db) should support this. */\n list?(filter?: RawProviderSinkFilter): Promise<RawProviderEvent[]>\n /** Optional teardown for backed implementations. */\n close?(): Promise<void>\n}\n\nexport type ProviderRedactor = (event: RawProviderEvent) => RawProviderEvent\n\n/**\n * The default redactor: the redaction core over the parts of an event that\n * carry provider traffic. Every replaced path is added to `redactedFields`.\n */\nexport function defaultProviderRedactor(event: RawProviderEvent): RawProviderEvent {\n const { requestHeaders, requestBody, responseHeaders, responseBody, errorMessage } = event\n const { value, report } = redact({\n requestHeaders,\n requestBody,\n responseHeaders,\n responseBody,\n errorMessage,\n })\n return {\n ...event,\n ...value,\n redactedFields: [\n ...(event.redactedFields ?? []),\n ...report.findings.map((finding) => finding.path),\n ],\n }\n}\n\n// ── In-memory ────────────────────────────────────────────────────────────\n\nexport interface InMemoryRawProviderSinkOptions {\n redactor?: ProviderRedactor\n}\n\nexport class InMemoryRawProviderSink implements RawProviderSink {\n private events: RawProviderEvent[] = []\n private redactor: ProviderRedactor\n\n constructor(opts: InMemoryRawProviderSinkOptions = {}) {\n this.redactor = opts.redactor ?? defaultProviderRedactor\n }\n\n async record(event: RawProviderEvent): Promise<void> {\n this.events.push(this.redactor({ ...event, redactedFields: event.redactedFields ?? [] }))\n }\n\n async list(filter: RawProviderSinkFilter = {}): Promise<RawProviderEvent[]> {\n return this.events.filter(\n (e) =>\n (filter.runId === undefined || e.runId === filter.runId) &&\n (filter.spanId === undefined || e.spanId === filter.spanId) &&\n (filter.direction === undefined || e.direction === filter.direction) &&\n (filter.attemptIndex === undefined || e.attemptIndex === filter.attemptIndex),\n )\n }\n\n size(): number {\n return this.events.length\n }\n}\n\nexport class NoopRawProviderSink implements RawProviderSink {\n async record(): Promise<void> {\n /* no-op */\n }\n /**\n * Returns an empty array. Implemented so `assertRunCaptured` does not\n * trip the `no_raw_sink` issue when a caller explicitly opts out of\n * capture by passing this sink — opt-out is a deliberate choice, not a\n * misconfiguration.\n */\n async list(): Promise<RawProviderEvent[]> {\n return []\n }\n}\n\n// ── Filesystem (NDJSON) ──────────────────────────────────────────────────\n\nexport interface FileSystemRawProviderSinkOptions {\n /** Directory the NDJSON file is written into. Created if missing. */\n dir: string\n /** File name; default `'raw-provider-events.ndjson'`. */\n fileName?: string\n /** Bytes after which the writer rolls over to a new file (default 32 MiB). */\n rollAtBytes?: number\n redactor?: ProviderRedactor\n}\n\nexport class FileSystemRawProviderSink implements RawProviderSink {\n private dir: string\n private fileName: string\n private rollAtBytes: number\n private redactor: ProviderRedactor\n private bytesWritten = 0\n private rollIndex = 0\n private initPromise: Promise<void> | null = null\n\n constructor(opts: FileSystemRawProviderSinkOptions) {\n this.dir = opts.dir\n this.fileName = opts.fileName ?? 'raw-provider-events.ndjson'\n this.rollAtBytes = opts.rollAtBytes ?? 32 * 1024 * 1024\n this.redactor = opts.redactor ?? defaultProviderRedactor\n }\n\n private async ensureInit(): Promise<void> {\n if (!this.initPromise) {\n this.initPromise = fs.mkdir(this.dir, { recursive: true }).then(() => undefined)\n }\n await this.initPromise\n }\n\n private currentPath(): string {\n if (this.rollIndex === 0) return path.join(this.dir, this.fileName)\n return path.join(this.dir, `${this.fileName}.${this.rollIndex}`)\n }\n\n async record(event: RawProviderEvent): Promise<void> {\n await this.ensureInit()\n const redacted = this.redactor({ ...event, redactedFields: event.redactedFields ?? [] })\n const line = `${JSON.stringify(redacted)}\\n`\n if (this.bytesWritten + line.length > this.rollAtBytes && this.bytesWritten > 0) {\n this.rollIndex += 1\n this.bytesWritten = 0\n }\n await fs.appendFile(this.currentPath(), line, 'utf8')\n this.bytesWritten += line.length\n }\n\n async list(filter: RawProviderSinkFilter = {}): Promise<RawProviderEvent[]> {\n await this.ensureInit()\n const out: RawProviderEvent[] = []\n for (let i = 0; i <= this.rollIndex; i++) {\n const file =\n i === 0 ? path.join(this.dir, this.fileName) : path.join(this.dir, `${this.fileName}.${i}`)\n let body: string\n try {\n body = await fs.readFile(file, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') continue\n throw err\n }\n for (const line of body.split('\\n')) {\n if (!line) continue\n const event = JSON.parse(line) as RawProviderEvent\n if (filter.runId !== undefined && event.runId !== filter.runId) continue\n if (filter.spanId !== undefined && event.spanId !== filter.spanId) continue\n if (filter.direction !== undefined && event.direction !== filter.direction) continue\n if (filter.attemptIndex !== undefined && event.attemptIndex !== filter.attemptIndex)\n continue\n out.push(event)\n }\n }\n return out\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────\n\n/**\n * Best-effort provider id from a base URL. Falls back to the URL host when\n * none of the well-known patterns match.\n */\nexport function providerFromBaseUrl(baseUrl: string): string {\n const lower = baseUrl.toLowerCase()\n if (lower.includes('api.openai.com')) return 'openai'\n if (lower.includes('api.anthropic.com')) return 'anthropic'\n if (lower.includes('generativelanguage.googleapis.com')) return 'google'\n if (lower.includes('api.together.ai') || lower.includes('api.together.xyz')) return 'together'\n if (lower.includes('api.deepseek.com')) return 'deepseek'\n if (lower.includes('router.tangle.tools')) return 'tangle-router'\n if (lower.includes('api.litellm') || lower.includes('litellm')) return 'litellm'\n try {\n return new URL(baseUrl).host\n } catch {\n return baseUrl\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"raw-provider-sink-75w4FWBj.js","names":["fs"],"sources":["../src/trace/raw-provider-sink.ts"],"sourcesContent":["/**\n * RawProviderSink — first-class persistence for the actual HTTP-level\n * request/response bodies of every LLM provider call.\n *\n * Why this is a separate sink from the structured `LlmSpan`:\n *\n * - `LlmSpan` records the *intent* — model name, messages, output text,\n * usage. It's what dashboards read; it's NOT enough for forensics.\n * - When a downstream consumer reports \"the verifier used the wrong route\"\n * or \"tokens look right but reasoning was missing,\" the only way to\n * answer is the raw HTTP body. Span fields can lie (a proxy can echo\n * a different `model` value than what actually answered); the raw\n * response is ground truth.\n *\n * Default behaviour: opt-in. Pass `rawSink` to `LlmClientOptions` (or the\n * matrix runner / BuilderSession sets it up automatically) and every\n * request, response, and error is recorded — including retries, with the\n * attempt index attached so a flaky call's full event chain is recoverable.\n *\n * Redaction is enforced at sink time. The default redactor runs the redaction\n * core (`./redact`, default profile) over headers, bodies and the error\n * message: credential headers and fields are replaced by name, credential and\n * personal-data values by shape. Override via the sink constructor or the\n * per-call `redactor`. The `redactedFields` array on the persisted event lets\n * a reviewer see what was replaced without exposing the values.\n */\n\nimport { promises as fs } from 'node:fs'\nimport * as path from 'node:path'\nimport { redact } from './redact'\n\nexport type RawProviderDirection = 'request' | 'response' | 'error'\n\nexport interface RawProviderEvent {\n /** Stable id. Generated by the sink if omitted. */\n eventId: string\n /** Trace context populated by `LlmClient` when the call is wrapped in a span. */\n runId?: string\n spanId?: string\n /**\n * Logical provider name. Free-form so callers can use whatever id matches\n * their topology (`'openai'`, `'anthropic'`, `'tangle-router'`, …). When\n * omitted, derived from `baseUrl` in `LlmClientOptions`.\n */\n provider: string\n model: string\n /** Endpoint path, e.g. `'/v1/chat/completions'`. */\n endpoint: string\n /** Base URL used for the call (already-normalised — no trailing slash). */\n baseUrl: string\n /** 0-indexed retry attempt. The first attempt is 0; a retried call gets 1, 2, … */\n attemptIndex: number\n direction: RawProviderDirection\n /** Unix ms. */\n timestamp: number\n /** Wall-clock duration of the call leg. Set on `response` and `error` events; null on `request`. */\n durationMs?: number\n statusCode?: number\n requestHeaders?: Record<string, string>\n requestBody?: unknown\n responseHeaders?: Record<string, string>\n responseBody?: unknown\n /** Set on `direction: 'error'` events. */\n errorMessage?: string\n /** JSON Pointers of the fields the redactor replaced ('/requestHeaders/Authorization', '/requestBody/apiKey', …). */\n redactedFields: string[]\n}\n\nexport interface RawProviderSinkFilter {\n runId?: string\n spanId?: string\n direction?: RawProviderDirection\n attemptIndex?: number\n}\n\nexport interface RawProviderSink {\n record(event: RawProviderEvent): Promise<void>\n /** Optional listing — implementations that durably persist (file, db) should support this. */\n list?(filter?: RawProviderSinkFilter): Promise<RawProviderEvent[]>\n /** Optional teardown for backed implementations. */\n close?(): Promise<void>\n}\n\nexport type ProviderRedactor = (event: RawProviderEvent) => RawProviderEvent\n\n/**\n * The default redactor: the redaction core over the parts of an event that\n * carry provider traffic. Every replaced path is added to `redactedFields`.\n */\nexport function defaultProviderRedactor(event: RawProviderEvent): RawProviderEvent {\n const { requestHeaders, requestBody, responseHeaders, responseBody, errorMessage } = event\n const { value, report } = redact({\n requestHeaders,\n requestBody,\n responseHeaders,\n responseBody,\n errorMessage,\n })\n return {\n ...event,\n ...value,\n redactedFields: [\n ...(event.redactedFields ?? []),\n ...report.findings.map((finding) => finding.path),\n ],\n }\n}\n\n// ── In-memory ────────────────────────────────────────────────────────────\n\nexport interface InMemoryRawProviderSinkOptions {\n redactor?: ProviderRedactor\n}\n\nexport class InMemoryRawProviderSink implements RawProviderSink {\n private events: RawProviderEvent[] = []\n private redactor: ProviderRedactor\n\n constructor(opts: InMemoryRawProviderSinkOptions = {}) {\n this.redactor = opts.redactor ?? defaultProviderRedactor\n }\n\n async record(event: RawProviderEvent): Promise<void> {\n this.events.push(this.redactor({ ...event, redactedFields: event.redactedFields ?? [] }))\n }\n\n async list(filter: RawProviderSinkFilter = {}): Promise<RawProviderEvent[]> {\n return this.events.filter(\n (e) =>\n (filter.runId === undefined || e.runId === filter.runId) &&\n (filter.spanId === undefined || e.spanId === filter.spanId) &&\n (filter.direction === undefined || e.direction === filter.direction) &&\n (filter.attemptIndex === undefined || e.attemptIndex === filter.attemptIndex),\n )\n }\n\n size(): number {\n return this.events.length\n }\n}\n\nexport class NoopRawProviderSink implements RawProviderSink {\n async record(): Promise<void> {\n /* no-op */\n }\n /**\n * Returns an empty array. Implemented so `assertRunCaptured` does not\n * trip the `no_raw_sink` issue when a caller explicitly opts out of\n * capture by passing this sink — opt-out is a deliberate choice, not a\n * misconfiguration.\n */\n async list(): Promise<RawProviderEvent[]> {\n return []\n }\n}\n\n// ── Filesystem (NDJSON) ──────────────────────────────────────────────────\n\nexport interface FileSystemRawProviderSinkOptions {\n /** Directory the NDJSON file is written into. Created if missing. */\n dir: string\n /** File name; default `'raw-provider-events.ndjson'`. */\n fileName?: string\n /** Bytes after which the writer rolls over to a new file (default 32 MiB). */\n rollAtBytes?: number\n redactor?: ProviderRedactor\n}\n\nexport class FileSystemRawProviderSink implements RawProviderSink {\n private dir: string\n private fileName: string\n private rollAtBytes: number\n private redactor: ProviderRedactor\n private bytesWritten = 0\n private rollIndex = 0\n private initPromise: Promise<void> | null = null\n\n constructor(opts: FileSystemRawProviderSinkOptions) {\n this.dir = opts.dir\n this.fileName = opts.fileName ?? 'raw-provider-events.ndjson'\n this.rollAtBytes = opts.rollAtBytes ?? 32 * 1024 * 1024\n this.redactor = opts.redactor ?? defaultProviderRedactor\n }\n\n private async ensureInit(): Promise<void> {\n if (!this.initPromise) {\n this.initPromise = fs.mkdir(this.dir, { recursive: true }).then(() => undefined)\n }\n await this.initPromise\n }\n\n private currentPath(): string {\n if (this.rollIndex === 0) return path.join(this.dir, this.fileName)\n return path.join(this.dir, `${this.fileName}.${this.rollIndex}`)\n }\n\n async record(event: RawProviderEvent): Promise<void> {\n await this.ensureInit()\n const redacted = this.redactor({ ...event, redactedFields: event.redactedFields ?? [] })\n const line = `${JSON.stringify(redacted)}\\n`\n if (this.bytesWritten + line.length > this.rollAtBytes && this.bytesWritten > 0) {\n this.rollIndex += 1\n this.bytesWritten = 0\n }\n await fs.appendFile(this.currentPath(), line, 'utf8')\n this.bytesWritten += line.length\n }\n\n async list(filter: RawProviderSinkFilter = {}): Promise<RawProviderEvent[]> {\n await this.ensureInit()\n const out: RawProviderEvent[] = []\n for (let i = 0; i <= this.rollIndex; i++) {\n const file =\n i === 0 ? path.join(this.dir, this.fileName) : path.join(this.dir, `${this.fileName}.${i}`)\n let body: string\n try {\n body = await fs.readFile(file, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') continue\n throw err\n }\n for (const line of body.split('\\n')) {\n if (!line) continue\n const event = JSON.parse(line) as RawProviderEvent\n if (filter.runId !== undefined && event.runId !== filter.runId) continue\n if (filter.spanId !== undefined && event.spanId !== filter.spanId) continue\n if (filter.direction !== undefined && event.direction !== filter.direction) continue\n if (filter.attemptIndex !== undefined && event.attemptIndex !== filter.attemptIndex)\n continue\n out.push(event)\n }\n }\n return out\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────\n\n/**\n * Best-effort provider id from a base URL. Falls back to the URL host when\n * none of the well-known patterns match.\n */\nexport function providerFromBaseUrl(baseUrl: string): string {\n const lower = baseUrl.toLowerCase()\n if (lower.includes('api.openai.com')) return 'openai'\n if (lower.includes('api.anthropic.com')) return 'anthropic'\n if (lower.includes('generativelanguage.googleapis.com')) return 'google'\n if (lower.includes('api.together.ai') || lower.includes('api.together.xyz')) return 'together'\n if (lower.includes('api.deepseek.com')) return 'deepseek'\n if (lower.includes('router.tangle.tools')) return 'tangle-router'\n if (lower.includes('api.litellm') || lower.includes('litellm')) return 'litellm'\n try {\n return new URL(baseUrl).host\n } catch {\n return baseUrl\n }\n}\n"],"mappings":"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"}
@@ -35,7 +35,6 @@
35
35
  * over every case.
36
36
  */
37
37
  type RedactionProfile = 'default' | 'share' | 'strict';
38
- declare const REDACTION_PROFILES: readonly RedactionProfile[];
39
38
  /** What a finding is about. `media` is embedded binary content (a `data:` URI) no text detector can read. */
40
39
  type SafetyCategory = 'credential' | 'personal-data' | 'identifier' | 'raw-content' | 'media';
41
40
  /**
@@ -140,5 +139,5 @@ declare function redactForShare<T>(value: T, options?: RedactOptions): {
140
139
  verdict: ShareSafetyVerdict;
141
140
  };
142
141
  //#endregion
143
- export { redactText as _, RedactionFinding as a, SafetyCategory as c, ShareSafetyVerdict as d, assessShareSafety as f, redactForShare as g, redact as h, RedactOptions as i, ShareSafetyFinding as l, emptyRedactionReport as m, REDACTION_PROFILES as n, RedactionProfile as o, combineVerdicts as p, REDACTION_VERSION as r, RedactionReport as s, AssessOptions as t, ShareSafetyStatus as u, shareAllowed as v };
144
- //# sourceMappingURL=redact-mtCCcT8z.d.ts.map
142
+ export { shareAllowed as _, RedactionProfile as a, ShareSafetyFinding as c, assessShareSafety as d, combineVerdicts as f, redactText as g, redactForShare as h, RedactionFinding as i, ShareSafetyStatus as l, redact as m, REDACTION_VERSION as n, RedactionReport as o, emptyRedactionReport as p, RedactOptions as r, SafetyCategory as s, AssessOptions as t, ShareSafetyVerdict as u };
143
+ //# sourceMappingURL=redact-DXdlFb_U.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact-DXdlFb_U.d.ts","names":[],"sources":["../src/trace/redact.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA8CY;;KAKA;;;;;;cAOC;UAEI;;EAEf;EACA,UAAU;EACV;EACA;;UAGe;EACf;EACA,SAAS;;EAET;EACA,YAAY;EACZ;EACA,UAAU;;UAGK;;EAEf,UAAU;;EAEV;;;;;;;;;EASA;;EAEA,SAAS;;UAGM;;EAEf,UAAU;;EAEV;;KAGU;UAEK;EACf,UAAU;EACV;EACA;EACA;;EAEA;;UAGe;EACf,QAAQ;EACR,SAAS;EACT,UAAU;;EAEV;;;iBAkVc,qBAAqB,UAAS,mBAA+B;;;;;;iBAkC7D,OAAO,GACrB,OAAO,GACP,UAAS;EACN,OAAO;EAAG,QAAQ;;;;;;iBAUP,WAAW,cAAc,UAAS;;;;;;;iBAgKlC,kBAAkB,gBAAgB,UAAS,gBAAqB;;;;;iBAoBhE,gBACd,SAAS,kBACT,mBAAmB,sBACnB,iCACC;;iBAsCa,aAAa,SAAS;;;;;;iBAStB,eAAe,GAC7B,OAAO,GACP,UAAS;EACN,OAAO;EAAG,QAAQ;EAAiB,SAAS"}
@@ -492,11 +492,6 @@ function credentialIn(text, knownSecrets) {
492
492
  * safety corpus with its MIT notice; `pnpm redaction:corpus` runs this module
493
493
  * over every case.
494
494
  */
495
- const REDACTION_PROFILES = [
496
- "default",
497
- "share",
498
- "strict"
499
- ];
500
495
  /**
501
496
  * Version of the detector set and profile rules. Stored work that depends on
502
497
  * redaction behavior (saved optimizer inputs, per-span redaction stamps) keys
@@ -971,6 +966,6 @@ function redactForShare(value, options = {}) {
971
966
  };
972
967
  }
973
968
  //#endregion
974
- export { emptyRedactionReport as a, redactText as c, detectCredential as d, detectPersonalData as f, combineVerdicts as i, shareAllowed as l, REDACTION_VERSION as n, redact as o, normalizeKey as p, assessShareSafety as r, redactForShare as s, REDACTION_PROFILES as t, classifyKey as u };
969
+ export { redact as a, shareAllowed as c, detectPersonalData as d, normalizeKey as f, emptyRedactionReport as i, classifyKey as l, assessShareSafety as n, redactForShare as o, combineVerdicts as r, redactText as s, REDACTION_VERSION as t, detectCredential as u };
975
970
 
976
- //# sourceMappingURL=redact-B5xXKqQ3.js.map
971
+ //# sourceMappingURL=redact-mtkTiJVk.js.map