@iowarp/clio-coder 0.4.4 → 0.4.6

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 (598) hide show
  1. package/CHANGELOG.md +116 -2
  2. package/CONTRIBUTING.md +39 -24
  3. package/NOTICE +16 -0
  4. package/README.md +343 -403
  5. package/dist/{acp-WNAYYF4F.js → acp-UVEVWSDL.js} +25 -24
  6. package/dist/{agents-3OKXHLOI.js → agents-VWY37DTK.js} +78 -77
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/{auth-VKNNMGPU.js → auth-PCV2XQDV.js} +38 -38
  9. package/dist/builtins-PD652MTK.js +22 -0
  10. package/dist/{chunk-TQAHXW6Y.js → chunk-22PQ4TX4.js} +4 -4
  11. package/dist/{chunk-NRO2BJRH.js → chunk-24T2YZ7A.js} +10686 -4464
  12. package/dist/{chunk-Y55JBDO5.js → chunk-2AKYFREM.js} +38 -23
  13. package/dist/{chunk-NEDJ26B5.js → chunk-2GPGAE5W.js} +6 -51
  14. package/dist/{chunk-IKCO5N3L.js → chunk-2QPI3TR3.js} +3 -3
  15. package/dist/{chunk-HRQMFLJP.js → chunk-32KJPXAM.js} +6 -6
  16. package/dist/{chunk-65DEGPJ6.js → chunk-3A3CUMKA.js} +6 -4
  17. package/dist/{chunk-UXCU4E3T.js → chunk-3BJGMT2D.js} +35 -14
  18. package/dist/{chunk-5ICU3EUH.js → chunk-3HQVBIKD.js} +5 -5
  19. package/dist/{chunk-GWZNEVM2.js → chunk-3JLFK5MW.js} +9 -9
  20. package/dist/{chunk-XXYSBZIQ.js → chunk-3O2ZAUGQ.js} +4 -4
  21. package/dist/{chunk-GX5WYQO4.js → chunk-3QKXHCGS.js} +8 -8
  22. package/dist/{chunk-JCI2ROMZ.js → chunk-3T4DXWP6.js} +7 -7
  23. package/dist/{chunk-DR52UMZW.js → chunk-3UW3KU4A.js} +2 -2
  24. package/dist/{chunk-OEJSLEPW.js → chunk-3WBALRQH.js} +337 -337
  25. package/dist/{chunk-ELWDPP3Y.js → chunk-4DU2TVI4.js} +8 -8
  26. package/dist/{chunk-JSD46VO2.js → chunk-4U4TKZFR.js} +43 -36
  27. package/dist/{chunk-FEAXX7B6.js → chunk-4VMV6OS6.js} +4 -4
  28. package/dist/{chunk-2ZSONWVL.js → chunk-536HXRFE.js} +13 -13
  29. package/dist/{chunk-W54I7H25.js → chunk-5A6XR3RJ.js} +44 -19
  30. package/dist/{chunk-YPC6ZR5L.js → chunk-5CMARGPF.js} +119 -5
  31. package/dist/{chunk-KXDSS5WJ.js → chunk-5CY4Q6QI.js} +4 -4
  32. package/dist/{chunk-D4CJV46V.js → chunk-5GZICIYO.js} +3 -3
  33. package/dist/{chunk-4IUZQIJ3.js → chunk-5PHVPU4G.js} +2 -2
  34. package/dist/{chunk-Q4WO54TA.js → chunk-5QRX7SLS.js} +11 -11
  35. package/dist/{chunk-3ODX73FK.js → chunk-5VTJP36Q.js} +4 -4
  36. package/dist/chunk-5ZSZEYJK.js +119 -0
  37. package/dist/{chunk-EBY63B7G.js → chunk-6EXUUOSN.js} +2 -2
  38. package/dist/{chunk-DT3LWJOB.js → chunk-6HAO6X5B.js} +24 -6
  39. package/dist/{chunk-SVNXH4L2.js → chunk-6ICZKDUC.js} +2 -2
  40. package/dist/{chunk-K6T2ZAMZ.js → chunk-6OII3LOK.js} +6 -6
  41. package/dist/{chunk-36CT5VVL.js → chunk-6RYDAVQT.js} +138 -89
  42. package/dist/{chunk-I7XBWTYH.js → chunk-6VRRJT7L.js} +5 -5
  43. package/dist/{chunk-DQOVN6KV.js → chunk-6YA46L5A.js} +4 -4
  44. package/dist/{chunk-NZMNUPZZ.js → chunk-77CZRFTE.js} +3 -3
  45. package/dist/{chunk-NAI6ZFCY.js → chunk-7JSSKXG2.js} +122 -11
  46. package/dist/{chunk-2VTFPG5O.js → chunk-7WLRF2U5.js} +2 -2
  47. package/dist/chunk-7WUZEB2M.js +165 -0
  48. package/dist/{chunk-3UUXNFEX.js → chunk-7YJWEF2L.js} +61 -34
  49. package/dist/{chunk-3EBYEESD.js → chunk-A46ILRS2.js} +5 -5
  50. package/dist/{chunk-IXIY2H4R.js → chunk-ACCKVSHU.js} +5 -5
  51. package/dist/{chunk-UOIZ7DA4.js → chunk-AP7HDJOP.js} +2 -2
  52. package/dist/{chunk-JEIYHLOR.js → chunk-B3MOMLJ4.js} +12 -12
  53. package/dist/{chunk-APJ265NV.js → chunk-B5GGDIHT.js} +146 -146
  54. package/dist/{chunk-PMZVFWSR.js → chunk-B5ZTR6KZ.js} +2 -2
  55. package/dist/{chunk-I5FWO7L5.js → chunk-B6UM3OZC.js} +2 -2
  56. package/dist/{chunk-2CU2H6KE.js → chunk-BBV5TKE6.js} +5 -5
  57. package/dist/{chunk-23L32XTI.js → chunk-BLTEAUCB.js} +68 -39
  58. package/dist/{chunk-4O6MANBS.js → chunk-BS4GAMUB.js} +14 -10
  59. package/dist/{chunk-XULDXHTN.js → chunk-BT7HGDOX.js} +105 -53
  60. package/dist/{chunk-S66XZJOF.js → chunk-C27U2TYG.js} +2 -2
  61. package/dist/{chunk-QZWQA4DE.js → chunk-CBSKDFWL.js} +3 -3
  62. package/dist/{chunk-2LEAKD4C.js → chunk-CKK25WN3.js} +3 -3
  63. package/dist/{chunk-BYP5D4HI.js → chunk-CTTI7G3T.js} +2 -2
  64. package/dist/{chunk-XAKHZX5N.js → chunk-CVDAFGPW.js} +4 -4
  65. package/dist/{chunk-RKKLTLYB.js → chunk-CXQ37WJH.js} +3 -3
  66. package/dist/{chunk-GTUD2WMY.js → chunk-DBREN25X.js} +44 -9
  67. package/dist/{chunk-NDDGJUXD.js → chunk-DNCE23JJ.js} +2 -2
  68. package/dist/{chunk-HVDIIIQW.js → chunk-DNHVRBH4.js} +3 -3
  69. package/dist/{chunk-D7E7WCDF.js → chunk-DVNAPPXU.js} +2 -2
  70. package/dist/{chunk-6UINWWS6.js → chunk-DXLUVUD4.js} +16 -16
  71. package/dist/{chunk-YXLYO42X.js → chunk-DXVMLM3Z.js} +3 -2
  72. package/dist/{chunk-5MEZN6CB.js → chunk-DZK63TZJ.js} +6 -6
  73. package/dist/{chunk-IWHMRKLL.js → chunk-E3LEPLQ2.js} +2 -2
  74. package/dist/{chunk-JT2RFCC5.js → chunk-E7RF4KBO.js} +5 -5
  75. package/dist/{chunk-3R73A4XB.js → chunk-ECBHH7LU.js} +3 -3
  76. package/dist/chunk-ECOMVOHP.js +139 -0
  77. package/dist/chunk-EFSEIZE6.js +56 -0
  78. package/dist/{chunk-4NSRCOYP.js → chunk-EHOSNVVM.js} +3 -2
  79. package/dist/chunk-EM2WNQS2.js +93 -0
  80. package/dist/{chunk-57XXR6DR.js → chunk-F5Z7EWMN.js} +967 -246
  81. package/dist/{chunk-HAXOFFRH.js → chunk-FQOOGXBH.js} +7 -7
  82. package/dist/{chunk-ZTJUVLTU.js → chunk-FXFVDPWY.js} +2 -2
  83. package/dist/{chunk-XPLRXC72.js → chunk-GD55RTIW.js} +3 -3
  84. package/dist/{chunk-5B2AEOW5.js → chunk-GH5ZR6JP.js} +472 -472
  85. package/dist/{chunk-TOIVGRUX.js → chunk-GJ24ODAX.js} +5 -5
  86. package/dist/{chunk-EXLD33WO.js → chunk-GLYBJ4RQ.js} +24 -9
  87. package/dist/{chunk-26QSH3EJ.js → chunk-HHVJNVUJ.js} +5 -5
  88. package/dist/{chunk-F4EKGO4N.js → chunk-HL26ADLH.js} +4 -2
  89. package/dist/{chunk-FFUPXJC4.js → chunk-HPTJF6DG.js} +32 -56
  90. package/dist/{chunk-ID64D7PE.js → chunk-HXHFDHB6.js} +24 -24
  91. package/dist/{chunk-CUSRQKPU.js → chunk-HZ2T2YED.js} +299 -89
  92. package/dist/{chunk-YD5GIKET.js → chunk-HZFBVU5X.js} +49 -580
  93. package/dist/{chunk-6QOTUPRG.js → chunk-I2K2NCZQ.js} +65 -17
  94. package/dist/{chunk-SZAA6XDG.js → chunk-IFDRAD6F.js} +2 -2
  95. package/dist/{chunk-I2DWJ4GM.js → chunk-IGLVVNEG.js} +54 -42
  96. package/dist/{chunk-6Q3CYFD3.js → chunk-IKRWLEDA.js} +186 -35
  97. package/dist/{chunk-2JH2WHGE.js → chunk-J2FYEQ5L.js} +4 -4
  98. package/dist/{chunk-BMS5RKQY.js → chunk-JABWPKFY.js} +3 -3
  99. package/dist/{chunk-2DSOYNFC.js → chunk-JMPL7NUB.js} +7 -7
  100. package/dist/{chunk-QDC3K2U3.js → chunk-K2BLQC5E.js} +3 -3
  101. package/dist/{chunk-AUPNRN7C.js → chunk-K2HL3GBL.js} +4 -4
  102. package/dist/{chunk-54X7T7DK.js → chunk-KAFMW7WM.js} +72 -81
  103. package/dist/{chunk-OZNBF4L3.js → chunk-KECNXMDE.js} +2 -2
  104. package/dist/{chunk-BTK3SSSK.js → chunk-KMF54VH3.js} +2 -2
  105. package/dist/chunk-KPRLAMP4.js +32 -0
  106. package/dist/{chunk-ECH6PKUQ.js → chunk-KQ6IDQIB.js} +2 -2
  107. package/dist/{chunk-3UNOLWNZ.js → chunk-KTFSFCVN.js} +20 -9
  108. package/dist/{chunk-IRXAATOX.js → chunk-L4N3DWNW.js} +3 -3
  109. package/dist/{chunk-JQLNNIKT.js → chunk-LIN2K3EL.js} +6 -6
  110. package/dist/{chunk-2STGEDFV.js → chunk-LK2FN5JY.js} +2 -2
  111. package/dist/{chunk-LCGCVYZ4.js → chunk-LQTKDAUO.js} +2 -2
  112. package/dist/{chunk-U6TMQNSI.js → chunk-LTR5QCLS.js} +4 -4
  113. package/dist/chunk-LUL5Z66S.js +221 -0
  114. package/dist/{chunk-ELZVTCGV.js → chunk-LVFANMOH.js} +151 -327
  115. package/dist/{chunk-H7IXIC72.js → chunk-LY4N4TTL.js} +17 -3
  116. package/dist/{chunk-VKPAQYEB.js → chunk-LZBMXNLP.js} +5 -5
  117. package/dist/{chunk-UL3WSD3F.js → chunk-M4KFUXS7.js} +2 -2
  118. package/dist/{chunk-NXYCB2VD.js → chunk-M6TAYK66.js} +6 -6
  119. package/dist/{chunk-CFGTUFWB.js → chunk-MCJKEGHO.js} +2 -2
  120. package/dist/{chunk-6XLNIQDB.js → chunk-MYI32N4R.js} +2 -2
  121. package/dist/{chunk-4WR7VSYB.js → chunk-N2OKBREN.js} +23 -9
  122. package/dist/{chunk-3GY4F45V.js → chunk-NC4KV7EL.js} +6 -6
  123. package/dist/{chunk-LLXSDWXS.js → chunk-NF3BK5WR.js} +5 -5
  124. package/dist/{chunk-4M6Z5QVF.js → chunk-NNWJYUNO.js} +11 -11
  125. package/dist/chunk-NTK3WTHM.js +141 -0
  126. package/dist/{chunk-GYV6VZOC.js → chunk-NTTS3O53.js} +2 -2
  127. package/dist/{chunk-4BJ5BYCE.js → chunk-O3VV6IVK.js} +2 -2
  128. package/dist/{chunk-W6GROXXM.js → chunk-O5F25NIE.js} +2 -2
  129. package/dist/{chunk-NXIMQY5W.js → chunk-ODUTYZIU.js} +5 -5
  130. package/dist/{chunk-KFV5L5SK.js → chunk-OQM5IVJY.js} +118 -232
  131. package/dist/{chunk-75W7L2E2.js → chunk-P5JMBPDJ.js} +1052 -171
  132. package/dist/{chunk-XRZT5WY5.js → chunk-P5SC4DLJ.js} +4 -4
  133. package/dist/{chunk-S6PYF2XF.js → chunk-P6M7RKMI.js} +4 -4
  134. package/dist/{chunk-R6Q67RJH.js → chunk-PECBKCDK.js} +34 -6
  135. package/dist/{chunk-33YXPOE3.js → chunk-PPEZJWUG.js} +2 -2
  136. package/dist/{chunk-RXTN6AKH.js → chunk-PWWSIB2A.js} +5 -5
  137. package/dist/{chunk-DXKJURES.js → chunk-PZN2LQY6.js} +14 -11
  138. package/dist/{chunk-N56KALIC.js → chunk-Q7NNUHQV.js} +62 -35
  139. package/dist/{chunk-RQCKCSRL.js → chunk-QCOV5DFY.js} +22 -22
  140. package/dist/{chunk-3DPEIQKN.js → chunk-QH3ZTUOA.js} +2 -2
  141. package/dist/{chunk-NEKRRTYW.js → chunk-QJMRYTCX.js} +8 -8
  142. package/dist/{chunk-YNFKXPEC.js → chunk-QNWRHOMF.js} +35 -66
  143. package/dist/{chunk-YAKGTXEV.js → chunk-QRFXEO6Y.js} +2 -2
  144. package/dist/{chunk-35MSIRKH.js → chunk-QUIJZSDW.js} +2 -2
  145. package/dist/{chunk-72YIHOZQ.js → chunk-QXFBABFJ.js} +10 -10
  146. package/dist/chunk-R2CT5YDO.js +66 -0
  147. package/dist/{chunk-HHV2GANA.js → chunk-R2P2U3ZS.js} +2 -2
  148. package/dist/{chunk-IGLP3ODT.js → chunk-RGZNQ5CT.js} +15 -15
  149. package/dist/chunk-SD7SHNDW.js +15 -0
  150. package/dist/chunk-SL2RDHKO.js +19 -0
  151. package/dist/{chunk-NUGM5KR6.js → chunk-SRCEQKQS.js} +2 -2
  152. package/dist/{chunk-OMQNJVKW.js → chunk-SRZOW5L2.js} +43 -13
  153. package/dist/{chunk-UEPWCCTY.js → chunk-SXQKNKRA.js} +12 -12
  154. package/dist/{chunk-3M6DQK6S.js → chunk-T334FW2H.js} +7 -7
  155. package/dist/{chunk-V76WTFTW.js → chunk-T52TPHYC.js} +6 -6
  156. package/dist/{chunk-5636DCO5.js → chunk-TJFDL26W.js} +59 -12
  157. package/dist/{chunk-3I7MS7N2.js → chunk-TK2BMCBZ.js} +2 -2
  158. package/dist/{chunk-5OIVVPHF.js → chunk-TN5FW4XY.js} +13 -6
  159. package/dist/{chunk-LL4KHSZI.js → chunk-U2MSJ57E.js} +2 -2
  160. package/dist/{chunk-FTMGRKEF.js → chunk-U44YYLVV.js} +4 -4
  161. package/dist/{chunk-YECAMM3D.js → chunk-U7H5WRG5.js} +5 -5
  162. package/dist/{chunk-5TUB6SLS.js → chunk-UFYNOQK4.js} +7 -7
  163. package/dist/{chunk-R346GLFC.js → chunk-UHW5V7HC.js} +2 -2
  164. package/dist/{chunk-VIA6RFQZ.js → chunk-UQIVHSE4.js} +4 -4
  165. package/dist/{chunk-RAY4OVGZ.js → chunk-URBGEOH3.js} +5 -5
  166. package/dist/chunk-USZA7GWL.js +341 -0
  167. package/dist/{chunk-ZA4VCIGV.js → chunk-UUQ5G6EZ.js} +60 -41
  168. package/dist/{chunk-VG7TBQIY.js → chunk-V552WL53.js} +68 -4
  169. package/dist/{chunk-7UGL4MB5.js → chunk-VAHLPXPY.js} +10 -10
  170. package/dist/{chunk-25QBEXRS.js → chunk-VANN3GDP.js} +7 -26
  171. package/dist/{chunk-BWH6N36D.js → chunk-VHKTOLEW.js} +272 -42
  172. package/dist/{chunk-QUFRYSWI.js → chunk-VHMX7SXF.js} +129 -48
  173. package/dist/{chunk-336NSSKI.js → chunk-VNBICSS2.js} +2 -2
  174. package/dist/{chunk-VAVR4IJY.js → chunk-VQD7NH7Z.js} +3 -3
  175. package/dist/{chunk-LBMZMYH2.js → chunk-W2RJEH6Q.js} +3 -3
  176. package/dist/{chunk-7CR24IG7.js → chunk-WDV62RKY.js} +2 -2
  177. package/dist/{chunk-BJVFZO5U.js → chunk-WJIMKGD6.js} +7 -7
  178. package/dist/{chunk-USR47QNF.js → chunk-WKUYQBCG.js} +14 -14
  179. package/dist/{chunk-GHS5EBTQ.js → chunk-WNGF5AJX.js} +36 -22
  180. package/dist/{chunk-MXHC5QYU.js → chunk-WTQGRBHV.js} +5 -144
  181. package/dist/{chunk-6OSVSQL5.js → chunk-WV6TDAPN.js} +41 -23
  182. package/dist/chunk-WXA2CFJO.js +23 -0
  183. package/dist/{chunk-2ASED4PZ.js → chunk-X3BI7HTV.js} +26 -26
  184. package/dist/{chunk-QSNYB6ZV.js → chunk-XCUDZQLX.js} +3 -3
  185. package/dist/{chunk-RZDWV63N.js → chunk-XWMSPJYN.js} +6 -6
  186. package/dist/chunk-YGDMBK7O.js +567 -0
  187. package/dist/{chunk-6PAZTBPA.js → chunk-YPRSNUTC.js} +15 -6
  188. package/dist/{chunk-2IR2NMPA.js → chunk-ZIDFQJRB.js} +2 -2
  189. package/dist/{chunk-LTIKRKFL.js → chunk-ZS43Y2FT.js} +4 -4
  190. package/dist/{chunk-6EJMN2Y3.js → chunk-ZTNFYMIO.js} +2 -2
  191. package/dist/{chunk-WEPFGWHJ.js → chunk-ZZFWWYLX.js} +2 -2
  192. package/dist/cli/index.js +44 -44
  193. package/dist/clio-QQCMTUZE.js +26 -0
  194. package/dist/{code-nav-IJR2DBPR.js → code-nav-GUPM6766.js} +48 -32
  195. package/dist/codewiki/build-worker.js +76 -29
  196. package/dist/{compile-cache-OQAVB7Y5.js → compile-cache-WJEPUZEJ.js} +4 -4
  197. package/dist/{components-2TGAI2RC.js → components-TNIKXCBH.js} +13 -13
  198. package/dist/{config-IUA6OYNS.js → config-IIM7YOD3.js} +211 -124
  199. package/dist/configure-4ZM5HWJX.js +73 -0
  200. package/dist/{context-BOYF5EJM.js → context-44BZLJ3J.js} +62 -31
  201. package/dist/{context-4MPR7WKB.js → context-AIDVQKMW.js} +126 -121
  202. package/dist/{context-2DKHWH2T.js → context-OL5P3HEP.js} +92 -62
  203. package/dist/context-clear-OQV76MYP.js +184 -0
  204. package/dist/{context-index-HNG3MOME.js → context-index-HP2JFUWA.js} +13 -11
  205. package/dist/{context-map-COB37XXN.js → context-map-INTXD54D.js} +71 -21
  206. package/dist/{context-working-set-3I3FYX6Y.js → context-working-set-ZUW3EGLS.js} +32 -31
  207. package/dist/detail-UXPWRANG.js +115 -0
  208. package/dist/{dispatch-runner-RJ5I2F2O.js → dispatch-runner-P3ZW6G77.js} +192 -116
  209. package/dist/{docs-SPOV3BAN.js → docs-BL7ROUFN.js} +4 -4
  210. package/dist/{doctor-DKICC2SN.js → doctor-JJVGPZWT.js} +59 -58
  211. package/dist/{eval-OQOQUDHK.js → eval-V2RTN3UH.js} +476 -170
  212. package/dist/{eval-inventory-Y6QRFOH5.js → eval-inventory-QOYZERXJ.js} +7 -7
  213. package/dist/evidence-35PYWGSO.js +225 -0
  214. package/dist/{evidence-4DQ25GUQ.js → evidence-CIGGKI6J.js} +111 -94
  215. package/dist/{evolve-GSS52E5J.js → evolve-33SM3NJP.js} +108 -91
  216. package/dist/{extensions-G7MFLYHT.js → extensions-YVRHX6ZI.js} +16 -16
  217. package/dist/{fleet-Q37YHHAQ.js → fleet-LFO7SIPC.js} +147 -146
  218. package/dist/{fleet-commands-G7E4N7SM.js → fleet-commands-RLK72GU3.js} +27 -26
  219. package/dist/{fleet-decisions-O7M6QBA2.js → fleet-decisions-3SBSCTCW.js} +16 -15
  220. package/dist/{fleet-graph-TOUBW6OW.js → fleet-graph-JZIBCGMW.js} +39 -38
  221. package/dist/{fleet-inspect-SW33JJNI.js → fleet-inspect-2L5YGGZJ.js} +108 -91
  222. package/dist/{fleet-new-RDVJLHHH.js → fleet-new-RCKGSRDV.js} +3 -3
  223. package/dist/{fleet-preflight-CV2655TW.js → fleet-preflight-QRSHIIDE.js} +10 -9
  224. package/dist/{fleet-validate-KESZX2YH.js → fleet-validate-LIAVKDUU.js} +46 -42
  225. package/dist/{fleet-verify-UQPMTVE3.js → fleet-verify-JIK3OQZR.js} +106 -89
  226. package/dist/fleet-view-IWHYGQKK.js +118 -0
  227. package/dist/{init-PXEXQSBF.js → init-NJEDOTQW.js} +124 -123
  228. package/dist/{install-NKNG7KD4.js → install-3RZDDP23.js} +5 -5
  229. package/dist/{interop-ZG5T62U3.js → interop-RVCAYECG.js} +25 -25
  230. package/dist/inventory-74UL7UHU.js +118 -0
  231. package/dist/{library-B2W4N74O.js → library-CTKZA7K3.js} +45 -44
  232. package/dist/{memory-YCANYS5A.js → memory-I76I5VUH.js} +108 -93
  233. package/dist/{models-GERTU3YI.js → models-D4YDIQZQ.js} +64 -62
  234. package/dist/{monitor-CPNIUULB.js → monitor-NKVD55HX.js} +137 -107
  235. package/dist/{orchestrator-J4BSH4WQ.js → orchestrator-I6OATVPK.js} +1715 -1687
  236. package/dist/{panes-BOHAEGYC.js → panes-7BTYH3XQ.js} +8 -8
  237. package/dist/{panes-NXSLDQZ2.js → panes-WPOMEMRH.js} +22 -22
  238. package/dist/{paths-VSUWNC22.js → paths-J3KN7UAO.js} +12 -12
  239. package/dist/preload-EJAWJEIO.js +116 -0
  240. package/dist/{registry-LG64LTF4.js → registry-DESGAXWK.js} +3 -3
  241. package/dist/{reset-TNWTB5LU.js → reset-4XMQKDNZ.js} +22 -20
  242. package/dist/{resources-4PXNMD5G.js → resources-TVYVXK3Q.js} +41 -40
  243. package/dist/{run-D6XJ34CN.js → run-OWQNNSJU.js} +164 -157
  244. package/dist/{share-2NWMJJEE.js → share-NPZZMUXG.js} +43 -42
  245. package/dist/{skills-KR7WON5G.js → skills-OXFEAWMT.js} +47 -46
  246. package/dist/{skills-eval-O2ZNOLDS.js → skills-eval-J5TCKSJA.js} +128 -107
  247. package/dist/{skills-inventory-ZZOUBK7O.js → skills-inventory-7II4DM57.js} +41 -40
  248. package/dist/slash-commands-MDSDSWYF.js +92 -0
  249. package/dist/{steer-XA25PSCS.js → steer-S7D7IKPU.js} +7 -7
  250. package/dist/{support-7EMVWYG2.js → support-5VAEC32W.js} +14 -14
  251. package/dist/{targets-OMH2XCSN.js → targets-KILZEOCE.js} +161 -94
  252. package/dist/tasks-R6P6OV22.js +36 -0
  253. package/dist/{terminal-lease-C2J3JYRE.js → terminal-lease-LZCG2KN3.js} +12 -11
  254. package/dist/tools-6OCQ6SVB.js +28 -0
  255. package/dist/{trace-FXMXUZUF.js → trace-JHLXWUMN.js} +18 -17
  256. package/dist/{tree-sitter-HGKH6LG4.js → tree-sitter-AQUUOSYM.js} +6 -6
  257. package/dist/{tui-primitives-K5PASC3O.js → tui-primitives-RCY2HN7G.js} +3 -3
  258. package/dist/{uninstall-HALS6BLF.js → uninstall-FXYMFFRT.js} +17 -17
  259. package/dist/{upgrade-MS72RJEP.js → upgrade-D2OZH6IQ.js} +42 -41
  260. package/dist/{usage-NHG6MCJM.js → usage-PIASNUS4.js} +137 -105
  261. package/dist/{verifiers-7AUNVXDY.js → verifiers-LTHUY2PX.js} +28 -27
  262. package/dist/verify-HYF7KBVE.js +30 -0
  263. package/dist/{version-KGEG7EPO.js → version-RFPKO6T7.js} +4 -4
  264. package/dist/{web-fetch-V4FKSDAV.js → web-fetch-MQN4FH3X.js} +169 -18
  265. package/dist/wiki-generate-RK7JQ5NP.js +615 -0
  266. package/dist/{with-panes-BDQEWBRT.js → with-panes-OFTNAR4Y.js} +34 -20
  267. package/dist/worker/entry.js +108 -95
  268. package/dist/{workspace-ZJ6BFM3Q.js → workspace-DZ7JADBG.js} +6 -6
  269. package/docs/README.md +7 -6
  270. package/docs/architecture/acp.md +10 -0
  271. package/docs/architecture/architecture.md +5 -5
  272. package/docs/architecture/context-engine.md +45 -60
  273. package/docs/architecture/context-working-set.md +7 -9
  274. package/docs/architecture/dispatch-architecture-rationale.md +1 -1
  275. package/docs/architecture/evidence-and-memory.md +10 -0
  276. package/docs/architecture/pi-boundary.md +37 -7
  277. package/docs/architecture/prompt-envelope-and-tools.md +7 -7
  278. package/docs/architecture/session-lifecycle.md +4 -4
  279. package/docs/architecture/tui-design.md +45 -30
  280. package/docs/architecture/worker-dispatch-mechanics.md +4 -0
  281. package/docs/guide/commands-and-modes.md +75 -61
  282. package/docs/guide/configuration-and-targets.md +126 -26
  283. package/docs/guide/configuration-reference.md +22 -7
  284. package/docs/guide/environment-variables.md +6 -2
  285. package/docs/guide/fleet-dispatch.md +13 -6
  286. package/docs/guide/glossary.md +1 -1
  287. package/docs/guide/installation-and-lifecycle.md +79 -20
  288. package/docs/guide/proactive-memory.md +1 -1
  289. package/docs/guide/skills-marketplace.md +11 -3
  290. package/docs/guide/tool-usage.md +9 -2
  291. package/docs/process/development-pipeline.md +11 -11
  292. package/docs/process/documentation-coverage.md +1 -1
  293. package/docs/process/documentation-guide.md +2 -2
  294. package/docs/process/eval-runner.md +15 -0
  295. package/docs/process/evals-internal.md +1 -1
  296. package/docs/process/release-cut-checklist.md +24 -12
  297. package/evals/README.md +4 -0
  298. package/evals/behavioral-corpus-grader.mjs +147 -14
  299. package/evals/behavioral-model-negative-control.yaml +1 -0
  300. package/evals/behavioral-model.yaml +266 -1
  301. package/evals/fixtures/docs-retrieval.json +102 -0
  302. package/evals/fixtures/scalar-decision.json +17 -0
  303. package/evals/fixtures/scout-citation-pipeline.json +55 -0
  304. package/evals/fixtures/source-explanation.json +74 -0
  305. package/evals/fixtures/tool-arguments.json +18 -0
  306. package/evals/fixtures/tool-surface/read.txt +4 -0
  307. package/evals/fixtures/tool-surface/subdir/keep.txt +1 -0
  308. package/evals/no-edit-memory-grader.mjs +149 -0
  309. package/evals/scalar-decision-grader.py +41 -0
  310. package/evals/scalar-decision-machinery.ts +145 -0
  311. package/evals/source-explanation-grader.mjs +118 -0
  312. package/evals/tool-surface-grader.mjs +53 -0
  313. package/evals/tool-surface-model.yaml +274 -0
  314. package/package.json +14 -14
  315. package/skills/README.md +6 -6
  316. package/skills/registry.yaml +1 -1
  317. package/skills/skill-marketplace.json +1 -1
  318. package/src/cli/ask.ts +10 -10
  319. package/src/cli/bootstrap-generate.ts +6 -0
  320. package/src/cli/config-inspect.ts +24 -7
  321. package/src/cli/config-trust.ts +62 -0
  322. package/src/cli/config.ts +8 -0
  323. package/src/cli/configure-editor.ts +51 -0
  324. package/src/cli/configure-interop.ts +1 -1
  325. package/src/cli/configure-oauth.ts +1 -1
  326. package/src/cli/configure-onboarding.ts +232 -96
  327. package/src/cli/configure-prompts.ts +76 -0
  328. package/src/cli/configure-quick.ts +274 -0
  329. package/src/cli/configure-target.ts +14 -2
  330. package/src/cli/configure.ts +413 -174
  331. package/src/cli/context-map.ts +75 -14
  332. package/src/cli/context.ts +46 -17
  333. package/src/cli/eval.ts +17 -3
  334. package/src/cli/modes/print.ts +32 -4
  335. package/src/cli/oauth-manual-input.ts +1 -1
  336. package/src/cli/reset.ts +2 -0
  337. package/src/cli/run.ts +16 -14
  338. package/src/cli/select.ts +35 -4
  339. package/src/cli/skills-eval.ts +10 -8
  340. package/src/cli/steer-channel.ts +31 -18
  341. package/src/cli/targets.ts +83 -31
  342. package/src/cli/tasks.ts +10 -1
  343. package/src/cli/upgrade.ts +11 -8
  344. package/src/cli/usage.ts +24 -0
  345. package/src/cli/wiki-generate.ts +239 -96
  346. package/src/core/bash-exec.ts +43 -15
  347. package/src/core/bus-events.ts +15 -0
  348. package/src/core/config.ts +39 -15
  349. package/src/core/defaults.ts +38 -15
  350. package/src/{interactive → core}/external-editor.ts +4 -4
  351. package/src/core/file-references.ts +11 -1
  352. package/src/core/incomplete-installation.ts +3 -1
  353. package/src/core/settings-layers.ts +21 -5
  354. package/src/core/termination.ts +26 -9
  355. package/src/core/untrusted-content.ts +16 -0
  356. package/src/core/workspace-trust.ts +179 -0
  357. package/src/domains/agents/builtins/coder.md +4 -2
  358. package/src/domains/agents/builtins/context-bootstrap.md +3 -1
  359. package/src/domains/agents/builtins/documenter.md +7 -4
  360. package/src/domains/agents/builtins/researcher.md +1 -0
  361. package/src/domains/agents/builtins/scout.md +7 -1
  362. package/src/domains/agents/result-contract.ts +199 -26
  363. package/src/domains/config/classify.ts +1 -1
  364. package/src/domains/config/keybindings.ts +3 -31
  365. package/src/domains/context/bootstrap-prompt.ts +11 -9
  366. package/src/domains/context/bootstrap.ts +74 -39
  367. package/src/domains/context/clio-md.ts +88 -26
  368. package/src/domains/context/codewiki/build-operation.ts +121 -0
  369. package/src/domains/context/codewiki/build-worker-protocol.ts +37 -3
  370. package/src/domains/context/codewiki/build-worker.ts +3 -35
  371. package/src/domains/context/codewiki/coordinator.ts +36 -6
  372. package/src/domains/context/codewiki/indexer.ts +59 -19
  373. package/src/domains/context/contract.ts +6 -2
  374. package/src/domains/context/extension.ts +72 -10
  375. package/src/domains/context/fingerprint.ts +39 -34
  376. package/src/domains/context/index.ts +7 -1
  377. package/src/domains/context/prompt-context.ts +55 -14
  378. package/src/domains/context/refresh.ts +9 -57
  379. package/src/domains/context/wiki/assemble.ts +14 -10
  380. package/src/domains/context/wiki/evidence.ts +209 -0
  381. package/src/domains/context/wiki/generate.ts +201 -67
  382. package/src/domains/context/wiki/meta.ts +10 -2
  383. package/src/domains/context/wiki/plan-store.ts +70 -14
  384. package/src/domains/context/wiki/plan.ts +71 -14
  385. package/src/domains/context/wiki/prompts.ts +42 -1
  386. package/src/domains/context/wiki/source-content.ts +106 -0
  387. package/src/domains/context/wiki/staleness.ts +33 -22
  388. package/src/domains/context/working-set/contract.ts +8 -2
  389. package/src/domains/context/working-set/engine.ts +17 -4
  390. package/src/domains/context/working-set/fold.ts +15 -2
  391. package/src/domains/context/working-set/marker.ts +2 -1
  392. package/src/domains/context/working-set/project.ts +18 -7
  393. package/src/domains/context/working-set/recall.ts +82 -56
  394. package/src/domains/dispatch/active-route-planner.ts +6 -3
  395. package/src/domains/dispatch/admission-queue.ts +19 -7
  396. package/src/domains/dispatch/admission.ts +3 -3
  397. package/src/domains/dispatch/budget-envelope.ts +47 -82
  398. package/src/domains/dispatch/capacity-lease.ts +57 -19
  399. package/src/domains/dispatch/contract.ts +10 -2
  400. package/src/domains/dispatch/event-pump.ts +28 -7
  401. package/src/domains/dispatch/execution-role.ts +49 -2
  402. package/src/domains/dispatch/execution-scheduler.ts +2 -0
  403. package/src/domains/dispatch/extension.ts +190 -105
  404. package/src/domains/dispatch/fleet-run.ts +20 -0
  405. package/src/domains/dispatch/gate-role-prompts.ts +4 -2
  406. package/src/domains/dispatch/parallel-writers.ts +34 -0
  407. package/src/domains/dispatch/reservation-store.ts +8 -34
  408. package/src/domains/dispatch/route-approval.ts +3 -3
  409. package/src/domains/dispatch/route-observer.ts +4 -2
  410. package/src/domains/dispatch/route-quality.ts +6 -1
  411. package/src/domains/dispatch/types.ts +4 -3
  412. package/src/domains/dispatch/worker-spawn.ts +58 -21
  413. package/src/domains/dispatch/workspace-checkpoint.ts +57 -0
  414. package/src/domains/eval/compare/behavioral.ts +81 -14
  415. package/src/domains/eval/compare/compare.ts +15 -5
  416. package/src/domains/eval/compare/envelope.ts +12 -5
  417. package/src/domains/eval/metrics/context.ts +24 -1
  418. package/src/domains/eval/metrics/tracked.ts +4 -28
  419. package/src/domains/eval/reports/comparison.ts +9 -9
  420. package/src/domains/eval/runners/clio-run.ts +5 -1
  421. package/src/domains/eval/schema/suite.ts +2 -0
  422. package/src/domains/eval/schema/validate.ts +1 -0
  423. package/src/domains/eval/suites/run.ts +189 -13
  424. package/src/domains/eval/verifiers/integrity.ts +39 -0
  425. package/src/domains/eval/verifiers/patch.ts +58 -2
  426. package/src/domains/eval/workspaces/temp-copy.ts +3 -0
  427. package/src/domains/evidence/build.ts +4 -2
  428. package/src/domains/interop/registry.ts +2 -2
  429. package/src/domains/middleware/hooks-io.ts +45 -26
  430. package/src/domains/middleware/hooks.ts +6 -0
  431. package/src/domains/middleware/injection-screen.ts +23 -0
  432. package/src/domains/middleware/rules.ts +5 -1
  433. package/src/domains/middleware/stalled-turn.ts +18 -3
  434. package/src/domains/middleware/task-board-reminder.ts +4 -2
  435. package/src/domains/middleware/task-nudge.ts +4 -1
  436. package/src/domains/mux/contract.ts +34 -1
  437. package/src/domains/mux/dock-controller.ts +8 -1
  438. package/src/domains/mux/index.ts +1 -0
  439. package/src/domains/mux/socket-client.ts +13 -3
  440. package/src/domains/observability/contract.ts +2 -2
  441. package/src/domains/observability/projection.ts +30 -9
  442. package/src/domains/prompts/compiler.ts +10 -2
  443. package/src/domains/prompts/contract.ts +7 -4
  444. package/src/domains/prompts/extension.ts +28 -64
  445. package/src/domains/prompts/fragments/identity/clio.md +23 -0
  446. package/src/domains/prompts/fragments/operating/contract.md +10 -0
  447. package/src/domains/prompts/fragments/operating/delegation.md +5 -0
  448. package/src/domains/prompts/fragments/wiki/page.md +28 -15
  449. package/src/domains/prompts/fragments/wiki/plan.md +4 -4
  450. package/src/domains/prompts/preload-prefix.ts +31 -0
  451. package/src/domains/prompts/preload.ts +135 -61
  452. package/src/domains/providers/auth/backend-file.ts +15 -11
  453. package/src/domains/providers/auth/storage.ts +3 -5
  454. package/src/domains/providers/catalog.ts +18 -3
  455. package/src/domains/providers/probe/fingerprint.ts +13 -6
  456. package/src/domains/providers/probe/reasoning.ts +2 -0
  457. package/src/domains/providers/runtime-resolution.ts +11 -9
  458. package/src/domains/providers/runtimes/cloud/openrouter.ts +2 -0
  459. package/src/domains/providers/runtimes/common/probe-helpers.ts +23 -7
  460. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +7 -2
  461. package/src/domains/providers/runtimes/protocol/openai-compat.ts +10 -4
  462. package/src/domains/resources/skills/promotion.ts +8 -1
  463. package/src/domains/safety/action-classifier.ts +9 -0
  464. package/src/domains/safety/autonomy.ts +10 -1
  465. package/src/domains/safety/contract.ts +5 -1
  466. package/src/domains/safety/default-path-policy.ts +11 -0
  467. package/src/domains/safety/extension.ts +11 -2
  468. package/src/domains/safety/policy-engine.ts +189 -32
  469. package/src/domains/safety/project-policy.ts +7 -2
  470. package/src/domains/safety/workspace-trust.ts +43 -0
  471. package/src/domains/session/compaction/compact.ts +384 -21
  472. package/src/domains/session/compaction/cut-point.ts +42 -5
  473. package/src/domains/session/compaction/tokens.ts +9 -1
  474. package/src/domains/session/decision-board.ts +43 -33
  475. package/src/domains/session/entries.ts +169 -4
  476. package/src/domains/session/prompt-manifest.ts +47 -8
  477. package/src/domains/session/task-board.ts +21 -3
  478. package/src/domains/user-tasks/handoff.ts +16 -0
  479. package/src/engine/acp/adapter.ts +44 -12
  480. package/src/engine/acp/server.ts +1 -0
  481. package/src/engine/acp/transport.ts +2 -1
  482. package/src/engine/acp/types.ts +6 -1
  483. package/src/engine/antigravity/subprocess-runtime.ts +20 -4
  484. package/src/engine/api-registry.ts +19 -2
  485. package/src/engine/apis/openai-completions.ts +13 -6
  486. package/src/engine/apis/output-budget.ts +26 -10
  487. package/src/engine/claude/sdk-runtime.ts +4 -3
  488. package/src/engine/env-api-keys.ts +2 -1
  489. package/src/engine/external-subprocess.ts +14 -3
  490. package/src/engine/loop-guard.ts +19 -2
  491. package/src/engine/provider-diagnostics.ts +129 -0
  492. package/src/engine/provider-payload.ts +3 -1
  493. package/src/engine/worker-runtime.ts +13 -2
  494. package/src/engine/worker-tools.ts +5 -1
  495. package/src/entry/extension-reload.ts +1 -0
  496. package/src/entry/orchestrator.ts +53 -15
  497. package/src/interactive/application-controller.ts +1 -31
  498. package/src/interactive/chat-loop-messages.ts +12 -4
  499. package/src/interactive/chat-loop.ts +115 -45
  500. package/src/interactive/chat-panel.ts +163 -637
  501. package/src/interactive/chat-renderer.ts +73 -30
  502. package/src/interactive/context-recall-command.ts +2 -1
  503. package/src/interactive/dispatch-board.ts +18 -5
  504. package/src/interactive/editor-submit.ts +21 -31
  505. package/src/interactive/footer/dashboard.ts +8 -3
  506. package/src/interactive/footer/widgets.ts +50 -91
  507. package/src/interactive/interactive-application.ts +24 -44
  508. package/src/interactive/interactive-event-projection.ts +9 -45
  509. package/src/interactive/interactive-input-runtime.ts +3 -28
  510. package/src/interactive/interactive-presentation.ts +45 -16
  511. package/src/interactive/interactive-slash-runtime.ts +5 -40
  512. package/src/interactive/layout.ts +31 -5
  513. package/src/interactive/model-session-replay.ts +2 -2
  514. package/src/interactive/overlay-frame.ts +1 -0
  515. package/src/interactive/overlay-general-openers.ts +5 -1
  516. package/src/interactive/overlay-lifecycle.ts +1 -0
  517. package/src/interactive/overlay-session-lifecycle.ts +7 -1
  518. package/src/interactive/overlays/ask-user.ts +1 -0
  519. package/src/interactive/overlays/message-picker.ts +1 -1
  520. package/src/interactive/overlays/settings.ts +9 -8
  521. package/src/interactive/renderers/preview.ts +16 -0
  522. package/src/interactive/renderers/tool-execution.ts +84 -161
  523. package/src/interactive/renderers/worker-entry.ts +74 -43
  524. package/src/interactive/slash-autocomplete.ts +1 -6
  525. package/src/interactive/slash-commands.ts +16 -46
  526. package/src/interactive/status/controller.ts +0 -5
  527. package/src/interactive/status/state-machine.ts +44 -26
  528. package/src/interactive/status/types.ts +3 -0
  529. package/src/interactive/status/verbs.ts +13 -12
  530. package/src/interactive/transcript-detail.ts +50 -112
  531. package/src/interactive/turn-context.ts +221 -53
  532. package/src/interactive/turn-middleware.ts +3 -1
  533. package/src/interactive/turn-persistence.ts +3 -0
  534. package/src/interactive/turn-runtime.ts +11 -2
  535. package/src/interactive/turn-state.ts +10 -9
  536. package/src/interactive/view/artifacts.ts +4 -0
  537. package/src/interactive/view/view-overlay.ts +44 -34
  538. package/src/interactive/watch-pane.ts +18 -4
  539. package/src/interactive/worker-stream.ts +7 -7
  540. package/src/tools/agent-tools.ts +6 -3
  541. package/src/tools/bash.ts +1 -1
  542. package/src/tools/builtin-tool-catalog.ts +9 -2
  543. package/src/tools/codewiki/code-nav.ts +4 -10
  544. package/src/tools/compete-judge-task.ts +71 -0
  545. package/src/tools/compete-worktrees.ts +34 -0
  546. package/src/tools/context/index.ts +32 -7
  547. package/src/tools/context/surface.ts +15 -4
  548. package/src/tools/decide.ts +1 -1
  549. package/src/tools/dispatch-admission.ts +12 -1
  550. package/src/tools/dispatch-arguments.ts +38 -1
  551. package/src/tools/dispatch-plan.ts +7 -7
  552. package/src/tools/dispatch-runner.ts +48 -32
  553. package/src/tools/dispatch-schema.ts +30 -23
  554. package/src/tools/dispatch-scout-admission.ts +10 -44
  555. package/src/tools/dispatch-scout.ts +2 -3
  556. package/src/tools/find.ts +13 -4
  557. package/src/tools/grep.ts +13 -1
  558. package/src/tools/ls.ts +7 -1
  559. package/src/tools/monitor.ts +26 -11
  560. package/src/tools/network-policy.ts +11 -24
  561. package/src/tools/observation.ts +39 -2
  562. package/src/tools/presentation.ts +1 -1
  563. package/src/tools/read.ts +112 -15
  564. package/src/tools/registry.ts +55 -18
  565. package/src/tools/result-shaping.ts +110 -2
  566. package/src/tools/tasks.ts +33 -7
  567. package/src/tools/verify/frontend.ts +67 -30
  568. package/src/tools/verify/numeric.ts +10 -5
  569. package/src/tools/web-fetch-network.ts +179 -0
  570. package/src/tools/web-fetch-surface.ts +2 -1
  571. package/src/tools/web-fetch.ts +15 -13
  572. package/src/tools/worker-evidence.ts +27 -0
  573. package/src/worker/spec-contract.ts +12 -8
  574. package/dist/builtins-WGALA46I.js +0 -22
  575. package/dist/chunk-2WZ546HR.js +0 -792
  576. package/dist/chunk-5PSMVOLM.js +0 -56
  577. package/dist/chunk-EL24TAU4.js +0 -1560
  578. package/dist/chunk-IZXGRF7P.js +0 -4048
  579. package/dist/chunk-JVCV3ICN.js +0 -47
  580. package/dist/chunk-MNJGS2IN.js +0 -33
  581. package/dist/chunk-O5CVSAG5.js +0 -122
  582. package/dist/chunk-ODGTEFFI.js +0 -50
  583. package/dist/chunk-OQE5J4C6.js +0 -73
  584. package/dist/chunk-UUVG37B4.js +0 -244
  585. package/dist/chunk-V6HJFQZE.js +0 -228
  586. package/dist/clio-QLICPCF5.js +0 -25
  587. package/dist/configure-VEPX4NMX.js +0 -55
  588. package/dist/context-clear-S4ZJCQUX.js +0 -182
  589. package/dist/detail-A7JAVSIG.js +0 -98
  590. package/dist/evidence-4F5USFKH.js +0 -208
  591. package/dist/fleet-view-MN2VG4MR.js +0 -101
  592. package/dist/inventory-C26CFDRR.js +0 -101
  593. package/dist/preload-P6DGH2PZ.js +0 -13
  594. package/dist/slash-commands-ZXPJD64J.js +0 -92
  595. package/dist/tasks-IPAGMEIX.js +0 -36
  596. package/dist/tools-EFFEAIDP.js +0 -28
  597. package/dist/verify-FWYGPKMR.js +0 -29
  598. package/dist/wiki-generate-743CIGJW.js +0 -476
