reeval 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/README.md +99 -64
  2. package/THIRD_PARTY_NOTICES.md +288 -112
  3. package/assets/package.json +1 -1
  4. package/assets/pnpm-lock.yaml +30 -30
  5. package/dist/adapter-Bwy3QxAK.js +279 -0
  6. package/dist/adapter-Bwy3QxAK.js.map +1 -0
  7. package/dist/{agent-6FefIhX7.js → agent-D483ru7D.js} +6 -6
  8. package/dist/{agent-6FefIhX7.js.map → agent-D483ru7D.js.map} +1 -1
  9. package/dist/{agent-WSmTaesf.js → agent-DpE80WPz.js} +46 -15
  10. package/dist/agent-DpE80WPz.js.map +1 -0
  11. package/dist/{analysis-DlGBDjTj.js → analysis-Bxub9LMT.js} +4 -4
  12. package/dist/{analysis-DlGBDjTj.js.map → analysis-Bxub9LMT.js.map} +1 -1
  13. package/dist/assemble-D5KGrwnJ.js +1 -0
  14. package/dist/{assemble-BCZzTyR7.js → assemble-D9GWr-HS.js} +69 -41
  15. package/dist/assemble-D9GWr-HS.js.map +1 -0
  16. package/dist/{client-Bbo9SPlK.js → assert-EUIoRdIt.js} +10 -113
  17. package/dist/assert-EUIoRdIt.js.map +1 -0
  18. package/dist/bridge/index.mjs +260 -60
  19. package/dist/{capture-Bp74Z6Fr.js → capture-BQlGHiMC.js} +146 -32
  20. package/dist/capture-BQlGHiMC.js.map +1 -0
  21. package/dist/capture-CYGLpWxR.js +1 -0
  22. package/dist/{cli-CVrMh_qz.js → cli-ClpPT8kn.js} +229 -537
  23. package/dist/cli-ClpPT8kn.js.map +1 -0
  24. package/dist/{cli-spec-CKEYa8V2.js → cli-spec-qmEnQ25_.js} +50 -22
  25. package/dist/cli-spec-qmEnQ25_.js.map +1 -0
  26. package/dist/cli.js +4 -2
  27. package/dist/cli.js.map +1 -1
  28. package/dist/client-fcwgwOAD.js +106 -0
  29. package/dist/client-fcwgwOAD.js.map +1 -0
  30. package/dist/{command-DUT5l13I.js → command-Bj39y-Wm.js} +329 -87
  31. package/dist/command-Bj39y-Wm.js.map +1 -0
  32. package/dist/{command-BFP0hKEb.js → command-BlM0y8jN.js} +14 -14
  33. package/dist/{command-BFP0hKEb.js.map → command-BlM0y8jN.js.map} +1 -1
  34. package/dist/command-C-cVjlny.js +1 -0
  35. package/dist/{command-CzIFp1JQ.js → command-DbAe1Rzb.js} +19 -19
  36. package/dist/command-DbAe1Rzb.js.map +1 -0
  37. package/dist/{command-C5xFPKHM.js → command-TgbzPizb.js} +378 -74
  38. package/dist/command-TgbzPizb.js.map +1 -0
  39. package/dist/commands-CthqwkAn.js +1 -0
  40. package/dist/{commands-CLmPBrTS.js → commands-YUwlyTbr.js} +14 -11
  41. package/dist/commands-YUwlyTbr.js.map +1 -0
  42. package/dist/config-DrVSEVN0.js +774 -0
  43. package/dist/config-DrVSEVN0.js.map +1 -0
  44. package/dist/{context-DbSMEVKs.js → context-C1mxXh80.js} +11 -3
  45. package/dist/context-C1mxXh80.js.map +1 -0
  46. package/dist/contrasts-5zsj32gk.js +101 -0
  47. package/dist/contrasts-5zsj32gk.js.map +1 -0
  48. package/dist/db-CKg5NtiW.js +2 -0
  49. package/dist/{db-CfQFwJtq.js → db-DfhipHEF.js} +467 -38
  50. package/dist/db-DfhipHEF.js.map +1 -0
  51. package/dist/debug-D7bEv_UV.js +1 -0
  52. package/dist/{dist-CTzThfu_.js → dist-CuY4ehEk.js} +95 -15
  53. package/dist/dist-CuY4ehEk.js.map +1 -0
  54. package/dist/{docker-CRQGQbIt.js → docker-D1HZDS6q.js} +22 -21
  55. package/dist/docker-D1HZDS6q.js.map +1 -0
  56. package/dist/docker-DNmMPOBb.js +1 -0
  57. package/dist/{docker-DV2GNgle.js → docker-DOvjji9I.js} +3 -3
  58. package/dist/docker-DOvjji9I.js.map +1 -0
  59. package/dist/{doctor-DlKycx5H.js → doctor-D2MbNO8L.js} +262 -84
  60. package/dist/doctor-D2MbNO8L.js.map +1 -0
  61. package/dist/{egress-BhzNh7Yi.js → egress-2-qzPvGi.js} +146 -15
  62. package/dist/egress-2-qzPvGi.js.map +1 -0
  63. package/dist/environment-Cca6a4wB.js +1132 -0
  64. package/dist/environment-Cca6a4wB.js.map +1 -0
  65. package/dist/{errors-yDAEwmZo.js → errors-B6BSMs03.js} +2 -2
  66. package/dist/errors-B6BSMs03.js.map +1 -0
  67. package/dist/{errors-C9w_ud7g.js → errors-r025B0Zb.js} +4 -4
  68. package/dist/errors-r025B0Zb.js.map +1 -0
  69. package/dist/evaluate-DKIl54Hb.js +2348 -0
  70. package/dist/evaluate-DKIl54Hb.js.map +1 -0
  71. package/dist/evaluate-DMyaGQEj.d.ts +92 -0
  72. package/dist/files-BAt0i00X.js +1 -0
  73. package/dist/{files-DJUFg-4e.js → files-BXHZFWmx.js} +5 -5
  74. package/dist/{files-DJUFg-4e.js.map → files-BXHZFWmx.js.map} +1 -1
  75. package/dist/files-Bk1mC3AN.js +43 -0
  76. package/dist/files-Bk1mC3AN.js.map +1 -0
  77. package/dist/{files-CSzVADHn.js → files-BpUYBwGu.js} +11 -10
  78. package/dist/{files-CSzVADHn.js.map → files-BpUYBwGu.js.map} +1 -1
  79. package/dist/files-Bw8lWEjg.js +1 -0
  80. package/dist/files-D6J0iSdx.js +1 -0
  81. package/dist/{git-DfG-YJ1u.js → git-Crl3b87o.js} +2 -2
  82. package/dist/{git-DfG-YJ1u.js.map → git-Crl3b87o.js.map} +1 -1
  83. package/dist/harness-CEuntrla.js +323 -0
  84. package/dist/harness-CEuntrla.js.map +1 -0
  85. package/dist/harness.d.ts +16 -30
  86. package/dist/harness.js +1 -2
  87. package/dist/{header-CALhmafp.js → header-DHQv_ZrF.js} +2 -2
  88. package/dist/{header-CALhmafp.js.map → header-DHQv_ZrF.js.map} +1 -1
  89. package/dist/{images-BMgdpMAX.js → images-Bi3aGxb9.js} +114 -45
  90. package/dist/images-Bi3aGxb9.js.map +1 -0
  91. package/dist/index.d.ts +9 -37
  92. package/dist/index.js +6 -2138
  93. package/dist/{init-BIdLF0F9.js → init-Cl3f3NBT.js} +26 -8
  94. package/dist/init-Cl3f3NBT.js.map +1 -0
  95. package/dist/init-fhOXED8F.js +1 -0
  96. package/dist/{invocations-CLaL8AuW.js → invocations-BYDPe3fV.js} +4 -4
  97. package/dist/{invocations-CLaL8AuW.js.map → invocations-BYDPe3fV.js.map} +1 -1
  98. package/dist/{judge-CeYPN8P_.js → judge-DW_GDOmB.js} +11 -19
  99. package/dist/{judge-CeYPN8P_.js.map → judge-DW_GDOmB.js.map} +1 -1
  100. package/dist/judge.d.ts +2 -2
  101. package/dist/judge.js +1 -1
  102. package/dist/{live-S0qODb6o.js → live-jlfszAbb.js} +9 -20
  103. package/dist/live-jlfszAbb.js.map +1 -0
  104. package/dist/matchers-Ddmc2z7H.js +118 -0
  105. package/dist/matchers-Ddmc2z7H.js.map +1 -0
  106. package/dist/model-CXhrziBe.js +1 -0
  107. package/dist/{model-B1BZoZ9b.js → model-D0IcOQao.js} +22 -20
  108. package/dist/model-D0IcOQao.js.map +1 -0
  109. package/dist/{model-DEQo3FkZ.js → model-DaVCY3rb.js} +2 -2
  110. package/dist/{model-DEQo3FkZ.js.map → model-DaVCY3rb.js.map} +1 -1
  111. package/dist/{model-BOnlAPzs.js → model-DaX4bNLZ.js} +123 -22
  112. package/dist/model-DaX4bNLZ.js.map +1 -0
  113. package/dist/model-_bxNrk2h.js +1 -0
  114. package/dist/{node-Co7EXge0.js → node-B3ydHo6t.js} +10 -47
  115. package/dist/node-B3ydHo6t.js.map +1 -0
  116. package/dist/object-CLf2-tNq.js +9 -0
  117. package/dist/object-CLf2-tNq.js.map +1 -0
  118. package/dist/{opencode-providers-ByD85Q0l.js → opencode-providers-J9colP0-.js} +96 -21
  119. package/dist/opencode-providers-J9colP0-.js.map +1 -0
  120. package/dist/options-C0d0AzeR.js +1118 -0
  121. package/dist/options-C0d0AzeR.js.map +1 -0
  122. package/dist/{pairs-DDsjgm5F.js → pairs-CnInRu-G.js} +76 -2
  123. package/dist/{pairs-DDsjgm5F.js.map → pairs-CnInRu-G.js.map} +1 -1
  124. package/dist/{patch-bDV8YFW0.js → patch-B1bnfhN-.js} +6 -6
  125. package/dist/{patch-bDV8YFW0.js.map → patch-B1bnfhN-.js.map} +1 -1
  126. package/dist/{plan-DUydFc_1.js → plan-DgQxp9yy.js} +34 -13
  127. package/dist/plan-DgQxp9yy.js.map +1 -0
  128. package/dist/{preflight-BkoSxf4C.js → preflight-BRzD30L5.js} +8 -7
  129. package/dist/preflight-BRzD30L5.js.map +1 -0
  130. package/dist/preflight-DlQvbySb.js +1 -0
  131. package/dist/{prepare-CUAWHebF.js → prepare-B_y-AFMv.js} +38 -30
  132. package/dist/prepare-B_y-AFMv.js.map +1 -0
  133. package/dist/prepare-DCKTLHN3.js +2 -0
  134. package/dist/{provenance-D7HK3vzt.js → provenance-DQ0AXn6c.js} +5 -5
  135. package/dist/{provenance-D7HK3vzt.js.map → provenance-DQ0AXn6c.js.map} +1 -1
  136. package/dist/provider-DehR4CMN.js +1 -0
  137. package/dist/providers-B9yTdIqF.js +1 -0
  138. package/dist/providers-DoTq1jHW.js +165 -0
  139. package/dist/providers-DoTq1jHW.js.map +1 -0
  140. package/dist/query-BO-ux7RB.js +139 -0
  141. package/dist/query-BO-ux7RB.js.map +1 -0
  142. package/dist/query-CRQfsw0e.js +1 -0
  143. package/dist/questions-C2dym2ce.js +524 -0
  144. package/dist/questions-C2dym2ce.js.map +1 -0
  145. package/dist/{record-BRP9vZrj.js → record-BKmMvZ6O.js} +9 -1
  146. package/dist/{record-BRP9vZrj.js.map → record-BKmMvZ6O.js.map} +1 -1
  147. package/dist/remote-CPPW86Q9.js +378 -0
  148. package/dist/remote-CPPW86Q9.js.map +1 -0
  149. package/dist/{results-Di7m8dQ3.js → results-BE2f-1XS.js} +6 -5
  150. package/dist/results-BE2f-1XS.js.map +1 -0
  151. package/dist/{resume-SUz1GskV.js → resume-Ca1c8vix.js} +10 -10
  152. package/dist/{resume-SUz1GskV.js.map → resume-Ca1c8vix.js.map} +1 -1
  153. package/dist/{root-CvdRlRZX.js → root-DICDHCtp.js} +4 -4
  154. package/dist/{root-CvdRlRZX.js.map → root-DICDHCtp.js.map} +1 -1
  155. package/dist/{runtime-DdsfnRz_.js → runtime-PX_oXiCS.js} +23 -71
  156. package/dist/runtime-PX_oXiCS.js.map +1 -0
  157. package/dist/sandbox-DLrsvu7U.js +70 -0
  158. package/dist/sandbox-DLrsvu7U.js.map +1 -0
  159. package/dist/sandbox.d.ts +19 -6
  160. package/dist/sandbox.js +1 -2
  161. package/dist/server-Dp8eOeK5.js +1 -0
  162. package/dist/{server-BNnXtmS8.js → server-TUY5xA_A.js} +11 -11
  163. package/dist/server-TUY5xA_A.js.map +1 -0
  164. package/dist/shared-CA61BuPJ.js +188 -0
  165. package/dist/shared-CA61BuPJ.js.map +1 -0
  166. package/dist/{source-Dof0NQBm.js → source-DJGS0a0u.js} +2 -2
  167. package/dist/{source-Dof0NQBm.js.map → source-DJGS0a0u.js.map} +1 -1
  168. package/dist/source-DdbLGR1M.js +1 -0
  169. package/dist/src-BxfCKA3_.js +2 -0
  170. package/dist/{src-C1E9HDWO.js → src-C7_1SqDP.js} +3 -3
  171. package/dist/{src-C1E9HDWO.js.map → src-C7_1SqDP.js.map} +1 -1
  172. package/dist/{src-DDNXsD9H.js → src-CF17Ug08.js} +5 -4
  173. package/dist/src-CF17Ug08.js.map +1 -0
  174. package/dist/{src-C_4Umgh2.js → src-CFp86GtV.js} +52 -51
  175. package/dist/src-CFp86GtV.js.map +1 -0
  176. package/dist/src-CLoOMVWI.js +3 -0
  177. package/dist/src-CcrQbpG8.js +2 -0
  178. package/dist/src-DCFtJRp0.js +2 -0
  179. package/dist/src-DIL0jST0.js +368 -0
  180. package/dist/src-DIL0jST0.js.map +1 -0
  181. package/dist/src-DSYYPEOj.js +2 -0
  182. package/dist/src-DYO3DdnQ.js +1 -0
  183. package/dist/src-DvCg0NBs.js +324 -0
  184. package/dist/src-DvCg0NBs.js.map +1 -0
  185. package/dist/{src-COgE7991.js → src-DvK0EIZx.js} +5 -5
  186. package/dist/{src-COgE7991.js.map → src-DvK0EIZx.js.map} +1 -1
  187. package/dist/{src-DVy58-zZ.js → src-FGXhkEkH.js} +5 -5
  188. package/dist/{src-DVy58-zZ.js.map → src-FGXhkEkH.js.map} +1 -1
  189. package/dist/src-WD-zgQYZ.js +2 -0
  190. package/dist/src-_oI9AePb.js +2 -0
  191. package/dist/{src-8rRXy4u9.js → src-ftu5wPSt.js} +1652 -182
  192. package/dist/src-ftu5wPSt.js.map +1 -0
  193. package/dist/src-qsKCqv7a.js +2 -0
  194. package/dist/{src-D95O-Smv.js → src-u8_ixn_F.js} +15 -11
  195. package/dist/src-u8_ixn_F.js.map +1 -0
  196. package/dist/state-CeR6oz0k.js +66 -0
  197. package/dist/state-CeR6oz0k.js.map +1 -0
  198. package/dist/{state-CiXyLqg0.js → state-DfpHox6b.js} +36 -24
  199. package/dist/state-DfpHox6b.js.map +1 -0
  200. package/dist/state-DpAxYyED.js +1 -0
  201. package/dist/studio-app/assets/index-CBkhNAv8.js +58 -0
  202. package/dist/studio-app/assets/index-CwQN3f_h.css +2 -0
  203. package/dist/studio-app/index.html +2 -2
  204. package/dist/suite-Cw_7G2RM.js +429 -0
  205. package/dist/suite-Cw_7G2RM.js.map +1 -0
  206. package/dist/suite-DamAEnNF.js +1 -0
  207. package/dist/summary-BUKfU-9l.js +611 -0
  208. package/dist/summary-BUKfU-9l.js.map +1 -0
  209. package/dist/{summary-2OAWF2N7.js → summary-Baa4rTHS.js} +7 -7
  210. package/dist/{summary-2OAWF2N7.js.map → summary-Baa4rTHS.js.map} +1 -1
  211. package/dist/testing.d.ts +3 -2
  212. package/dist/testing.js +3 -2
  213. package/dist/{tool-target-BU1JnSE9.js → tool-target-D2mcYlSQ.js} +14 -7
  214. package/dist/tool-target-D2mcYlSQ.js.map +1 -0
  215. package/dist/{tools-B10Uj7OI.js → tools-DLHgetpx.js} +6 -6
  216. package/dist/tools-DLHgetpx.js.map +1 -0
  217. package/dist/transcript-BNNANU8A.js +64 -0
  218. package/dist/transcript-BNNANU8A.js.map +1 -0
  219. package/dist/{types-D8RLfkFP.d.ts → types-BYdlwMwo.d.ts} +398 -46
  220. package/dist/{usage-DDF_6tkV.js → usage-CleNKkly.js} +4 -2
  221. package/dist/{usage-DDF_6tkV.js.map → usage-CleNKkly.js.map} +1 -1
  222. package/dist/view/index.d.ts +290 -8
  223. package/dist/view/index.js +7 -7
  224. package/dist/{views-Dqa5ojfZ.js → views-B8w2J-gD.js} +19 -24
  225. package/dist/views-B8w2J-gD.js.map +1 -0
  226. package/dist/views-DblnI3kA.js +2 -0
  227. package/dist/{worker-entry-BAikHl9F.js → worker-entry-DNnveLqx.js} +16 -229
  228. package/dist/worker-entry-DNnveLqx.js.map +1 -0
  229. package/dist/{workspace-C-TrNIUc.js → workspace-C4RA3srV.js} +7 -7
  230. package/dist/{workspace-C-TrNIUc.js.map → workspace-C4RA3srV.js.map} +1 -1
  231. package/dist/workspace-C_X0tdv6.js +1 -0
  232. package/package.json +12 -12
  233. package/dist/agent-WSmTaesf.js.map +0 -1
  234. package/dist/assemble-BCZzTyR7.js.map +0 -1
  235. package/dist/assemble-C5qq5yT2.js +0 -2
  236. package/dist/capture-Bp74Z6Fr.js.map +0 -1
  237. package/dist/capture-DS-cPyuE.js +0 -2
  238. package/dist/cli-CVrMh_qz.js.map +0 -1
  239. package/dist/cli-spec-CKEYa8V2.js.map +0 -1
  240. package/dist/client-Bbo9SPlK.js.map +0 -1
  241. package/dist/command-BrmXUC-W.js +0 -2
  242. package/dist/command-C5xFPKHM.js.map +0 -1
  243. package/dist/command-CzIFp1JQ.js.map +0 -1
  244. package/dist/command-DUT5l13I.js.map +0 -1
  245. package/dist/commands-CLmPBrTS.js.map +0 -1
  246. package/dist/commands-fI3G2Wnh.js +0 -2
  247. package/dist/config-CGvBeewH.js +0 -457
  248. package/dist/config-CGvBeewH.js.map +0 -1
  249. package/dist/context-DbSMEVKs.js.map +0 -1
  250. package/dist/db-CSSFtGcN.js +0 -3
  251. package/dist/db-CfQFwJtq.js.map +0 -1
  252. package/dist/debug-SEmW4w8f.js +0 -2
  253. package/dist/dist-CTzThfu_.js.map +0 -1
  254. package/dist/docker-CRQGQbIt.js.map +0 -1
  255. package/dist/docker-DV2GNgle.js.map +0 -1
  256. package/dist/docker-Df_YOxxB.js +0 -2
  257. package/dist/doctor-DlKycx5H.js.map +0 -1
  258. package/dist/duration-JsJrIWXq.js +0 -26
  259. package/dist/duration-JsJrIWXq.js.map +0 -1
  260. package/dist/egress-BhzNh7Yi.js.map +0 -1
  261. package/dist/env-BQqj93gu.js +0 -21
  262. package/dist/env-BQqj93gu.js.map +0 -1
  263. package/dist/environment-1jE-HhO-.js +0 -657
  264. package/dist/environment-1jE-HhO-.js.map +0 -1
  265. package/dist/errors-C9w_ud7g.js.map +0 -1
  266. package/dist/errors-yDAEwmZo.js.map +0 -1
  267. package/dist/fake-instructions-CUI33I_F.js +0 -32
  268. package/dist/fake-instructions-CUI33I_F.js.map +0 -1
  269. package/dist/family-D2b7WD10.js +0 -67
  270. package/dist/family-D2b7WD10.js.map +0 -1
  271. package/dist/files-AiEKuEZe.js +0 -2
  272. package/dist/files-BM78_nnF.js +0 -2
  273. package/dist/files-BMCvfB4X.js +0 -2
  274. package/dist/harness-CeCp2GSW.js +0 -171
  275. package/dist/harness-CeCp2GSW.js.map +0 -1
  276. package/dist/images-BMgdpMAX.js.map +0 -1
  277. package/dist/index.js.map +0 -1
  278. package/dist/init-B6vegaP_.js +0 -2
  279. package/dist/init-BIdLF0F9.js.map +0 -1
  280. package/dist/jiti-BcJHCtrb.js +0 -46
  281. package/dist/jiti-BcJHCtrb.js.map +0 -1
  282. package/dist/live-S0qODb6o.js.map +0 -1
  283. package/dist/model-B1BZoZ9b.js.map +0 -1
  284. package/dist/model-BOnlAPzs.js.map +0 -1
  285. package/dist/model-DWeg5J7z.js +0 -2
  286. package/dist/model-FXko2kl7.js +0 -2
  287. package/dist/node-Co7EXge0.js.map +0 -1
  288. package/dist/opencode-providers-ByD85Q0l.js.map +0 -1
  289. package/dist/options-CKqyPGxX.js +0 -739
  290. package/dist/options-CKqyPGxX.js.map +0 -1
  291. package/dist/plan-DUydFc_1.js.map +0 -1
  292. package/dist/preflight-BkoSxf4C.js.map +0 -1
  293. package/dist/preflight-D5LW7Oqi.js +0 -2
  294. package/dist/prepare-CUAWHebF.js.map +0 -1
  295. package/dist/prepare-oji2oO8W.js +0 -3
  296. package/dist/process-CSVO_jsc.js +0 -119
  297. package/dist/process-CSVO_jsc.js.map +0 -1
  298. package/dist/provider-BDbNOQhQ.js +0 -2
  299. package/dist/providers-B1DzMvmH.js +0 -107
  300. package/dist/providers-B1DzMvmH.js.map +0 -1
  301. package/dist/providers-CpEfNU1F.js +0 -2
  302. package/dist/query-BjBMLa-C.js +0 -91
  303. package/dist/query-BjBMLa-C.js.map +0 -1
  304. package/dist/query-oPO_XrTy.js +0 -2
  305. package/dist/questions-B8by4Bbt.js +0 -234
  306. package/dist/questions-B8by4Bbt.js.map +0 -1
  307. package/dist/results-Di7m8dQ3.js.map +0 -1
  308. package/dist/runtime-DdsfnRz_.js.map +0 -1
  309. package/dist/sandbox-D5v-of6d.js +0 -139
  310. package/dist/sandbox-D5v-of6d.js.map +0 -1
  311. package/dist/server-BNnXtmS8.js.map +0 -1
  312. package/dist/server-BNwoKzlm.js +0 -2
  313. package/dist/source-Bk_0ZaEY.js +0 -2
  314. package/dist/src-8rRXy4u9.js.map +0 -1
  315. package/dist/src-BGWuWp6I.js +0 -3
  316. package/dist/src-BRt0O02i.js +0 -3
  317. package/dist/src-Bx2x1ekD.js +0 -3
  318. package/dist/src-C_4Umgh2.js.map +0 -1
  319. package/dist/src-D95O-Smv.js.map +0 -1
  320. package/dist/src-DDNXsD9H.js.map +0 -1
  321. package/dist/src-DLa-ESW0.js +0 -4
  322. package/dist/src-cN0aB-WR.js +0 -3
  323. package/dist/src-cdIVjC5b.js +0 -2
  324. package/dist/src-sIsDHWYq.js +0 -3
  325. package/dist/state-Bo5zg4da.js +0 -2
  326. package/dist/state-CiXyLqg0.js.map +0 -1
  327. package/dist/studio-app/assets/index-B9MCTfuu.css +0 -2
  328. package/dist/studio-app/assets/index-CROH2NB3.js +0 -58
  329. package/dist/summary-BTksrIxn.js +0 -254
  330. package/dist/summary-BTksrIxn.js.map +0 -1
  331. package/dist/tool-target-BU1JnSE9.js.map +0 -1
  332. package/dist/tools-B10Uj7OI.js.map +0 -1
  333. package/dist/views-Cs2Oqayd.js +0 -3
  334. package/dist/views-Dqa5ojfZ.js.map +0 -1
  335. package/dist/worker-entry-BAikHl9F.js.map +0 -1
  336. package/dist/workspace-Do_SiWBs.js +0 -2