@@ -132,7 +132,7 @@ export function compareEvalArtifactsV4(
132
132
  export function renderEvalComparisonV4(summary: EvalCompareV4Summary): string {
133
133
  const envelopeFailures = summary.envelopeMismatches.map(
134
134
  (mismatch) =>
135
- ` incomparable envelope: ${mismatch.scenarioId} ${mismatch.role} ${mismatch.target.id}/${mismatch.target.model ?? "none"} fields=${mismatch.fields.join(",")}`,
135
+ ` incomparable envelope: ${mismatch.scenarioId} ${mismatch.role} ${renderEvalComparisonRoutesV1(mismatch)} fields=${mismatch.fields.join(",")}`,
136
136
  );
137
137
  const affected = summary.affectedCorpusResults.map(
138
138
  (result) =>
@@ -142,7 +142,7 @@ export function renderEvalComparisonV4(summary: EvalCompareV4Summary): string {
142
142
  const roleReports = renderRollups("per-role baseline/candidate report", summary.roleReports);
143
143
  const hardFailures = summary.hardGate.failures.map(
144
144
  (failure) =>
145
- ` hard failure: ${failure.scenarioId} ${failure.role} ${failure.target.id}/${failure.target.model ?? "none"} ${failure.metric} ${failure.change}`,
145
+ ` hard failure: ${failure.scenarioId} ${failure.role} ${renderEvalComparisonRoutesV1(failure)} ${failure.metric} ${failure.change}`,
146
146
  );
147
147
  const tracked = summary.trackedMetrics.flatMap((row, index) => [
148
148
  ...(index === 0
@@ -172,14 +172,13 @@ export function renderEvalComparisonV4(summary: EvalCompareV4Summary): string {
172
172
  ...(index === 0
173
173
  ? [
174
174
  "behavioral metrics:",
175
- "scenario role target model family metric baseline_mean baseline_variance baseline_coverage candidate_mean candidate_variance candidate_coverage mean_delta variance_delta change variance_change comparability gate source",
175
+ "scenario role baseline_target/model -> candidate_target/model family metric baseline_mean baseline_variance baseline_coverage candidate_mean candidate_variance candidate_coverage mean_delta variance_delta noise_band change variance_change comparability gate source",
176
176
  ]
177
177
  : []),
178
178
  [
179
179
  row.scenarioId,
180
180
  row.role,
181
- row.target.id,
182
- row.target.model ?? "none",
181
+ renderEvalComparisonRoutesV1(row),
183
182
  row.family,
184
183
  row.metric,
185
184
  formatMetric(row.baseline.mean),
@@ -190,6 +189,7 @@ export function renderEvalComparisonV4(summary: EvalCompareV4Summary): string {
190
189
  `${row.candidate.measured}/${row.candidate.observations}`,
191
190
  formatSignedMetric(row.meanDelta),
192
191
  formatSignedMetric(row.varianceDelta),
192
+ formatMetric(row.noiseBand),
193
193
  row.change,
194
194
  row.varianceChange,
195
195
  row.comparability.comparable ? "comparable" : `incomparable:${row.comparability.mismatchedFields.join(",")}`,
@@ -218,6 +218,16 @@ export function renderEvalComparisonV4(summary: EvalCompareV4Summary): string {
218
218
  ].join("\n");
219
219
  }
220
220
 
221
+ export function renderEvalComparisonRoutesV1(identity: {
222
+ target: { id: string; model: string | null };
223
+ baselineTargets?: ReadonlyArray<{ id: string; model: string | null }>;
224
+ candidateTargets?: ReadonlyArray<{ id: string; model: string | null }>;
225
+ }): string {
226
+ const render = (targets: ReadonlyArray<{ id: string; model: string | null }>) =>
227
+ targets.map((target) => `${target.id}/${target.model ?? "none"}`).join(",") || "missing";
228
+ return `${render(identity.baselineTargets ?? [identity.target])} -> ${render(identity.candidateTargets ?? [identity.target])}`;
229
+ }
230
+
221
231
  function behaviorRollups(
222
232
  rows: ReadonlyArray<EvalBehaviorMetricComparisonV1>,
223
233
  keyOf: (row: EvalBehaviorMetricComparisonV1) => string,
@@ -5,6 +5,8 @@ export interface EvalEnvelopeMismatchV1 {
5
5
  scenarioId: string;
6
6
  role: string;
7
7
  target: { id: string; model: string | null };
8
+ baselineTargets?: Array<{ id: string; model: string | null }>;
9
+ candidateTargets?: Array<{ id: string; model: string | null }>;
8
10
  fields: string[];
9
11
  }
10
12
 
@@ -20,10 +22,15 @@ export function compareEvalExecutionEnvelopesV1(
20
22
  baselineDimensions: ReadonlyArray<EvalExecutionMatrixDimensionV1>,
21
23
  candidateDimensions: ReadonlyArray<EvalExecutionMatrixDimensionV1>,
22
24
  ): EvalEnvelopeMismatchV1 | null {
25
+ const mismatchIdentity = {
26
+ scenarioId: identity.scenarioId,
27
+ role: identity.role,
28
+ target: { id: identity.target.id, model: identity.target.model },
29
+ };
23
30
  const leftDimensions = [...baselineDimensions].sort();
24
31
  const rightDimensions = [...candidateDimensions].sort();
25
32
  if (stableJson(leftDimensions) !== stableJson(rightDimensions)) {
26
- return { ...identity, fields: ["matrix.dimensions"] };
33
+ return { ...mismatchIdentity, fields: ["matrix.dimensions"] };
27
34
  }
28
35
  if (
29
36
  (baseline.some((result) => result.executionEnvelope !== undefined) &&
@@ -31,22 +38,22 @@ export function compareEvalExecutionEnvelopesV1(
31
38
  (candidate.some((result) => result.executionEnvelope !== undefined) &&
32
39
  candidate.some((result) => result.executionEnvelope === undefined))
33
40
  ) {
34
- return { ...identity, fields: ["executionEnvelope.missingTrial"] };
41
+ return { ...mismatchIdentity, fields: ["executionEnvelope.missingTrial"] };
35
42
  }
36
43
  const ignored = new Set(leftDimensions);
37
44
  const baselineEnvelopes = uniqueEnvelopes(baseline, ignored);
38
45
  const candidateEnvelopes = uniqueEnvelopes(candidate, ignored);
39
46
  if (baselineEnvelopes.length === 0 && candidateEnvelopes.length === 0) return null;
40
47
  if (baselineEnvelopes.length === 0 || candidateEnvelopes.length === 0) {
41
- return { ...identity, fields: ["executionEnvelope"] };
48
+ return { ...mismatchIdentity, fields: ["executionEnvelope"] };
42
49
  }
43
50
  if (baselineEnvelopes.length > 1 || candidateEnvelopes.length > 1) {
44
- return { ...identity, fields: ["executionEnvelope.withinRunVariance"] };
51
+ return { ...mismatchIdentity, fields: ["executionEnvelope.withinRunVariance"] };
45
52
  }
46
53
  const left = baselineEnvelopes[0];
47
54
  const right = candidateEnvelopes[0];
48
55
  if (left === undefined || right === undefined || stableJson(left) === stableJson(right)) return null;
49
- return { ...identity, fields: differingFields(left, right, ignored) };
56
+ return { ...mismatchIdentity, fields: differingFields(left, right, ignored) };
50
57
  }
51
58
 
52
59
  function uniqueEnvelopes(
@@ -1,3 +1,6 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFileSync } from "node:fs";
3
+ import { join } from "node:path";
1
4
  import { enumerateWorkspaceFiles } from "../../../core/workspace-files.js";
2
5
  import { readCodewiki, structuralCodewikiHash } from "../../context/codewiki/artifact.js";
3
6
  import { renderCodewikiDigest } from "../../context/codewiki/digest.js";
@@ -10,13 +13,31 @@ export function collectContextMetrics(cwd: string): Record<string, number | stri
10
13
  const visiblePaths = new Set(enumerateWorkspaceFiles(cwd));
11
14
  const artifactSourceFiles = codewiki.files.filter((file) => file.lang !== "config");
12
15
  const indexedFiles = artifactSourceFiles.filter((file) => visiblePaths.has(file.path)).length;
13
- const staleFiles = artifactSourceFiles.length - indexedFiles;
16
+ let contentValidFiles = 0;
17
+ let missingFiles = 0;
18
+ for (const file of artifactSourceFiles) {
19
+ try {
20
+ // Match the indexer's UTF-8 source identity, including legacy records
21
+ // whose missing hash cannot establish content validity.
22
+ const hash = createHash("sha256")
23
+ .update(readFileSync(join(cwd, file.path), "utf8"))
24
+ .digest("hex")
25
+ .slice(0, 16);
26
+ if (visiblePaths.has(file.path) && file.hash === hash) contentValidFiles += 1;
27
+ } catch (error) {
28
+ const code = (error as NodeJS.ErrnoException).code;
29
+ if (code === "ENOENT" || code === "ENOTDIR") missingFiles += 1;
30
+ }
31
+ }
32
+ const staleFiles = artifactSourceFiles.length - contentValidFiles;
14
33
  const sourceFiles = detectProjectProfile(cwd).sourceFiles;
15
34
  const digest = renderCodewikiDigest(codewiki);
16
35
  return {
17
36
  "context.indexedFiles": indexedFiles,
18
37
  "context.artifactFiles": artifactSourceFiles.length,
19
38
  "context.staleFiles": staleFiles,
39
+ "context.contentValidFiles": contentValidFiles,
40
+ "context.missingFiles": missingFiles,
20
41
  "context.coverage": sourceFiles === 0 ? (artifactSourceFiles.length === 0 ? 1 : 0) : indexedFiles / sourceFiles,
21
42
  "context.structuralHash": structuralCodewikiHash(codewiki),
22
43
  "context.digestTokens": Math.ceil(digest.length / 4),
@@ -26,6 +47,8 @@ export function collectContextMetrics(cwd: string): Record<string, number | stri
26
47
  "context.indexedFiles": 0,
27
48
  "context.artifactFiles": 0,
28
49
  "context.staleFiles": 0,
50
+ "context.contentValidFiles": 0,
51
+ "context.missingFiles": 0,
29
52
  "context.coverage": 0,
30
53
  "context.structuralHash": null,
31
54
  "context.digestTokens": 0,
@@ -1,9 +1,11 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import { dirname, join } from "node:path";
3
3
  import type { RunReceipt } from "../../dispatch/types.js";
4
+ import type { ProjectPreloadClass } from "../../prompts/preload.js";
4
5
  import { listSessionLedgerRefs, parseSessionEntries } from "../../session/archive-readers.js";
5
6
  import { extractReasoningTokens } from "../../session/context-accounting.js";
6
7
  import type { SessionEntry } from "../../session/entries.js";
8
+ import { isProjectPreloadClass } from "../../session/prompt-manifest.js";
7
9
  import { evalHarnessMetricsFromReceipt } from "../harness-metrics.js";
8
10
  import type {
9
11
  EvalMetricSource,
@@ -22,14 +24,7 @@ export interface EvalLedgerSnapshot {
22
24
  export interface EvalPromptManifestObservation {
23
25
  systemPromptHash: string;
24
26
  thinkingLevel: string | null;
25
- projectPreload: {
26
- mode: "full" | "synopsis" | "none";
27
- chars: number;
28
- lines: number;
29
- reason: string | null;
30
- nearLimit: boolean;
31
- label: string;
32
- } | null;
27
+ projectPreload: ProjectPreloadClass | null;
33
28
  fragments: Array<{ id: string; contentHash: string }>;
34
29
  }
35
30
 
@@ -408,26 +403,7 @@ function promptManifestObservation(record: Record<string, unknown>): EvalPromptM
408
403
  return contentHash === null ? [] : [{ id: entry.id, contentHash }];
409
404
  });
410
405
  const preload = record.projectPreload;
411
- const projectPreload: EvalPromptManifestObservation["projectPreload"] =
412
- preload === null
413
- ? null
414
- : isRecord(preload) &&
415
- (preload.mode === "full" || preload.mode === "synopsis" || preload.mode === "none") &&
416
- typeof preload.chars === "number" &&
417
- Number.isInteger(preload.chars) &&
418
- typeof preload.lines === "number" &&
419
- Number.isInteger(preload.lines) &&
420
- typeof preload.nearLimit === "boolean" &&
421
- typeof preload.label === "string"
422
- ? {
423
- mode: preload.mode as "full" | "synopsis" | "none",
424
- chars: preload.chars,
425
- lines: preload.lines,
426
- reason: nullableString(preload.reason),
427
- nearLimit: preload.nearLimit,
428
- label: preload.label,
429
- }
430
- : null;
406
+ const projectPreload = isProjectPreloadClass(preload) ? preload : null;
431
407
  return {
432
408
  systemPromptHash,
433
409
  thinkingLevel: nullableString(record.thinkingLevel),
@@ -1,5 +1,5 @@
1
1
  import type { EvalCompareV4Summary } from "../compare/compare.js";
2
- import { renderEvalComparisonV4 } from "../compare/compare.js";
2
+ import { renderEvalComparisonRoutesV1, renderEvalComparisonV4 } from "../compare/compare.js";
3
3
 
4
4
  export type EvalComparisonReportFormat = "text" | "json" | "md" | "junit";
5
5
 
@@ -16,7 +16,7 @@ export function renderEvalComparisonReportV1(
16
16
  function renderMarkdown(summary: EvalCompareV4Summary): string {
17
17
  const rows = summary.behavioralMetrics.map(
18
18
  (row) =>
19
- `| ${cell(row.scenarioId)} | ${cell(row.role)} | ${cell(`${row.target.id}/${row.target.model ?? "none"}`)} | ${row.family} | ${row.metric} | ${format(row.baseline.mean)} | ${format(row.baseline.variance)} | ${row.baseline.measured}/${row.baseline.observations} | ${format(row.candidate.mean)} | ${format(row.candidate.variance)} | ${row.candidate.measured}/${row.candidate.observations} | ${row.change} | ${row.varianceChange} | ${row.comparability.comparable ? "comparable" : cell(row.comparability.mismatchedFields.join(", "))} | ${row.hardGate ? "hard" : "informational"} |`,
19
+ `| ${cell(row.scenarioId)} | ${cell(row.role)} | ${cell(renderEvalComparisonRoutesV1(row))} | ${row.family} | ${row.metric} | ${format(row.baseline.mean)} | ${format(row.baseline.variance)} | ${row.baseline.measured}/${row.baseline.observations} | ${format(row.candidate.mean)} | ${format(row.candidate.variance)} | ${row.candidate.measured}/${row.candidate.observations} | ${format(row.noiseBand)} | ${row.change} | ${row.varianceChange} | ${row.comparability.comparable ? "comparable" : cell(row.comparability.mismatchedFields.join(", "))} | ${row.hardGate ? "hard" : "informational"} |`,
20
20
  );
21
21
  const scenarioRows = summary.scenarioReports.map(
22
22
  (report) => `| ${cell(report.id)} | ${changeCounts(report.metrics)} | ${changeCounts(report.variance)} |`,
@@ -30,11 +30,11 @@ function renderMarkdown(summary: EvalCompareV4Summary): string {
30
30
  `Behavioral hard gate: **${summary.hardGate.pass ? "pass" : "fail"}**`,
31
31
  ...summary.hardGate.failures.map(
32
32
  (failure) =>
33
- `- Hard failure: ${failure.scenarioId} / ${failure.role} / ${failure.target.id}/${failure.target.model ?? "none"} / ${failure.metric}: ${failure.change}`,
33
+ `- Hard failure: ${failure.scenarioId} / ${failure.role} / ${renderEvalComparisonRoutesV1(failure)} / ${failure.metric}: ${failure.change}`,
34
34
  ),
35
35
  ...summary.envelopeMismatches.map(
36
36
  (mismatch) =>
37
- `- Incomparable envelope: ${mismatch.scenarioId} / ${mismatch.role} / ${mismatch.target.id}/${mismatch.target.model ?? "none"}: ${mismatch.fields.join(", ")}`,
37
+ `- Incomparable envelope: ${mismatch.scenarioId} / ${mismatch.role} / ${renderEvalComparisonRoutesV1(mismatch)}: ${mismatch.fields.join(", ")}`,
38
38
  ),
39
39
  ...summary.affectedCorpusResults.map(
40
40
  (result) => `- Affected corpus result: ${result.scenarioId} / ${result.role}: ${result.changedFields.join(", ")}`,
@@ -43,8 +43,8 @@ function renderMarkdown(summary: EvalCompareV4Summary): string {
43
43
  `Token delta: ${summary.tokenDelta === null ? "unmeasured" : summary.tokenDelta}`,
44
44
  `Wall-time delta ms: ${summary.wallTimeDelta}`,
45
45
  "",
46
- "| Scenario | Role | Target/model | Family | Metric | Baseline mean | Baseline variance | Baseline measured | Candidate mean | Candidate variance | Candidate measured | Change | Variance | Comparability | Gate |",
47
- "|---|---|---|---|---|---:|---:|---:|---:|---:|---:|---|---|---|---|",
46
+ "| Scenario | Role | Baseline -> candidate target/model | Family | Metric | Baseline mean | Baseline variance | Baseline measured | Candidate mean | Candidate variance | Candidate measured | Noise band | Change | Variance | Comparability | Gate |",
47
+ "|---|---|---|---|---|---:|---:|---:|---:|---:|---:|---:|---|---|---|---|",
48
48
  ...rows,
49
49
  "",
50
50
  "## Per-scenario baseline/candidate report",
@@ -70,7 +70,7 @@ function renderJunit(summary: EvalCompareV4Summary): string {
70
70
  );
71
71
  const represented = new Set<string>();
72
72
  const cases = summary.behavioralMetrics.map((row) => {
73
- const name = `${row.scenarioId}[${row.role}:${row.target.id}:${row.target.model ?? "none"}].${row.metric}`;
73
+ const name = `${row.scenarioId}[${row.role}:${renderEvalComparisonRoutesV1(row)}].${row.metric}`;
74
74
  const key = JSON.stringify([row.scenarioId, row.role, row.target.id, row.target.model, row.metric]);
75
75
  represented.add(key);
76
76
  const detail = `change=${row.change} variance=${row.varianceChange} baseline=${format(row.baseline.mean)} candidate=${format(row.candidate.mean)}`;
@@ -87,13 +87,13 @@ function renderJunit(summary: EvalCompareV4Summary): string {
87
87
  failure.metric,
88
88
  ]);
89
89
  if (represented.has(key)) continue;
90
- const name = `${failure.scenarioId}[${failure.role}:${failure.target.id}:${failure.target.model ?? "none"}].${failure.metric}`;
90
+ const name = `${failure.scenarioId}[${failure.role}:${renderEvalComparisonRoutesV1(failure)}].${failure.metric}`;
91
91
  cases.push(
92
92
  ` <testcase classname="eval.behavior.hard" name="${escapeXml(name)}"><failure message="${escapeXml(failure.change)}">hard behavioral gate</failure></testcase>`,
93
93
  );
94
94
  }
95
95
  for (const failure of summary.hardGate.envelopeFailures) {
96
- const name = `${failure.scenarioId}[${failure.role}:${failure.target.id}:${failure.target.model ?? "none"}].execution-envelope`;
96
+ const name = `${failure.scenarioId}[${failure.role}:${renderEvalComparisonRoutesV1(failure)}].execution-envelope`;
97
97
  cases.push(
98
98
  ` <testcase classname="eval.behavior.envelope" name="${escapeXml(name)}"><failure message="incomparable">${escapeXml(failure.fields.join(", "))}</failure></testcase>`,
99
99
  );
@@ -1,5 +1,6 @@
1
1
  import { isAbsolute, relative, resolve, sep } from "node:path";
2
2
  import { normalizeClioCoderEventRecord } from "../../../core/naming-events.js";
3
+ import { ALL_TOOL_NAMES } from "../../../core/tool-names.js";
3
4
  import { clioStateDir } from "../../../core/xdg.js";
4
5
  import {
5
6
  evidenceMetricsFromReceipt,
@@ -205,19 +206,22 @@ export function toolBehaviorMetricEntriesFromJsonl(
205
206
  const terminals = canonicalFinishes.length > 0 ? canonicalFinishes : executionEnds;
206
207
  const calls = new Map<string, number>();
207
208
  const succeeded = new Map<string, number>();
209
+ const failed = new Map<string, number>();
208
210
  const blocked = new Map<string, number>();
209
211
  for (const terminal of terminals) {
210
212
  const tool = metricToolName(terminal.tool);
211
213
  calls.set(tool, (calls.get(tool) ?? 0) + 1);
212
214
  if (terminal.outcome === "ok") succeeded.set(tool, (succeeded.get(tool) ?? 0) + 1);
213
215
  if (terminal.outcome === "blocked") blocked.set(tool, (blocked.get(tool) ?? 0) + 1);
216
+ if (terminal.outcome === "error") failed.set(tool, (failed.get(tool) ?? 0) + 1);
214
217
  }
215
- const namedTools = new Set(["bash", "dispatch", "read", ...calls.keys(), ...succeeded.keys(), ...blocked.keys()]);
218
+ const namedTools = new Set([...ALL_TOOL_NAMES, ...calls.keys()]);
216
219
  const entries: Record<string, number> = { "tools.read.distinctPaths": readPaths.size };
217
220
  for (const tool of [...namedTools].sort()) {
218
221
  entries[`tools.calls.${tool}`] = calls.get(tool) ?? 0;
219
222
  entries[`tools.succeeded.${tool}`] = succeeded.get(tool) ?? 0;
220
223
  entries[`tools.blocked.${tool}`] = blocked.get(tool) ?? 0;
224
+ entries[`tools.failed.${tool}`] = failed.get(tool) ?? 0;
221
225
  }
222
226
  if (readObservation !== undefined) {
223
227
  const allowed = readObservation.allowedPaths.map((path) => normalizeObservedPath(cwd, path));
@@ -230,6 +230,8 @@ export interface EvalRunnerV2 {
230
230
  }
231
231
 
232
232
  export interface EvalVerifyV2 {
233
+ /** Workspace-relative grader code and dependencies that the runner must not change. */
234
+ protectedFiles?: string[];
233
235
  commands?: string[];
234
236
  /**
235
237
  * Commands that grade the task outcome. They run in the workspace before the
@@ -247,6 +247,7 @@ function readVerify(
247
247
  return {
248
248
  commands: readOptionalStringArray(value, "commands", `${path}.commands`, issues),
249
249
  measure: readOptionalStringArray(value, "measure", `${path}.measure`, issues),
250
+ protectedFiles: readOptionalStringArray(value, "protectedFiles", `${path}.protectedFiles`, issues),
250
251
  assertions: readAssertions(value.assertions, `${path}.assertions`, issues),
251
252
  forbidPaths: readOptionalStringArray(value, "forbidPaths", `${path}.forbidPaths`, issues),
252
253
  };
@@ -1,7 +1,9 @@
1
- import { mkdtemp, rm, writeFile } from "node:fs/promises";
1
+ import { constants } from "node:fs";
2
+ import { lstat, mkdir, mkdtemp, open, readdir, realpath, rm, writeFile } from "node:fs/promises";
2
3
  import { tmpdir } from "node:os";
3
- import { resolve } from "node:path";
4
+ import { isAbsolute, relative, resolve, sep } from "node:path";
4
5
  import { namingCompatibilityEnvironment } from "../../../core/naming-compat.js";
6
+ import { clioDataDir } from "../../../core/xdg.js";
5
7
  import { resolveMetricAssertion } from "../compare/thresholds.js";
6
8
  import { buildEvalExecutionEnvelopeV1, type EvalExecutionObservationV1 } from "../execution-provenance.js";
7
9
  import { aggregateEvalVerdicts } from "../metrics/aggregate.js";
@@ -44,7 +46,8 @@ import type { EvalMetricAssertion, EvalSuiteTargetV2, LoadedEvalSuiteV2 } from "
44
46
  import { createEvalId } from "../store.js";
45
47
  import { runCommandVerifiers } from "../verifiers/command.js";
46
48
  import { forbiddenPathHits } from "../verifiers/file-exists.js";
47
- import { collectPatchMetrics } from "../verifiers/patch.js";
49
+ import { EvalGraderIntegrityError, protectGraderFiles } from "../verifiers/integrity.js";
50
+ import { collectPatchMetrics, forgetPatchBaseline, recordPatchBaseline } from "../verifiers/patch.js";
48
51
  import { prepareGitWorkspace } from "../workspaces/git.js";
49
52
  import { type PreparedEvalWorkspace, prepareLocalWorkspace } from "../workspaces/local.js";
50
53
  import { type PrepareTempCopyWorkspaceOptions, prepareTempCopyWorkspace } from "../workspaces/temp-copy.js";
@@ -99,6 +102,7 @@ export async function runEvalSuiteV2(
99
102
  options.clioEntry,
100
103
  options.freshWorkspaces === true,
101
104
  options.tempCopy,
105
+ resolve(clioDataDir(), "evals", evalId, "transcripts", String(results.length)),
102
106
  );
103
107
  spentUsd += resultCostUsd(completed.result);
104
108
  results.push(completed.result);
@@ -154,10 +158,13 @@ async function runMatrixItem(
154
158
  clioEntry: string,
155
159
  freshWorkspace: boolean,
156
160
  tempCopy: PrepareTempCopyWorkspaceOptions | undefined,
161
+ transcriptDir: string,
157
162
  ): Promise<CompletedMatrixItem> {
158
163
  let workspace: PreparedEvalWorkspace | null = null;
159
164
  let receipt: EvalRunnerOutput["receipt"] = null;
160
165
  let runnerWallTimeMs = 0;
166
+ let runnerEvidence: EvalRunnerOutput | null = null;
167
+ let retention: Promise<RetainedSessionLedgers> | undefined;
161
168
  let executionObservation: EvalExecutionObservationV1 | undefined;
162
169
  // One matrix item, one Clio journal. An item measures Clio, and a shared
163
170
  // state directory would mix sibling processes' runs and yesterday's sessions
@@ -170,20 +177,24 @@ async function runMatrixItem(
170
177
  // A fixture that never came up measured nothing, so the item fails as a
171
178
  // harness failure rather than reporting an invariant it never observed.
172
179
  if (!setup.pass) throw new EvalWorkspaceSetupError(setup.exitCode, setup.stderr);
180
+ if (task.workspace.kind !== "local" || freshWorkspace) recordPatchBaseline(workspace.dir);
181
+ const checkGraderIntegrity = await protectGraderFiles(workspace.dir, task.verify.protectedFiles ?? []);
173
182
  const runner = await runTaskRunner(task, target, workspace.dir, clioEntry, {
174
183
  CLIO_CODER_STATE_DIR: stateDir,
175
184
  CLIO_CODER_ENTRY: clioEntry,
176
185
  });
177
- const runnerStdoutFile = resolve(stateDir, "eval-runner-output.jsonl");
178
- await writeFile(runnerStdoutFile, runner.stdout, "utf8");
186
+ runnerEvidence = runner;
179
187
  receipt = runner.receipt ?? null;
180
188
  runnerWallTimeMs = runner.wallTimeMs;
189
+ const runnerStdoutFile = resolve(stateDir, "eval-runner-output.jsonl");
190
+ await writeFile(runnerStdoutFile, runner.stdout, { encoding: "utf8", mode: 0o600, flag: "wx" });
181
191
  const patch = collectPatchMetrics(workspace.dir);
182
192
  const receiptExitCode = runner.exitCode;
183
193
  // Read after the runner returned and before the journal is removed: what
184
194
  // Clio sealed for this item, judged against its own ledger, and whether
185
195
  // the workers it attested are still running.
186
196
  const journalMetrics = invariantMetrics(stateDir, receiptExitCode);
197
+ await checkGraderIntegrity();
187
198
  const measurement = await measureTaskOutcome(task, workspace.dir, {
188
199
  ...namingCompatibilityEnvironment(
189
200
  "CLIO_CODER_EVAL_RUNNER_STDOUT_FILE",
@@ -202,14 +213,20 @@ async function runMatrixItem(
202
213
  // The one reading that needs both sides: what the loop reported it
203
214
  // spent, and what the journal shows it sealed.
204
215
  ...fleetLoopReceiptAgreement(runner.metrics as Record<string, number | boolean>, journalMetrics),
205
- "patch.bytes": patch.bytes,
206
- "patch.filesChanged": patch.filesChanged,
207
- "patch.testFilesModified": patch.testFilesModified,
216
+ ...(patch === null
217
+ ? {}
218
+ : {
219
+ "patch.bytes": patch.bytes,
220
+ "patch.filesChanged": patch.filesChanged,
221
+ "patch.testFilesModified": patch.testFilesModified,
222
+ }),
208
223
  "result.pass": runner.exitCode === 0,
209
224
  "result.failureClass": runner.exitCode === 0 ? null : "runner_failed",
210
225
  ...measurement.metrics,
211
226
  };
227
+ await checkGraderIntegrity();
212
228
  const verifier = await runVerifiers(task, workspace.dir, metrics);
229
+ await checkGraderIntegrity();
213
230
  const graderFailed = metrics["task.solved"] === false;
214
231
  const pass = runner.exitCode === 0 && verifier.pass && !graderFailed;
215
232
  const failureClass = pass
@@ -238,7 +255,10 @@ async function runMatrixItem(
238
255
  ...(verifier.stderr.length > 0 ? { verifierStderr: verifier.stderr } : {}),
239
256
  },
240
257
  };
241
- const snapshot = await readEvalLedgerSnapshot(stateDir);
258
+ retention ??= retainSessionLedgers(stateDir, transcriptDir, runnerEvidence?.stdout);
259
+ const retained = await retention;
260
+ applyRetainedSessionLedgers(result, retained);
261
+ const snapshot = retained.errors.length > 0 ? emptyLedgerSnapshot() : await readEvalLedgerSnapshot(stateDir);
242
262
  const selected = selectEvalLedgerEntries(snapshot.entries, runner.ledgerEntries ?? []);
243
263
  result.artifacts.trackedMetricSources = JSON.stringify({
244
264
  assistantCalls: selected.source,
@@ -271,10 +291,15 @@ async function runMatrixItem(
271
291
  serving: evalServingObservationFrom(target, receipt ?? null, snapshot.compiledPromptHashes),
272
292
  };
273
293
  } catch (error) {
274
- const failureClass = error instanceof EvalWorkspaceSetupError ? "setup_failed" : "command_error";
294
+ const failureClass =
295
+ error instanceof EvalGraderIntegrityError
296
+ ? "grader_integrity"
297
+ : error instanceof EvalWorkspaceSetupError
298
+ ? "setup_failed"
299
+ : "command_error";
275
300
  const result: EvalArtifactResultV4 = {
276
- assignmentId: null,
277
- terminalReceiptDigest: null,
301
+ assignmentId: runnerEvidence?.assignmentId ?? null,
302
+ terminalReceiptDigest: runnerEvidence?.terminalReceiptDigest ?? null,
278
303
  taskId: task.id,
279
304
  repeatIndex,
280
305
  target: { id: target.id, model: target.model ?? null, thinking: target.thinking ?? null },
@@ -287,11 +312,15 @@ async function runMatrixItem(
287
312
  "latency.wallMs": 0,
288
313
  },
289
314
  artifacts: {
315
+ ...runnerEvidence?.artifacts,
290
316
  error: error instanceof Error ? error.message : String(error),
291
317
  ...(workspace === null ? {} : { workspace: workspace.dir }),
292
318
  },
293
319
  };
294
- const snapshot = await readEvalLedgerSnapshot(stateDir);
320
+ retention ??= retainSessionLedgers(stateDir, transcriptDir, runnerEvidence?.stdout);
321
+ const retained = await retention;
322
+ applyRetainedSessionLedgers(result, retained);
323
+ const snapshot = retained.errors.length > 0 ? emptyLedgerSnapshot() : await readEvalLedgerSnapshot(stateDir);
295
324
  result.verdict = adaptSuiteV2ResultToVerdictV1(
296
325
  result,
297
326
  buildEvalTrackedMetrics({
@@ -316,6 +345,7 @@ async function runMatrixItem(
316
345
  };
317
346
  } finally {
318
347
  try {
348
+ if (workspace !== null) forgetPatchBaseline(workspace.dir);
319
349
  await workspace?.cleanup();
320
350
  } finally {
321
351
  // A workspace cleanup error must not strand the suite-owned journal.
@@ -575,3 +605,149 @@ function nullableNonNegativeInteger(value: unknown): number | null {
575
605
  function stringArray(value: unknown): string[] {
576
606
  return Array.isArray(value) ? value.filter((entry): entry is string => typeof entry === "string") : [];
577
607
  }
608
+
609
+ interface RetainedSessionLedgers {
610
+ runnerStdoutPath?: string;
611
+ paths: string[];
612
+ errors: string[];
613
+ }
614
+
615
+ function applyRetainedSessionLedgers(result: EvalArtifactResultV4, retained: RetainedSessionLedgers): void {
616
+ if (retained.runnerStdoutPath !== undefined) result.artifacts.runnerStdoutFile = retained.runnerStdoutPath;
617
+ if (retained.paths.length > 0 || retained.errors.length > 0) result.artifacts.sessionLedgers = retained.paths;
618
+ if (retained.errors.length === 0) return;
619
+ result.artifacts.sessionLedgerErrors = retained.errors;
620
+ result.metrics["evidence.retentionComplete"] = false;
621
+ // Keep a runner/integrity failure as the primary cause; an otherwise healthy
622
+ // task outcome cannot claim successful grading with unsafe or missing evidence.
623
+ if (result.pass || result.failureClass === "grader_failed") {
624
+ result.artifacts.outcomeBeforeEvidenceFailure = result.failureClass ?? "pass";
625
+ result.pass = false;
626
+ result.failureClass = "evidence_integrity";
627
+ result.metrics["result.pass"] = false;
628
+ result.metrics["result.failureClass"] = "evidence_integrity";
629
+ }
630
+ }
631
+
632
+ /** Reject symlinks at every component inside the owned source directory. */
633
+ async function plainLedgerPath(root: string, path: string): Promise<void> {
634
+ const rel = relative(root, path);
635
+ if (isAbsolute(rel) || rel === ".." || rel.startsWith(`..${sep}`)) throw new Error("unsafe ledger path");
636
+ let current = root;
637
+ for (const part of ["", ...rel.split(sep)]) {
638
+ current = resolve(current, part);
639
+ if ((await lstat(current)).isSymbolicLink()) throw new Error("unsafe ledger symlink");
640
+ }
641
+ }
642
+
643
+ async function readOwnedLedger(root: string, path: string): Promise<Buffer> {
644
+ await plainLedgerPath(root, path);
645
+ const before = await lstat(path);
646
+ if (!before.isFile()) throw new Error("ledger is not a regular file");
647
+ const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
648
+ try {
649
+ const opened = await file.stat();
650
+ await plainLedgerPath(root, path);
651
+ if (opened.dev !== before.dev || opened.ino !== before.ino) throw new Error("ledger changed while opening");
652
+ return await file.readFile();
653
+ } finally {
654
+ await file.close();
655
+ }
656
+ }
657
+
658
+ /** Create a private, unique capture below the operator's artifact root. */
659
+ async function transcriptCaptureDirectory(destination: string): Promise<string> {
660
+ const base = clioDataDir();
661
+ await mkdir(base, { recursive: true, mode: 0o700 });
662
+ let current = await realpath(base);
663
+ const rel = relative(base, destination);
664
+ if (isAbsolute(rel) || rel === ".." || rel.startsWith(`..${sep}`)) throw new Error("unsafe transcript destination");
665
+ for (const part of rel.split(sep)) {
666
+ current = resolve(current, part);
667
+ try {
668
+ await mkdir(current, { mode: 0o700 });
669
+ } catch (error) {
670
+ if ((error as NodeJS.ErrnoException).code !== "EEXIST") throw error;
671
+ }
672
+ const info = await lstat(current);
673
+ if (info.isSymbolicLink() || !info.isDirectory()) throw new Error("unsafe transcript destination");
674
+ }
675
+ return mkdtemp(resolve(current, "capture-"));
676
+ }
677
+
678
+ /** Enumerate only ordinary directories; never traverse a runner-created alias. */
679
+ async function discoverOwnedLedgers(stateDir: string, errors: string[]): Promise<string[]> {
680
+ const root = resolve(stateDir, "sessions");
681
+ try {
682
+ await plainLedgerPath(stateDir, root);
683
+ } catch (error) {
684
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
685
+ throw error;
686
+ }
687
+ const paths: string[] = [];
688
+ for (const cwd of await readdir(root, { withFileTypes: true })) {
689
+ if (cwd.isSymbolicLink()) {
690
+ errors.push("session directory rejected: symlink");
691
+ continue;
692
+ }
693
+ if (!cwd.isDirectory()) continue;
694
+ const cwdPath = resolve(root, cwd.name);
695
+ try {
696
+ await plainLedgerPath(stateDir, cwdPath);
697
+ for (const session of await readdir(cwdPath, { withFileTypes: true })) {
698
+ if (session.isSymbolicLink()) {
699
+ errors.push("session directory rejected: symlink");
700
+ continue;
701
+ }
702
+ if (session.isDirectory()) paths.push(resolve(cwdPath, session.name, "current.jsonl"));
703
+ }
704
+ } catch {
705
+ errors.push("session directory unreadable or unsafe");
706
+ }
707
+ }
708
+ return paths.sort();
709
+ }
710
+
711
+ /** Best-effort evidence collection never throws into (or retries) the failure path. */
712
+ async function retainSessionLedgers(
713
+ stateDir: string,
714
+ destination: string,
715
+ runnerStdout?: string,
716
+ ): Promise<RetainedSessionLedgers> {
717
+ const retained: RetainedSessionLedgers = { paths: [], errors: [] };
718
+ try {
719
+ const refs = await discoverOwnedLedgers(stateDir, retained.errors);
720
+ if (refs.length === 0 && !runnerStdout) return retained;
721
+ const directory = await transcriptCaptureDirectory(destination);
722
+ if (runnerStdout) {
723
+ const path = resolve(directory, "runner-stdout.jsonl");
724
+ await writeFile(path, runnerStdout, { mode: 0o600, flag: "wx" });
725
+ retained.runnerStdoutPath = path;
726
+ }
727
+ for (const [index, pathToLedger] of refs.entries()) {
728
+ try {
729
+ let content: Buffer;
730
+ try {
731
+ content = await readOwnedLedger(stateDir, pathToLedger);
732
+ } catch (error) {
733
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
734
+ content = await readOwnedLedger(stateDir, `${pathToLedger}.tmp`);
735
+ retained.errors.push(`ledger ${index}: incomplete current ledger; temporary evidence retained`);
736
+ }
737
+ const path = resolve(directory, `${index}.jsonl`);
738
+ await writeFile(path, content, { mode: 0o600, flag: "wx" });
739
+ retained.paths.push(path);
740
+ } catch (error) {
741
+ // Error codes describe missing/unreadable/unsafe evidence without echoing
742
+ // runner-controlled paths or external file contents into the artifact.
743
+ const code = (error as NodeJS.ErrnoException).code;
744
+ retained.errors.push(
745
+ `ledger ${index}: retention failed (${code === "ENOENT" ? "missing" : "unsafe or unreadable"})`,
746
+ );
747
+ }
748
+ }
749
+ } catch {
750
+ retained.errors.push("session ledger retention failed: artifact storage unavailable or unsafe");
751
+ }
752
+ return retained;
753
+ }