@@ -1,34 +1,42 @@
1
- import { n as UsageError } from "./errors-yDAEwmZo.js";
1
+ import { n as UsageError } from "./errors-B6BSMs03.js";
2
2
  import { a as fromCwd, l as sha256 } from "./ids-Bp6ut7ZD.js";
3
+ import { r as questionShows, t as DEFAULT_QUESTION_STATE } from "./state-CeR6oz0k.js";
3
4
  import { n as clip } from "./text-gEcKjAyp.js";
4
- import { c as resolveAnalysisModel, l as SYSTEM_PROMPT, n as callAnalysisModel, t as analysisModelName } from "./model-B1BZoZ9b.js";
5
- import { t as ANALYSIS_PROMPT_VERSION } from "./analysis-DlGBDjTj.js";
6
- import { dt as compare } from "./model-BOnlAPzs.js";
7
- import { a as familyLiftLabel, o as familyRateLabel, r as familyEffortLabel } from "./family-D2b7WD10.js";
8
- import { t as runHeader } from "./header-CALhmafp.js";
9
- import { a as sampleReasons } from "./pairs-DDsjgm5F.js";
10
- import { o as parseRecord, p as scratchDir } from "./files-CSzVADHn.js";
11
- import { l as writeCached, o as readCached, s as saveAnalysis } from "./files-DJUFg-4e.js";
12
- import { c as resolveRun, s as pickBaseline, t as RefError } from "./views-Dqa5ojfZ.js";
13
- import { c as lines, n as allRuns, t as CommandError, u as reachability } from "./commands-CLmPBrTS.js";
14
- import { a as commandSummary, i as checkCommand } from "./cli-spec-CKEYa8V2.js";
15
- import { s as openHistoryDb } from "./db-CfQFwJtq.js";
16
- import { t as author } from "./provenance-D7HK3vzt.js";
5
+ import { c as resolveAnalysisModel, l as SYSTEM_PROMPT, n as callAnalysisModel, t as analysisModelName } from "./model-D0IcOQao.js";
6
+ import { n as formatTokens } from "./usage-CleNKkly.js";
7
+ import { t as ANALYSIS_PROMPT_VERSION } from "./analysis-Bxub9LMT.js";
8
+ import { V as labelledJudgements, Y as bothUnderATenth, bt as compare } from "./model-DaX4bNLZ.js";
9
+ import { f as familyLiftLabel, p as familyRateLabel, u as familyEffortLabel } from "./suite-Cw_7G2RM.js";
10
+ import { t as runHeader } from "./header-DHQv_ZrF.js";
11
+ import { n as headToHeadLines, r as pairTallies, s as sampleReasons, u as splitsLabel } from "./pairs-CnInRu-G.js";
12
+ import { o as parseRecord, p as scratchDir } from "./files-BpUYBwGu.js";
13
+ import { l as writeCached, o as readCached, s as saveAnalysis } from "./files-BXHZFWmx.js";
14
+ import { c as resolveRun, s as pickBaseline, t as RefError } from "./views-B8w2J-gD.js";
15
+ import { r as contrastsOf } from "./contrasts-5zsj32gk.js";
16
+ import { c as lines, n as allRuns, t as CommandError, u as reachability } from "./commands-YUwlyTbr.js";
17
+ import { i as checkCommand, o as commandSummary } from "./cli-spec-qmEnQ25_.js";
18
+ import { l as TOOL_CLASSES, s as openHistoryDb } from "./db-DfhipHEF.js";
19
+ import { t as author } from "./provenance-DQ0AXn6c.js";
17
20
  import { basename, join } from "node:path";
18
21
  import { readFile } from "node:fs/promises";
19
22
  //#region src/analysis/digest.ts
20
23
  const RULES = [
21
24
  `Lift (variant pass@1 minus control pass@1) is insufficient (not measured, never a results line) when either side has fewer than 2 counted attempts; otherwise it is an effect only when its 95% interval (Newcombe) excludes 0, and within noise when the interval spans 0, whatever the point estimate.`,
22
25
  "When sources or the eval fingerprint differ across the compared runs, the pass@1 difference is not comparable: the eval changed. Never call it an effect. Do not put those mixed counts on a results line. The first line of the analysis says the eval changed. A lift is an effect only when sources match; the two-attempt floor still applies then.",
23
- "Effort (tool calls, agent time, and tokens when both sides have usage samples) is compared with an exact Mann-Whitney test: \"fewer\"/\"more\" at p < 0.05; \"insufficient\" when the attempt counts can never reach it (2 vs 2 cannot) — never because a harness dropped usage. Attempts without usage are left out of the token sample only. If either side then has no token sample, the token metric is omitted (no line, not insufficient). A Goose cell does not blank tokens on Cursor cells in the same study. Pooled across evals, tokens are an effect only when at least 2/3 of the strata that reported usage agree.",
26
+ `Effort (tool calls, agent time, and tokens when both sides have usage samples) is compared with an exact Mann-Whitney test: "fewer"/"more" at p < 0.05; "insufficient" when the attempt counts can never reach it (2 vs 2 cannot) — never because a harness dropped usage. Attempts without usage are left out of the token sample only. If either side then has no token sample, the token metric is omitted (no line, not insufficient). A Goose cell does not blank tokens on Cursor cells in the same study. Pooled across evals, tokens are an effect only when at least 2/3 of the strata that reported usage agree. Effort's separated (given from 3 vs 3) says, per metric, that the two sides' ranges do not overlap: every attempt on one side beat every attempt on the other. insufficient with separated true is a directional signal: report the ratio, the n and "no overlap, not significant" as directional, never as an effect. separated false is no direction at all.`,
24
27
  "A family fact is one pooled evaluate.each: its cases are paired samples of one suite, so its lift (Newcombe paired interval and McNemar at one attempt a case, a t interval over cases otherwise) is the result for those cases; their own pass-rate facts carry no lift. insufficient (fewer than 6 discordant pairs or 6 cases) is not measured. A family's minLift gates the pooled lower bound.",
25
28
  "Each factor claim has a tier: controlled (two cells in one run that differ in one factor), pooled (the same contrast over comparable runs, and across evals), observed (a change between runs, which is weaker; \"confounded\" when several parts changed), not_measured (one level only).",
26
29
  `A cell with mixed outcomes is flaky only with at least 6 counted attempts over comparable runs; below that it is "insufficient", not flaky.`,
27
30
  "Drift marked noise changed only an agent CLI's own runtime state (e.g. ~/.cursor/cli-config.json): not a real change, and those runs stay comparable.",
28
31
  "An eval where every cell passes at least 95% is saturated: pass@1 cannot tell cells apart there, effort can.",
29
32
  "Judge verdicts carry no recorded reason; an explanation of a failed verdict is your reading of the cited output, and must say so.",
33
+ "A criteria fact lists each check (expect label, judges included) per cell: rows only for labels whose rate differs between cells, or is mixed within one; neverMet labels failed on every counted attempt of every cell, alwaysMet passed on all of them. A neverMet or alwaysMet label is the same in every arm: it can't explain a difference between arms.",
34
+ "frame study means every cell in scope is ungated (gate: 'none'): the run measures how its arms differ, so attempts that fail are data, not a failed gate.",
35
+ "setup, rules and cli give context and are not citable: cite facts, evidence and attempts.",
36
+ "A context-use fact counts each attempt's tool calls by class (context, dependency, web, verify, workspace) and lists which placed files each arm opened: how much an arm leaned on what its environment declared versus digging in installed packages. The classes are a heuristic over tool names and paths; cite them as counts, not as proof of intent.",
37
+ "A contrast fact (kind contrast) is one pair of arms on one harness, a against b, when an eval has two variants or more: pass rate and lift of a over b, the checks that tell them apart (discriminates or mixed; sameOnBoth counts the rest) and effort. It answers how two variants differ from each other, not only from the control; gating stays each variant against its control.",
30
38
  "A check (kind checks) whose verdict is both-pass or both-fail passes, or fails, on both the variant and its control: it is no evidence for or against the variant. Only discriminates rows say which requirement separated them.",
31
- "Compare-question win rates annotate the run: they never change pass, fail or the exit code. Cite them as annotation, never as a result that gates the run. A vote's reason is the model's wording: do not treat it as a check."
39
+ "Compare-question win rates annotate the run: they never change pass, fail or the exit code. Cite them as annotation, never as a result that gates the run. A vote's reason is the model's wording: do not treat it as a check. Each pair is voted in both orders; splits counts pairs whose two orders picked opposite sides (the position decided, not the work), and rates count such a pair as one win each. With more than two arms, read headToHead (a–b wins per pair, splits apart), not the pooled rates. shows lists what each side was shown: a question that shows output or transcript can favour the better-written account rather than the better work, and one that shows artifacts rests on screenshots."
32
40
  ];
33
41
  const pts = (x) => x === null || x === void 0 ? null : `${x >= 0 ? "+" : "−"}${Math.round(Math.abs(x) * 100)}`;
34
42
  const liftText = (points, lo, hi) => `${pts(points)} pts (95% ${pts(lo)}…${pts(hi)})`;
@@ -56,7 +64,7 @@ function evalSourcesChanged(base, head) {
56
64
  /** Short tags for the evals in scope: the file's base name, numbered when a file has several. */
57
65
  function evalTags(evals) {
58
66
  const tags = /* @__PURE__ */ new Map();
59
- const bases = evals.map((e) => basename(e.file).replace(/\.(?:eval|es)\.ts$|\.[jt]s$/, ""));
67
+ const bases = evals.map((e) => basename(e.file).replace(/(?:\.\w+)?\.[jt]s$/, ""));
60
68
  evals.forEach((e, i) => {
61
69
  const b = bases[i];
62
70
  const same = bases.filter((x) => x === b).length;
@@ -71,7 +79,97 @@ function cellTags(e) {
71
79
  const prefix = (c) => harnesses.length < 2 ? "" : `${kinds.length === harnesses.length ? c.harnessKind : c.harness}:`;
72
80
  return new Map(e.cells.map((c) => [c.key, `${prefix(c)}${c.variant ?? "control"}`]));
73
81
  }
82
+ /**
83
+ * Cell names for facts: each tag, with a compare's control named by its environment
84
+ * (`no-skill (control)`) so a reading can name the arm. Attempt ids keep the tag.
85
+ */
86
+ function cellNames(e, tags) {
87
+ const compare = e.cells.some((c) => c.role === "variant");
88
+ return new Map(e.cells.map((c) => {
89
+ const tag = tags.get(c.key) ?? c.key;
90
+ const named = compare && c.role === "control" && c.environment && c.environment !== "-";
91
+ return [c.key, named ? tag.replace(/control$/, `${c.environment} (control)`) : tag];
92
+ }));
93
+ }
74
94
  const counted = (a) => a.outcome === "pass" || a.outcome === "fail";
95
+ const LABEL_CHARS = 60;
96
+ const round2 = (x) => Math.round(x * 100) / 100;
97
+ const round1 = (x) => Math.round(x * 10) / 10;
98
+ const ratioText = (r) => r == null ? "×–" : `×${Number(r).toFixed(2)}`;
99
+ /** The labels of an attempt's assertions that failed or couldn't answer. */
100
+ const failedLabels = (a) => (a.assertions ?? []).filter((x) => x.status !== "pass").map((x) => clip(x.label, LABEL_CHARS));
101
+ /** The counted attempts that reached a check: one stopped before it by a hard failure didn't. */
102
+ const answered = (t) => t.pass + t.fail + t.error;
103
+ /** Every counted attempt passed (`all`), none did, or some; undefined when none answered. */
104
+ const sideOf = (t) => {
105
+ const n = answered(t);
106
+ if (n === 0) return void 0;
107
+ return t.pass === n ? "all" : t.pass === 0 ? "none" : "some";
108
+ };
109
+ /** `2/3`, or `not run` when no counted attempt reached the check. */
110
+ const rateOf = (t) => answered(t) ? `${t.pass}/${answered(t)}` : "not run";
111
+ /** A side of a check with a verdict, counted as the verdict counts it: passes over pass or fail. */
112
+ const verdictRate = (t) => `${t.pass}/${t.pass + t.fail}`;
113
+ /** Items interleaved by group, groups in order of first appearance: one from each, then the next. */
114
+ function roundRobin(items, key) {
115
+ const groups = /* @__PURE__ */ new Map();
116
+ for (const item of items) groups.set(key(item), [...groups.get(key(item)) ?? [], item]);
117
+ const out = [];
118
+ for (let i = 0; out.length < items.length; i++) for (const g of groups.values()) if (i < g.length) out.push(g[i]);
119
+ return out;
120
+ }
121
+ /** `study` when every cell in scope is ungated, so the run compares arms rather than gating them. */
122
+ const frameOf = (evals) => {
123
+ const cells = evals.flatMap((e) => e.cells);
124
+ return cells.length && cells.every((c) => c.gate === "none") ? "study" : "gate";
125
+ };
126
+ /**
127
+ * One eval's checks per cell: a row with each cell's rate (and mean judge score) for each label
128
+ * that differs between cells or is mixed within one, and the labels every cell failed, or passed,
129
+ * on every counted attempt.
130
+ */
131
+ function criteriaOf(e, tag) {
132
+ const cells = e.cells.filter((c) => c.checks?.length);
133
+ const labels = [...new Set(cells.flatMap((c) => (c.checks ?? []).map((k) => k.label)))];
134
+ if (!labels.length) return null;
135
+ const scores = /* @__PURE__ */ new Map();
136
+ for (const a of e.attempts) {
137
+ if (!counted(a)) continue;
138
+ for (const j of labelledJudgements(a)) {
139
+ if (j.check === void 0) continue;
140
+ const id = `${a.cell}\0${j.check}`;
141
+ scores.set(id, [...scores.get(id) ?? [], j.judgement.score]);
142
+ }
143
+ }
144
+ const rows = [];
145
+ const neverMet = [];
146
+ const alwaysMet = [];
147
+ for (const label of labels) {
148
+ const tallies = cells.flatMap((c) => {
149
+ const k = c.checks?.find((x) => x.label === label);
150
+ return k ? [{
151
+ c,
152
+ k
153
+ }] : [];
154
+ });
155
+ const sides = new Set(tallies.map(({ k }) => sideOf(k)));
156
+ if (sides.size === 1 && sides.has("none")) neverMet.push(clip(label, LABEL_CHARS));
157
+ else if (sides.size === 1 && sides.has("all")) alwaysMet.push(clip(label, LABEL_CHARS));
158
+ else rows.push({
159
+ label: clip(label, LABEL_CHARS),
160
+ cells: Object.fromEntries(tallies.map(({ c, k }) => {
161
+ const s = scores.get(`${c.key}\0${label}`);
162
+ const mean = s?.length ? ` · ${(s.reduce((x, y) => x + y, 0) / s.length).toFixed(2)}` : "";
163
+ return [tag(c.key), `${rateOf(k)}${mean}`];
164
+ }))
165
+ });
166
+ }
167
+ return {
168
+ rows,
169
+ neverMet,
170
+ alwaysMet
171
+ };
172
+ }
75
173
  /** The digest, and the evidence dropped from it to fit its cap, whole, for tools to read back. */
76
174
  async function buildDigestKeepingDropped(input) {
77
175
  const { head, base, db } = input;
@@ -80,6 +178,7 @@ async function buildDigestKeepingDropped(input) {
80
178
  const needle = input.evalFilter?.toLowerCase() ?? null;
81
179
  const inScope = (e) => !needle || e.id.toLowerCase().includes(needle);
82
180
  const scopeEvals = head.record.evals.filter(inScope);
181
+ const frame = frameOf(scopeEvals);
83
182
  const tags = evalTags(scopeEvals);
84
183
  const evalKeys = new Set(scopeEvals.map((e) => e.key));
85
184
  const tagOf = (key) => tags.get(key) ?? key;
@@ -90,25 +189,30 @@ async function buildDigestKeepingDropped(input) {
90
189
  for (const r of runs) for (const e of r.record.evals) {
91
190
  if (!evalKeys.has(e.key)) continue;
92
191
  const cells = cellTags(e);
93
- for (const [key, tag] of cells) cellTagOf.set(`${r.record.runId}\0${e.key}\0${key}`, tag);
192
+ const names = cellNames(e, cells);
193
+ for (const [key, name] of names) cellTagOf.set(`${r.record.runId}\0${e.key}\0${key}`, name);
94
194
  for (const a of e.attempts) {
95
195
  const id = `${short.get(r.record.runId)}/${tagOf(e.key)}/${cells.get(a.cell)}#${a.n}`;
96
196
  idOf.set(`${r.record.runId}\0${a.key}`, id);
97
- const judge = a.judgements[0];
98
197
  const any = a.files.transcript ?? a.files.judgeInput ?? a.checks.find((c) => c.log)?.log;
198
+ const assertions = a.assertions ?? [];
199
+ const failed = failedLabels(a);
200
+ const judges = labelledJudgements(a);
99
201
  attempts[id] = {
100
202
  run: short.get(r.record.runId),
101
203
  runId: r.record.runId,
102
204
  key: a.key,
103
205
  eval: tagOf(e.key),
104
206
  evalSlug: e.slug,
105
- cell: cells.get(a.cell),
207
+ cell: names.get(a.cell),
106
208
  attempt: a.id,
107
209
  outcome: a.outcome,
108
210
  tools: a.activity.tools,
109
211
  agentS: Math.round(a.timings.agentMs / 1e3),
110
- ...judge ? { judge: Math.round(judge.score * 100) / 100 } : {},
111
- checks: a.checks.length,
212
+ ...assertions.length ? { checks: `${assertions.filter((x) => x.status === "pass").length}/${assertions.length}` } : {},
213
+ ...failed.length ? { failed } : {},
214
+ ...judges.length ? { judges: Object.fromEntries(judges.map((j) => [clip(j.label, LABEL_CHARS), round2(j.judgement.score)])) } : {},
215
+ execs: a.checks.length,
112
216
  artifacts: any ? `${r.record.runId}/${any.path.split("/").slice(0, 3).join("/")}` : null
113
217
  };
114
218
  }
@@ -155,7 +259,7 @@ async function buildDigestKeepingDropped(input) {
155
259
  cases: f.ran === f.cases ? f.cases : `${f.ran} of ${f.cases}`,
156
260
  rates: f.rates.map((x) => ({
157
261
  cell: cellTag(r.record.runId, member.key, x.cell),
158
- passRate: familyRateLabel(x)
262
+ passAt1: familyRateLabel(x)
159
263
  })),
160
264
  lifts: f.lifts.map((l) => ({
161
265
  cell: cellTag(r.record.runId, member.key, l.variant),
@@ -188,16 +292,27 @@ async function buildDigestKeepingDropped(input) {
188
292
  medianToolCalls: row.tools_median,
189
293
  medianAgentS: row.agent_s_median,
190
294
  ...row.tokens_median != null ? { medianTokens: row.tokens_median } : {},
295
+ ...row.workspace_calls_median != null ? { medianCallsByClass: Object.fromEntries(TOOL_CLASSES.flatMap((k) => {
296
+ const m = row[`${k}_calls_median`];
297
+ return m ? [[k, m]] : [];
298
+ })) } : {},
191
299
  ...row.control_key ? { vsControl: {
192
- toolCalls: `${row.tools_median} vs ${row.control_tools_median} (×${Number(row.tools_ratio).toFixed(2)})`,
193
- agentS: `${row.agent_s_median} vs ${row.control_agent_s_median}`,
300
+ n: `${row.n} vs ${row.control_n}`,
301
+ toolCalls: `${row.tools_median} vs ${row.control_tools_median} (${ratioText(row.tools_ratio)})`,
302
+ agentS: bothUnderATenth(Number(row.agent_s_median) * 1e3, Number(row.control_agent_s_median) * 1e3) ? "<0.1 vs <0.1" : `${row.agent_s_median} vs ${row.control_agent_s_median} (${ratioText(row.agent_s_ratio)})`,
194
303
  p: row.tools_p,
195
304
  verdict: row.verdict,
305
+ timeVerdict: row.time_verdict,
196
306
  ...row.tokens_verdict ? {
197
- tokens: `${row.tokens_median} vs ${row.control_tokens_median} (×${Number(row.tokens_ratio).toFixed(2)})`,
307
+ tokens: `${formatTokens(row.tokens_median)} vs ${formatTokens(row.control_tokens_median)} (${ratioText(row.tokens_ratio)})`,
198
308
  tokensP: row.tokens_p,
199
309
  tokensVerdict: row.tokens_verdict
200
310
  } : {},
311
+ ...Math.min(Number(row.n), Number(row.control_n)) >= 3 ? { separated: {
312
+ tools: row.separated === 1,
313
+ agentS: row.time_separated === 1,
314
+ ...row.tokens_separated != null ? { tokens: row.tokens_separated === 1 } : {}
315
+ } } : {},
201
316
  ...row.tokens_note ? { unreportedUsage: row.tokens_note } : {}
202
317
  } } : {}
203
318
  }))
@@ -215,7 +330,7 @@ async function buildDigestKeepingDropped(input) {
215
330
  OR (tier = 'observed' AND run_id IN (${runList}) AND eval_key IN (${evalList}))
216
331
  OR tier = 'not_measured'
217
332
  ORDER BY CASE tier WHEN 'pooled' THEN 0 WHEN 'controlled' THEN 1 WHEN 'observed' THEN 2 ELSE 3 END,
218
- factor, level, eval_key`).filter((f) => f.tier !== "pooled" || f.factor !== "environment" || harnesses.includes(f.context));
333
+ factor, level, eval_key`).filter((f) => f.tier !== "pooled" || f.factor !== "environment" || f.context !== null && harnesses.includes(f.context));
219
334
  for (const f of factors) {
220
335
  if (!base && (f.tier === "pooled" || f.tier === "observed")) continue;
221
336
  if (f.tier === "not_measured") {
@@ -295,6 +410,51 @@ async function buildDigestKeepingDropped(input) {
295
410
  firstReadAtLines: [...c.lines].sort((a, b) => a - b)
296
411
  }))
297
412
  });
413
+ const classRows = q(`SELECT t.run_id, a.eval_key, a.cell_key, a.n, t.class, COUNT(*) AS calls
414
+ FROM tool_calls t JOIN attempts a ON a.run_id = t.run_id AND a.key = t.attempt_key
415
+ WHERE t.run_id IN (${runList}) AND a.eval_key IN (${evalList}) AND a.outcome IN ('pass', 'fail')
416
+ GROUP BY t.run_id, a.key, t.class ORDER BY t.run_id, a.eval_key, a.cell_key, a.n`);
417
+ const fileRows = q(`SELECT run_id, eval_key, cell_key, path, COUNT(*) AS attempts, SUM(reads > 0) AS read
418
+ FROM skill_files WHERE run_id IN (${runList}) AND eval_key IN (${evalList})
419
+ GROUP BY run_id, eval_key, cell_key, path ORDER BY run_id, eval_key, cell_key, path`);
420
+ const useOf = /* @__PURE__ */ new Map();
421
+ const useEntry = (row) => {
422
+ const id = `${row.run_id}\0${row.eval_key}\0${row.cell_key}`;
423
+ const entry = useOf.get(id) ?? {
424
+ classes: /* @__PURE__ */ new Map(),
425
+ files: []
426
+ };
427
+ useOf.set(id, entry);
428
+ return entry;
429
+ };
430
+ for (const r of classRows) {
431
+ const entry = useEntry(r);
432
+ const per = entry.classes.get(r.class) ?? /* @__PURE__ */ new Map();
433
+ per.set(r.n, r.calls);
434
+ entry.classes.set(r.class, per);
435
+ }
436
+ for (const r of fileRows) useEntry(r).files.push(`${r.path} ${r.read}/${r.attempts}`);
437
+ if (classRows.length) {
438
+ const attemptNs = /* @__PURE__ */ new Map();
439
+ for (const r of classRows) {
440
+ const id = `${r.run_id}\0${r.eval_key}\0${r.cell_key}`;
441
+ attemptNs.set(id, [.../* @__PURE__ */ new Set([...attemptNs.get(id) ?? [], r.n])]);
442
+ }
443
+ fact("context-use", {
444
+ note: "Tool calls per counted attempt by class (context: a placed skill, rules or MCP tool; dependency: node_modules, site-packages, vendor, --help; web; verify: a check command or test/build/lint; workspace: the rest), a heuristic. files: each placed file, opened in k/n attempts.",
445
+ cells: [...useOf].map(([id, u]) => {
446
+ const [runId, evalKey, cellKey] = id.split("\0");
447
+ const ns = (attemptNs.get(id) ?? []).sort((a, b) => a - b);
448
+ return {
449
+ run: short.get(runId),
450
+ eval: tagOf(evalKey),
451
+ cell: cellTag(runId, evalKey, cellKey),
452
+ perAttempt: Object.fromEntries([...u.classes].map(([k, per]) => [k, ns.map((n) => per.get(n) ?? 0).join(" ")])),
453
+ ...u.files.length ? { files: u.files } : {}
454
+ };
455
+ })
456
+ });
457
+ }
298
458
  const pooled = /* @__PURE__ */ new Map();
299
459
  for (const r of runs) for (const e of r.record.evals) {
300
460
  if (!evalKeys.has(e.key)) continue;
@@ -319,46 +479,59 @@ async function buildDigestKeepingDropped(input) {
319
479
  })),
320
480
  saturated
321
481
  });
322
- const judged = runs.flatMap((r) => r.record.evals.filter((e) => evalKeys.has(e.key)).flatMap((e) => e.attempts.flatMap((a) => a.judgements.map((j) => ({
323
- r,
324
- a,
325
- j
326
- })))));
482
+ const differing = /* @__PURE__ */ new Map();
483
+ for (const r of runs) for (const e of r.record.evals) {
484
+ if (!evalKeys.has(e.key)) continue;
485
+ const criteria = criteriaOf(e, (cell) => cellTag(r.record.runId, e.key, cell));
486
+ if (!criteria) continue;
487
+ differing.set(`${r.record.runId}\0${e.key}`, new Set(criteria.rows.map((x) => x.label)));
488
+ fact("criteria", {
489
+ run: short.get(r.record.runId),
490
+ eval: tagOf(e.key),
491
+ note: "Each check (expect label) per cell: passed/counted, then the mean judge score for a judge.",
492
+ ...criteria
493
+ });
494
+ }
495
+ const judged = runs.flatMap((r) => r.record.evals.filter((e) => evalKeys.has(e.key)).flatMap((e) => e.attempts.flatMap((a) => a.judgements)));
327
496
  if (judged.length) fact("judge", {
328
- models: [...new Set(judged.map(({ j }) => j.resolvedModel ?? j.model))],
329
- threshold: [...new Set(judged.map(({ j }) => j.threshold))],
497
+ models: [...new Set(judged.map((j) => j.resolvedModel ?? j.model))],
498
+ threshold: [...new Set(judged.map((j) => j.threshold))],
330
499
  verdicts: judged.length,
331
- pass: judged.filter(({ j }) => j.verdict === "pass").length,
332
- scoresAtLeast098: judged.filter(({ j }) => j.score >= .98).length,
333
- nearThreshold: judged.filter(({ j }) => Math.abs(j.score - j.threshold) <= .1).length,
334
- failures: judged.filter(({ j }) => j.verdict === "fail").map(({ r, a, j }) => ({
335
- attempt: idOf.get(`${r.record.runId}\0${a.key}`),
336
- score: j.score
337
- })),
500
+ pass: judged.filter((j) => j.verdict === "pass").length,
501
+ scoresAtLeast098: judged.filter((j) => j.score >= .98).length,
502
+ nearThreshold: judged.filter((j) => Math.abs(j.score - j.threshold) <= .1).length,
338
503
  reasons: "not recorded"
339
504
  });
340
- const failures = runs.slice().reverse().flatMap((r) => r.record.evals.filter((e) => evalKeys.has(e.key)).flatMap((e) => e.attempts.filter((a) => a.outcome === "fail" || a.outcome === "infra_error").map((a) => ({
505
+ const failures = roundRobin(runs.slice().reverse().flatMap((r) => r.record.evals.filter((e) => evalKeys.has(e.key)).flatMap((e) => e.attempts.filter((a) => a.outcome === "fail" || a.outcome === "infra_error").map((a) => ({
341
506
  r,
342
507
  e,
343
508
  a
344
- }))));
345
- for (const { r, e, a } of failures.slice(0, 8)) {
346
- const j = a.judgements.find((x) => x.verdict === "fail");
509
+ })))), ({ r, e, a }) => `${r.record.runId}\0${e.key}\0${a.cell}`);
510
+ const cellsSeen = /* @__PURE__ */ new Set();
511
+ const failureFacts = frame === "study" ? failures.filter(({ r, e, a }) => {
512
+ const id = `${r.record.runId}\0${e.key}\0${a.cell}`;
513
+ return !cellsSeen.has(id) && !!cellsSeen.add(id);
514
+ }) : failures.slice(0, 8);
515
+ for (const { r, e, a } of failureFacts) {
516
+ const failed = failedLabels(a);
517
+ const judges = labelledJudgements(a).filter((j) => j.judgement.verdict === "fail");
347
518
  fact("failure", {
348
519
  attempt: idOf.get(`${r.record.runId}\0${a.key}`),
349
520
  outcome: a.outcome,
350
521
  errorKind: a.error?.kind ?? null,
351
522
  message: a.error ? clip(a.error.message.split("\n")[0] ?? "", 300) : null,
352
523
  gated: e.cells.find((c) => c.key === a.cell)?.gate !== "none",
353
- ...j ? { judge: {
354
- question: j.question,
355
- score: j.score,
356
- threshold: j.threshold
357
- } } : {},
358
- failingChecks: a.checks.map((c, i) => ({
359
- check: i + 1,
524
+ ...failed.length ? { failed } : {},
525
+ ...judges.length ? { judges: judges.map((j) => ({
526
+ label: clip(j.label, LABEL_CHARS),
527
+ question: clip(j.judgement.question, 300),
528
+ score: j.judgement.score,
529
+ threshold: j.judgement.threshold
530
+ })) } : {},
531
+ failingExecs: a.checks.map((c, i) => ({
532
+ exec: i + 1,
360
533
  exit: c.exitCode,
361
- command: c.command
534
+ command: clip(c.command, 300)
362
535
  })).filter((c) => c.exit !== 0)
363
536
  });
364
537
  }
@@ -411,11 +584,14 @@ async function buildDigestKeepingDropped(input) {
411
584
  for (const a of e.answers ?? []) {
412
585
  const ties = a.votes.filter((v) => v.winner === "tie").length;
413
586
  const reasons = sampleReasons(a.votes);
587
+ const splits = splitsLabel(pairTallies(a.votes));
588
+ const headToHead = headToHeadLines(a.votes);
414
589
  fact("compare-question", {
415
590
  run: short.get(r.record.runId),
416
591
  eval: tagOf(e.key),
417
592
  question: clip(a.question, 120),
418
593
  model: a.resolvedModel ?? a.model,
594
+ shows: questionShows(a.stateOptions ?? DEFAULT_QUESTION_STATE, a.artifacts),
419
595
  votes: a.votes.length,
420
596
  ties,
421
597
  ...a.rates.length ? { rates: a.rates.map((x) => ({
@@ -424,6 +600,8 @@ async function buildDigestKeepingDropped(input) {
424
600
  wins: x.wins,
425
601
  n: x.n
426
602
  })) } : {},
603
+ ...splits ? { splits } : {},
604
+ ...headToHead.length ? { headToHead } : {},
427
605
  ...a.error ? { error: clip(a.error, 200) } : {},
428
606
  ...a.votes.length === 0 && a.error === void 0 ? { note: "no pairs to judge: attempts that failed their checks are left out" } : {},
429
607
  ...reasons.length ? { reasons } : {}
@@ -432,8 +610,52 @@ async function buildDigestKeepingDropped(input) {
432
610
  }
433
611
  for (const r of runs) for (const e of r.record.evals) {
434
612
  if (!evalKeys.has(e.key)) continue;
613
+ const tag = (key) => cellTag(r.record.runId, e.key, key);
614
+ const contrasts = contrastsOf(e);
615
+ for (const x of contrasts) {
616
+ const apart = x.checks.filter((k) => k.verdict === "discriminates" || k.verdict === "mixed");
617
+ const ef = x.effort;
618
+ fact("contrast", {
619
+ run: short.get(r.record.runId),
620
+ eval: tagOf(e.key),
621
+ a: tag(x.a),
622
+ b: tag(x.b),
623
+ ...x.lift ? {
624
+ passRate: `${x.lift.variant.pass}/${x.lift.variant.counted} vs ${x.lift.control.pass}/${x.lift.control.counted}`,
625
+ lift: digestLift(x.lift.variant.counted, x.lift.control.counted, x.lift.points, x.lift.interval.lo, x.lift.interval.hi),
626
+ liftVerdict: digestLiftVerdict(x.lift.variant.counted, x.lift.control.counted, x.lift.withinNoise)
627
+ } : {},
628
+ checks: apart.map((k) => ({
629
+ label: clip(k.label, LABEL_CHARS),
630
+ a: verdictRate(k.a),
631
+ b: verdictRate(k.b),
632
+ verdict: k.verdict
633
+ })),
634
+ sameOnBoth: x.checks.length - apart.length,
635
+ ...ef ? { effort: {
636
+ n: `${ef.variant.n} vs ${ef.control.n}`,
637
+ toolCalls: `${ef.variant.tools.median} vs ${ef.control.tools.median} (${ratioText(ef.toolsRatio)})`,
638
+ agentS: bothUnderATenth(ef.variant.agentMs.median, ef.control.agentMs.median) ? "<0.1 vs <0.1" : `${round1(ef.variant.agentMs.median / 1e3)} vs ${round1(ef.control.agentMs.median / 1e3)} (${ratioText(ef.agentMsRatio)})`,
639
+ verdict: ef.verdict,
640
+ timeVerdict: ef.timeVerdict,
641
+ ...ef.tokensVerdict && ef.variant.tokens && ef.control.tokens ? {
642
+ tokens: `${formatTokens(ef.variant.tokens.median)} vs ${formatTokens(ef.control.tokens.median)} (${ratioText(ef.tokensRatio)})`,
643
+ tokensVerdict: ef.tokensVerdict
644
+ } : {},
645
+ ...Math.min(ef.variant.n, ef.control.n) >= 3 ? { separated: {
646
+ tools: ef.separated,
647
+ agentS: ef.timeSeparated,
648
+ ...ef.tokensSeparated !== null ? { tokens: ef.tokensSeparated } : {}
649
+ } } : {}
650
+ } } : {}
651
+ });
652
+ }
653
+ if (contrasts.length) continue;
435
654
  for (const c of e.cells) {
436
- const rows = (c.checks ?? []).filter((k) => k.control && k.verdict);
655
+ const rows = (c.checks ?? []).flatMap((k) => k.control && k.verdict ? [{
656
+ ...k,
657
+ control: k.control
658
+ }] : []);
437
659
  if (!rows.length) continue;
438
660
  fact("checks", {
439
661
  run: short.get(r.record.runId),
@@ -441,8 +663,8 @@ async function buildDigestKeepingDropped(input) {
441
663
  cell: c.key,
442
664
  rows: rows.map((k) => ({
443
665
  label: clip(k.label, 80),
444
- variant: `${k.pass}/${k.pass + k.fail + k.notRun}`,
445
- control: `${k.control?.pass}/${(k.control?.pass ?? 0) + (k.control?.fail ?? 0) + (k.control?.notRun ?? 0)}`,
666
+ variant: verdictRate(k),
667
+ control: verdictRate(k.control),
446
668
  verdict: k.verdict
447
669
  }))
448
670
  });
@@ -474,18 +696,29 @@ async function buildDigestKeepingDropped(input) {
474
696
  } catch {}
475
697
  return [];
476
698
  };
477
- for (const { r, e, a } of failures.slice(0, 3)) {
699
+ const discriminating = ({ r, e, a }) => failedLabels(a).some((l) => differing.get(`${r.record.runId}\0${e.key}`)?.has(l));
700
+ const perCell = /* @__PURE__ */ new Map();
701
+ for (const f of failures) {
702
+ const id = `${f.r.record.runId}\0${f.e.key}\0${f.a.cell}`;
703
+ const prev = perCell.get(id);
704
+ if (!prev || !discriminating(prev) && discriminating(f)) perCell.set(id, f);
705
+ }
706
+ for (const [i, { r, e, a }] of [...perCell.values()].slice(0, 6).entries()) {
478
707
  const id = idOf.get(`${r.record.runId}\0${a.key}`);
479
708
  const lines = await lastText(r.record.runId, a);
480
- const j = a.judgements.find((x) => x.verdict === "fail");
481
- if (j) lines.push(`judge question: ${j.question}`, `judge score: ${j.score} (threshold ${j.threshold})`);
482
- for (const [i, c] of a.checks.entries()) {
709
+ const judges = labelledJudgements(a).filter((j) => j.judgement.verdict === "fail");
710
+ for (const { label, judgement: j } of judges) lines.push(`judge ${clip(label, LABEL_CHARS)}: ${j.question}`, `judge score: ${j.score} (threshold ${j.threshold})`);
711
+ for (const x of a.assertions ?? []) {
712
+ if (x.status === "pass" || /(^|\.)toPass$/.test(x.matcher)) continue;
713
+ lines.push(`check ${x.status}: ${clip(x.label, LABEL_CHARS)}: ${clip(x.message ?? "", 300)}`);
714
+ }
715
+ for (const [n, c] of a.checks.entries()) {
483
716
  if (c.exitCode === 0 || !c.log) continue;
484
717
  const log = await readFile(join(r.dir, r.record.runId, ...c.log.path.split("/")), "utf8").catch(() => "");
485
- lines.push(`check ${i + 1} (exit ${c.exitCode}) ${c.command}:`, ...log.trimEnd().split("\n").slice(-15));
718
+ lines.push(`exec ${n + 1} (exit ${c.exitCode}) ${c.command}:`, ...log.trimEnd().split("\n").slice(-15));
486
719
  }
487
- add(`attempt:${id}`, `a failing attempt: its final message${j ? " and the judge question it failed" : ""}`, lines, 1);
488
- if (j) {
720
+ add(`attempt:${id}`, `a failing attempt of ${cellTag(r.record.runId, e.key, a.cell)}: its final message${judges.length ? " and the judge questions it failed" : ""}`, lines, 1);
721
+ if (judges[0] && i < 3) {
489
722
  const twin = e.attempts.find((x) => x.cell === a.cell && x.outcome === "pass");
490
723
  if (twin) add(`attempt:${idOf.get(`${r.record.runId}\0${twin.key}`)}`, `the passing twin of ${id} (same cell): its final message`, await lastText(r.record.runId, twin), 2);
491
724
  }
@@ -505,13 +738,14 @@ async function buildDigestKeepingDropped(input) {
505
738
  }
506
739
  }
507
740
  const digest = {
508
- digestVersion: 8,
741
+ digestVersion: 10,
509
742
  scope: {
510
743
  kind: "run",
511
744
  head: short.get(head.record.runId),
512
745
  base: base ? "r1" : null,
513
746
  evals: input.evalFilter
514
747
  },
748
+ frame,
515
749
  runs: Object.fromEntries(runs.map((r) => [short.get(r.record.runId), {
516
750
  runId: r.record.runId,
517
751
  commit: r.record.git?.sha.slice(0, 7) ?? null,
@@ -640,7 +874,7 @@ function renderText(doc) {
640
874
  }
641
875
  //#endregion
642
876
  //#region src/analysis/validate.ts
643
- const CHECK = /^(.+):check(\d+)$/;
877
+ const EXEC = /^(.+):exec(\d+)$/;
644
878
  const LINE = /^(E\d+):L(\d+)$/;
645
879
  const TRANSCRIPT = /^transcript:(.+)#L(\d+)$/;
646
880
  const normal = (s) => s.replace(/\s+/g, " ").trim().toLowerCase();
@@ -657,21 +891,21 @@ function citations(digest) {
657
891
  if (ids.has(c)) return factText.get(c) ?? evidenceText.get(c) ?? JSON.stringify(digest.attempts[c]);
658
892
  const line = LINE.exec(c);
659
893
  if (line) {
660
- const [, id, n] = line;
894
+ const [, id = "", n = ""] = line;
661
895
  if (!lines.get(id)?.has(Number(n))) return null;
662
896
  return digest.evidence.find((e) => e.id === id)?.lines.find((l) => l.startsWith(`L${n} `)) ?? null;
663
897
  }
664
898
  const transcript = TRANSCRIPT.exec(c);
665
899
  if (transcript) {
666
- const [, attempt, n] = transcript;
900
+ const [, attempt = "", n = ""] = transcript;
667
901
  for (const id of evidenceOf(attempt)) if (lines.get(id)?.has(Number(n))) return resolve(`${id}:L${n}`);
668
902
  return null;
669
903
  }
670
- const check = CHECK.exec(c);
671
- if (check) {
672
- const [, attempt, n] = check;
904
+ const exec = EXEC.exec(c);
905
+ if (exec) {
906
+ const [, attempt = "", n = ""] = exec;
673
907
  const a = digest.attempts[attempt];
674
- return a && Number(n) >= 1 && Number(n) <= a.checks ? JSON.stringify(a) : null;
908
+ return a && Number(n) >= 1 && Number(n) <= a.execs ? JSON.stringify(a) : null;
675
909
  }
676
910
  return null;
677
911
  };
@@ -679,7 +913,7 @@ function citations(digest) {
679
913
  }
680
914
  const ANY_NUMBER = /[−-]?\d+(?:\.\d+)?/g;
681
915
  const FRACTION = /(\d+)\/(\d+)/g;
682
- const ATTEMPT_CITE = /:check\d+$|:L\d+$/;
916
+ const ATTEMPT_CITE = /:exec\d+$|:L\d+$/;
683
917
  /** A decimal in [0, 1]: the form a judge score or threshold takes in the digest. */
684
918
  const looksLikeScore = (raw) => {
685
919
  if (!raw.includes(".")) return false;
@@ -691,23 +925,24 @@ const addScore = (scores, n) => {
691
925
  };
692
926
  /**
693
927
  * Recorded judge scores (and thresholds) on the cited attempt, fact or evidence. The digest stores
694
- * them as `attempt.judge`, `judge: { score, threshold }` on a failure, and `judge score:` lines.
928
+ * them as an attempt's `judges`, a failure's `judges: [{ score, threshold }]`, a criteria row's mean
929
+ * scores, and `judge score:` lines.
695
930
  */
696
931
  function citedJudgeScores(cites, digest) {
697
932
  const scores = [];
698
933
  for (const cite of cites) {
699
934
  const id = cite.trim().replace(/^\[|\]$/g, "").replace(ATTEMPT_CITE, "");
700
- addScore(scores, digest.attempts[id]?.judge);
935
+ for (const s of Object.values(digest.attempts[id]?.judges ?? {})) addScore(scores, s);
701
936
  const fact = digest.facts.find((f) => f.id === id);
702
937
  if (fact) {
703
- const j = fact.judge;
704
- if (typeof j === "number") addScore(scores, j);
705
- else if (j && typeof j === "object") {
706
- addScore(scores, j.score);
707
- addScore(scores, j.threshold);
938
+ if (Array.isArray(fact.judges)) for (const row of fact.judges) {
939
+ if (!row || typeof row !== "object") continue;
940
+ addScore(scores, row.score);
941
+ addScore(scores, row.threshold);
708
942
  }
709
- if (Array.isArray(fact.failures)) {
710
- for (const row of fact.failures) if (row && typeof row === "object") addScore(scores, row.score);
943
+ if (Array.isArray(fact.rows)) for (const row of fact.rows) for (const v of Object.values(row?.cells ?? {})) {
944
+ const mean = / · (\d+(?:\.\d+)?)$/.exec(String(v));
945
+ if (mean) addScore(scores, Number(mean[1]));
711
946
  }
712
947
  if (Array.isArray(fact.threshold)) for (const t of fact.threshold) addScore(scores, t);
713
948
  }
@@ -881,8 +1116,8 @@ async function load(config, entry) {
881
1116
  bytes
882
1117
  };
883
1118
  }
884
- /** The model's input: the digest as JSON, after the project's own instructions. */
885
- const promptOf = (d) => `${d.instructions ? `PROJECT INSTRUCTIONS: ${d.instructions}\n\n` : ""}DIGEST:\n${JSON.stringify(d)}`;
1119
+ /** The model's input: the project's own instructions, which set the question, then the digest as JSON. */
1120
+ const promptOf = (d) => `${d.instructions ? `PROJECT INSTRUCTIONS (the question this analysis answers): ${d.instructions}\n\n` : ""}DIGEST:\n${JSON.stringify(d)}`;
886
1121
  /** `--context`: the same digest and rules, for the user's own coding agent. */
887
1122
  function contextMarkdown(d, head, base) {
888
1123
  return [
@@ -890,6 +1125,13 @@ function contextMarkdown(d, head, base) {
890
1125
  "",
891
1126
  "Analyse this reeval run for the engineer who wrote the evals. The digest below holds facts reeval computed (F…), evidence excerpts (E…, transcript lines as L<n>) and the attempts table. Cite those ids for every claim, keep to the verdicts in the facts, and suggest at most 5 concrete actions, each verified with a reeval command from the CLI list.",
892
1127
  "",
1128
+ ...d.frame === "study" ? ["This run is a study: every cell is ungated (gate: 'none'), so it measures how the arms differ. Failing attempts are data, not a failed gate.", ""] : [],
1129
+ ...d.instructions ? [
1130
+ "## Project instructions (the question this analysis answers)",
1131
+ "",
1132
+ d.instructions,
1133
+ ""
1134
+ ] : [],
893
1135
  "## How reeval decided each verdict",
894
1136
  "",
895
1137
  ...RULES.map((r) => `- ${r}`),
@@ -921,14 +1163,14 @@ function citedSummary(d, cites) {
921
1163
  for (const c of cites) {
922
1164
  const fact = d.facts.find((f) => f.id === c);
923
1165
  const evidence = d.evidence.find((e) => e.id === c || c.startsWith(`${e.id}:`));
924
- const attempt = d.attempts[c.replace(/:check\d+$/, "")];
1166
+ const attempt = d.attempts[c.replace(/:exec\d+$/, "")];
925
1167
  if (fact) {
926
1168
  const { id: _id, ...rest } = fact;
927
1169
  out[c] = clip(JSON.stringify(rest), 400);
928
1170
  } else if (evidence) {
929
1171
  const line = /:L(\d+)$/.exec(c);
930
1172
  out[c] = line ? clip(evidence.lines.find((l) => l.startsWith(`L${line[1]} `)) ?? evidence.ref, 400) : `${evidence.ref}: ${evidence.why}`;
931
- } else if (attempt) out[c] = `${attempt.runId} · ${attempt.attempt} · ${attempt.outcome} · ${attempt.tools} tool calls`;
1173
+ } else if (attempt) out[c] = `${attempt.runId} · ${attempt.attempt} · ${attempt.outcome} · ${attempt.tools} tool calls${attempt.checks ? ` · checks ${attempt.checks}` : ""}`;
932
1174
  }
933
1175
  return out;
934
1176
  }
@@ -996,7 +1238,7 @@ async function prepareAnalysis(config, head, base, evalFilter) {
996
1238
  };
997
1239
  }
998
1240
  const docBase = async (config, p) => ({
999
- kind: "es-analysis",
1241
+ kind: "reeval-analysis",
1000
1242
  schemaVersion: 1,
1001
1243
  scope: p.scope,
1002
1244
  anchor: p.head.runId,
@@ -1146,4 +1388,4 @@ async function analyzeCommand(ctx, args) {
1146
1388
  //#endregion
1147
1389
  export { failedAnalysis as a, defaultBase as i, analyzeCommand as n, prepareAnalysis as o, contextMarkdown as r, promptOf as s, analyseDigest as t };
1148
1390
 
1149
- //# sourceMappingURL=command-DUT5l13I.js.map
1391
+ //# sourceMappingURL=command-Bj39y-Wm.js.map