@ebrindley/build 0.0.0-stage → 1.42.1-rc28

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 (878) hide show
  1. package/.build-project/providers/catalog.json +13951 -0
  2. package/.build-project/providers/pricing.json +1978 -0
  3. package/.build-project/providers/registry.json +4103 -0
  4. package/.github/SECURITY.md +75 -0
  5. package/.nvmrc +1 -0
  6. package/CHANGELOG.md +661 -0
  7. package/CODE_OF_CONDUCT.md +44 -0
  8. package/CONTRIBUTING.md +24 -0
  9. package/INSTALL.md +623 -0
  10. package/LICENSE +21 -0
  11. package/README.md +118 -2
  12. package/THIRD_PARTY_NOTICES.txt +26 -0
  13. package/dist/ai-judge-UE5UOYOO.js +191 -0
  14. package/dist/allowlist-grounding-KPLN6NC5.js +16 -0
  15. package/dist/allowlist-utils-MZZKKXRD.js +31 -0
  16. package/dist/apply-completion-mode-EM37UZHB.js +110 -0
  17. package/dist/artifact-migrator-WPACNSEP.js +276 -0
  18. package/dist/ask-2OZ4JFQR.js +176 -0
  19. package/dist/auth-6UKBTJUQ.js +185 -0
  20. package/dist/auth-H5KJL6HL.js +165 -0
  21. package/dist/auth-LVJRJDMU.js +12 -0
  22. package/dist/auth-NHZOCNRR.js +94 -0
  23. package/dist/auth-PBXHWXGW.js +95 -0
  24. package/dist/auth-T7Y5DCAH.js +91 -0
  25. package/dist/auth-TVVKCHQW.js +13 -0
  26. package/dist/auth-UHB2UCSS.js +97 -0
  27. package/dist/auth-VACA3VUL.js +98 -0
  28. package/dist/auth-VVLC77S3.js +44 -0
  29. package/dist/auth-liveness-XO4AGDDD.js +53 -0
  30. package/dist/autoloop-cleanup-SI3VGAAR.js +106 -0
  31. package/dist/autoloop-evidence-gates-J5GG5YQB.js +39 -0
  32. package/dist/autoloop-gate-policy-SUNAEP6Q.js +169 -0
  33. package/dist/autoloop-helpers-VQGQNTT6.js +52 -0
  34. package/dist/autoloop-ledger-P6TIDP7C.js +96 -0
  35. package/dist/autoloop-ledger-subscriber-HFAGOZXH.js +161 -0
  36. package/dist/autoloop-run-defaults-GWGZBNT7.js +27 -0
  37. package/dist/autoloop-run-lock-GBWRM5A2.js +197 -0
  38. package/dist/autoloop-success-C32QVWOP.js +93 -0
  39. package/dist/autoloop-termination-summary-GI6IBQWD.js +58 -0
  40. package/dist/autoloop-trajectory-AMKSQISD.js +70 -0
  41. package/dist/autoloop-wall-clock-T7ZVIQOC.js +12 -0
  42. package/dist/automatic-branch-cleanup-R62X2C5O.js +49 -0
  43. package/dist/autonomous-loop-controller-2WL363LW.js +4386 -0
  44. package/dist/backend-YUTFDZXZ.js +30 -0
  45. package/dist/background-executor-Z3ODTMD7.js +260 -0
  46. package/dist/backlog-75QPEAMW.js +403 -0
  47. package/dist/backlog-execution-intent-GWUV5TUK.js +19 -0
  48. package/dist/backup-active-store-XHWLN34M.js +16 -0
  49. package/dist/backup-machine-stores-UI4LTJOY.js +251 -0
  50. package/dist/backup-telemetry-db-Z4ICYCNW.js +26 -0
  51. package/dist/branch-archive-manager-FMSQ7YJF.js +18 -0
  52. package/dist/branch-cleanup-manager-ST6FJGND.js +35 -0
  53. package/dist/build-gate-7NKWPY62.js +68 -0
  54. package/dist/build-root-S7DINODY.js +18 -0
  55. package/dist/change-summary-R6CB6VXJ.js +50 -0
  56. package/dist/chunk-24MNKKOM.js +173 -0
  57. package/dist/chunk-2H6VZFIO.js +235 -0
  58. package/dist/chunk-2JIX3EKV.js +39 -0
  59. package/dist/chunk-2KO7HVZM.js +106 -0
  60. package/dist/chunk-2L36U25O.js +100 -0
  61. package/dist/chunk-2NMNFUQA.js +475 -0
  62. package/dist/chunk-2OUAEH67.js +83 -0
  63. package/dist/chunk-2VLJUXJU.js +115 -0
  64. package/dist/chunk-2VUEDIUM.js +77 -0
  65. package/dist/chunk-2Y2IIHPI.js +430 -0
  66. package/dist/chunk-2YRG3LHZ.js +220 -0
  67. package/dist/chunk-2Z5Q3SUY.js +65 -0
  68. package/dist/chunk-32IYXIE5.js +873 -0
  69. package/dist/chunk-33IGPPUI.js +292 -0
  70. package/dist/chunk-352PCJLK.js +283 -0
  71. package/dist/chunk-35J4NE6S.js +226 -0
  72. package/dist/chunk-3C7WBIVK.js +1016 -0
  73. package/dist/chunk-3H3EY6U7.js +1225 -0
  74. package/dist/chunk-3H4MWYIC.js +198 -0
  75. package/dist/chunk-3HHWQR3N.js +2479 -0
  76. package/dist/chunk-3JKNRYEE.js +14 -0
  77. package/dist/chunk-3LECCYZY.js +128 -0
  78. package/dist/chunk-3LOY6YZI.js +852 -0
  79. package/dist/chunk-3M57DADF.js +44 -0
  80. package/dist/chunk-3NOTLVLG.js +3803 -0
  81. package/dist/chunk-3OPP2OZB.js +1480 -0
  82. package/dist/chunk-3P5IN5E7.js +9 -0
  83. package/dist/chunk-3PL22IYZ.js +20 -0
  84. package/dist/chunk-3REDAJUJ.js +14 -0
  85. package/dist/chunk-3S2R4XJI.js +203 -0
  86. package/dist/chunk-3UBZI5DW.js +61 -0
  87. package/dist/chunk-3VV5OBGG.js +308 -0
  88. package/dist/chunk-3WY5TU2O.js +823 -0
  89. package/dist/chunk-43OKHTW4.js +82 -0
  90. package/dist/chunk-45KUJBDI.js +112 -0
  91. package/dist/chunk-47X5LM7B.js +224 -0
  92. package/dist/chunk-4B6FQJ77.js +268 -0
  93. package/dist/chunk-4BTDUT2S.js +42 -0
  94. package/dist/chunk-4DJL2VXA.js +24 -0
  95. package/dist/chunk-4EBSXZ73.js +48 -0
  96. package/dist/chunk-4QKP6I4C.js +294 -0
  97. package/dist/chunk-4U6XK2DG.js +300 -0
  98. package/dist/chunk-4UMRUFBD.js +132 -0
  99. package/dist/chunk-4US4SYJ4.js +569 -0
  100. package/dist/chunk-4ZPLWEZO.js +154 -0
  101. package/dist/chunk-56WPYDJH.js +624 -0
  102. package/dist/chunk-57WRCJJW.js +50 -0
  103. package/dist/chunk-5AW4RMNG.js +24 -0
  104. package/dist/chunk-5EQN56OZ.js +155 -0
  105. package/dist/chunk-5F43TUIN.js +38 -0
  106. package/dist/chunk-5FKHIKTS.js +115 -0
  107. package/dist/chunk-5HDP7XZG.js +91 -0
  108. package/dist/chunk-5KQETTNS.js +152 -0
  109. package/dist/chunk-5PDVN2KO.js +498 -0
  110. package/dist/chunk-5UBIFVRD.js +509 -0
  111. package/dist/chunk-5YDE3Q62.js +46 -0
  112. package/dist/chunk-626AJVMU.js +302 -0
  113. package/dist/chunk-633XZ7UF.js +3583 -0
  114. package/dist/chunk-63DHNHGA.js +236 -0
  115. package/dist/chunk-666656AR.js +568 -0
  116. package/dist/chunk-67YRJPJO.js +19 -0
  117. package/dist/chunk-6CAU7VBA.js +20 -0
  118. package/dist/chunk-6CB3KJRY.js +21 -0
  119. package/dist/chunk-6DBMALXL.js +29 -0
  120. package/dist/chunk-6E25C4IA.js +269 -0
  121. package/dist/chunk-6FIBNIQU.js +73 -0
  122. package/dist/chunk-6G57FYBV.js +189 -0
  123. package/dist/chunk-6KZKRTG3.js +4885 -0
  124. package/dist/chunk-6LAH2UV2.js +525 -0
  125. package/dist/chunk-6PZY2TTU.js +921 -0
  126. package/dist/chunk-6T6NHXK4.js +230 -0
  127. package/dist/chunk-6TBEX4R4.js +432 -0
  128. package/dist/chunk-6TRD7TEE.js +911 -0
  129. package/dist/chunk-6XCP2RAI.js +47 -0
  130. package/dist/chunk-726G6WDL.js +351 -0
  131. package/dist/chunk-75EMT7BF.js +616 -0
  132. package/dist/chunk-762ACDZJ.js +4696 -0
  133. package/dist/chunk-77I6G4CO.js +1 -0
  134. package/dist/chunk-7DJ6SQH3.js +510 -0
  135. package/dist/chunk-7HPCIOMA.js +1383 -0
  136. package/dist/chunk-7HYBSRPZ.js +17503 -0
  137. package/dist/chunk-7KBEOPVB.js +73 -0
  138. package/dist/chunk-7LHJDJB3.js +2222 -0
  139. package/dist/chunk-7NVJMH52.js +306 -0
  140. package/dist/chunk-7RMARDVH.js +33 -0
  141. package/dist/chunk-7SEWU4QG.js +36 -0
  142. package/dist/chunk-7TUTZTI2.js +911 -0
  143. package/dist/chunk-7VBDFPUM.js +340 -0
  144. package/dist/chunk-7VRJHTGZ.js +6406 -0
  145. package/dist/chunk-7YAOUUKK.js +493 -0
  146. package/dist/chunk-AAAODV76.js +860 -0
  147. package/dist/chunk-AB4HUJVQ.js +339 -0
  148. package/dist/chunk-AEQWV746.js +611 -0
  149. package/dist/chunk-AHU3FKPA.js +11639 -0
  150. package/dist/chunk-AISTV5XU.js +226 -0
  151. package/dist/chunk-AJBTKGJZ.js +48 -0
  152. package/dist/chunk-AJJNW7XT.js +248 -0
  153. package/dist/chunk-AJN5Y5YZ.js +160 -0
  154. package/dist/chunk-ALDTFNZ3.js +150 -0
  155. package/dist/chunk-ARARVIZK.js +281 -0
  156. package/dist/chunk-ATBM6AW5.js +53 -0
  157. package/dist/chunk-ATKEKM3E.js +206 -0
  158. package/dist/chunk-AUJLW6JZ.js +92 -0
  159. package/dist/chunk-AY3MHEFM.js +24 -0
  160. package/dist/chunk-B7PYTV72.js +236 -0
  161. package/dist/chunk-B7YRSULE.js +1423 -0
  162. package/dist/chunk-BAWJNMWF.js +339 -0
  163. package/dist/chunk-BBPIILO2.js +88 -0
  164. package/dist/chunk-BD3PGW6A.js +957 -0
  165. package/dist/chunk-BDPYFAB4.js +44 -0
  166. package/dist/chunk-BIUV23HH.js +729 -0
  167. package/dist/chunk-BQ3VAGXH.js +243 -0
  168. package/dist/chunk-BQJOGAWT.js +31 -0
  169. package/dist/chunk-BT7EG7CO.js +68 -0
  170. package/dist/chunk-BV3XQQLU.js +27 -0
  171. package/dist/chunk-BY6ODHNZ.js +78 -0
  172. package/dist/chunk-BZRLSZNV.js +79 -0
  173. package/dist/chunk-C3DH3NCY.js +2773 -0
  174. package/dist/chunk-C3KCMAJP.js +756 -0
  175. package/dist/chunk-C7AGUJ5K.js +267 -0
  176. package/dist/chunk-CBSWKQCX.js +342 -0
  177. package/dist/chunk-CE5OZBYY.js +21 -0
  178. package/dist/chunk-CFCVYHSW.js +373 -0
  179. package/dist/chunk-CHA2HDE5.js +126 -0
  180. package/dist/chunk-CIHWPGS5.js +146 -0
  181. package/dist/chunk-CJBSZX3F.js +127 -0
  182. package/dist/chunk-CLA6QIJM.js +43 -0
  183. package/dist/chunk-CPSVQR2I.js +365 -0
  184. package/dist/chunk-CRPRVNQ4.js +254 -0
  185. package/dist/chunk-CSIE4Y7C.js +1093 -0
  186. package/dist/chunk-CSOPSYDY.js +142 -0
  187. package/dist/chunk-CSXLLEGB.js +205 -0
  188. package/dist/chunk-CTDLERWU.js +293 -0
  189. package/dist/chunk-CULBXMSK.js +110 -0
  190. package/dist/chunk-D2M2Y5ID.js +21 -0
  191. package/dist/chunk-D37WY7SH.js +1060 -0
  192. package/dist/chunk-D4VJFCGZ.js +89 -0
  193. package/dist/chunk-D6WTZMZB.js +48 -0
  194. package/dist/chunk-DBHOWDUH.js +976 -0
  195. package/dist/chunk-DCACX7BV.js +19364 -0
  196. package/dist/chunk-DFHX4XYA.js +128 -0
  197. package/dist/chunk-DIKBRRKE.js +176 -0
  198. package/dist/chunk-DJG5RIOR.js +9 -0
  199. package/dist/chunk-DNIOIISW.js +616 -0
  200. package/dist/chunk-DOA5G7IA.js +315 -0
  201. package/dist/chunk-DP7FKP6W.js +855 -0
  202. package/dist/chunk-DS2JZ677.js +79 -0
  203. package/dist/chunk-DSRLVYBS.js +82 -0
  204. package/dist/chunk-EAEVKNJA.js +209 -0
  205. package/dist/chunk-EEUESN3T.js +575 -0
  206. package/dist/chunk-EJ4LUU5Y.js +73 -0
  207. package/dist/chunk-EJIWTPSZ.js +1063 -0
  208. package/dist/chunk-EJVCDTAN.js +116 -0
  209. package/dist/chunk-EKLUBDBQ.js +627 -0
  210. package/dist/chunk-EN62WLFD.js +849 -0
  211. package/dist/chunk-ENYRCL43.js +26 -0
  212. package/dist/chunk-EP22ZMFO.js +273 -0
  213. package/dist/chunk-EP4SVAVI.js +87 -0
  214. package/dist/chunk-EPAMVGI3.js +1562 -0
  215. package/dist/chunk-EPRMH6HO.js +24 -0
  216. package/dist/chunk-ES6NWJ36.js +4057 -0
  217. package/dist/chunk-ETA2K4KI.js +30 -0
  218. package/dist/chunk-ETAD4NKD.js +31 -0
  219. package/dist/chunk-EUWIIDQ7.js +93 -0
  220. package/dist/chunk-EVE3OD2W.js +141 -0
  221. package/dist/chunk-EXA26FFC.js +459 -0
  222. package/dist/chunk-EXSPAA35.js +244 -0
  223. package/dist/chunk-F55YABKV.js +258 -0
  224. package/dist/chunk-F5DNGU5W.js +27 -0
  225. package/dist/chunk-F622MJYV.js +103 -0
  226. package/dist/chunk-F6NIQD74.js +5111 -0
  227. package/dist/chunk-FAWJTC34.js +43 -0
  228. package/dist/chunk-FAZBRHGG.js +47 -0
  229. package/dist/chunk-FIEUSGNJ.js +39 -0
  230. package/dist/chunk-FKCG7K6H.js +1146 -0
  231. package/dist/chunk-FOVVXV45.js +229 -0
  232. package/dist/chunk-FRBPKBFE.js +30 -0
  233. package/dist/chunk-FSA5BPFI.js +268 -0
  234. package/dist/chunk-FSJ5TTZ3.js +29 -0
  235. package/dist/chunk-FT7SGLXT.js +193 -0
  236. package/dist/chunk-FUUVZZUB.js +62 -0
  237. package/dist/chunk-FYMRVUNZ.js +1697 -0
  238. package/dist/chunk-FYTAA5FG.js +162 -0
  239. package/dist/chunk-G3VB2UCZ.js +3892 -0
  240. package/dist/chunk-G6OIMVXH.js +405 -0
  241. package/dist/chunk-G7PQCXVH.js +228 -0
  242. package/dist/chunk-GAB6UW52.js +1087 -0
  243. package/dist/chunk-GAFJEYLK.js +29 -0
  244. package/dist/chunk-GC4CRMTS.js +642 -0
  245. package/dist/chunk-GFHSIWHL.js +5297 -0
  246. package/dist/chunk-GI5M67YA.js +735 -0
  247. package/dist/chunk-GIJWHUWF.js +191 -0
  248. package/dist/chunk-GO6DRECI.js +1 -0
  249. package/dist/chunk-GOFVBTMN.js +314 -0
  250. package/dist/chunk-GQIP72ZJ.js +13 -0
  251. package/dist/chunk-GQXLXRFA.js +28 -0
  252. package/dist/chunk-GT6HFKJB.js +48 -0
  253. package/dist/chunk-GVJGSSKM.js +174 -0
  254. package/dist/chunk-GWHGTG37.js +36 -0
  255. package/dist/chunk-GZAJHLKO.js +18 -0
  256. package/dist/chunk-GZK62I3N.js +314 -0
  257. package/dist/chunk-H3HGMISG.js +483 -0
  258. package/dist/chunk-H3ISZJMJ.js +403 -0
  259. package/dist/chunk-H4HXVWEC.js +9 -0
  260. package/dist/chunk-H6MJGKAW.js +120 -0
  261. package/dist/chunk-HBTTGVR5.js +353 -0
  262. package/dist/chunk-HBZ322WZ.js +35 -0
  263. package/dist/chunk-HEP3ILP4.js +34 -0
  264. package/dist/chunk-HGFXODKO.js +106 -0
  265. package/dist/chunk-HHWDTB6S.js +59 -0
  266. package/dist/chunk-HKO45NLZ.js +286 -0
  267. package/dist/chunk-HLVTEA6A.js +89 -0
  268. package/dist/chunk-HS3SY6HN.js +160 -0
  269. package/dist/chunk-HT5OCGKN.js +899 -0
  270. package/dist/chunk-HXIIEMGF.js +78 -0
  271. package/dist/chunk-I56TH7VM.js +46 -0
  272. package/dist/chunk-I6FN3R5D.js +352 -0
  273. package/dist/chunk-I7SCBHJN.js +655 -0
  274. package/dist/chunk-IJM4GKAT.js +529 -0
  275. package/dist/chunk-IMEYU36R.js +344 -0
  276. package/dist/chunk-INJ3SS6A.js +936 -0
  277. package/dist/chunk-IUKOPCCE.js +441 -0
  278. package/dist/chunk-IVEPZQJO.js +33 -0
  279. package/dist/chunk-IVZEONFC.js +43 -0
  280. package/dist/chunk-IWBHRSG7.js +936 -0
  281. package/dist/chunk-IYY3HQAD.js +484 -0
  282. package/dist/chunk-J2ICMYDA.js +48 -0
  283. package/dist/chunk-J2QCFLUN.js +505 -0
  284. package/dist/chunk-J5HM6V5P.js +1039 -0
  285. package/dist/chunk-J6NZX6QH.js +398 -0
  286. package/dist/chunk-JBBB2Y47.js +432 -0
  287. package/dist/chunk-JDCZQZU7.js +42 -0
  288. package/dist/chunk-JEDNXGSS.js +169 -0
  289. package/dist/chunk-JHP7OT6K.js +89 -0
  290. package/dist/chunk-JLS65NUQ.js +14 -0
  291. package/dist/chunk-JNMWYMC6.js +38 -0
  292. package/dist/chunk-JNSTWNNW.js +25 -0
  293. package/dist/chunk-JOSK6GEU.js +9564 -0
  294. package/dist/chunk-JQUMSIGC.js +100 -0
  295. package/dist/chunk-JVHGMURQ.js +1106 -0
  296. package/dist/chunk-JYXS47FQ.js +951 -0
  297. package/dist/chunk-K2ZMW2Z5.js +2147 -0
  298. package/dist/chunk-K7FAFORM.js +14 -0
  299. package/dist/chunk-KBJXX3ON.js +333 -0
  300. package/dist/chunk-KHFKVQWY.js +486 -0
  301. package/dist/chunk-KHMEI3DQ.js +173 -0
  302. package/dist/chunk-KHW3UD7B.js +69 -0
  303. package/dist/chunk-KKQKWAMF.js +365 -0
  304. package/dist/chunk-KOKXJV2U.js +455 -0
  305. package/dist/chunk-KQ4NGOJI.js +14 -0
  306. package/dist/chunk-KQYQOXMS.js +342 -0
  307. package/dist/chunk-KTMW65UX.js +14 -0
  308. package/dist/chunk-KUEWV2JH.js +593 -0
  309. package/dist/chunk-KXYDV3HP.js +1523 -0
  310. package/dist/chunk-KZ4JMGZ5.js +96 -0
  311. package/dist/chunk-KZWGBUIO.js +2659 -0
  312. package/dist/chunk-L2CBG5IX.js +1892 -0
  313. package/dist/chunk-L2S235CU.js +314 -0
  314. package/dist/chunk-L32WD57F.js +98 -0
  315. package/dist/chunk-LDJCKAJP.js +123 -0
  316. package/dist/chunk-LDWNBEN7.js +541 -0
  317. package/dist/chunk-LJVH57G2.js +241 -0
  318. package/dist/chunk-LPQ7NZEN.js +209 -0
  319. package/dist/chunk-LRGH3CCV.js +148 -0
  320. package/dist/chunk-LULOGMMM.js +1133 -0
  321. package/dist/chunk-LWGKN2GY.js +8284 -0
  322. package/dist/chunk-LX4F24ZH.js +157 -0
  323. package/dist/chunk-M4BUEXXF.js +839 -0
  324. package/dist/chunk-M6UHOC4I.js +553 -0
  325. package/dist/chunk-MCBNWZNO.js +657 -0
  326. package/dist/chunk-MEMSY6VY.js +223 -0
  327. package/dist/chunk-MHLEZQQI.js +145 -0
  328. package/dist/chunk-MJ6WNSIX.js +192 -0
  329. package/dist/chunk-MKASIKWZ.js +442 -0
  330. package/dist/chunk-MNOVBYFU.js +60 -0
  331. package/dist/chunk-MO2BYAAF.js +2896 -0
  332. package/dist/chunk-MP6P7Y2A.js +180 -0
  333. package/dist/chunk-MQ4TFJAG.js +3365 -0
  334. package/dist/chunk-MT2WAIR3.js +131 -0
  335. package/dist/chunk-MTU7VTNN.js +1122 -0
  336. package/dist/chunk-MULMXX4V.js +150 -0
  337. package/dist/chunk-MW2DWWVA.js +147 -0
  338. package/dist/chunk-MY3ZPUN4.js +151 -0
  339. package/dist/chunk-MYLH2S4G.js +64 -0
  340. package/dist/chunk-MZ5WYKNA.js +28 -0
  341. package/dist/chunk-N3Q2JNPV.js +249 -0
  342. package/dist/chunk-N5DX4JAK.js +12 -0
  343. package/dist/chunk-NAINGKHF.js +35 -0
  344. package/dist/chunk-NEQUQHOX.js +223 -0
  345. package/dist/chunk-NHNPEZS4.js +1408 -0
  346. package/dist/chunk-NHTIXJCR.js +17 -0
  347. package/dist/chunk-NKLPMBNV.js +1154 -0
  348. package/dist/chunk-NMVZ5YES.js +199 -0
  349. package/dist/chunk-NRFRY3GE.js +256 -0
  350. package/dist/chunk-NTD6CSI6.js +1266 -0
  351. package/dist/chunk-NUO7B3SH.js +318 -0
  352. package/dist/chunk-NVOHIJKG.js +1319 -0
  353. package/dist/chunk-NXH3RX7O.js +523 -0
  354. package/dist/chunk-NXZ3DURF.js +257 -0
  355. package/dist/chunk-O26L6F7F.js +209 -0
  356. package/dist/chunk-O5RRIUEP.js +124 -0
  357. package/dist/chunk-O5X6BKAO.js +10 -0
  358. package/dist/chunk-O6ZQUVTR.js +31 -0
  359. package/dist/chunk-O7FE75QZ.js +306 -0
  360. package/dist/chunk-OC7Z6AJQ.js +81 -0
  361. package/dist/chunk-OH7IEZ63.js +307 -0
  362. package/dist/chunk-OI734GRS.js +115 -0
  363. package/dist/chunk-OJBH62DK.js +684 -0
  364. package/dist/chunk-OKJLVSTJ.js +247 -0
  365. package/dist/chunk-OMX5VL43.js +79 -0
  366. package/dist/chunk-ONHAMBN6.js +12 -0
  367. package/dist/chunk-ONYPLIVE.js +753 -0
  368. package/dist/chunk-OSK7QWPD.js +637 -0
  369. package/dist/chunk-OTXLMJKP.js +438 -0
  370. package/dist/chunk-OV5PKQMA.js +213 -0
  371. package/dist/chunk-OXK5HA4B.js +31 -0
  372. package/dist/chunk-OYDWFQA4.js +272 -0
  373. package/dist/chunk-OZAUKWHB.js +22 -0
  374. package/dist/chunk-P5P2EKGH.js +94 -0
  375. package/dist/chunk-P6SSWAKY.js +29 -0
  376. package/dist/chunk-P7CQGPLS.js +30 -0
  377. package/dist/chunk-P7RVCHQV.js +197 -0
  378. package/dist/chunk-PEBWDYIW.js +726 -0
  379. package/dist/chunk-PFCXFO7A.js +9193 -0
  380. package/dist/chunk-PFLDWMX6.js +168 -0
  381. package/dist/chunk-PHZGLQSK.js +15883 -0
  382. package/dist/chunk-PNFTPNSR.js +20 -0
  383. package/dist/chunk-PPHXX4W7.js +175 -0
  384. package/dist/chunk-PPZESPJT.js +262 -0
  385. package/dist/chunk-PRDHI2L5.js +296 -0
  386. package/dist/chunk-PSTKWHHN.js +32 -0
  387. package/dist/chunk-PV53ODOT.js +555 -0
  388. package/dist/chunk-PVJBTI7P.js +24 -0
  389. package/dist/chunk-PXKERBKX.js +100 -0
  390. package/dist/chunk-PZ5AY32C.js +10 -0
  391. package/dist/chunk-Q3DHEZA5.js +85 -0
  392. package/dist/chunk-Q5RZDVQK.js +204 -0
  393. package/dist/chunk-Q64IR2Z2.js +4933 -0
  394. package/dist/chunk-Q6Z5UGPL.js +398 -0
  395. package/dist/chunk-QAMAV4DT.js +627 -0
  396. package/dist/chunk-QBWF4444.js +112 -0
  397. package/dist/chunk-QDKYT4CI.js +22805 -0
  398. package/dist/chunk-QFLBRWCJ.js +126 -0
  399. package/dist/chunk-QILAQACE.js +107 -0
  400. package/dist/chunk-QJ6OEH4K.js +3683 -0
  401. package/dist/chunk-QK3NLYTV.js +320 -0
  402. package/dist/chunk-QOFLUS24.js +535 -0
  403. package/dist/chunk-QOIASNEJ.js +98 -0
  404. package/dist/chunk-QP4UTSOV.js +3587 -0
  405. package/dist/chunk-QP5ST7RI.js +904 -0
  406. package/dist/chunk-QS5AGRZN.js +167 -0
  407. package/dist/chunk-QTAOU53N.js +107 -0
  408. package/dist/chunk-QTCLJHLZ.js +351 -0
  409. package/dist/chunk-QTOLTG4L.js +119 -0
  410. package/dist/chunk-QWDV4OSL.js +142 -0
  411. package/dist/chunk-QWMQ74KD.js +508 -0
  412. package/dist/chunk-QX6LOMMH.js +158 -0
  413. package/dist/chunk-QXBKIHY7.js +238 -0
  414. package/dist/chunk-QXBKTJT6.js +270 -0
  415. package/dist/chunk-QYQOVOLR.js +196 -0
  416. package/dist/chunk-R2CKS6WT.js +73 -0
  417. package/dist/chunk-R2TIYG7U.js +68 -0
  418. package/dist/chunk-R2W3LESH.js +465 -0
  419. package/dist/chunk-R5EXHMUN.js +100 -0
  420. package/dist/chunk-RBBTBCHX.js +289 -0
  421. package/dist/chunk-RBKLOUXA.js +121 -0
  422. package/dist/chunk-RCP2Y6DQ.js +86 -0
  423. package/dist/chunk-RCYEJSD5.js +260 -0
  424. package/dist/chunk-RFDVSI4N.js +134 -0
  425. package/dist/chunk-RGJU63FV.js +1717 -0
  426. package/dist/chunk-RI4EX2QE.js +18 -0
  427. package/dist/chunk-RIMARPCF.js +152 -0
  428. package/dist/chunk-RJ6RSNT6.js +42 -0
  429. package/dist/chunk-RNI2GUIF.js +131 -0
  430. package/dist/chunk-RPHUWJ3K.js +264 -0
  431. package/dist/chunk-RPIMAMV7.js +361 -0
  432. package/dist/chunk-RQFX6YRN.js +49 -0
  433. package/dist/chunk-RRC5BL7B.js +285 -0
  434. package/dist/chunk-RSYTSBOO.js +79 -0
  435. package/dist/chunk-RWQQIKIC.js +35 -0
  436. package/dist/chunk-RZUBOZH2.js +373 -0
  437. package/dist/chunk-S2E632FQ.js +380 -0
  438. package/dist/chunk-S2VQCZO4.js +22 -0
  439. package/dist/chunk-S2XIMQJQ.js +681 -0
  440. package/dist/chunk-S47ISY27.js +183 -0
  441. package/dist/chunk-S6I4KISU.js +142 -0
  442. package/dist/chunk-S6TAFQI5.js +2403 -0
  443. package/dist/chunk-SBBNT5ZJ.js +27 -0
  444. package/dist/chunk-SDJV2DTQ.js +491 -0
  445. package/dist/chunk-SDPIFNLD.js +33 -0
  446. package/dist/chunk-SF6YK3JI.js +835 -0
  447. package/dist/chunk-SK3ZFONO.js +976 -0
  448. package/dist/chunk-SKTFRFQ7.js +1775 -0
  449. package/dist/chunk-SNGM452K.js +2002 -0
  450. package/dist/chunk-STW7OFOA.js +581 -0
  451. package/dist/chunk-SU6UFUQY.js +1351 -0
  452. package/dist/chunk-SVJM3LJA.js +27 -0
  453. package/dist/chunk-SVUNZOPG.js +129 -0
  454. package/dist/chunk-T5XLUYV3.js +34 -0
  455. package/dist/chunk-T7E5JS6N.js +57 -0
  456. package/dist/chunk-TA3N5MMO.js +450 -0
  457. package/dist/chunk-TAJPCXSB.js +13 -0
  458. package/dist/chunk-TDEMDRN2.js +1639 -0
  459. package/dist/chunk-TDSEX5CF.js +24 -0
  460. package/dist/chunk-TGCVL74Y.js +28 -0
  461. package/dist/chunk-TGXXYDL4.js +1012 -0
  462. package/dist/chunk-TIKTYUJO.js +296 -0
  463. package/dist/chunk-TIZAJD4M.js +6029 -0
  464. package/dist/chunk-TLSEZZCG.js +5549 -0
  465. package/dist/chunk-TMBDRHAX.js +19 -0
  466. package/dist/chunk-TRURQUBP.js +1217 -0
  467. package/dist/chunk-TSQ256N5.js +152 -0
  468. package/dist/chunk-TUQMMFEQ.js +2244 -0
  469. package/dist/chunk-U424MJLC.js +81 -0
  470. package/dist/chunk-U4DRS6ZW.js +11 -0
  471. package/dist/chunk-U5KS22IN.js +204 -0
  472. package/dist/chunk-UAPHFJPN.js +673 -0
  473. package/dist/chunk-UB7LQITD.js +1040 -0
  474. package/dist/chunk-UBVRHGAZ.js +237 -0
  475. package/dist/chunk-UDNNAQN5.js +98 -0
  476. package/dist/chunk-UJP3XM54.js +342 -0
  477. package/dist/chunk-UJYDH2MW.js +305 -0
  478. package/dist/chunk-UKMPASIC.js +399 -0
  479. package/dist/chunk-UKUL3EHK.js +763 -0
  480. package/dist/chunk-UPHU64NB.js +1327 -0
  481. package/dist/chunk-URMSZXAD.js +43 -0
  482. package/dist/chunk-US3RT6CY.js +525 -0
  483. package/dist/chunk-UTDEOPKV.js +30 -0
  484. package/dist/chunk-UUUDKV7N.js +13 -0
  485. package/dist/chunk-UVKWU3SM.js +39 -0
  486. package/dist/chunk-V2TVPO3X.js +521 -0
  487. package/dist/chunk-V3KLVK7B.js +398 -0
  488. package/dist/chunk-V3YFFHDR.js +17 -0
  489. package/dist/chunk-VAG6GUBR.js +1162 -0
  490. package/dist/chunk-VBENAHDA.js +1814 -0
  491. package/dist/chunk-VBNCKCCI.js +16 -0
  492. package/dist/chunk-VCGSWN5M.js +1300 -0
  493. package/dist/chunk-VE2O2I7M.js +115 -0
  494. package/dist/chunk-VIFHYTI5.js +31 -0
  495. package/dist/chunk-VJER3FUS.js +5080 -0
  496. package/dist/chunk-VLMDM56Q.js +268 -0
  497. package/dist/chunk-VMFZEVVX.js +99 -0
  498. package/dist/chunk-VNDPQVUZ.js +1853 -0
  499. package/dist/chunk-VSPJRLGA.js +4783 -0
  500. package/dist/chunk-VSWC5ZXI.js +103 -0
  501. package/dist/chunk-VYI4DSZP.js +2017 -0
  502. package/dist/chunk-W4BAIQ6L.js +1212 -0
  503. package/dist/chunk-W7VQAL2K.js +2203 -0
  504. package/dist/chunk-WEI3ZDZH.js +33 -0
  505. package/dist/chunk-WEIUS5NT.js +26 -0
  506. package/dist/chunk-WEW7UFWE.js +546 -0
  507. package/dist/chunk-WGQAXLNA.js +384 -0
  508. package/dist/chunk-WJAL4JL3.js +206 -0
  509. package/dist/chunk-WKFOJ5ZG.js +141 -0
  510. package/dist/chunk-WMWQEFLN.js +2177 -0
  511. package/dist/chunk-WNECKKO2.js +154 -0
  512. package/dist/chunk-WPKLYOAM.js +195 -0
  513. package/dist/chunk-WSH37YQN.js +243 -0
  514. package/dist/chunk-WV3KQDPE.js +84 -0
  515. package/dist/chunk-WZFC4V4U.js +389 -0
  516. package/dist/chunk-XCOIBNET.js +13 -0
  517. package/dist/chunk-XDM65LBX.js +53 -0
  518. package/dist/chunk-XGU6PBO5.js +645 -0
  519. package/dist/chunk-XHOI4V62.js +43 -0
  520. package/dist/chunk-XIBVFMLQ.js +6858 -0
  521. package/dist/chunk-XJ2E7YEJ.js +117 -0
  522. package/dist/chunk-XON4ZCYX.js +69 -0
  523. package/dist/chunk-XQPEWJPI.js +127 -0
  524. package/dist/chunk-XSJTIFUY.js +31 -0
  525. package/dist/chunk-XT7OVWM3.js +64 -0
  526. package/dist/chunk-XTXYIISX.js +1104 -0
  527. package/dist/chunk-XV7NZL4B.js +57 -0
  528. package/dist/chunk-XWIZ6B5S.js +109 -0
  529. package/dist/chunk-XWLIKOBX.js +240 -0
  530. package/dist/chunk-XZOXEIN4.js +156 -0
  531. package/dist/chunk-XZRS7I7W.js +3673 -0
  532. package/dist/chunk-Y4ZDDHB6.js +44 -0
  533. package/dist/chunk-Y733RB7T.js +194 -0
  534. package/dist/chunk-YBHUB4XR.js +14931 -0
  535. package/dist/chunk-YKC75XK4.js +147 -0
  536. package/dist/chunk-YKMXFVK7.js +27 -0
  537. package/dist/chunk-YO5BAJ55.js +225 -0
  538. package/dist/chunk-YPDCLXNZ.js +568 -0
  539. package/dist/chunk-YSQPGVFK.js +116 -0
  540. package/dist/chunk-YTVVTIWJ.js +716 -0
  541. package/dist/chunk-YVCMDVBB.js +698 -0
  542. package/dist/chunk-YYTOA6DP.js +114 -0
  543. package/dist/chunk-Z5WGNULV.js +88 -0
  544. package/dist/chunk-Z6NGVVXG.js +66 -0
  545. package/dist/chunk-Z7CDQNH3.js +20 -0
  546. package/dist/chunk-ZH4G3FU5.js +187 -0
  547. package/dist/chunk-ZJB6SQPA.js +257 -0
  548. package/dist/chunk-ZL6E4HMY.js +42 -0
  549. package/dist/chunk-ZMLOC3DW.js +62 -0
  550. package/dist/chunk-ZORW64QH.js +101 -0
  551. package/dist/chunk-ZVVD2XGV.js +1369 -0
  552. package/dist/cli-utils-ER33ODC5.js +31 -0
  553. package/dist/cli-validation-6CHPTANV.js +146 -0
  554. package/dist/commit-utils-3STAY7C7.js +49 -0
  555. package/dist/compatibility-notice-IHNXR2JR.js +21 -0
  556. package/dist/compete-config-resolver-V3GDNJMM.js +125 -0
  557. package/dist/compete-results-XUM3PJHS.js +318 -0
  558. package/dist/competition-outcome-tracker-NWSMVUPG.js +62 -0
  559. package/dist/config-4HHE4OIK.js +238 -0
  560. package/dist/config-D6YAZASH.js +10 -0
  561. package/dist/config-MIPRDYYV.js +46 -0
  562. package/dist/config-audit-GA5DCUAI.js +371 -0
  563. package/dist/config-explain-4LMO556H.js +71 -0
  564. package/dist/config-loader-RGP634PC.js +51 -0
  565. package/dist/config-manager-J2UTO635.js +114 -0
  566. package/dist/config-merger-TVUJBZTS.js +14 -0
  567. package/dist/config-validator-H4ZVIE56.js +122 -0
  568. package/dist/cost-HSIV5U2Y.js +85 -0
  569. package/dist/data-migration-state-OAUL2WPQ.js +35 -0
  570. package/dist/db-migrator-NUOW5NKR.js +34 -0
  571. package/dist/default-paths-UILB62BN.js +49 -0
  572. package/dist/discovery-V6GYUJUC.js +53 -0
  573. package/dist/doctor-BBSMCDWE.js +271 -0
  574. package/dist/doctor-context-blocks-LPY75VZA.js +231 -0
  575. package/dist/doctor-instructions-import-JXHDDOE5.js +70 -0
  576. package/dist/doctor-purpose-6YJOXPBE.js +30 -0
  577. package/dist/domain-analyzer-S35ABUNA.js +48 -0
  578. package/dist/ensure-initialized-Q6PEU55O.js +78 -0
  579. package/dist/entry.js +922 -0
  580. package/dist/error-parser-core-MZFMFANN.js +70 -0
  581. package/dist/evaluation-context-GQBYDAEV.js +63 -0
  582. package/dist/evidence-plan-resolver-5FUAP3SA.js +111 -0
  583. package/dist/execution-data-writer-YCG5UH37.js +72 -0
  584. package/dist/execution-policy-applier-PWZM5LNA.js +63 -0
  585. package/dist/execution-preflight-DASJWWQF.js +223 -0
  586. package/dist/execution-roles-KNSNNB2D.js +112 -0
  587. package/dist/exit-code-error-QIY5DOKF.js +18 -0
  588. package/dist/external-temp-cleanup-CAW7LQ6R.js +360 -0
  589. package/dist/factory-YCYCB7AE.js +209 -0
  590. package/dist/file-utils-ZQYNBQBW.js +45 -0
  591. package/dist/flywheel-allowlist-revert-H22HA6JE.js +21 -0
  592. package/dist/flywheel-autoloop-executor-PDOASJEZ.js +316 -0
  593. package/dist/flywheel-autoloop-unverified-TOKYFCDC.js +36 -0
  594. package/dist/flywheel-competition-executor-YJUMMEJO.js +320 -0
  595. package/dist/flywheel-executor-JWU43KAY.js +437 -0
  596. package/dist/flywheel-git-isolation-FQ2TRWMB.js +56 -0
  597. package/dist/flywheel-manifest-HDPNMWWF.js +114 -0
  598. package/dist/flywheel-model-defaults-UHAKTZT3.js +110 -0
  599. package/dist/flywheel-preflight-III2C7TH.js +163 -0
  600. package/dist/flywheel-resume-2O45MS7Y.js +31 -0
  601. package/dist/flywheel-resume-execution-lease-P2BK257J.js +59 -0
  602. package/dist/flywheel-safety-AVAVFXIJ.js +19 -0
  603. package/dist/flywheel-scope-decision-ALJUUNGG.js +14 -0
  604. package/dist/get-telemetry-logger-MPDVO2JA.js +155 -0
  605. package/dist/git-message-style-KCXGMTDT.js +104 -0
  606. package/dist/guidance-profile-config-G3K5YQOO.js +113 -0
  607. package/dist/guidance-profile-renderer-TX4TNDFL.js +23 -0
  608. package/dist/identity-XLQJ4YJF.js +25 -0
  609. package/dist/index-query-6NUY4FKX.js +37 -0
  610. package/dist/index.js +85588 -0
  611. package/dist/indexer-DL54CM3K.js +44 -0
  612. package/dist/init-OUZ72344.js +245 -0
  613. package/dist/instructions-import-offer-NSYXSITC.js +363 -0
  614. package/dist/instructions-run-NBII7W36.js +114 -0
  615. package/dist/interrupted-work-E4TLKJLE.js +43 -0
  616. package/dist/invoke-provider-auth-NEWEIHCI.js +38 -0
  617. package/dist/judge-scoring.json +64 -0
  618. package/dist/lab-mode-YXQ2Y3NG.js +44 -0
  619. package/dist/lab-utils-5QAMDJR5.js +29 -0
  620. package/dist/linux-host-class-YDWQX65O.js +31 -0
  621. package/dist/llm-judge-executor-OJSNCTFJ.js +179 -0
  622. package/dist/local-ci-config-VZ4WWDT5.js +48 -0
  623. package/dist/local-executor-DCMDDRX2.js +280 -0
  624. package/dist/logger-5KNKS3O4.js +154 -0
  625. package/dist/matrix-prompt-builder-4ZBOGZSB.js +527 -0
  626. package/dist/matrix-result-parser-EZJM4YXP.js +14 -0
  627. package/dist/merge-batch-RTEEMVDB.js +313 -0
  628. package/dist/merge-batch-members-VIWGVRHP.js +24 -0
  629. package/dist/merge-queue-TIIUSOY6.js +126 -0
  630. package/dist/merge-queue-trust-DUNZ4J65.js +21 -0
  631. package/dist/metadata-UKSMWM6J.js +29 -0
  632. package/dist/model-catalog-readiness-R5KJBP5M.js +202 -0
  633. package/dist/model-invocations-db-XTUPPQ34.js +70 -0
  634. package/dist/model-resolver-JFZ2MHOJ.js +39 -0
  635. package/dist/model-resolver-SCQ57KAQ.js +217 -0
  636. package/dist/model-roles-D3OR4NAH.js +110 -0
  637. package/dist/monitor-F4SIU5G2.js +96 -0
  638. package/dist/nested-worktrees-2WUWQ75N.js +23 -0
  639. package/dist/next-S3IRLVER.js +96 -0
  640. package/dist/next-UKPFRXOO.js +148 -0
  641. package/dist/opportunistic-TL4S26VX.js +86 -0
  642. package/dist/optimization-config-resolver-NAEIYU6A.js +148 -0
  643. package/dist/package-HJR4QJT4.js +10 -0
  644. package/dist/parse-git-status-7PIYFPS2.js +21 -0
  645. package/dist/path-security-5WJSY56G.js +41 -0
  646. package/dist/paths-JUI7C4KU.js +45 -0
  647. package/dist/plan-backlog-list-fast-SSTQL5XP.js +89 -0
  648. package/dist/plan-backlog-show-fast-PFRAQ3JB.js +114 -0
  649. package/dist/plan-sprint-list-fast-HD2KBZSY.js +110 -0
  650. package/dist/plan-sprint-status-fast-YFYH7WQF.js +116 -0
  651. package/dist/plan-task-status-fast-JU5PNLUU.js +114 -0
  652. package/dist/plan-to-flywheel-PY5MSY2H.js +529 -0
  653. package/dist/preflight-PJHGTJNZ.js +12 -0
  654. package/dist/process-registry-B4ZUCN7T.js +28 -0
  655. package/dist/process-scanner-TU3QHWVB.js +23 -0
  656. package/dist/processes-6FHVGT72.js +28 -0
  657. package/dist/processes-json-fast-YWTMUWXB.js +72 -0
  658. package/dist/profile-HWTC56SG.js +209 -0
  659. package/dist/project-runtime-paths-2UQNG5Y4.js +41 -0
  660. package/dist/protected-branches-N36LDBFY.js +71 -0
  661. package/dist/provider-aware-resource-manager-YTFAHNGJ.js +40 -0
  662. package/dist/provider-matrix-2KO2V5OM.js +214 -0
  663. package/dist/provider-matrix-renderer-MEC3PER7.js +139 -0
  664. package/dist/provider-output-forwarding-2AHL7YMA.js +26 -0
  665. package/dist/provider-registry-WCZ65QHC.js +136 -0
  666. package/dist/provider-temp-cleanup-IUNPJCZF.js +14 -0
  667. package/dist/prune-engine-EOQVWEP6.js +448 -0
  668. package/dist/publication-turn-S42RZTQF.js +44 -0
  669. package/dist/quality-gate-JQMVCKOO.js +72 -0
  670. package/dist/quickstart-3O6FRCFB.js +105 -0
  671. package/dist/readiness-GW6ABRHB.js +139 -0
  672. package/dist/readiness-KFZCXDTT.js +215 -0
  673. package/dist/registry-7XG376SY.js +217 -0
  674. package/dist/repair-helpers-TTV5FEF4.js +117 -0
  675. package/dist/repo-root-YG6MQZDW.js +28 -0
  676. package/dist/resolution-engine-FFEK7HQ2.js +187 -0
  677. package/dist/resolve-provider-cli-ZEXVZKET.js +44 -0
  678. package/dist/restore-telemetry-db-E7BR5PO7.js +459 -0
  679. package/dist/routing-events-AW6SRZ6G.js +13 -0
  680. package/dist/routing-history-store-FMDDQL6W.js +39 -0
  681. package/dist/routing-planner-C6OHO3EY.js +221 -0
  682. package/dist/runner-KHDNQ5KU.js +1194 -0
  683. package/dist/runner-PIS2BW7Y.js +1801 -0
  684. package/dist/safety-E3JJVSFL.js +67 -0
  685. package/dist/safety-stanza-HE6GXP4G.js +49 -0
  686. package/dist/sandbox-7LBZC5PE.js +72 -0
  687. package/dist/sandbox-ASWCDYZL.js +80 -0
  688. package/dist/schema-extensions.sql +234 -0
  689. package/dist/security-JI22TBEB.js +17 -0
  690. package/dist/setup-bb-plugin-FQXLA76Y.js +531 -0
  691. package/dist/setup-claude-code-NF4ZSHVE.js +197 -0
  692. package/dist/setup-temp-cleanup-2APZ4HMA.js +29 -0
  693. package/dist/shared-utils-34HJZ6JX.js +40 -0
  694. package/dist/simple-artifact-goal-MQLDDMMX.js +29 -0
  695. package/dist/sprint-N7JFTEGL.js +403 -0
  696. package/dist/sprint-bridge-KJXIBNRJ.js +117 -0
  697. package/dist/sprint-completion-dependents-34SR7JVL.js +43 -0
  698. package/dist/sprint-execution-service-A6JPUBWY.js +376 -0
  699. package/dist/sprint-manager-MU2ZUWN2.js +140 -0
  700. package/dist/sqlite-timeout-config-U2CT4LKU.js +13 -0
  701. package/dist/sqlite-wrapper-FSGJ2QEW.js +19 -0
  702. package/dist/stale-cleanup-orchestrator-4X6324VF.js +71 -0
  703. package/dist/storage-access-I3V5LER7.js +31 -0
  704. package/dist/store-XVG64ZR2.js +25 -0
  705. package/dist/task-classifier-MN2DYE5R.js +558 -0
  706. package/dist/task-list-fast-7AT6LTTA.js +112 -0
  707. package/dist/task-manager-LHPBBRRE.js +136 -0
  708. package/dist/task-report-OLPAWBTK.js +64 -0
  709. package/dist/task-type-detector-6RG3YNZF.js +27 -0
  710. package/dist/task-type-resolver-EQHOUIHT.js +64 -0
  711. package/dist/telemetry-5VYSK772.js +212 -0
  712. package/dist/telemetry-health-tracker-4GFW2EMP.js +12 -0
  713. package/dist/telemetry-path-resolver-H3NFHHQY.js +34 -0
  714. package/dist/telemetry-reliability-URJDTNPZ.js +76 -0
  715. package/dist/transports-NREZQTJK.js +106 -0
  716. package/dist/unified-cost-tracker-5MTBJ2CL.js +59 -0
  717. package/dist/unified-state-cleanup-GGAXLHXF.js +292 -0
  718. package/dist/universal-cost-calculator-JTFEJVWK.js +70 -0
  719. package/dist/user-agents-QLIGPLP2.js +30 -0
  720. package/dist/variant-execution-I4ZZUAWY.js +319 -0
  721. package/dist/variant-opt-parser-JHCXKY2K.js +251 -0
  722. package/dist/variant-request-input-PL37N3AN.js +11 -0
  723. package/dist/variant-state-cleanup-KHMXRBZN.js +287 -0
  724. package/dist/variant-worker-COB5YTJX.js +4517 -0
  725. package/dist/variant-worker.js +26 -0
  726. package/dist/variants-XGDSXYG3.js +267 -0
  727. package/dist/verification-command-YSPU4VBH.js +66 -0
  728. package/dist/verify-command-timeout-DQUYH33Z.js +11 -0
  729. package/dist/verify-commands-LOHMOFKC.js +65 -0
  730. package/dist/warning-JSKSFKBT.js +13 -0
  731. package/dist/work-edge-K65NHVWY.js +50 -0
  732. package/dist/work-item-writer-KY5ZWZWW.js +30 -0
  733. package/dist/worker-JNXXEIT6.js +1504 -0
  734. package/dist/worker.js +21 -0
  735. package/dist/workspace-tree-identity-JO5PSKTW.js +52 -0
  736. package/dist/worktree-environment-WTVABAQW.js +64 -0
  737. package/dist/worktree-metrics-VZRQI26T.js +66 -0
  738. package/dist/writeback-TQFQBJNU.js +50 -0
  739. package/docs/CLI_REFERENCE.md +8287 -0
  740. package/docs/PROVIDER_SETUP.md +1737 -0
  741. package/docs/README.md +96 -0
  742. package/docs/TROUBLESHOOTING.md +2209 -0
  743. package/docs/getting-started/QUICK_START.md +260 -0
  744. package/docs/getting-started/README.md +198 -0
  745. package/docs/getting-started/SETUP.md +25 -0
  746. package/docs/reference/AGENT_CONTEXT.md +84 -0
  747. package/docs/reference/DELIVERY_ONBOARDING.md +198 -0
  748. package/docs/reference/PROVIDER_RELEASE_TIERS.md +34 -0
  749. package/docs/reference/SECURITY.md +291 -0
  750. package/docs/reference/TELEMETRY_PRIVACY.md +259 -0
  751. package/integrations/bb-plugin-build/README.md +391 -0
  752. package/integrations/bb-plugin-build/app.css +431 -0
  753. package/integrations/bb-plugin-build/app.tsx +6210 -0
  754. package/integrations/bb-plugin-build/package.json +45 -0
  755. package/integrations/bb-plugin-build/server.ts +488 -0
  756. package/integrations/bb-plugin-build/src/adapter.ts +3672 -0
  757. package/integrations/bb-plugin-build/src/backlog-authoring-model.ts +150 -0
  758. package/integrations/bb-plugin-build/src/backlog-authoring-schema.ts +458 -0
  759. package/integrations/bb-plugin-build/src/backlog-authoring-service.ts +467 -0
  760. package/integrations/bb-plugin-build/src/backlog-authoring-view.ts +1025 -0
  761. package/integrations/bb-plugin-build/src/command-evidence-schema.ts +13 -0
  762. package/integrations/bb-plugin-build/src/competition-defaults-schema.ts +122 -0
  763. package/integrations/bb-plugin-build/src/competition-defaults-service.ts +105 -0
  764. package/integrations/bb-plugin-build/src/competition-defaults-view.ts +138 -0
  765. package/integrations/bb-plugin-build/src/contract.ts +718 -0
  766. package/integrations/bb-plugin-build/src/execution-activity-view.ts +98 -0
  767. package/integrations/bb-plugin-build/src/finalize-model.ts +205 -0
  768. package/integrations/bb-plugin-build/src/finalize-schema.ts +150 -0
  769. package/integrations/bb-plugin-build/src/finalize-service.ts +330 -0
  770. package/integrations/bb-plugin-build/src/finalize-view.ts +159 -0
  771. package/integrations/bb-plugin-build/src/judge-operations-readback.ts +303 -0
  772. package/integrations/bb-plugin-build/src/judge-operations-schema.ts +33 -0
  773. package/integrations/bb-plugin-build/src/judge-operations-view.ts +459 -0
  774. package/integrations/bb-plugin-build/src/model.ts +1318 -0
  775. package/integrations/bb-plugin-build/src/monitor-service.ts +233 -0
  776. package/integrations/bb-plugin-build/src/panel-read-ux.ts +97 -0
  777. package/integrations/bb-plugin-build/src/patch-preview-schema.ts +166 -0
  778. package/integrations/bb-plugin-build/src/patch-preview-service.ts +480 -0
  779. package/integrations/bb-plugin-build/src/patch-preview-view.ts +109 -0
  780. package/integrations/bb-plugin-build/src/planning-readback.ts +228 -0
  781. package/integrations/bb-plugin-build/src/planning-service.ts +647 -0
  782. package/integrations/bb-plugin-build/src/planning-sync-evidence.ts +37 -0
  783. package/integrations/bb-plugin-build/src/planning-workspace-readback.ts +33 -0
  784. package/integrations/bb-plugin-build/src/planning-workspace-schema.ts +131 -0
  785. package/integrations/bb-plugin-build/src/planning-workspace.ts +333 -0
  786. package/integrations/bb-plugin-build/src/poll-handoff.ts +136 -0
  787. package/integrations/bb-plugin-build/src/project-target-server.ts +21 -0
  788. package/integrations/bb-plugin-build/src/project-target.ts +45 -0
  789. package/integrations/bb-plugin-build/src/reference-index.ts +218 -0
  790. package/integrations/bb-plugin-build/src/repository-identity.ts +17 -0
  791. package/integrations/bb-plugin-build/src/repository-schema.ts +30 -0
  792. package/integrations/bb-plugin-build/src/result-explorer-view.ts +597 -0
  793. package/integrations/bb-plugin-build/src/result-readback-model.ts +163 -0
  794. package/integrations/bb-plugin-build/src/result-readback-schema.ts +319 -0
  795. package/integrations/bb-plugin-build/src/result-readback-service.ts +333 -0
  796. package/integrations/bb-plugin-build/src/run-page-view.ts +332 -0
  797. package/integrations/bb-plugin-build/src/setup-config-schema.ts +293 -0
  798. package/integrations/bb-plugin-build/src/setup-config-service.ts +620 -0
  799. package/integrations/bb-plugin-build/src/setup-config-view.ts +388 -0
  800. package/integrations/bb-plugin-build/src/sprint-close-model.ts +150 -0
  801. package/integrations/bb-plugin-build/src/sprint-close-schema.ts +128 -0
  802. package/integrations/bb-plugin-build/src/sprint-close-service.ts +293 -0
  803. package/integrations/bb-plugin-build/src/sprint-close-view.ts +116 -0
  804. package/integrations/bb-plugin-build/src/sprint-composition-model.ts +709 -0
  805. package/integrations/bb-plugin-build/src/sprint-composition-readback.ts +231 -0
  806. package/integrations/bb-plugin-build/src/sprint-composition-schema.ts +597 -0
  807. package/integrations/bb-plugin-build/src/sprint-composition-service.ts +773 -0
  808. package/integrations/bb-plugin-build/src/sprint-composition-view.ts +1221 -0
  809. package/integrations/bb-plugin-build/src/sprint-execution-schema.ts +188 -0
  810. package/integrations/bb-plugin-build/src/sprint-execution-service.ts +289 -0
  811. package/integrations/bb-plugin-build/src/sprint-execution-view.ts +54 -0
  812. package/integrations/bb-plugin-build/src/task-authoring-model.ts +563 -0
  813. package/integrations/bb-plugin-build/src/task-authoring-schema.ts +629 -0
  814. package/integrations/bb-plugin-build/src/task-authoring-service.ts +842 -0
  815. package/integrations/bb-plugin-build/src/task-authoring-view.ts +1227 -0
  816. package/integrations/bb-plugin-build/src/task-catalog-schema.ts +46 -0
  817. package/integrations/bb-plugin-build/src/task-catalog-service.ts +44 -0
  818. package/integrations/bb-plugin-build/src/task-detail-readback.ts +56 -0
  819. package/integrations/bb-plugin-build/src/task-detail-schema.ts +171 -0
  820. package/integrations/bb-plugin-build/src/task-navigation.ts +446 -0
  821. package/integrations/bb-plugin-build/src/workbench-route.ts +74 -0
  822. package/package.json +306 -4
  823. package/schemas/README.md +80 -0
  824. package/schemas/build.config.schema.json +2110 -0
  825. package/schemas/config-v1.schema.json +136 -0
  826. package/schemas/execution-config.schema.json +47 -0
  827. package/schemas/judge-scoring.schema.json +257 -0
  828. package/schemas/provider-config.schema.json +179 -0
  829. package/schemas/telemetry-config.schema.json +79 -0
  830. package/schemas/user-preferences.schema.json +141 -0
  831. package/scripts/assert-node-runtime.mjs +146 -0
  832. package/scripts/preflight-native.mjs +49 -0
  833. package/scripts/setup-git-hooks.mjs +39 -0
  834. package/scripts/sync.sh +2871 -0
  835. package/scripts/write-node-launcher.sh +138 -0
  836. package/src/resources/gemini/slash-packs/default/plan.toml +15 -0
  837. package/src/resources/gemini/slash-packs/default/summary.toml +16 -0
  838. package/src/resources/gemini/slash-packs/default/tests.toml +16 -0
  839. package/templates/.build-project/README.md +41 -0
  840. package/templates/.build-project/agents/README.md +50 -0
  841. package/templates/.build-project/agents/architect.md +10 -0
  842. package/templates/.build-project/agents/code-reviewer.md +10 -0
  843. package/templates/.build-project/agents/debugger.md +10 -0
  844. package/templates/.build-project/agents/documenter.md +10 -0
  845. package/templates/.build-project/agents/test-automator.md +10 -0
  846. package/templates/.build-project/config/build.config.jsonc +64 -0
  847. package/templates/.build-project/config/project-context.template.json +6 -0
  848. package/templates/.build-project/config/task-type-aliases.presets/kanban.yaml +14 -0
  849. package/templates/.build-project/config/task-type-aliases.presets/scrum.yaml +17 -0
  850. package/templates/.build-project/config/task-type-aliases.presets/xp.yaml +12 -0
  851. package/templates/.build-project/config/task-type-aliases.yaml +29 -0
  852. package/templates/.build-project/gitignore.template +70 -0
  853. package/templates/.build-project/task-types/analysis.yaml +38 -0
  854. package/templates/.build-project/task-types/architecture.yaml +35 -0
  855. package/templates/.build-project/task-types/doc.yaml +34 -0
  856. package/templates/.build-project/task-types/feature.yaml +22 -0
  857. package/templates/.build-project/task-types/general.yaml +4 -0
  858. package/templates/.build-project/task-types/security.yaml +38 -0
  859. package/templates/AGENTS.template.md +85 -0
  860. package/templates/CLAUDE.template.md +1 -0
  861. package/templates/GEMINI.template.md +1 -0
  862. package/templates/builtin-workflows/code-review.yaml +73 -0
  863. package/templates/builtin-workflows/skills/code-review/SKILL.md +61 -0
  864. package/templates/builtin-workflows/skills/execution-contract-analysis/SKILL.md +24 -0
  865. package/templates/builtin-workflows/skills/execution-contract-code/SKILL.md +19 -0
  866. package/templates/builtin-workflows/skills/execution-contract-structured/SKILL.md +17 -0
  867. package/templates/ci/incident-intake.mjs +787 -0
  868. package/templates/ci/incidents.yml.template +103 -0
  869. package/templates/ci/node.yml.template +17 -0
  870. package/templates/ci/python.yml.template +17 -0
  871. package/templates/guard-kit/GUARD_SETUP.md.template +258 -0
  872. package/templates/guard-kit/build-guard.yml.template +189 -0
  873. package/templates/guard-kit/check.mjs.template +932 -0
  874. package/templates/guard-kit/config.json.template +7 -0
  875. package/templates/guard-kit/policy.json.template +1 -0
  876. package/templates/profiles/README.md +57 -0
  877. package/templates/profiles/frontier-claude.json +23 -0
  878. package/templates/profiles/frontier-codex.json +23 -0
@@ -0,0 +1,4517 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ProcessLifecycleManager,
4
+ createCliBreadcrumb,
5
+ evaluateExecutionSpec,
6
+ findGateControllingEdits,
7
+ findOffScopeConfigEdits,
8
+ formatGateConfigUnverifiedReason,
9
+ formatOffScopeConfigEdits
10
+ } from "./chunk-WMWQEFLN.js";
11
+ import {
12
+ isNativeResearchEnabledFor,
13
+ scanWebToolEvents
14
+ } from "./chunk-OSK7QWPD.js";
15
+ import {
16
+ hasValidationArtifactTarget
17
+ } from "./chunk-3PL22IYZ.js";
18
+ import "./chunk-OMX5VL43.js";
19
+ import {
20
+ classifyTask
21
+ } from "./chunk-JHP7OT6K.js";
22
+ import {
23
+ isValidationArtifactEntry
24
+ } from "./chunk-GOFVBTMN.js";
25
+ import {
26
+ WORKER_CLEANUP_BUDGET_MS,
27
+ estimateTimeoutCompletenessFromScope,
28
+ parseShortStatSummary,
29
+ resolveVariantEvaluation
30
+ } from "./chunk-DIKBRRKE.js";
31
+ import {
32
+ PROVIDER_ACTIVITY_WORKER_EVENT_PREFIX,
33
+ PROVIDER_OUTPUT_WORKER_EVENT_PREFIX,
34
+ ResultStreamer
35
+ } from "./chunk-WEW7UFWE.js";
36
+ import "./chunk-QILAQACE.js";
37
+ import {
38
+ ACTIVE_HANDLES_MARKER_PREFIX,
39
+ CLEANUP_COMPLETE_MARKER_PREFIX,
40
+ CLEANUP_START_MARKER_PREFIX,
41
+ POST_PROVIDER_PHASES_MARKER_PREFIX,
42
+ RESULT_WRITTEN_MARKER_PREFIX,
43
+ getOrCaptureVerificationBaseline,
44
+ withValidationSlot
45
+ } from "./chunk-3C7WBIVK.js";
46
+ import "./chunk-EKLUBDBQ.js";
47
+ import "./chunk-NEQUQHOX.js";
48
+ import "./chunk-DJG5RIOR.js";
49
+ import {
50
+ presentUntrustedRepairEvidence,
51
+ renderRepairConstraints,
52
+ renderUntrustedCommandOutput,
53
+ renderUntrustedFailingTests
54
+ } from "./chunk-QS5AGRZN.js";
55
+ import {
56
+ isTestRunProhibited
57
+ } from "./chunk-NMVZ5YES.js";
58
+ import "./chunk-N3Q2JNPV.js";
59
+ import "./chunk-H4HXVWEC.js";
60
+ import "./chunk-BZRLSZNV.js";
61
+ import "./chunk-C7AGUJ5K.js";
62
+ import "./chunk-VLMDM56Q.js";
63
+ import "./chunk-HBZ322WZ.js";
64
+ import {
65
+ computeProcessReliabilityMetrics,
66
+ generateBranchName,
67
+ getVerificationResult,
68
+ sanitizeVariantResult
69
+ } from "./chunk-DCACX7BV.js";
70
+ import "./chunk-EUWIIDQ7.js";
71
+ import "./chunk-ARARVIZK.js";
72
+ import "./chunk-HHWDTB6S.js";
73
+ import {
74
+ runDeterministicTestGateWithArtifacts,
75
+ runLintOnDiffWithArtifacts
76
+ } from "./chunk-JOSK6GEU.js";
77
+ import "./chunk-CFCVYHSW.js";
78
+ import "./chunk-VCGSWN5M.js";
79
+ import "./chunk-6CAU7VBA.js";
80
+ import "./chunk-IYY3HQAD.js";
81
+ import "./chunk-ONYPLIVE.js";
82
+ import "./chunk-PVJBTI7P.js";
83
+ import {
84
+ runTypecheckWithArtifacts
85
+ } from "./chunk-IWBHRSG7.js";
86
+ import "./chunk-UKMPASIC.js";
87
+ import "./chunk-CTDLERWU.js";
88
+ import "./chunk-LPQ7NZEN.js";
89
+ import "./chunk-TGCVL74Y.js";
90
+ import {
91
+ applyExactArtifactGoalSuccessGate,
92
+ isSimpleArtifactGoalSatisfied,
93
+ parseSimpleArtifactGoal
94
+ } from "./chunk-QXBKIHY7.js";
95
+ import "./chunk-Q3DHEZA5.js";
96
+ import "./chunk-QTOLTG4L.js";
97
+ import "./chunk-7HYBSRPZ.js";
98
+ import "./chunk-L32WD57F.js";
99
+ import "./chunk-6DBMALXL.js";
100
+ import "./chunk-MKASIKWZ.js";
101
+ import "./chunk-UDNNAQN5.js";
102
+ import "./chunk-GIJWHUWF.js";
103
+ import "./chunk-HKO45NLZ.js";
104
+ import {
105
+ extractChangedFilesMeta
106
+ } from "./chunk-QTCLJHLZ.js";
107
+ import "./chunk-SU6UFUQY.js";
108
+ import "./chunk-FSA5BPFI.js";
109
+ import {
110
+ parsePromptSpec
111
+ } from "./chunk-INJ3SS6A.js";
112
+ import "./chunk-LDJCKAJP.js";
113
+ import "./chunk-3LOY6YZI.js";
114
+ import "./chunk-HS3SY6HN.js";
115
+ import "./chunk-ENYRCL43.js";
116
+ import "./chunk-D37WY7SH.js";
117
+ import "./chunk-Z7CDQNH3.js";
118
+ import "./chunk-PRDHI2L5.js";
119
+ import "./chunk-URMSZXAD.js";
120
+ import "./chunk-JVHGMURQ.js";
121
+ import "./chunk-2YRG3LHZ.js";
122
+ import "./chunk-JYXS47FQ.js";
123
+ import "./chunk-B7PYTV72.js";
124
+ import "./chunk-4QKP6I4C.js";
125
+ import "./chunk-GWHGTG37.js";
126
+ import {
127
+ FIELD_DISPLAY_NAMES,
128
+ generateSpecQualitySignals
129
+ } from "./chunk-UAPHFJPN.js";
130
+ import "./chunk-GI5M67YA.js";
131
+ import "./chunk-XON4ZCYX.js";
132
+ import "./chunk-PPHXX4W7.js";
133
+ import "./chunk-5AW4RMNG.js";
134
+ import {
135
+ ExitCodeError
136
+ } from "./chunk-Y4ZDDHB6.js";
137
+ import "./chunk-BIUV23HH.js";
138
+ import "./chunk-RI4EX2QE.js";
139
+ import "./chunk-ETA2K4KI.js";
140
+ import "./chunk-CRPRVNQ4.js";
141
+ import "./chunk-W4BAIQ6L.js";
142
+ import "./chunk-4UMRUFBD.js";
143
+ import "./chunk-3M57DADF.js";
144
+ import "./chunk-HT5OCGKN.js";
145
+ import "./chunk-FUUVZZUB.js";
146
+ import "./chunk-32IYXIE5.js";
147
+ import "./chunk-7RMARDVH.js";
148
+ import "./chunk-HXIIEMGF.js";
149
+ import {
150
+ stageCommitEligibleChanges
151
+ } from "./chunk-ZMLOC3DW.js";
152
+ import "./chunk-FIEUSGNJ.js";
153
+ import "./chunk-WEIUS5NT.js";
154
+ import "./chunk-KQYQOXMS.js";
155
+ import "./chunk-S47ISY27.js";
156
+ import "./chunk-U424MJLC.js";
157
+ import "./chunk-YKMXFVK7.js";
158
+ import "./chunk-O6ZQUVTR.js";
159
+ import "./chunk-RCYEJSD5.js";
160
+ import "./chunk-FAWJTC34.js";
161
+ import "./chunk-UBVRHGAZ.js";
162
+ import "./chunk-5HDP7XZG.js";
163
+ import "./chunk-H3ISZJMJ.js";
164
+ import "./chunk-ATKEKM3E.js";
165
+ import "./chunk-S6I4KISU.js";
166
+ import "./chunk-EJIWTPSZ.js";
167
+ import "./chunk-MYLH2S4G.js";
168
+ import "./chunk-3P5IN5E7.js";
169
+ import "./chunk-2Y2IIHPI.js";
170
+ import "./chunk-WEI3ZDZH.js";
171
+ import "./chunk-H6MJGKAW.js";
172
+ import "./chunk-67YRJPJO.js";
173
+ import {
174
+ setProcessLifecycleManager
175
+ } from "./chunk-633XZ7UF.js";
176
+ import "./chunk-SF6YK3JI.js";
177
+ import "./chunk-JBBB2Y47.js";
178
+ import "./chunk-WJAL4JL3.js";
179
+ import "./chunk-RBKLOUXA.js";
180
+ import "./chunk-4EBSXZ73.js";
181
+ import "./chunk-CSOPSYDY.js";
182
+ import "./chunk-VMFZEVVX.js";
183
+ import "./chunk-U5KS22IN.js";
184
+ import "./chunk-UUUDKV7N.js";
185
+ import {
186
+ TelemetryLogger
187
+ } from "./chunk-PFCXFO7A.js";
188
+ import "./chunk-SDPIFNLD.js";
189
+ import "./chunk-GO6DRECI.js";
190
+ import "./chunk-XIBVFMLQ.js";
191
+ import "./chunk-QWMQ74KD.js";
192
+ import "./chunk-GAFJEYLK.js";
193
+ import "./chunk-YKC75XK4.js";
194
+ import "./chunk-T7E5JS6N.js";
195
+ import "./chunk-ZJB6SQPA.js";
196
+ import "./chunk-GZK62I3N.js";
197
+ import {
198
+ signalCoordinator
199
+ } from "./chunk-GC4CRMTS.js";
200
+ import "./chunk-P7CQGPLS.js";
201
+ import "./chunk-C3DH3NCY.js";
202
+ import "./chunk-IVZEONFC.js";
203
+ import "./chunk-XTXYIISX.js";
204
+ import "./chunk-MEMSY6VY.js";
205
+ import "./chunk-VBNCKCCI.js";
206
+ import "./chunk-33IGPPUI.js";
207
+ import "./chunk-UPHU64NB.js";
208
+ import "./chunk-JLS65NUQ.js";
209
+ import "./chunk-FRBPKBFE.js";
210
+ import "./chunk-BAWJNMWF.js";
211
+ import "./chunk-LX4F24ZH.js";
212
+ import "./chunk-BBPIILO2.js";
213
+ import "./chunk-2NMNFUQA.js";
214
+ import "./chunk-I7SCBHJN.js";
215
+ import {
216
+ formatVariantIdentifier
217
+ } from "./chunk-TGXXYDL4.js";
218
+ import "./chunk-D2M2Y5ID.js";
219
+ import "./chunk-UJP3XM54.js";
220
+ import "./chunk-MULMXX4V.js";
221
+ import {
222
+ parseGitWorktreeBranches
223
+ } from "./chunk-UTDEOPKV.js";
224
+ import "./chunk-RFDVSI4N.js";
225
+ import "./chunk-M4BUEXXF.js";
226
+ import "./chunk-ZH4G3FU5.js";
227
+ import "./chunk-726G6WDL.js";
228
+ import {
229
+ captureWorktreeDiff,
230
+ normalizeWorktreeDiff
231
+ } from "./chunk-EP22ZMFO.js";
232
+ import {
233
+ getGitChangeSummary
234
+ } from "./chunk-5UBIFVRD.js";
235
+ import "./chunk-O7FE75QZ.js";
236
+ import "./chunk-Q64IR2Z2.js";
237
+ import "./chunk-YVCMDVBB.js";
238
+ import "./chunk-7HPCIOMA.js";
239
+ import {
240
+ parseJsonWithContext
241
+ } from "./chunk-P6SSWAKY.js";
242
+ import "./chunk-ETAD4NKD.js";
243
+ import "./chunk-XQPEWJPI.js";
244
+ import "./chunk-7YAOUUKK.js";
245
+ import {
246
+ analyzeRepairScope,
247
+ buildRepairDiffSnapshot,
248
+ resolveRepairArtifactPolicy
249
+ } from "./chunk-SKTFRFQ7.js";
250
+ import "./chunk-O5X6BKAO.js";
251
+ import "./chunk-R2CKS6WT.js";
252
+ import {
253
+ applyKnownFailureDowngrade,
254
+ compareVerificationOutcomeToBaseline,
255
+ createLogger,
256
+ deriveVariantOutcome,
257
+ detectGateRegressions,
258
+ hasUnavailableVerificationGateEvidence,
259
+ hasVerifiedTouchedTestFailure,
260
+ latestVerificationIteration,
261
+ markLintIdenticalToBase,
262
+ persistingIssuesOnBase,
263
+ repairOutcomeCanSupersedeRawTouchedFailure,
264
+ stableBaselineProvesClean,
265
+ stableComparisonToBaselineComparison,
266
+ trustedLoopBaselineComparison,
267
+ verificationOutcomesFromGateArtifacts
268
+ } from "./chunk-3OPP2OZB.js";
269
+ import "./chunk-EPRMH6HO.js";
270
+ import "./chunk-XHOI4V62.js";
271
+ import "./chunk-S2VQCZO4.js";
272
+ import {
273
+ dominantVerificationStatus
274
+ } from "./chunk-6TBEX4R4.js";
275
+ import "./chunk-PXKERBKX.js";
276
+ import "./chunk-QYQOVOLR.js";
277
+ import "./chunk-QFLBRWCJ.js";
278
+ import "./chunk-AEQWV746.js";
279
+ import "./chunk-SVUNZOPG.js";
280
+ import "./chunk-KUEWV2JH.js";
281
+ import "./chunk-R2TIYG7U.js";
282
+ import "./chunk-5FKHIKTS.js";
283
+ import "./chunk-S2E632FQ.js";
284
+ import "./chunk-XJ2E7YEJ.js";
285
+ import "./chunk-B7YRSULE.js";
286
+ import "./chunk-4U6XK2DG.js";
287
+ import "./chunk-BY6ODHNZ.js";
288
+ import "./chunk-3H4MWYIC.js";
289
+ import "./chunk-DP7FKP6W.js";
290
+ import "./chunk-VIFHYTI5.js";
291
+ import "./chunk-XGU6PBO5.js";
292
+ import "./chunk-F55YABKV.js";
293
+ import {
294
+ captureCurrentWorkspaceTreeIdentity
295
+ } from "./chunk-YO5BAJ55.js";
296
+ import "./chunk-EVE3OD2W.js";
297
+ import {
298
+ mkBuildTempDir
299
+ } from "./chunk-D6WTZMZB.js";
300
+ import "./chunk-5EQN56OZ.js";
301
+ import "./chunk-RBBTBCHX.js";
302
+ import "./chunk-4DJL2VXA.js";
303
+ import {
304
+ channelsFailingIdenticallyOnBase,
305
+ requiredVerificationControlChannels,
306
+ resolveVerificationChannelScope,
307
+ selectScopedTestCommands
308
+ } from "./chunk-AHU3FKPA.js";
309
+ import "./chunk-TUQMMFEQ.js";
310
+ import {
311
+ describeVerificationCommand
312
+ } from "./chunk-EPAMVGI3.js";
313
+ import "./chunk-6CB3KJRY.js";
314
+ import "./chunk-L2S235CU.js";
315
+ import "./chunk-D4VJFCGZ.js";
316
+ import {
317
+ PROJECT_SOURCE_EXTENSIONS,
318
+ isProjectSourcePath
319
+ } from "./chunk-RPIMAMV7.js";
320
+ import "./chunk-ALDTFNZ3.js";
321
+ import "./chunk-QOIASNEJ.js";
322
+ import {
323
+ resolveVerifyCommandTimeoutMs
324
+ } from "./chunk-2VUEDIUM.js";
325
+ import "./chunk-MJ6WNSIX.js";
326
+ import "./chunk-5KQETTNS.js";
327
+ import "./chunk-J2ICMYDA.js";
328
+ import {
329
+ truncateToByteLimit
330
+ } from "./chunk-2VLJUXJU.js";
331
+ import "./chunk-PPZESPJT.js";
332
+ import "./chunk-XCOIBNET.js";
333
+ import "./chunk-Y733RB7T.js";
334
+ import "./chunk-H3HGMISG.js";
335
+ import "./chunk-FAZBRHGG.js";
336
+ import "./chunk-CJBSZX3F.js";
337
+ import {
338
+ initializeLabModeFromEnv
339
+ } from "./chunk-C3KCMAJP.js";
340
+ import "./chunk-FKCG7K6H.js";
341
+ import "./chunk-AJN5Y5YZ.js";
342
+ import {
343
+ execGit
344
+ } from "./chunk-MHLEZQQI.js";
345
+ import "./chunk-HEP3ILP4.js";
346
+ import "./chunk-BQJOGAWT.js";
347
+ import "./chunk-WV3KQDPE.js";
348
+ import {
349
+ isSensitiveKey,
350
+ sanitizeSynthesisArtifactForPersistence,
351
+ sanitizeSynthesisStringForPersistence
352
+ } from "./chunk-VSWC5ZXI.js";
353
+ import "./chunk-XV7NZL4B.js";
354
+ import "./chunk-KKQKWAMF.js";
355
+ import "./chunk-RWQQIKIC.js";
356
+ import "./chunk-GVJGSSKM.js";
357
+ import "./chunk-QJ6OEH4K.js";
358
+ import "./chunk-BD3PGW6A.js";
359
+ import "./chunk-43OKHTW4.js";
360
+ import "./chunk-MNOVBYFU.js";
361
+ import "./chunk-QXBKTJT6.js";
362
+ import "./chunk-4BTDUT2S.js";
363
+ import "./chunk-35J4NE6S.js";
364
+ import "./chunk-RIMARPCF.js";
365
+ import "./chunk-HGFXODKO.js";
366
+ import "./chunk-N5DX4JAK.js";
367
+ import "./chunk-V2TVPO3X.js";
368
+ import {
369
+ ProviderExecutionError
370
+ } from "./chunk-RRC5BL7B.js";
371
+ import "./chunk-352PCJLK.js";
372
+ import "./chunk-RCP2Y6DQ.js";
373
+ import {
374
+ HostTimeoutError,
375
+ VARIANT_WORKER_SIGTERM_SOURCE,
376
+ classifyHostTermination,
377
+ createHostTerminationParsedError,
378
+ hostTerminationMetadataFromUnknown
379
+ } from "./chunk-M6UHOC4I.js";
380
+ import "./chunk-PSTKWHHN.js";
381
+ import "./chunk-KTMW65UX.js";
382
+ import "./chunk-3JKNRYEE.js";
383
+ import "./chunk-MT2WAIR3.js";
384
+ import "./chunk-WGQAXLNA.js";
385
+ import "./chunk-ONHAMBN6.js";
386
+ import "./chunk-XSJTIFUY.js";
387
+ import "./chunk-XWIZ6B5S.js";
388
+ import "./chunk-U4DRS6ZW.js";
389
+ import {
390
+ DEFAULT_PER_VARIANT_TIMEOUT_MINUTES,
391
+ DEFAULT_REPAIR_LOOP_ITERATION_TIMEOUT_MS,
392
+ DEFAULT_REPAIR_LOOP_MAX_ITERATIONS
393
+ } from "./chunk-I56TH7VM.js";
394
+ import {
395
+ getWorktreeBaseDir
396
+ } from "./chunk-Z5WGNULV.js";
397
+ import "./chunk-O26L6F7F.js";
398
+ import "./chunk-RJ6RSNT6.js";
399
+ import {
400
+ assertBuildRuntimeReady
401
+ } from "./chunk-ZORW64QH.js";
402
+ import "./chunk-TAJPCXSB.js";
403
+ import "./chunk-56WPYDJH.js";
404
+ import "./chunk-RSYTSBOO.js";
405
+ import "./chunk-STW7OFOA.js";
406
+ import {
407
+ resolveBuildRoot
408
+ } from "./chunk-CHA2HDE5.js";
409
+ import "./chunk-JNMWYMC6.js";
410
+ import {
411
+ BUILD_ALLOW_OFF_SCOPE_REPAIR,
412
+ BUILD_COMPLETION_MODE,
413
+ BUILD_TELEMETRY_DIR,
414
+ createExecutionContext,
415
+ createWarning,
416
+ emitWarning,
417
+ getRuntimeEnv,
418
+ mergeExecutionContextEnvOverrides,
419
+ readEnv,
420
+ resolveBuildDirFromContext,
421
+ resolveCliRepoRoot,
422
+ setExecutionContext
423
+ } from "./chunk-7VRJHTGZ.js";
424
+ import "./chunk-XDM65LBX.js";
425
+ import {
426
+ sanitizeError
427
+ } from "./chunk-CPSVQR2I.js";
428
+ import "./chunk-PZ5AY32C.js";
429
+
430
+ // src/cli/variant-worker.ts
431
+ import { randomBytes } from "crypto";
432
+ import { closeSync, fsyncSync, openSync } from "fs";
433
+ import * as fs2 from "fs/promises";
434
+ import * as path2 from "path";
435
+ import { fileURLToPath } from "url";
436
+ import chalk from "chalk";
437
+ import { Command } from "commander";
438
+ import { execa as execa3 } from "execa";
439
+
440
+ // src/core/verification/known-pre-existing-failures.ts
441
+ import * as fs from "fs/promises";
442
+ import * as path from "path";
443
+ var logger = createLogger("KnownPreExistingFailures");
444
+ var MIN_ERROR_FINGERPRINT_LENGTH = 4;
445
+ var EMPTY_REGISTRY = Object.freeze({
446
+ schemaVersion: 1,
447
+ generatedAt: "",
448
+ baseCommit: "",
449
+ failures: []
450
+ });
451
+ var _cachedRegistry;
452
+ async function loadKnownPreExistingFailures(repoRoot = process.cwd()) {
453
+ if (_cachedRegistry !== void 0) {
454
+ return _cachedRegistry;
455
+ }
456
+ const registryPath = process.env.BUILD_KNOWN_FAILURES_PATH ?? path.join(repoRoot, ".build-project", "verification", "known-pre-existing-failures.json");
457
+ let raw;
458
+ try {
459
+ raw = await fs.readFile(registryPath, "utf-8");
460
+ } catch (err) {
461
+ const isNotFound = err instanceof Error && "code" in err && err.code === "ENOENT";
462
+ if (!isNotFound) {
463
+ logger.warn("Failed to read known-pre-existing-failures registry", {
464
+ registryPath,
465
+ error: err instanceof Error ? err.message : String(err)
466
+ });
467
+ }
468
+ _cachedRegistry = { ...EMPTY_REGISTRY };
469
+ return _cachedRegistry;
470
+ }
471
+ try {
472
+ const parsed = JSON.parse(raw);
473
+ if (typeof parsed !== "object" || parsed === null || !Array.isArray(parsed.failures)) {
474
+ throw new Error("Registry JSON does not match expected shape");
475
+ }
476
+ const registry = parsed;
477
+ const validFailures = registry.failures.filter(isValidKnownFailureEntry);
478
+ if (validFailures.length !== registry.failures.length) {
479
+ logger.warn("Ignoring invalid known-pre-existing-failures registry entries", {
480
+ registryPath,
481
+ ignoredCount: registry.failures.length - validFailures.length
482
+ });
483
+ }
484
+ _cachedRegistry = {
485
+ ...registry,
486
+ failures: validFailures
487
+ };
488
+ logger.debug("Loaded known-pre-existing-failures registry", {
489
+ registryPath,
490
+ entryCount: _cachedRegistry.failures.length,
491
+ baseCommit: _cachedRegistry.baseCommit
492
+ });
493
+ return _cachedRegistry;
494
+ } catch (err) {
495
+ logger.warn("Malformed known-pre-existing-failures registry \u2014 treating as empty", {
496
+ registryPath,
497
+ error: err instanceof Error ? err.message : String(err)
498
+ });
499
+ _cachedRegistry = { ...EMPTY_REGISTRY };
500
+ return _cachedRegistry;
501
+ }
502
+ }
503
+ function isValidKnownFailureEntry(entry) {
504
+ return normalizeFingerprint(entry.errorFingerprint) !== null;
505
+ }
506
+ function normalizeFingerprint(fingerprint) {
507
+ const normalized = fingerprint?.trim();
508
+ if (!normalized || normalized.length < MIN_ERROR_FINGERPRINT_LENGTH) {
509
+ return null;
510
+ }
511
+ return normalized.toLowerCase();
512
+ }
513
+ function detectRuntimeEnvironment() {
514
+ if (process.env.CLAUDECODE === "1" || process.env.CLAUDE_CODE === "true" || process.env.AI_SDK === "claude-code") {
515
+ return "claude-code";
516
+ }
517
+ if (process.env.CI === "true" || process.env.CI === "1" || process.env.GITHUB_ACTIONS === "true" || process.env.CIRCLECI === "true" || process.env.TRAVIS === "true") {
518
+ return "ci";
519
+ }
520
+ return "local";
521
+ }
522
+ function looksLikeProjectFileToken(token) {
523
+ const trimmed = token.trim();
524
+ if (trimmed.length === 0) return false;
525
+ if (isProjectSourcePath(trimmed)) return true;
526
+ return (trimmed.includes("/") || trimmed.includes("\\")) && !/\s/.test(trimmed);
527
+ }
528
+ function parseLiveFailure(raw) {
529
+ const trimmed = raw.trim();
530
+ for (const separator of [/\s*>\s*/, /::/]) {
531
+ const match = separator.exec(trimmed);
532
+ if (!match || match.index <= 0) continue;
533
+ const head = trimmed.slice(0, match.index).trim();
534
+ const tail = trimmed.slice(match.index + match[0].length).trim();
535
+ if (looksLikeProjectFileToken(head) && tail.length > 0) {
536
+ return { file: head, testPath: tail, raw };
537
+ }
538
+ }
539
+ const goMatch = /^(.+?):(\d+)$/.exec(trimmed);
540
+ if (goMatch && looksLikeProjectFileToken(goMatch[1] ?? "")) {
541
+ return { file: (goMatch[1] ?? "").trim(), testPath: trimmed, raw };
542
+ }
543
+ return { file: "", testPath: trimmed, raw };
544
+ }
545
+ function escapeRegExp(value) {
546
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
547
+ }
548
+ var VITEST_FAILURE_MARKER_SOURCE = "(?:\\s*(?:FAIL|FAILURES?|FAILED)\\s+)?[^\\n]*\\.(?:test|spec)\\.[jt]sx?\\s*>\\s+";
549
+ var GENERIC_FAILURE_MARKER_SOURCE = "(?:\\s*(?:FAIL|FAILURES?|FAILED)\\s+)?[^\\n\\s]*[\\\\/][^\\n\\s]*(?:::|\\s>\\s)";
550
+ function findNextFailureMarker(output, startIndex) {
551
+ const rest = output.slice(startIndex + 1);
552
+ const match = new RegExp(
553
+ `\\n(?:${VITEST_FAILURE_MARKER_SOURCE}|${GENERIC_FAILURE_MARKER_SOURCE})`,
554
+ "i"
555
+ ).exec(rest);
556
+ return match ? startIndex + 1 + match.index : output.length;
557
+ }
558
+ function hasFailureMarkers(output) {
559
+ return new RegExp(
560
+ `(?:^|\\n)(?:${VITEST_FAILURE_MARKER_SOURCE}|${GENERIC_FAILURE_MARKER_SOURCE})`,
561
+ "i"
562
+ ).test(output);
563
+ }
564
+ function extractScopedFailureOutput(live, testOutputTail) {
565
+ const rawNeedle = live.raw.trim();
566
+ const candidates = [
567
+ rawNeedle,
568
+ live.file && live.testPath ? `${live.file} > ${live.testPath}` : "",
569
+ live.testPath
570
+ ].filter((candidate) => candidate.length > 0);
571
+ for (const candidate of candidates) {
572
+ const markerPattern = new RegExp(
573
+ `(?:^|\\n)[^\\n]*${escapeRegExp(candidate)}(?:\\s+\\([^\\n)]*\\))?\\s*(?=\\n|$)`,
574
+ "i"
575
+ );
576
+ const marker = markerPattern.exec(testOutputTail);
577
+ if (!marker || marker.index === void 0) continue;
578
+ const start = marker.index;
579
+ const end = findNextFailureMarker(testOutputTail, start);
580
+ return testOutputTail.slice(start, end);
581
+ }
582
+ return null;
583
+ }
584
+ function matchesRegisteredFailure(live, entry, testOutputTail, runtimeEnvironment = detectRuntimeEnvironment()) {
585
+ if (live.file !== entry.file) {
586
+ return false;
587
+ }
588
+ const normalizedPath = live.testPath.trim();
589
+ const normalizedName = entry.testName.trim();
590
+ if (!normalizedPath.startsWith(normalizedName)) {
591
+ return false;
592
+ }
593
+ const fingerprint = normalizeFingerprint(entry.errorFingerprint);
594
+ if (!fingerprint) {
595
+ return false;
596
+ }
597
+ const scopedOutput = extractScopedFailureOutput(live, testOutputTail);
598
+ if (!scopedOutput && hasFailureMarkers(testOutputTail)) {
599
+ return false;
600
+ }
601
+ const searchableOutput = scopedOutput ?? testOutputTail;
602
+ if (!searchableOutput.toLowerCase().includes(fingerprint)) return false;
603
+ if (entry.environments !== void 0 && entry.environments.length > 0) {
604
+ if (!entry.environments.includes(runtimeEnvironment)) {
605
+ return false;
606
+ }
607
+ }
608
+ return true;
609
+ }
610
+ function allFailuresAreRegistered(liveFailures, registry, testOutputTail, runtimeEnvironment = detectRuntimeEnvironment()) {
611
+ if (liveFailures.length === 0) return true;
612
+ if (registry.failures.length === 0) return false;
613
+ for (const raw of liveFailures) {
614
+ const live = parseLiveFailure(raw);
615
+ const matched = registry.failures.some(
616
+ (entry) => matchesRegisteredFailure(live, entry, testOutputTail, runtimeEnvironment)
617
+ );
618
+ if (!matched) {
619
+ return false;
620
+ }
621
+ }
622
+ return true;
623
+ }
624
+
625
+ // src/orchestrator/verification/verification-loop.ts
626
+ import { execa as execa2 } from "execa";
627
+
628
+ // src/core/verification/repair-artifacts.ts
629
+ import { mkdir, readFile as readFile2, rm, writeFile } from "fs/promises";
630
+ import { dirname, join as join2 } from "path";
631
+ import { execa } from "execa";
632
+ var DEFAULT_CONFIG = {
633
+ modes: ["patch"],
634
+ patchDir: ".build-project/repair-patches",
635
+ refNamespace: "refs/build/repair",
636
+ branchPrefix: "build/repair"
637
+ };
638
+ function sanitizeForPathSegment(input) {
639
+ const trimmed = input.trim();
640
+ if (!trimmed) return "unknown";
641
+ return trimmed.replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 200);
642
+ }
643
+ function sanitizeForGitRefSegment(input) {
644
+ const trimmed = input.trim();
645
+ if (!trimmed) return "unknown";
646
+ const safe = trimmed.replace(/[\s~^:?*[\\]+/g, "_").replace(/\.\.+/g, ".").replace(/^\.*/, "").replace(/\/+/g, "/");
647
+ return (safe || "unknown").slice(0, 200);
648
+ }
649
+ async function generatePatch(worktreePath, baseRef) {
650
+ const scratch = await mkBuildTempDir("repair-patch");
651
+ const indexPath = join2(scratch, "index");
652
+ const env = { ...process.env, GIT_INDEX_FILE: indexPath };
653
+ try {
654
+ const readTree = await execa("git", ["read-tree", baseRef], {
655
+ cwd: worktreePath,
656
+ env,
657
+ stdio: "pipe",
658
+ reject: false
659
+ });
660
+ if (readTree.exitCode !== 0) {
661
+ throw new Error(`Failed to read base tree: ${readTree.stderr}`);
662
+ }
663
+ const add = await execa("git", ["add", "-A"], {
664
+ cwd: worktreePath,
665
+ env,
666
+ stdio: "pipe",
667
+ reject: false
668
+ });
669
+ if (add.exitCode !== 0) {
670
+ throw new Error(`Failed to stage worktree changes: ${add.stderr}`);
671
+ }
672
+ const diff = await execa("git", ["diff", "--cached", "--binary", baseRef, "--"], {
673
+ cwd: worktreePath,
674
+ env,
675
+ stdio: "pipe",
676
+ reject: false,
677
+ stripFinalNewline: false
678
+ });
679
+ if (diff.exitCode !== 0) {
680
+ throw new Error(`Failed to generate patch: ${diff.stderr}`);
681
+ }
682
+ return diff.stdout;
683
+ } finally {
684
+ await rm(scratch, { recursive: true, force: true });
685
+ }
686
+ }
687
+ async function createCommitFromPatch(opts) {
688
+ const scratch = await mkBuildTempDir("repair");
689
+ const indexPath = join2(scratch, "index");
690
+ const env = { ...process.env, GIT_INDEX_FILE: indexPath };
691
+ const patch = opts.patchContent.endsWith("\n") ? opts.patchContent : `${opts.patchContent}
692
+ `;
693
+ try {
694
+ const readTree = await execa("git", ["read-tree", opts.baseRef], {
695
+ cwd: opts.worktreePath,
696
+ env,
697
+ stdio: "pipe",
698
+ reject: false
699
+ });
700
+ if (readTree.exitCode !== 0) {
701
+ throw new Error(`Failed to read base tree: ${readTree.stderr}`);
702
+ }
703
+ const apply = await execa("git", ["apply", "--cached", "-"], {
704
+ cwd: opts.worktreePath,
705
+ env,
706
+ input: patch,
707
+ stdio: "pipe",
708
+ reject: false
709
+ });
710
+ if (apply.exitCode !== 0) {
711
+ throw new Error(`Failed to apply patch to temp index: ${apply.stderr}`);
712
+ }
713
+ const writeTree = await execa("git", ["write-tree"], {
714
+ cwd: opts.worktreePath,
715
+ env,
716
+ stdio: "pipe",
717
+ reject: false
718
+ });
719
+ if (writeTree.exitCode !== 0) {
720
+ throw new Error(`Failed to write tree: ${writeTree.stderr}`);
721
+ }
722
+ const treeSha = writeTree.stdout.trim();
723
+ const commitTree = await execa(
724
+ "git",
725
+ ["commit-tree", treeSha, "-p", opts.baseRef, "-m", opts.message],
726
+ { cwd: opts.worktreePath, env, stdio: "pipe", reject: false }
727
+ );
728
+ if (commitTree.exitCode !== 0) {
729
+ throw new Error(`Failed to create commit: ${commitTree.stderr}`);
730
+ }
731
+ return commitTree.stdout.trim();
732
+ } finally {
733
+ await rm(scratch, { recursive: true, force: true });
734
+ }
735
+ }
736
+ async function savePatchFile(patchContent, patchDir, taskId, variantId, iteration) {
737
+ const safeTaskId = sanitizeForPathSegment(taskId);
738
+ const safeVariantId = sanitizeForPathSegment(variantId);
739
+ const patchPath = join2(patchDir, safeTaskId, `${safeVariantId}-iteration-${iteration}.patch`);
740
+ await mkdir(dirname(patchPath), { recursive: true });
741
+ await writeFile(patchPath, patchContent, "utf-8");
742
+ return patchPath;
743
+ }
744
+ async function createGitRef(worktreePath, refNamespace, taskId, variantId, iteration, commitSha) {
745
+ const safeTaskId = sanitizeForGitRefSegment(taskId);
746
+ const safeVariantId = sanitizeForGitRefSegment(variantId);
747
+ const refName = `${refNamespace}/${safeTaskId}/${safeVariantId}/${iteration}`;
748
+ const updateResult = await execa("git", ["update-ref", refName, commitSha], {
749
+ cwd: worktreePath,
750
+ stdio: "pipe",
751
+ reject: false
752
+ });
753
+ if (updateResult.exitCode !== 0) {
754
+ throw new Error(`Failed to create ref: ${updateResult.stderr}`);
755
+ }
756
+ return refName;
757
+ }
758
+ async function createBranch(worktreePath, branchPrefix, taskId, variantId, iteration, commitSha) {
759
+ const flat = (part) => sanitizeForGitRefSegment(part).replace(/\//g, "-");
760
+ const branchName = `${branchPrefix}/${flat(taskId)}-${flat(variantId)}-${iteration}`;
761
+ const result = await execa("git", ["branch", "-f", branchName, commitSha], {
762
+ cwd: worktreePath,
763
+ stdio: "pipe",
764
+ reject: false
765
+ });
766
+ if (result.exitCode !== 0) {
767
+ throw new Error(`Failed to create branch: ${result.stderr}`);
768
+ }
769
+ return branchName;
770
+ }
771
+ async function preserveRepairIteration(worktreePath, baseRef, taskId, variantId, iteration, config = {}) {
772
+ const cfg = { ...DEFAULT_CONFIG, ...config };
773
+ const results = [];
774
+ let patchContent = null;
775
+ let preservedCommitSha = null;
776
+ for (const mode of cfg.modes) {
777
+ try {
778
+ let artifactPath;
779
+ switch (mode) {
780
+ case "patch": {
781
+ patchContent = patchContent ?? await generatePatch(worktreePath, baseRef);
782
+ artifactPath = await savePatchFile(
783
+ patchContent,
784
+ cfg.patchDir,
785
+ taskId,
786
+ variantId,
787
+ iteration.iteration
788
+ );
789
+ break;
790
+ }
791
+ case "ref": {
792
+ patchContent = patchContent ?? await generatePatch(worktreePath, baseRef);
793
+ preservedCommitSha = preservedCommitSha ?? await createCommitFromPatch({
794
+ worktreePath,
795
+ baseRef,
796
+ patchContent,
797
+ message: `build: preserve repair (${taskId}, ${variantId}, iter ${iteration.iteration})`
798
+ });
799
+ artifactPath = await createGitRef(
800
+ worktreePath,
801
+ cfg.refNamespace,
802
+ taskId,
803
+ variantId,
804
+ iteration.iteration,
805
+ preservedCommitSha
806
+ );
807
+ break;
808
+ }
809
+ case "branch": {
810
+ patchContent = patchContent ?? await generatePatch(worktreePath, baseRef);
811
+ preservedCommitSha = preservedCommitSha ?? await createCommitFromPatch({
812
+ worktreePath,
813
+ baseRef,
814
+ patchContent,
815
+ message: `build: preserve repair (${taskId}, ${variantId}, iter ${iteration.iteration})`
816
+ });
817
+ artifactPath = await createBranch(
818
+ worktreePath,
819
+ cfg.branchPrefix,
820
+ taskId,
821
+ variantId,
822
+ iteration.iteration,
823
+ preservedCommitSha
824
+ );
825
+ break;
826
+ }
827
+ }
828
+ results.push({
829
+ artifactPath,
830
+ mode,
831
+ success: true
832
+ });
833
+ } catch (error) {
834
+ results.push({
835
+ artifactPath: "",
836
+ mode,
837
+ success: false,
838
+ error: error instanceof Error ? error.message : String(error)
839
+ });
840
+ }
841
+ }
842
+ return results;
843
+ }
844
+ function findBestIteration(iterations) {
845
+ if (iterations.length === 0) {
846
+ return null;
847
+ }
848
+ let bestIndex = 0;
849
+ let bestIteration = iterations[0];
850
+ for (let i = 1; i < iterations.length; i++) {
851
+ const current = iterations[i];
852
+ if (current.passed && !bestIteration.passed) {
853
+ bestIndex = i;
854
+ bestIteration = current;
855
+ continue;
856
+ }
857
+ if (current.passed === bestIteration.passed) {
858
+ if (current.newIssueCount < bestIteration.newIssueCount) {
859
+ bestIndex = i;
860
+ bestIteration = current;
861
+ continue;
862
+ }
863
+ if (current.newIssueCount === bestIteration.newIssueCount && current.fixedIssueCount > bestIteration.fixedIssueCount) {
864
+ bestIndex = i;
865
+ bestIteration = current;
866
+ }
867
+ }
868
+ }
869
+ return { index: bestIndex, iteration: bestIteration };
870
+ }
871
+ async function applyPatchFile(worktreePath, patchPath) {
872
+ const raw = await readFile2(patchPath, "utf-8");
873
+ if (raw.trim().length === 0) {
874
+ return { success: true };
875
+ }
876
+ const patchContent = raw.endsWith("\n") ? raw : `${raw}
877
+ `;
878
+ const result = await execa("git", ["apply", "--3way", "-"], {
879
+ cwd: worktreePath,
880
+ input: patchContent,
881
+ stdio: "pipe",
882
+ reject: false
883
+ });
884
+ if (result.exitCode !== 0) {
885
+ return {
886
+ success: false,
887
+ error: `Failed to apply patch: ${result.stderr}`
888
+ };
889
+ }
890
+ return { success: true };
891
+ }
892
+ async function cherryPickFromRef(worktreePath, refName) {
893
+ const result = await execa("git", ["cherry-pick", "--no-commit", refName], {
894
+ cwd: worktreePath,
895
+ stdio: "pipe",
896
+ reject: false
897
+ });
898
+ if (result.exitCode !== 0) {
899
+ return {
900
+ success: false,
901
+ error: `Failed to cherry-pick: ${result.stderr}`
902
+ };
903
+ }
904
+ return { success: true };
905
+ }
906
+
907
+ // src/orchestrator/verification/repair-diff-inventory.ts
908
+ var EMPTY = { stdout: "" };
909
+ function git(args, cwd) {
910
+ return execGit(args, { cwd }).catch(() => EMPTY);
911
+ }
912
+ async function getUntrackedFiles(worktreePath) {
913
+ const result = await git(["ls-files", "-z", "--others", "--exclude-standard"], worktreePath);
914
+ return result.stdout.split("\0").filter(Boolean);
915
+ }
916
+ function sumNumstat(stdout) {
917
+ let total = 0;
918
+ for (const line of stdout.split(/\r?\n/)) {
919
+ const trimmed = line.trim();
920
+ if (!trimmed) continue;
921
+ const parts = trimmed.split(/\s+/);
922
+ if (parts.length < 3) continue;
923
+ const added = Number.parseInt(parts[0] ?? "0", 10);
924
+ const deleted = Number.parseInt(parts[1] ?? "0", 10);
925
+ total += (Number.isFinite(added) ? added : 0) + (Number.isFinite(deleted) ? deleted : 0);
926
+ }
927
+ return total;
928
+ }
929
+ async function getChangedFiles(worktreePath, baselineRef) {
930
+ const [result, untracked] = await Promise.all([
931
+ git(["diff", "--name-only", "-z", baselineRef, "--"], worktreePath),
932
+ getUntrackedFiles(worktreePath)
933
+ ]);
934
+ const tracked = result.stdout.split("\0").filter(Boolean);
935
+ return [.../* @__PURE__ */ new Set([...tracked, ...untracked])].sort();
936
+ }
937
+ async function getDiffSize(worktreePath, baselineRef) {
938
+ const [result, untracked] = await Promise.all([
939
+ git(["diff", "--numstat", baselineRef, "--"], worktreePath),
940
+ getUntrackedFiles(worktreePath)
941
+ ]);
942
+ const untrackedStats = await Promise.all(
943
+ untracked.map(
944
+ (file) => git(["diff", "--no-index", "--numstat", "--", "/dev/null", file], worktreePath)
945
+ )
946
+ );
947
+ return [result, ...untrackedStats].reduce((total, stat) => total + sumNumstat(stat.stdout), 0);
948
+ }
949
+
950
+ // src/orchestrator/verification/verification-coverage.ts
951
+ function taskIrrelevantGate(channel) {
952
+ return {
953
+ status: "skipped",
954
+ exitCode: 0,
955
+ command: `${channel} (not task-relevant)`,
956
+ verificationCoverage: {
957
+ status: "skipped_not_relevant",
958
+ reason: "Channel is not relevant to the changed files."
959
+ },
960
+ durationMs: 0,
961
+ outputTail: `Skipped ${channel} gate: not task-relevant to the changed files.`
962
+ };
963
+ }
964
+ function controlsPassed(gates, controls) {
965
+ return controls.every(
966
+ (channel) => gates[channel === "test" ? "tests" : channel]?.status === "passed"
967
+ );
968
+ }
969
+ function buildHasNoCoveringCommand(gates) {
970
+ return gates.build.status === "unavailable" && gates.build.verificationCoverage?.status === "skipped_no_command";
971
+ }
972
+ function testsSupersedeUncoveredBuild(gates, checkTestGate) {
973
+ return checkTestGate && buildHasNoCoveringCommand(gates) && gates.tests?.status === "passed";
974
+ }
975
+ function gatesHavePromotableCoverage(gates, checkTestGate, controls = []) {
976
+ if (!controlsPassed(gates, controls)) return false;
977
+ if (gates.build.status === "unavailable" && !testsSupersedeUncoveredBuild(gates, checkTestGate)) {
978
+ return false;
979
+ }
980
+ if (!checkTestGate) return true;
981
+ if (gates.build.status !== "passed" && gates.build.status !== "skipped") return true;
982
+ const testStatus = gates.tests?.status;
983
+ return testStatus === "skipped" && controls.length > 0 || testStatus === "passed" || testStatus === "failed" || testStatus === "timeout" || testStatus === "error";
984
+ }
985
+ function isHardGateStatus(status) {
986
+ return status === "failed" || status === "timeout" || status === "error";
987
+ }
988
+ function gatesHaveNoHardFailures(gates, checkTestGate) {
989
+ if (isHardGateStatus(gates.build.status)) return false;
990
+ if (!checkTestGate) return true;
991
+ const testStatus = gates.tests?.status;
992
+ return testStatus === void 0 || !isHardGateStatus(testStatus);
993
+ }
994
+ function hardGateIncomplete(gates, checkTestGate) {
995
+ const incomplete = (channel) => [channel?.status, ...(channel?.commandResults ?? []).map((r) => r.status)].some(
996
+ (status) => status === "timeout" || status === "error"
997
+ );
998
+ return incomplete(gates.build) || checkTestGate && incomplete(gates.tests);
999
+ }
1000
+ function onlyUnavailableChannelsRemain(gates, options) {
1001
+ const statuses = [
1002
+ gates.build.status,
1003
+ ...options.checkTestGate ? [gates.tests?.status] : [],
1004
+ ...options.controls.map((channel) => gates[channel === "test" ? "tests" : channel]?.status)
1005
+ ].filter((status) => status !== void 0);
1006
+ const notPassing = statuses.filter((status) => status !== "passed" && status !== "skipped");
1007
+ return notPassing.length > 0 && notPassing.every((status) => status === "unavailable");
1008
+ }
1009
+ function iterationPassesBaseline(input) {
1010
+ const { gates, checkTestGate, controls } = input;
1011
+ const provenNewFailures = input.provenNewFailures || checkTestGate && input.comparison.comparableTestTotalRegressed === true;
1012
+ if (hardGateIncomplete(gates, checkTestGate) || !controlsPassed(gates, controls)) return false;
1013
+ const buildPassedOrOutOfScope = gates.build.status === "passed" || checkTestGate && gates.build.status === "skipped" || testsSupersedeUncoveredBuild(gates, checkTestGate);
1014
+ const passedOutright = !provenNewFailures && buildPassedOrOutOfScope && (!checkTestGate || gates.tests?.status === "passed");
1015
+ const identical = input.identicalToBaseChannels ?? [];
1016
+ const hardChannels = (checkTestGate ? ["build", "test"] : ["build"]).filter(
1017
+ (channel) => !identical.includes(channel)
1018
+ );
1019
+ return passedOutright || stableBaselineProvesClean(input.comparison, provenNewFailures, hardChannels);
1020
+ }
1021
+
1022
+ // src/orchestrator/verification/verification-loop-outcome-iteration.ts
1023
+ function toOutcomeIteration(it, baseline) {
1024
+ return {
1025
+ iteration: it.iteration,
1026
+ passed: it.passed,
1027
+ passedBaseline: it.passedBaseline,
1028
+ newIssueCount: it.newIssueCount,
1029
+ fixedIssueCount: it.fixedIssueCount,
1030
+ durationMs: it.durationMs,
1031
+ costUsd: it.costUsd,
1032
+ cumulativeCostUsd: it.cumulativeCostUsd,
1033
+ constraints: it.constraints,
1034
+ build: it.gates.build,
1035
+ lint: it.gates.lint,
1036
+ tests: it.gates.tests,
1037
+ persistingIssues: it.baselineComparison && persistingIssuesOnBase(it.baselineComparison, baseline, it.gates)
1038
+ };
1039
+ }
1040
+
1041
+ // src/orchestrator/verification/verification-loop.ts
1042
+ function channelCommands2(channel) {
1043
+ if (Array.isArray(channel.commands) && channel.commands.length > 0) return channel.commands;
1044
+ if (typeof channel.command === "string" && channel.command.trim()) return [channel.command];
1045
+ return [];
1046
+ }
1047
+ function dominateGateStatus(statuses) {
1048
+ return dominantVerificationStatus(statuses) ?? "unavailable";
1049
+ }
1050
+ function isUnavailableCoverage(coverage) {
1051
+ return coverage?.status === "skipped_no_command" || coverage?.status === "skipped_tool_unavailable";
1052
+ }
1053
+ function buildStatusFromArtifact(build) {
1054
+ if (build.ok) return "passed";
1055
+ if (isUnavailableCoverage(build.verificationCoverage)) return "unavailable";
1056
+ if (build.exitCode === 124) return "timeout";
1057
+ return "failed";
1058
+ }
1059
+ function lintStatusFromArtifact(lint) {
1060
+ if (isUnavailableCoverage(lint.verificationCoverage)) return "unavailable";
1061
+ if (lint.exitCode === 0) return "passed";
1062
+ if (lint.exitCode === 124) return "timeout";
1063
+ return "failed";
1064
+ }
1065
+ function testStatusFromArtifact(status) {
1066
+ if (status === "passed") return "passed";
1067
+ if (status === "timeout") return "timeout";
1068
+ if (status === "error") return "error";
1069
+ if (status === "unavailable") return "unavailable";
1070
+ if (status === "skipped") return "skipped";
1071
+ return "failed";
1072
+ }
1073
+ async function detectRemovedExportsInPublicBarrels(worktreePath, baselineRef) {
1074
+ const PUBLIC_BARRELS = /* @__PURE__ */ new Set(["src/cli/index.ts", "src/orchestrator/index.ts"]);
1075
+ const result = await execa2("git", ["diff", "-U0", baselineRef, "--", "src"], {
1076
+ cwd: worktreePath,
1077
+ stdio: "pipe",
1078
+ reject: false
1079
+ });
1080
+ const diff = String(result.stdout ?? "");
1081
+ const removed = [];
1082
+ let currentFile = null;
1083
+ for (const line of diff.split(/\r?\n/)) {
1084
+ if (line.startsWith("diff --git ")) {
1085
+ const match = /^diff --git a\/(.+?) b\/(.+)$/.exec(line);
1086
+ currentFile = match?.[2] ?? null;
1087
+ continue;
1088
+ }
1089
+ if (!currentFile) continue;
1090
+ if (!PUBLIC_BARRELS.has(currentFile)) continue;
1091
+ if (line.startsWith("-export") || line.startsWith("- export")) {
1092
+ removed.push(`${currentFile}: ${line.slice(1).trim()}`);
1093
+ }
1094
+ }
1095
+ return {
1096
+ removedExportLines: removed.length,
1097
+ sample: removed.slice(0, 3).join("\n") || void 0
1098
+ };
1099
+ }
1100
+ async function runDeterministicGates(worktreePath, baselineRef, timeoutMs, changedFiles = [], budget = "shared", skipTests = false) {
1101
+ return withValidationSlot(
1102
+ `gates:${worktreePath}`,
1103
+ () => runDeterministicGatesUnpaced(
1104
+ worktreePath,
1105
+ baselineRef,
1106
+ timeoutMs,
1107
+ changedFiles,
1108
+ budget,
1109
+ skipTests
1110
+ ),
1111
+ { maxWaitMs: Math.min(5 * 60 * 1e3, Math.max(5e3, timeoutMs)) }
1112
+ );
1113
+ }
1114
+ async function runDeterministicGatesUnpaced(worktreePath, baselineRef, timeoutMs, changedFiles = [], budget = "shared", skipTests = false) {
1115
+ const MIN_GATE_TIMEOUT_MS = 5e3;
1116
+ const effectiveTimeoutMs = Math.max(MIN_GATE_TIMEOUT_MS, timeoutMs);
1117
+ const scope = resolveVerificationChannelScope(
1118
+ worktreePath,
1119
+ changedFiles
1120
+ );
1121
+ const buildCommands = channelCommands2(scope.build);
1122
+ const lintCommands = channelCommands2(scope.lint);
1123
+ const testCommands = selectScopedTestCommands(scope);
1124
+ const buildStart = Date.now();
1125
+ const buildChannelBudgetMs = budget === "per-channel" ? effectiveTimeoutMs : Math.min(resolveVerifyCommandTimeoutMs(), effectiveTimeoutMs);
1126
+ const buildArtifacts = scope.build.availability === "unavailable" ? {
1127
+ status: "unavailable",
1128
+ exitCode: 127,
1129
+ command: "build (verification unavailable)",
1130
+ durationMs: 0,
1131
+ stdoutTail: "",
1132
+ stderrTail: "",
1133
+ outputTail: "Build verification unavailable: no covering command for changed language.",
1134
+ verificationCoverage: {
1135
+ status: "skipped_no_command",
1136
+ reason: "No covering build/typecheck command for changed language."
1137
+ }
1138
+ } : scope.build.relevant ? await (async () => {
1139
+ if (buildCommands.length > 0) {
1140
+ let remaining = buildChannelBudgetMs;
1141
+ const commandResults = [];
1142
+ for (const command of buildCommands) {
1143
+ if (remaining <= 0) {
1144
+ commandResults.push({
1145
+ command,
1146
+ language: describeVerificationCommand(command).language,
1147
+ status: "timeout",
1148
+ exitCode: 124,
1149
+ durationMs: 0,
1150
+ outputTail: "Build command skipped: channel timeout budget exhausted."
1151
+ });
1152
+ continue;
1153
+ }
1154
+ const cmdStart = Date.now();
1155
+ const build2 = await runTypecheckWithArtifacts(worktreePath, {
1156
+ timeoutMs: remaining,
1157
+ command
1158
+ });
1159
+ const durationMs = Math.max(build2.durationMs ?? 0, Date.now() - cmdStart);
1160
+ remaining = Math.max(0, remaining - durationMs);
1161
+ const status = buildStatusFromArtifact(build2);
1162
+ commandResults.push({
1163
+ command: build2.command,
1164
+ language: build2.language ?? describeVerificationCommand(command).language,
1165
+ status,
1166
+ exitCode: build2.exitCode,
1167
+ durationMs,
1168
+ outputTail: build2.outputTail,
1169
+ stdoutTail: build2.stdoutTail,
1170
+ stderrTail: build2.stderrTail
1171
+ });
1172
+ }
1173
+ const statuses = commandResults.map((r) => r.status);
1174
+ const aggregateStatus = dominateGateStatus(statuses);
1175
+ const representative = commandResults.find((r) => r.status === aggregateStatus) ?? commandResults[0];
1176
+ const totalDuration = commandResults.reduce((sum, r) => sum + (r.durationMs ?? 0), 0);
1177
+ return {
1178
+ status: aggregateStatus,
1179
+ exitCode: representative.exitCode,
1180
+ command: representative.command,
1181
+ durationMs: Math.max(totalDuration, Date.now() - buildStart),
1182
+ stdoutTail: representative.stdoutTail ?? "",
1183
+ stderrTail: representative.stderrTail ?? "",
1184
+ outputTail: representative.outputTail,
1185
+ language: representative.language,
1186
+ verificationCoverage: aggregateStatus === "unavailable" ? {
1187
+ status: "skipped_tool_unavailable",
1188
+ command: representative.command,
1189
+ reason: "One or more scoped build commands were unavailable."
1190
+ } : aggregateStatus === "passed" ? { status: "verified", command: representative.command } : { status: "unverified", command: representative.command },
1191
+ commandResults
1192
+ };
1193
+ }
1194
+ const build = await runTypecheckWithArtifacts(worktreePath, {
1195
+ timeoutMs: buildChannelBudgetMs,
1196
+ ...scope.scoped && scope.build.command ? { command: scope.build.command } : {}
1197
+ });
1198
+ const buildDurationMs = Date.now() - buildStart;
1199
+ const buildStatus = buildStatusFromArtifact(build);
1200
+ return {
1201
+ status: buildStatus,
1202
+ exitCode: build.exitCode,
1203
+ command: build.command,
1204
+ durationMs: Math.max(build.durationMs ?? 0, buildDurationMs),
1205
+ stdoutTail: build.stdoutTail,
1206
+ stderrTail: build.stderrTail,
1207
+ outputTail: build.outputTail,
1208
+ verificationCoverage: build.verificationCoverage,
1209
+ // Carry the SOURCE-tagged language through so the current side parses by the
1210
+ // same (channel, language) the baseline recorded (root invariant). Fall back
1211
+ // to the scoped command's descriptor when the gate did not tag one.
1212
+ language: build.language ?? (scope.build.command ? describeVerificationCommand(scope.build.command).language : void 0)
1213
+ };
1214
+ })() : {
1215
+ // OUT-OF-SCOPE: this channel was intentionally not run for the task scope
1216
+ // (e.g. a Python-only change does not exercise the Node build). This is a
1217
+ // 'skipped' status (deliberately not run), DISTINCT from 'unavailable' (the
1218
+ // tool was relevant but missing/could-not-run). gatesHavePromotableCoverage
1219
+ // allows an out-of-scope 'skipped' build but still rejects an in-scope
1220
+ // 'unavailable' build, so an out-of-scope channel does not block promotion
1221
+ // while a genuinely-missing in-scope tool stays non-promotable (fail-closed).
1222
+ ...taskIrrelevantGate("build"),
1223
+ stdoutTail: "",
1224
+ stderrTail: ""
1225
+ };
1226
+ const remainingMs = budget === "per-channel" ? effectiveTimeoutMs : Math.max(MIN_GATE_TIMEOUT_MS, effectiveTimeoutMs - (Date.now() - buildStart));
1227
+ const lintTimeoutMs = remainingMs;
1228
+ const testTimeoutMs = remainingMs;
1229
+ const runLintChannel = async () => {
1230
+ if (scope.lint.availability === "unavailable") {
1231
+ return {
1232
+ status: "unavailable",
1233
+ exitCode: 127,
1234
+ command: "lint (verification unavailable)",
1235
+ durationMs: 0,
1236
+ outputTail: "Lint verification unavailable: no covering command for changed language.",
1237
+ verificationCoverage: {
1238
+ status: "skipped_no_command",
1239
+ reason: "No covering lint command for changed language."
1240
+ }
1241
+ };
1242
+ }
1243
+ if (!scope.lint.relevant) {
1244
+ return taskIrrelevantGate("lint");
1245
+ }
1246
+ if (lintCommands.length > 0) {
1247
+ let remaining = lintTimeoutMs;
1248
+ const commandResults = [];
1249
+ for (const command of lintCommands) {
1250
+ if (remaining <= 0) {
1251
+ commandResults.push({
1252
+ command,
1253
+ language: describeVerificationCommand(command).language,
1254
+ status: "timeout",
1255
+ exitCode: 124,
1256
+ durationMs: 0,
1257
+ outputTail: "Lint command skipped: channel timeout budget exhausted."
1258
+ });
1259
+ continue;
1260
+ }
1261
+ const lint3 = await runLintOnDiffWithArtifacts(worktreePath, {
1262
+ baseBranch: baselineRef,
1263
+ timeoutMs: remaining,
1264
+ command
1265
+ });
1266
+ remaining = Math.max(0, remaining - (lint3.durationMs ?? 0));
1267
+ commandResults.push({
1268
+ command: lint3.command,
1269
+ language: lint3.language ?? describeVerificationCommand(command).language,
1270
+ status: lintStatusFromArtifact(lint3),
1271
+ exitCode: lint3.exitCode,
1272
+ durationMs: lint3.durationMs,
1273
+ outputTail: lint3.outputTail
1274
+ });
1275
+ }
1276
+ const aggregateStatus = dominateGateStatus(commandResults.map((r) => r.status));
1277
+ const representative = commandResults.find((r) => r.status === aggregateStatus) ?? commandResults[0];
1278
+ return {
1279
+ status: aggregateStatus,
1280
+ exitCode: representative.exitCode,
1281
+ command: representative.command,
1282
+ durationMs: commandResults.reduce((sum, r) => sum + (r.durationMs ?? 0), 0),
1283
+ outputTail: representative.outputTail,
1284
+ language: representative.language,
1285
+ verificationCoverage: aggregateStatus === "unavailable" ? {
1286
+ status: "skipped_tool_unavailable",
1287
+ command: representative.command,
1288
+ reason: "One or more scoped lint commands were unavailable."
1289
+ } : aggregateStatus === "passed" ? { status: "verified", command: representative.command } : { status: "unverified", command: representative.command },
1290
+ commandResults
1291
+ };
1292
+ }
1293
+ const lint2 = await runLintOnDiffWithArtifacts(worktreePath, {
1294
+ baseBranch: baselineRef,
1295
+ timeoutMs: lintTimeoutMs,
1296
+ ...scope.scoped && scope.lint.command ? { command: scope.lint.command } : {}
1297
+ });
1298
+ return {
1299
+ status: lintStatusFromArtifact(lint2),
1300
+ exitCode: lint2.exitCode,
1301
+ command: lint2.command,
1302
+ durationMs: lint2.durationMs,
1303
+ outputTail: lint2.outputTail,
1304
+ verificationCoverage: lint2.verificationCoverage,
1305
+ language: lint2.language ?? (scope.lint.command ? describeVerificationCommand(scope.lint.command).language : void 0)
1306
+ };
1307
+ };
1308
+ const runTestChannel = async () => {
1309
+ if (skipTests) {
1310
+ return {
1311
+ status: "skipped",
1312
+ exitCode: 0,
1313
+ command: "test (prohibited by task)",
1314
+ durationMs: 0,
1315
+ outputTail: "Skipped test gate: the task prohibits running tests.",
1316
+ failingTests: []
1317
+ };
1318
+ }
1319
+ if (scope.test.availability === "unavailable") {
1320
+ return {
1321
+ status: "unavailable",
1322
+ exitCode: 127,
1323
+ command: "test (verification unavailable)",
1324
+ durationMs: 0,
1325
+ outputTail: "Test verification unavailable: no covering command for changed language.",
1326
+ failingTests: []
1327
+ };
1328
+ }
1329
+ if (!scope.test.relevant) {
1330
+ return {
1331
+ // OUT-OF-SCOPE: intentionally not run for this task scope. 'skipped' (not
1332
+ // run on purpose) is distinct from 'unavailable' (relevant tool missing).
1333
+ ...taskIrrelevantGate("test"),
1334
+ failingTests: []
1335
+ };
1336
+ }
1337
+ if (testCommands.length > 0) {
1338
+ let remaining = testTimeoutMs;
1339
+ const commandResults = [];
1340
+ for (const command of testCommands) {
1341
+ if (remaining <= 0) {
1342
+ commandResults.push({
1343
+ command,
1344
+ language: describeVerificationCommand(command).language,
1345
+ status: "timeout",
1346
+ exitCode: 124,
1347
+ durationMs: 0,
1348
+ outputTail: "Test command skipped: channel timeout budget exhausted.",
1349
+ failingTests: []
1350
+ });
1351
+ continue;
1352
+ }
1353
+ const tests3 = await runDeterministicTestGateWithArtifacts(worktreePath, {
1354
+ baseRef: baselineRef,
1355
+ timeoutMs: remaining,
1356
+ command
1357
+ });
1358
+ remaining = Math.max(0, remaining - (tests3.durationMs ?? 0));
1359
+ const status = testStatusFromArtifact(tests3.status);
1360
+ commandResults.push({
1361
+ command: tests3.command,
1362
+ ...tests3.executables?.length ? { executables: tests3.executables } : {},
1363
+ language: tests3.language ?? describeVerificationCommand(command).language,
1364
+ status,
1365
+ exitCode: tests3.exitCode,
1366
+ durationMs: tests3.durationMs,
1367
+ outputTail: tests3.outputTail,
1368
+ failingTests: tests3.failingTests,
1369
+ failingTestIdentities: tests3.failingTestIdentities
1370
+ });
1371
+ }
1372
+ const aggregateStatus = dominateGateStatus(commandResults.map((r) => r.status));
1373
+ const representative = commandResults.find((r) => r.status === aggregateStatus) ?? commandResults[0];
1374
+ const failingTests = Array.from(new Set(commandResults.flatMap((r) => r.failingTests ?? [])));
1375
+ const failingTestIdentities = Array.from(
1376
+ new Set(commandResults.flatMap((r) => r.failingTestIdentities ?? r.failingTests ?? []))
1377
+ );
1378
+ return {
1379
+ status: aggregateStatus,
1380
+ exitCode: representative.exitCode,
1381
+ command: representative.command,
1382
+ durationMs: commandResults.reduce((sum, r) => sum + (r.durationMs ?? 0), 0),
1383
+ outputTail: representative.outputTail,
1384
+ failingTests,
1385
+ failingTestIdentities,
1386
+ language: representative.language,
1387
+ commandResults,
1388
+ ...commandResults.some((result) => result.executables?.length) ? { executables: commandResults.flatMap((result) => result.executables ?? []) } : {}
1389
+ };
1390
+ }
1391
+ const tests2 = await runDeterministicTestGateWithArtifacts(worktreePath, {
1392
+ baseRef: baselineRef,
1393
+ timeoutMs: testTimeoutMs,
1394
+ ...scope.scoped && scope.test.command ? { command: scope.test.command } : {}
1395
+ });
1396
+ return {
1397
+ status: testStatusFromArtifact(tests2.status),
1398
+ exitCode: tests2.exitCode,
1399
+ command: tests2.command,
1400
+ ...tests2.executables?.length ? { executables: tests2.executables } : {},
1401
+ durationMs: tests2.durationMs,
1402
+ outputTail: tests2.outputTail,
1403
+ failingTests: tests2.failingTests,
1404
+ failingTestIdentities: tests2.failingTestIdentities,
1405
+ language: tests2.language ?? (scope.test.command ? describeVerificationCommand(scope.test.command).language : void 0)
1406
+ };
1407
+ };
1408
+ const [lint, tests] = await Promise.all([runLintChannel(), runTestChannel()]);
1409
+ const gates = {
1410
+ build: buildArtifacts,
1411
+ lint: {
1412
+ status: lint.status,
1413
+ exitCode: lint.exitCode,
1414
+ command: lint.command,
1415
+ durationMs: lint.durationMs,
1416
+ outputTail: lint.outputTail,
1417
+ verificationCoverage: lint.verificationCoverage,
1418
+ language: lint.language,
1419
+ ...lint.commandResults ? { commandResults: lint.commandResults } : {}
1420
+ },
1421
+ tests: {
1422
+ verificationCoverage: tests.verificationCoverage,
1423
+ ...tests.executables?.length ? { executables: tests.executables } : {},
1424
+ status: tests.status,
1425
+ exitCode: tests.exitCode,
1426
+ command: tests.command,
1427
+ durationMs: tests.durationMs,
1428
+ outputTail: tests.outputTail,
1429
+ failingTests: tests.failingTests,
1430
+ failingTestIdentities: tests.failingTestIdentities,
1431
+ language: tests.language,
1432
+ ...tests.commandResults ? { commandResults: tests.commandResults } : {}
1433
+ }
1434
+ };
1435
+ const passed = buildArtifacts.status === "passed" && (tests.status === "passed" || tests.status === "skipped");
1436
+ return { passed, gates };
1437
+ }
1438
+ function buildVerificationFindings(gates, passedBaseline, controls = []) {
1439
+ if (passedBaseline) return [];
1440
+ const findings = [];
1441
+ for (const kind of ["build", "lint"]) {
1442
+ const channel = gates[kind];
1443
+ if (channel && (kind === "build" || controls.includes(kind)) && isHardGateStatus(channel.status)) {
1444
+ findings.push({
1445
+ kind,
1446
+ command: channel.command,
1447
+ exitCode: channel.exitCode,
1448
+ outputTail: channel.outputTail,
1449
+ severity: "error"
1450
+ });
1451
+ }
1452
+ }
1453
+ if (gates.tests && gates.tests.status !== "passed" && gates.tests.status !== "skipped" && gates.tests.status !== "unavailable") {
1454
+ findings.push({
1455
+ kind: "test",
1456
+ command: gates.tests.command,
1457
+ exitCode: gates.tests.exitCode,
1458
+ outputTail: gates.tests.outputTail,
1459
+ failingTests: gates.tests.failingTests,
1460
+ severity: "error"
1461
+ });
1462
+ }
1463
+ return findings;
1464
+ }
1465
+ async function runDeterministicVerificationOnce(params) {
1466
+ const checkTestGate = params.checkTestGate ?? true;
1467
+ const controls = requiredVerificationControlChannels(params.changedFiles ?? []);
1468
+ const started = Date.now();
1469
+ const gateRun = params.precomputedGates ? {
1470
+ gates: params.precomputedGates,
1471
+ passed: params.precomputedGates.build.status === "passed" && (!checkTestGate || params.precomputedGates.tests?.status === "passed")
1472
+ } : await runDeterministicGates(
1473
+ params.worktreePath,
1474
+ params.baselineRef,
1475
+ params.timeoutMs,
1476
+ params.changedFiles ?? [],
1477
+ params.budget,
1478
+ !checkTestGate
1479
+ );
1480
+ let passedBaseline = gatesHaveNoHardFailures(gateRun.gates, checkTestGate) && controlsPassed(gateRun.gates, controls);
1481
+ let newIssueCount = 0;
1482
+ let fixedIssueCount = 0;
1483
+ let persistingIssues;
1484
+ if (params.baseline) {
1485
+ const comparisonOutcomes = verificationOutcomesFromGateArtifacts(gateRun.gates, {
1486
+ source: "verification-loop",
1487
+ cwd: params.worktreePath
1488
+ });
1489
+ const baselineComparison = compareVerificationOutcomeToBaseline(
1490
+ params.baseline,
1491
+ comparisonOutcomes
1492
+ );
1493
+ const gateExitRegressions = cleanBaselineGateExitRegressions(
1494
+ params.baseline,
1495
+ baselineComparison,
1496
+ comparisonOutcomes,
1497
+ checkTestGate
1498
+ );
1499
+ const hardStructuredNewIssueCount = baselineComparison.delta.build.newIssues.size + (checkTestGate ? baselineComparison.delta.test.newIssues.size : 0);
1500
+ passedBaseline = iterationPassesBaseline({
1501
+ gates: gateRun.gates,
1502
+ checkTestGate,
1503
+ controls,
1504
+ comparison: baselineComparison,
1505
+ provenNewFailures: hardStructuredNewIssueCount > 0 || gateExitRegressions.length > 0,
1506
+ identicalToBaseChannels: channelsFailingIdenticallyOnBase(
1507
+ params.baseline,
1508
+ gateRun.gates,
1509
+ checkTestGate ? ["build", "test"] : ["build"],
1510
+ [params.worktreePath]
1511
+ )
1512
+ });
1513
+ const unparsedGateRegressionCount = gateExitRegressions.filter((kind) => {
1514
+ if (kind === "build") return baselineComparison.delta.build.newIssues.size === 0;
1515
+ return baselineComparison.delta.test.newIssues.size === 0;
1516
+ }).length;
1517
+ newIssueCount = hardStructuredNewIssueCount + unparsedGateRegressionCount;
1518
+ fixedIssueCount = baselineComparison.delta.totalFixedIssues;
1519
+ persistingIssues = persistingIssuesOnBase(baselineComparison, params.baseline, gateRun.gates);
1520
+ }
1521
+ const durationMs = Date.now() - started;
1522
+ const findings = buildVerificationFindings(gateRun.gates, passedBaseline, controls);
1523
+ const promotable = passedBaseline && gatesHavePromotableCoverage(gateRun.gates, checkTestGate, controls);
1524
+ return {
1525
+ verification: {
1526
+ passed: promotable,
1527
+ passedBaseline,
1528
+ findings
1529
+ },
1530
+ verificationLoop: {
1531
+ enabled: true,
1532
+ passed: promotable,
1533
+ passedBaseline,
1534
+ stopReason: passedBaseline ? "single_iteration_no_new_regressions" : "single_iteration_gates_failed",
1535
+ bestIterationIndex: 0,
1536
+ bestIterationPromotable: promotable,
1537
+ iterations: [
1538
+ {
1539
+ iteration: 1,
1540
+ passed: gateRun.passed,
1541
+ passedBaseline,
1542
+ newIssueCount,
1543
+ fixedIssueCount,
1544
+ durationMs,
1545
+ costUsd: 0,
1546
+ cumulativeCostUsd: 0,
1547
+ constraints: {
1548
+ maxFilesTouched: 0,
1549
+ diffSizeCap: 0,
1550
+ apiBreakAllowed: false,
1551
+ violations: []
1552
+ },
1553
+ build: gateRun.gates.build,
1554
+ lint: gateRun.gates.lint,
1555
+ tests: gateRun.gates.tests,
1556
+ persistingIssues,
1557
+ ...params.precomputedGates ? { gateSource: "precomputed" } : {}
1558
+ }
1559
+ ]
1560
+ }
1561
+ };
1562
+ }
1563
+ function gateVector(gates) {
1564
+ const build = gates.build.status === "passed" ? 1 : 0;
1565
+ const lint = 1;
1566
+ const tests = gates.tests?.status === "passed" ? 1 : 0;
1567
+ return [build, lint, tests];
1568
+ }
1569
+ function isRegression(prev, next) {
1570
+ const [pb, pl, pt] = gateVector(prev);
1571
+ const [nb, nl, nt] = gateVector(next);
1572
+ if (nb < pb) return true;
1573
+ const prevSum = pb + pl + pt;
1574
+ const nextSum = nb + nl + nt;
1575
+ return nextSum < prevSum;
1576
+ }
1577
+ function cleanBaselineGateExitRegressions(baseline, comparison, outcomes, checkTestGate) {
1578
+ const regressed = detectGateRegressions(
1579
+ baseline,
1580
+ { build: outcomes.build, tests: checkTestGate ? outcomes.tests : void 0 },
1581
+ comparison.baseline
1582
+ );
1583
+ return [
1584
+ ...regressed.build ? ["build"] : [],
1585
+ ...regressed.test ? ["test"] : []
1586
+ ];
1587
+ }
1588
+ function buildRepairPrompt(opts) {
1589
+ const { originalPrompt, iteration, gates, constraints, allowedFiles, scopePolicy } = opts;
1590
+ const parts = [];
1591
+ parts.push(originalPrompt.trimEnd());
1592
+ parts.push("\n\n---\n\n");
1593
+ parts.push(
1594
+ `VERIFICATION-DRIVEN REPAIR (iteration ${iteration}): Fix the deterministic gate failures below.`
1595
+ );
1596
+ parts.push(
1597
+ "Stabilization approach:",
1598
+ "- Prioritize high-leverage, low-cost fixes first (e.g., lint/formatting, obvious type errors).",
1599
+ "- Keep the diff cohesive and targeted; preserve the core solution unless a change is clearly required.",
1600
+ "- Only attempt deeper behavioral/test fixes once cheap failures are resolved or if time remains."
1601
+ );
1602
+ parts.push("Make the MINIMUM change set required to improve gate outcomes.");
1603
+ parts.push(
1604
+ `HARD CONSTRAINTS (enforced): maxFilesTouched=${constraints.maxFilesTouched}, diffSizeCap=${constraints.diffSizeCap}, apiBreakAllowed=${constraints.apiBreakAllowed}`
1605
+ );
1606
+ if (constraints.violations.length > 0) {
1607
+ parts.push(
1608
+ `CONSTRAINT VIOLATIONS DETECTED (must be fixed/undone):
1609
+ - ${constraints.violations.join("\n- ")}`
1610
+ );
1611
+ }
1612
+ if (allowedFiles.length > 0) {
1613
+ parts.push(`ALLOWED FILES (derived from prompt/gates):
1614
+ - ${allowedFiles.join("\n- ")}`);
1615
+ if (scopePolicy === "strict") {
1616
+ parts.push("SCOPE POLICY: strict - do not modify files outside the allowed list.");
1617
+ }
1618
+ }
1619
+ const gateBlock = (label, g) => {
1620
+ return [
1621
+ `
1622
+ ${label}:`,
1623
+ `Command: ${g.command}`,
1624
+ `Exit Code: ${g.exitCode}`,
1625
+ `Output (tail):
1626
+ ${renderUntrustedCommandOutput(g.outputTail)}`
1627
+ ].join("\n");
1628
+ };
1629
+ parts.push(
1630
+ gateBlock("BUILD/TYPECHECK", {
1631
+ command: gates.build.command,
1632
+ exitCode: gates.build.exitCode,
1633
+ outputTail: gates.build.outputTail
1634
+ })
1635
+ );
1636
+ if (gates.lint && gates.lint.status !== "passed") {
1637
+ parts.push(
1638
+ gateBlock("LINT", {
1639
+ command: gates.lint.command,
1640
+ exitCode: gates.lint.exitCode,
1641
+ outputTail: gates.lint.outputTail
1642
+ })
1643
+ );
1644
+ }
1645
+ if (gates.tests && gates.tests.status !== "passed" && gates.tests.status !== "skipped" && gates.tests.status !== "unavailable") {
1646
+ const failing = renderUntrustedFailingTests(gates.tests.failingTests);
1647
+ parts.push(
1648
+ `${gateBlock("TESTS", { command: gates.tests.command, exitCode: gates.tests.exitCode, outputTail: gates.tests.outputTail })}
1649
+ ${failing}`
1650
+ );
1651
+ }
1652
+ parts.push("\nDo not remove public exports unless explicitly allowed.");
1653
+ parts.push("Keep refactors tightly scoped to what is required for correctness.");
1654
+ parts.push(`
1655
+ ${renderRepairConstraints()}`);
1656
+ return parts.join("\n");
1657
+ }
1658
+ var GATE_EVIDENCE_EXTRA_EXTENSIONS = ["json", "css", "scss", "md", "ya?ml", "toml", "snap"];
1659
+ function buildGateEvidencePathPattern() {
1660
+ const escapeForClass = (ext) => ext.replace(/[+.]/g, "\\$&");
1661
+ const sourceExtensions = [...PROJECT_SOURCE_EXTENSIONS].map(
1662
+ (ext) => escapeForClass(ext.replace(/^\./, ""))
1663
+ );
1664
+ const extensionAlternation = [...sourceExtensions, ...GATE_EVIDENCE_EXTRA_EXTENSIONS].join("|");
1665
+ return new RegExp(
1666
+ `(?:^|[\\s'"([])((?:\\.{1,2}\\/)?(?:[A-Za-z0-9_.@+-]+\\/)*[A-Za-z0-9_.@+-]+\\.(?:${extensionAlternation}))(?:[:(]|$)`,
1667
+ "gm"
1668
+ );
1669
+ }
1670
+ var GATE_EVIDENCE_PATH_PATTERN = buildGateEvidencePathPattern();
1671
+ function extractFilePathsFromText(text) {
1672
+ if (!text) return [];
1673
+ const paths = /* @__PURE__ */ new Set();
1674
+ for (const match of text.matchAll(GATE_EVIDENCE_PATH_PATTERN)) {
1675
+ const filePath = match[1]?.trim();
1676
+ if (filePath) paths.add(filePath.replace(/^\.\//, ""));
1677
+ }
1678
+ return [...paths];
1679
+ }
1680
+ function collectIssueFiles(issues) {
1681
+ return issues?.toArray?.().flatMap((issue) => issue.file ? [issue.file] : []) ?? [];
1682
+ }
1683
+ function deriveAllowedFilesFromGateEvidence(gates, comparison) {
1684
+ const files = /* @__PURE__ */ new Set();
1685
+ for (const file of [
1686
+ ...collectIssueFiles(comparison?.delta.build.newIssues),
1687
+ ...collectIssueFiles(comparison?.delta.lint.newIssues),
1688
+ ...collectIssueFiles(comparison?.delta.test.newIssues),
1689
+ ...extractFilePathsFromText(gates.build.outputTail),
1690
+ ...extractFilePathsFromText(gates.build.stderrTail),
1691
+ ...extractFilePathsFromText(gates.build.stdoutTail),
1692
+ ...extractFilePathsFromText(gates.lint?.outputTail),
1693
+ ...extractFilePathsFromText(gates.tests?.outputTail),
1694
+ ...gates.tests?.failingTests.flatMap(extractFilePathsFromText) ?? []
1695
+ ]) {
1696
+ files.add(file);
1697
+ }
1698
+ return [...files].sort();
1699
+ }
1700
+ function mergeRepairAllowedFiles(promptAllowedFiles, gateDerivedAllowedFiles) {
1701
+ const merged = /* @__PURE__ */ new Set();
1702
+ for (const file of [...promptAllowedFiles, ...gateDerivedAllowedFiles]) {
1703
+ const normalized = file.trim();
1704
+ if (normalized.length > 0) {
1705
+ merged.add(normalized);
1706
+ }
1707
+ }
1708
+ return [...merged].sort();
1709
+ }
1710
+ function buildScopedRepairPrompt(opts) {
1711
+ const { originalPrompt, iteration, gates, constraints, comparison, allowedFiles, scopePolicy } = opts;
1712
+ const parts = [];
1713
+ parts.push(originalPrompt.trimEnd());
1714
+ parts.push("\n\n---\n\n");
1715
+ parts.push(
1716
+ `BASELINE-AWARE REPAIR (iteration ${iteration}): Fix only the NEW issues introduced by your changes.`
1717
+ );
1718
+ if (allowedFiles.length > 0) {
1719
+ parts.push(`
1720
+ ALLOWED FILES (you may only modify these):
1721
+ - ${allowedFiles.join("\n- ")}`);
1722
+ if (scopePolicy === "strict") {
1723
+ parts.push(
1724
+ "\nSCOPE POLICY: strict - Do NOT modify files outside the allowed list, even if they have errors."
1725
+ );
1726
+ } else {
1727
+ parts.push(
1728
+ "\nSCOPE POLICY: expand - You may modify dependent files if they have new errors caused by your changes."
1729
+ );
1730
+ }
1731
+ }
1732
+ parts.push("\nStabilization approach:");
1733
+ parts.push("- Focus ONLY on NEW issues listed below - ignore pre-existing issues.");
1734
+ parts.push("- Prioritize high-leverage, low-cost fixes (lint, obvious type errors).");
1735
+ parts.push("- Keep the diff cohesive; preserve your core solution.");
1736
+ parts.push("- Make the MINIMUM change set to resolve new issues.");
1737
+ const newBuild = comparison.delta.build.newIssues.toArray();
1738
+ const newLint = comparison.delta.lint.newIssues.toArray();
1739
+ const newTest = comparison.delta.test.newIssues.toArray();
1740
+ const totalNew = newBuild.length + newLint.length + newTest.length;
1741
+ if (totalNew > 0) {
1742
+ parts.push(`
1743
+ === NEW ISSUES TO FIX (${totalNew} total) ===`);
1744
+ if (newBuild.length > 0) {
1745
+ parts.push(`
1746
+ NEW TYPE ERRORS (${newBuild.length}):`);
1747
+ for (const issue of newBuild.slice(0, 20)) {
1748
+ const loc = issue.line ? `:${issue.line}${issue.col ? `:${issue.col}` : ""}` : "";
1749
+ const message = presentUntrustedRepairEvidence(issue.originalMessage ?? "");
1750
+ parts.push(`- ${issue.file}${loc}: ${issue.code} - ${message}`);
1751
+ }
1752
+ if (newBuild.length > 20) {
1753
+ parts.push(` ... and ${newBuild.length - 20} more`);
1754
+ }
1755
+ }
1756
+ if (newLint.length > 0) {
1757
+ parts.push(`
1758
+ NEW LINT ERRORS (${newLint.length}):`);
1759
+ for (const issue of newLint.slice(0, 20)) {
1760
+ const loc = issue.line ? `:${issue.line}${issue.col ? `:${issue.col}` : ""}` : "";
1761
+ parts.push(`- ${issue.file}${loc}: ${issue.code}`);
1762
+ }
1763
+ if (newLint.length > 20) {
1764
+ parts.push(` ... and ${newLint.length - 20} more`);
1765
+ }
1766
+ }
1767
+ if (newTest.length > 0) {
1768
+ parts.push(`
1769
+ NEW TEST FAILURES (${newTest.length}):`);
1770
+ for (const issue of newTest.slice(0, 10)) {
1771
+ parts.push(`- ${issue.file ? `${issue.file}: ` : ""}${issue.code}`);
1772
+ }
1773
+ if (newTest.length > 10) {
1774
+ parts.push(` ... and ${newTest.length - 10} more`);
1775
+ }
1776
+ }
1777
+ } else {
1778
+ parts.push("\n=== NO NEW ISSUES ===");
1779
+ parts.push("Your changes have not introduced any new issues vs baseline.");
1780
+ parts.push("If gates are still failing, it is due to pre-existing issues (listed below).");
1781
+ }
1782
+ if (!comparison.passed && totalNew === 0) {
1783
+ const gateBlock = (label, g) => [
1784
+ `
1785
+ ${label}:`,
1786
+ `Status: ${g.status}`,
1787
+ `Command: ${g.command}`,
1788
+ `Exit Code: ${g.exitCode}`,
1789
+ `Output (tail):
1790
+ ${renderUntrustedCommandOutput(g.outputTail)}`
1791
+ ].join("\n");
1792
+ parts.push("\n=== UNPARSED GATE REGRESSION OUTPUT ===");
1793
+ parts.push(
1794
+ "A clean baseline gate now exits non-zero, but no stable issue identity could be extracted. Fix the gate failure shown below."
1795
+ );
1796
+ if (gates.build.status !== "passed") {
1797
+ parts.push(gateBlock("BUILD/TYPECHECK", gates.build));
1798
+ }
1799
+ if (gates.lint && gates.lint.status !== "passed") {
1800
+ parts.push(gateBlock("LINT", gates.lint));
1801
+ }
1802
+ if (gates.tests && gates.tests.status !== "passed" && gates.tests.status !== "skipped" && gates.tests.status !== "unavailable") {
1803
+ parts.push(gateBlock("TESTS", gates.tests));
1804
+ }
1805
+ }
1806
+ const persistBuild = comparison.delta.build.persistingIssues.size;
1807
+ const persistLint = comparison.delta.lint.persistingIssues.size;
1808
+ const persistTest = comparison.delta.test.persistingIssues.size;
1809
+ const totalPersist = persistBuild + persistLint + persistTest;
1810
+ if (totalPersist > 0) {
1811
+ parts.push(`
1812
+ === PRE-EXISTING ISSUES (${totalPersist} total - DO NOT fix these) ===`);
1813
+ parts.push("These existed before your changes and are NOT your responsibility:");
1814
+ if (persistBuild > 0) parts.push(`- ${persistBuild} type error(s)`);
1815
+ if (persistLint > 0) parts.push(`- ${persistLint} lint error(s)`);
1816
+ if (persistTest > 0) parts.push(`- ${persistTest} test failure(s)`);
1817
+ }
1818
+ parts.push(
1819
+ `
1820
+ HARD CONSTRAINTS: maxFilesTouched=${constraints.maxFilesTouched}, diffSizeCap=${constraints.diffSizeCap}`
1821
+ );
1822
+ if (constraints.violations.length > 0) {
1823
+ parts.push(`CONSTRAINT VIOLATIONS:
1824
+ - ${constraints.violations.join("\n- ")}`);
1825
+ }
1826
+ parts.push("\nDo not remove public exports unless explicitly allowed.");
1827
+ parts.push(`
1828
+ ${renderRepairConstraints()}`);
1829
+ return parts.join("\n");
1830
+ }
1831
+ async function runVerificationDrivenRepairLoop(params) {
1832
+ const {
1833
+ config,
1834
+ worktreePath,
1835
+ baselineRef,
1836
+ originalPrompt,
1837
+ executeRepair,
1838
+ baseline,
1839
+ taskId,
1840
+ variantId
1841
+ } = params;
1842
+ const repairMode = config.repairMode ?? "auto";
1843
+ const scopePolicy = config.scopePolicy ?? "strict";
1844
+ const allowedFiles = config.allowedFiles ?? [];
1845
+ const repairSaveModes = config.repairSaveModes ?? ["patch"];
1846
+ const checkTestGate = config.checkTestGate ?? true;
1847
+ if (!config.enabled || repairMode === "none") {
1848
+ return {
1849
+ verification: { passed: true, passedBaseline: true, findings: [] },
1850
+ verificationLoop: {
1851
+ enabled: false,
1852
+ passed: true,
1853
+ passedBaseline: true,
1854
+ bestIterationIndex: 0,
1855
+ bestIterationPromotable: true,
1856
+ iterations: []
1857
+ }
1858
+ };
1859
+ }
1860
+ const repairBaseRefResult = await execa2("git", ["rev-parse", "HEAD"], {
1861
+ cwd: worktreePath,
1862
+ stdio: "pipe",
1863
+ reject: false
1864
+ });
1865
+ const repairBaseRef = (repairBaseRefResult.exitCode ?? 0) === 0 ? repairBaseRefResult.stdout.trim() : baselineRef;
1866
+ const iterations = [];
1867
+ const controlScopes = /* @__PURE__ */ new Map();
1868
+ const initialCostUsdRaw = Number(params.initialCostUsd ?? 0);
1869
+ const initialCostUsd = Number.isFinite(initialCostUsdRaw) && initialCostUsdRaw > 0 ? initialCostUsdRaw : 0;
1870
+ let cumulativeCostUsd = initialCostUsd;
1871
+ let initialFilesTouched = 0;
1872
+ let initialDiffSize = 0;
1873
+ let stopReason;
1874
+ let bestIterationIndex = 0;
1875
+ const preserved = [];
1876
+ let unverifiedRepairEdits = false;
1877
+ for (let iteration = 1; iteration <= config.maxIterations; iteration++) {
1878
+ const iterStart = Date.now();
1879
+ unverifiedRepairEdits = false;
1880
+ if (iteration === 1) {
1881
+ const [files, diffSize] = await Promise.all([
1882
+ getChangedFiles(worktreePath, baselineRef),
1883
+ getDiffSize(worktreePath, baselineRef)
1884
+ ]);
1885
+ initialFilesTouched = files.length;
1886
+ initialDiffSize = Math.max(1, diffSize);
1887
+ }
1888
+ const maxFilesTouched = initialFilesTouched + 1;
1889
+ const diffSizeCap = initialDiffSize * 2;
1890
+ const constraints = {
1891
+ maxFilesTouched,
1892
+ diffSizeCap,
1893
+ apiBreakAllowed: config.allowApiBreak,
1894
+ violations: []
1895
+ };
1896
+ const [currentFiles, currentDiffSize, removedExports] = await Promise.all([
1897
+ getChangedFiles(worktreePath, baselineRef),
1898
+ getDiffSize(worktreePath, baselineRef),
1899
+ detectRemovedExportsInPublicBarrels(worktreePath, baselineRef)
1900
+ ]);
1901
+ if (currentFiles.length > maxFilesTouched) {
1902
+ constraints.violations.push(
1903
+ `max_files_touched exceeded: ${currentFiles.length} > ${maxFilesTouched} (${currentFiles.slice(0, 8).join(", ")}${currentFiles.length > 8 ? "\u2026" : ""})`
1904
+ );
1905
+ }
1906
+ if (currentDiffSize > diffSizeCap) {
1907
+ constraints.violations.push(`diff_size_cap exceeded: ${currentDiffSize} > ${diffSizeCap}`);
1908
+ }
1909
+ if (!config.allowApiBreak && removedExports.removedExportLines > 0) {
1910
+ constraints.violations.push(
1911
+ `api_break_detection: removed export lines detected (${removedExports.removedExportLines})${removedExports.sample ? `
1912
+ ${removedExports.sample}` : ""}`
1913
+ );
1914
+ }
1915
+ const timeboxMs = config.iterationTimeoutMs;
1916
+ const timeRemainingMs = Math.max(0, timeboxMs - (Date.now() - iterStart));
1917
+ const gateRun = constraints.violations.length ? {
1918
+ passed: false,
1919
+ gates: {
1920
+ build: {
1921
+ status: "failed",
1922
+ exitCode: 1,
1923
+ command: "constraint-check",
1924
+ durationMs: 0,
1925
+ stdoutTail: "",
1926
+ stderrTail: "",
1927
+ outputTail: `Constraint violations:
1928
+ - ${constraints.violations.join("\n- ")}`
1929
+ }
1930
+ }
1931
+ } : await runDeterministicGates(
1932
+ worktreePath,
1933
+ baselineRef,
1934
+ timeRemainingMs,
1935
+ currentFiles,
1936
+ "shared",
1937
+ config.skipTests === true
1938
+ );
1939
+ const controls = requiredVerificationControlChannels(currentFiles);
1940
+ controlScopes.set(gateRun.gates, controls);
1941
+ const passed = gateRun.passed && controlsPassed(gateRun.gates, controls);
1942
+ const durationMs = Date.now() - iterStart;
1943
+ let baselineComparison;
1944
+ let passedBaseline = gatesHaveNoHardFailures(gateRun.gates, checkTestGate) && controlsPassed(gateRun.gates, controls);
1945
+ let newIssueCount = 0;
1946
+ let fixedIssueCount = 0;
1947
+ if (baseline) {
1948
+ const comparisonOutcomes = verificationOutcomesFromGateArtifacts(gateRun.gates, {
1949
+ source: "verification-loop",
1950
+ cwd: worktreePath
1951
+ });
1952
+ baselineComparison = compareVerificationOutcomeToBaseline(baseline, comparisonOutcomes);
1953
+ const gateExitRegressions = cleanBaselineGateExitRegressions(
1954
+ baseline,
1955
+ baselineComparison,
1956
+ comparisonOutcomes,
1957
+ checkTestGate
1958
+ );
1959
+ const hardStructuredNewIssueCount = baselineComparison.delta.build.newIssues.size + (checkTestGate ? baselineComparison.delta.test.newIssues.size : 0);
1960
+ passedBaseline = iterationPassesBaseline({
1961
+ gates: gateRun.gates,
1962
+ checkTestGate,
1963
+ controls,
1964
+ comparison: baselineComparison,
1965
+ provenNewFailures: hardStructuredNewIssueCount > 0 || gateExitRegressions.length > 0,
1966
+ identicalToBaseChannels: channelsFailingIdenticallyOnBase(
1967
+ baseline,
1968
+ gateRun.gates,
1969
+ checkTestGate ? ["build", "test"] : ["build"],
1970
+ [worktreePath]
1971
+ )
1972
+ });
1973
+ const comparisonForCounts = baselineComparison;
1974
+ const unparsedGateRegressionCount = gateExitRegressions.filter((kind) => {
1975
+ if (kind === "build") return comparisonForCounts.delta.build.newIssues.size === 0;
1976
+ return comparisonForCounts.delta.test.newIssues.size === 0;
1977
+ }).length;
1978
+ newIssueCount = hardStructuredNewIssueCount + unparsedGateRegressionCount;
1979
+ fixedIssueCount = baselineComparison.delta.totalFixedIssues;
1980
+ }
1981
+ const record = {
1982
+ iteration,
1983
+ passed,
1984
+ passedBaseline,
1985
+ newIssueCount,
1986
+ fixedIssueCount,
1987
+ durationMs,
1988
+ costUsd: 0,
1989
+ cumulativeCostUsd,
1990
+ constraints,
1991
+ gates: gateRun.gates,
1992
+ baselineComparison
1993
+ };
1994
+ iterations.push(record);
1995
+ if (taskId && variantId && repairSaveModes.length > 0) {
1996
+ try {
1997
+ const info = {
1998
+ iteration,
1999
+ newIssueCount,
2000
+ fixedIssueCount,
2001
+ passed: passedBaseline,
2002
+ durationMs,
2003
+ costUsd: 0
2004
+ };
2005
+ const artifacts = await preserveRepairIteration(
2006
+ worktreePath,
2007
+ repairBaseRef,
2008
+ taskId,
2009
+ variantId,
2010
+ info,
2011
+ { modes: repairSaveModes }
2012
+ );
2013
+ preserved.push({ info, artifacts });
2014
+ } catch {
2015
+ }
2016
+ }
2017
+ if (config.abortIfRegression && iterations.length >= 2) {
2018
+ const prev = iterations[iterations.length - 2];
2019
+ const next = iterations[iterations.length - 1];
2020
+ const hasBaselineRegression = baseline && next.newIssueCount > prev.newIssueCount;
2021
+ const hasGateRegression = isRegression(prev.gates, next.gates);
2022
+ const hasTestRegression = checkTestGate && baseline && next.baselineComparison && prev.baselineComparison && next.baselineComparison.delta.test.newIssues.size > prev.baselineComparison.delta.test.newIssues.size;
2023
+ if (hasBaselineRegression || hasGateRegression || hasTestRegression) {
2024
+ stopReason = "abort_if_regression";
2025
+ break;
2026
+ }
2027
+ }
2028
+ const effectivePassed = repairMode === "strict" ? passed : passedBaseline;
2029
+ if (effectivePassed) {
2030
+ stopReason = passed ? "gates_passed" : "no_new_regressions";
2031
+ break;
2032
+ }
2033
+ if (newIssueCount === 0 && onlyUnavailableChannelsRemain(gateRun.gates, {
2034
+ checkTestGate: checkTestGate || repairMode === "strict",
2035
+ controls
2036
+ })) {
2037
+ stopReason = "verification_unavailable";
2038
+ break;
2039
+ }
2040
+ if (iteration >= config.maxIterations) {
2041
+ stopReason = "max_iterations_reached";
2042
+ break;
2043
+ }
2044
+ if (durationMs > config.iterationTimeoutMs) {
2045
+ stopReason = "iteration_timebox_exceeded";
2046
+ break;
2047
+ }
2048
+ if (baseline && iterations.length >= 2) {
2049
+ const prevRecord = iterations[iterations.length - 2];
2050
+ if (prevRecord.newIssueCount === newIssueCount && newIssueCount > 0) {
2051
+ stopReason = "no_progress";
2052
+ break;
2053
+ }
2054
+ }
2055
+ let prompt;
2056
+ const repairAllowedFiles = mergeRepairAllowedFiles(
2057
+ allowedFiles,
2058
+ deriveAllowedFilesFromGateEvidence(gateRun.gates, baselineComparison)
2059
+ );
2060
+ if (baseline && baselineComparison) {
2061
+ prompt = buildScopedRepairPrompt({
2062
+ originalPrompt,
2063
+ iteration,
2064
+ gates: gateRun.gates,
2065
+ constraints,
2066
+ comparison: baselineComparison,
2067
+ allowedFiles: repairAllowedFiles,
2068
+ scopePolicy
2069
+ });
2070
+ } else {
2071
+ prompt = buildRepairPrompt({
2072
+ originalPrompt,
2073
+ iteration,
2074
+ gates: gateRun.gates,
2075
+ constraints,
2076
+ allowedFiles: repairAllowedFiles,
2077
+ scopePolicy
2078
+ });
2079
+ }
2080
+ unverifiedRepairEdits = true;
2081
+ const repairStart = Date.now();
2082
+ const repairTimeoutMs = Math.max(1, config.iterationTimeoutMs);
2083
+ const repairAbort = new AbortController();
2084
+ let timeoutId;
2085
+ let repairTimedOut = false;
2086
+ const timeoutRepair = new Promise((_, reject) => {
2087
+ timeoutId = setTimeout(() => {
2088
+ repairTimedOut = true;
2089
+ repairAbort.abort();
2090
+ reject(
2091
+ new Error(
2092
+ `executeRepair exceeded iteration timeout (${repairTimeoutMs}ms) at iteration ${iteration}`
2093
+ )
2094
+ );
2095
+ }, repairTimeoutMs);
2096
+ timeoutId.unref?.();
2097
+ });
2098
+ const repairPromise = executeRepair(prompt, iteration - 1, repairAbort.signal);
2099
+ let repair;
2100
+ try {
2101
+ repair = await Promise.race([repairPromise, timeoutRepair]);
2102
+ } catch (err) {
2103
+ repairAbort.abort();
2104
+ repairPromise.catch((repairErr) => {
2105
+ if (repairTimedOut && process.env.BUILD_DEBUG_REPAIR_ABORT === "1") {
2106
+ console.warn(
2107
+ `[verification-loop] repair subprocess exited after abort: ${repairErr instanceof Error ? repairErr.message : String(repairErr)}`
2108
+ );
2109
+ }
2110
+ });
2111
+ stopReason = repairTimedOut ? "iteration_timebox_exceeded" : "repair_execution_failed";
2112
+ record.durationMs = Math.max(record.durationMs, Date.now() - iterStart);
2113
+ if (err instanceof Error) {
2114
+ console.warn(`[verification-loop] ${err.message}`);
2115
+ }
2116
+ break;
2117
+ } finally {
2118
+ if (timeoutId) {
2119
+ clearTimeout(timeoutId);
2120
+ }
2121
+ }
2122
+ const repairDuration = Date.now() - repairStart;
2123
+ cumulativeCostUsd += Math.max(0, repair.costUsd);
2124
+ record.costUsd = Math.max(0, repair.costUsd);
2125
+ record.cumulativeCostUsd = cumulativeCostUsd;
2126
+ record.durationMs = Math.max(record.durationMs, Date.now() - iterStart);
2127
+ if (preserved.length > 0) {
2128
+ const lastPreserved = preserved[preserved.length - 1];
2129
+ if (lastPreserved?.info.iteration === iteration) {
2130
+ lastPreserved.info.costUsd = record.costUsd;
2131
+ lastPreserved.info.durationMs = record.durationMs;
2132
+ }
2133
+ }
2134
+ if (Date.now() - iterStart > config.iterationTimeoutMs || repairDuration > config.iterationTimeoutMs) {
2135
+ stopReason = "iteration_timebox_exceeded";
2136
+ break;
2137
+ }
2138
+ }
2139
+ const lastIteration = iterations.length > 0 ? iterations[iterations.length - 1] : void 0;
2140
+ let effectiveIteration = lastIteration;
2141
+ let finalPassed = false;
2142
+ let finalPassedBaseline = false;
2143
+ const bestChoice = findBestIteration(
2144
+ iterations.map((it) => ({
2145
+ iteration: it.iteration,
2146
+ newIssueCount: it.newIssueCount,
2147
+ fixedIssueCount: it.fixedIssueCount,
2148
+ passed: it.passedBaseline,
2149
+ durationMs: it.durationMs,
2150
+ costUsd: it.costUsd
2151
+ }))
2152
+ );
2153
+ bestIterationIndex = bestChoice?.index ?? 0;
2154
+ let bestIteration = iterations[bestIterationIndex];
2155
+ let bestIterationPromotable = bestIteration !== void 0 && (bestChoice?.iteration.passed ?? false) ? gatesHavePromotableCoverage(
2156
+ bestIteration.gates,
2157
+ checkTestGate,
2158
+ controlScopes.get(bestIteration.gates)
2159
+ ) : false;
2160
+ let artifactSelectionFinding;
2161
+ let restoreFinding;
2162
+ let repairArtifacts;
2163
+ if (taskId && variantId && preserved.length > 0) {
2164
+ let bestIndex = bestIteration ? preserved.findIndex((p) => p.info.iteration === bestIteration?.iteration) : -1;
2165
+ if (bestIndex < 0) {
2166
+ const bestPreserved = findBestIteration(preserved.map((p) => p.info));
2167
+ bestIndex = bestPreserved?.index ?? 0;
2168
+ const fallbackIteration = preserved[bestIndex]?.info;
2169
+ if (fallbackIteration) {
2170
+ const fallbackIndex = iterations.findIndex(
2171
+ (it) => it.iteration === fallbackIteration.iteration
2172
+ );
2173
+ if (fallbackIndex >= 0) {
2174
+ bestIterationIndex = fallbackIndex;
2175
+ const selectedIteration = iterations[fallbackIndex];
2176
+ bestIteration = selectedIteration;
2177
+ bestIterationPromotable = fallbackIteration.passed && selectedIteration !== void 0 && gatesHavePromotableCoverage(
2178
+ selectedIteration.gates,
2179
+ checkTestGate,
2180
+ controlScopes.get(selectedIteration.gates)
2181
+ );
2182
+ }
2183
+ artifactSelectionFinding = {
2184
+ kind: "other",
2185
+ command: "select-best-repair-artifact",
2186
+ exitCode: 0,
2187
+ severity: "warning",
2188
+ outputTail: "Best verification iteration did not have preserved repair artifacts; selected the best preserved iteration instead."
2189
+ };
2190
+ }
2191
+ }
2192
+ const bestIterationInfo = preserved[bestIndex]?.info ?? preserved[0]?.info;
2193
+ const bestArtifacts = preserved[bestIndex]?.artifacts ?? [];
2194
+ const bestArtifactPath = bestArtifacts.find((a) => a.success)?.artifactPath;
2195
+ repairArtifacts = {
2196
+ taskId,
2197
+ variantId,
2198
+ iterations: preserved,
2199
+ bestIterationIndex: bestIndex,
2200
+ bestIteration: bestIterationInfo,
2201
+ bestArtifactPath
2202
+ };
2203
+ }
2204
+ if (repairArtifacts && repairArtifacts.iterations.length > 0 && repairArtifacts.bestIteration.passed && repairArtifacts.bestIterationIndex !== repairArtifacts.iterations.length - 1) {
2205
+ const bestArtifacts = repairArtifacts.iterations[repairArtifacts.bestIterationIndex]?.artifacts ?? [];
2206
+ const lastArtifacts = repairArtifacts.iterations[repairArtifacts.iterations.length - 1]?.artifacts ?? [];
2207
+ const bestPatch = bestArtifacts.find((a) => a.success && a.mode === "patch")?.artifactPath;
2208
+ const bestRef = bestArtifacts.find(
2209
+ (a) => a.success && (a.mode === "ref" || a.mode === "branch")
2210
+ )?.artifactPath;
2211
+ const lastPatch = lastArtifacts.find((a) => a.success && a.mode === "patch")?.artifactPath;
2212
+ const lastRef = lastArtifacts.find(
2213
+ (a) => a.success && (a.mode === "ref" || a.mode === "branch")
2214
+ )?.artifactPath;
2215
+ const resetToBase = async () => {
2216
+ await execa2("git", ["reset", "--hard", repairBaseRef], {
2217
+ cwd: worktreePath,
2218
+ stdio: "pipe",
2219
+ reject: false
2220
+ });
2221
+ await execa2("git", ["clean", "-fd"], {
2222
+ cwd: worktreePath,
2223
+ stdio: "pipe",
2224
+ reject: false
2225
+ });
2226
+ };
2227
+ const applyArtifact = async (patchPath, refName) => {
2228
+ if (patchPath) {
2229
+ const applied = await applyPatchFile(worktreePath, patchPath);
2230
+ return applied.success;
2231
+ }
2232
+ if (refName) {
2233
+ const applied = await cherryPickFromRef(worktreePath, refName);
2234
+ return applied.success;
2235
+ }
2236
+ return false;
2237
+ };
2238
+ try {
2239
+ await resetToBase();
2240
+ const ok = await applyArtifact(bestPatch, bestRef);
2241
+ unverifiedRepairEdits = false;
2242
+ if (ok) {
2243
+ effectiveIteration = bestIteration;
2244
+ } else {
2245
+ await resetToBase();
2246
+ const restoredLast = await applyArtifact(lastPatch, lastRef);
2247
+ if (!restoredLast) {
2248
+ throw new Error("failed to restore best or last repair artifact");
2249
+ }
2250
+ effectiveIteration = lastIteration;
2251
+ bestIterationPromotable = lastIteration?.passedBaseline === true && gatesHavePromotableCoverage(
2252
+ lastIteration.gates,
2253
+ checkTestGate,
2254
+ controlScopes.get(lastIteration.gates)
2255
+ );
2256
+ restoreFinding = {
2257
+ kind: "other",
2258
+ command: "restore-best-repair-artifact",
2259
+ exitCode: 0,
2260
+ severity: "warning",
2261
+ outputTail: "Best repair artifact could not be restored; restored the last iteration artifact instead."
2262
+ };
2263
+ }
2264
+ } catch (restoreError) {
2265
+ effectiveIteration = void 0;
2266
+ bestIterationPromotable = false;
2267
+ stopReason = "artifact_restore_failed";
2268
+ restoreFinding = {
2269
+ kind: "other",
2270
+ command: "restore-best-repair-artifact",
2271
+ exitCode: 1,
2272
+ severity: "error",
2273
+ outputTail: restoreError instanceof Error ? restoreError.message : String(restoreError)
2274
+ };
2275
+ }
2276
+ }
2277
+ if (unverifiedRepairEdits) {
2278
+ bestIterationPromotable = false;
2279
+ }
2280
+ finalPassed = effectiveIteration?.passed ?? false;
2281
+ finalPassedBaseline = effectiveIteration?.passedBaseline ?? false;
2282
+ const findings = effectiveIteration ? buildVerificationFindings(
2283
+ effectiveIteration.gates,
2284
+ effectiveIteration.passedBaseline,
2285
+ controlScopes.get(effectiveIteration.gates)
2286
+ ) : [];
2287
+ return {
2288
+ verification: {
2289
+ passed: finalPassed,
2290
+ passedBaseline: finalPassedBaseline,
2291
+ findings: [
2292
+ ...findings,
2293
+ ...artifactSelectionFinding ? [artifactSelectionFinding] : [],
2294
+ ...restoreFinding ? [restoreFinding] : []
2295
+ ]
2296
+ },
2297
+ verificationLoop: {
2298
+ enabled: true,
2299
+ passed: finalPassed,
2300
+ passedBaseline: finalPassedBaseline,
2301
+ stopReason: stopReason ?? (finalPassedBaseline ? "no_new_regressions" : "gates_failed"),
2302
+ bestIterationIndex,
2303
+ bestIterationPromotable,
2304
+ iterations: iterations.map((it) => toOutcomeIteration(it, baseline))
2305
+ },
2306
+ repairArtifacts
2307
+ };
2308
+ }
2309
+
2310
+ // src/cli/variant-off-scope-warning.ts
2311
+ function attachOffScopeConfigWarning(result, context) {
2312
+ const prior = (result.warnings ?? []).filter((warning2) => warning2.code === "WS-204");
2313
+ if (prior.length > 0) {
2314
+ result.warnings = (result.warnings ?? []).filter((warning2) => warning2.code !== "WS-204");
2315
+ result.warningCount = Math.max(0, (result.warningCount ?? 0) - prior.length);
2316
+ }
2317
+ delete result.offScopeGateConfig;
2318
+ const diff = result.worktreeDiff;
2319
+ const changedPaths = context.changedPaths ?? (typeof diff === "string" && diff.trim().length > 0 ? extractChangedFilesMeta(diff).map((meta) => meta.path) : []);
2320
+ const edits = findOffScopeConfigEdits(changedPaths, context.prompt);
2321
+ if (edits.length === 0) return;
2322
+ const warning = createWarning(
2323
+ "WS-204",
2324
+ {
2325
+ taskId: context.taskId,
2326
+ subsystem: "variant-worker",
2327
+ executionPhase: "validation"
2328
+ },
2329
+ {
2330
+ metadata: {
2331
+ paths: edits.map((edit) => edit.path),
2332
+ summary: formatOffScopeConfigEdits(edits)
2333
+ }
2334
+ }
2335
+ );
2336
+ const gateEdits = findGateControllingEdits(edits);
2337
+ if (gateEdits.length > 0) {
2338
+ result.offScopeGateConfig = {
2339
+ paths: gateEdits.map((edit) => edit.path),
2340
+ reason: formatGateConfigUnverifiedReason(gateEdits)
2341
+ };
2342
+ }
2343
+ result.warnings = [...result.warnings ?? [], warning];
2344
+ result.warningCount = (result.warningCount ?? 0) + 1;
2345
+ }
2346
+
2347
+ // src/cli/variant-worker-timeout-snapshot.ts
2348
+ async function resolveTimeoutSnapshotCommit(commit, baselineRef, resolveParent) {
2349
+ const autoCommitFailed = commit.exitCode !== 0 || Boolean(
2350
+ commit.failed || commit.timedOut || commit.isCanceled || commit.isTerminated || commit.signal
2351
+ );
2352
+ if (!autoCommitFailed && !baselineRef) baselineRef = await resolveParent();
2353
+ return { autoCommitFailed, baselineRef };
2354
+ }
2355
+
2356
+ // src/cli/variant-worker.ts
2357
+ var MIN_ANALYSIS_COMPLETENESS = 60;
2358
+ var PARTIAL_GIT_TIMEOUT_MS = 3e3;
2359
+ var SIGNAL_CLEANUP_TIMEOUT_MS = WORKER_CLEANUP_BUDGET_MS;
2360
+ var SIGNAL_CLEANUP_WRAPPER_TIMEOUT_MS = SIGNAL_CLEANUP_TIMEOUT_MS + 200;
2361
+ var POST_PROVIDER_PHASE_WARN_MS = 3e4;
2362
+ function elapsedMsSince(startTime) {
2363
+ return Number((process.hrtime.bigint() - startTime) / 1000000n);
2364
+ }
2365
+ function addPostProviderPhaseDuration(durations, phase, durationMs) {
2366
+ if (!Number.isFinite(durationMs) || durationMs < 0) return;
2367
+ durations[phase] = (durations[phase] ?? 0) + Math.round(durationMs);
2368
+ }
2369
+ async function measurePostProviderPhase(durations, phase, verbose, run) {
2370
+ const started = process.hrtime.bigint();
2371
+ try {
2372
+ return await run();
2373
+ } finally {
2374
+ const durationMs = Number((process.hrtime.bigint() - started) / 1000000n);
2375
+ addPostProviderPhaseDuration(durations, phase, durationMs);
2376
+ if (verbose && durationMs >= POST_PROVIDER_PHASE_WARN_MS) {
2377
+ console.log(chalk.gray(` post-provider phase ${phase} took ${durationMs}ms`));
2378
+ }
2379
+ }
2380
+ }
2381
+ function measurePostProviderPhaseSync(durations, phase, verbose, run) {
2382
+ const started = process.hrtime.bigint();
2383
+ try {
2384
+ return run();
2385
+ } finally {
2386
+ const durationMs = Number((process.hrtime.bigint() - started) / 1000000n);
2387
+ addPostProviderPhaseDuration(durations, phase, durationMs);
2388
+ if (verbose && durationMs >= POST_PROVIDER_PHASE_WARN_MS) {
2389
+ console.log(chalk.gray(` post-provider phase ${phase} took ${durationMs}ms`));
2390
+ }
2391
+ }
2392
+ }
2393
+ function buildShutdownAbortReason(signal) {
2394
+ if (signal === "SIGINT") {
2395
+ return new Error("Variant worker received SIGINT");
2396
+ }
2397
+ return new HostTimeoutError("Variant worker received SIGTERM: host time limit reached", {
2398
+ source: VARIANT_WORKER_SIGTERM_SOURCE
2399
+ });
2400
+ }
2401
+ function shouldDowngradeSuccessfulResultForShutdown(input) {
2402
+ if (!input.shutdownRequested) return false;
2403
+ if (input.shutdownRequestedAtMs === void 0) return true;
2404
+ if (input.executionResultSettledAtMs === void 0) return true;
2405
+ return input.shutdownRequestedAtMs <= input.executionResultSettledAtMs;
2406
+ }
2407
+ function activeHandleSummary() {
2408
+ const getActiveHandles = process._getActiveHandles;
2409
+ if (typeof getActiveHandles !== "function") return [];
2410
+ return getActiveHandles().map((handle) => {
2411
+ const record = handle;
2412
+ const type = record.constructor?.name ?? typeof handle;
2413
+ let detail;
2414
+ if (typeof record.fd === "number") {
2415
+ detail = `fd=${record.fd}`;
2416
+ } else if (typeof record.path === "string") {
2417
+ detail = record.path;
2418
+ } else if (typeof record.address === "function") {
2419
+ try {
2420
+ const address = record.address();
2421
+ detail = typeof address === "string" ? address : JSON.stringify(address);
2422
+ } catch {
2423
+ detail = void 0;
2424
+ }
2425
+ }
2426
+ return detail ? { type, detail } : { type };
2427
+ });
2428
+ }
2429
+ function emitWorkerLifecycleMarker(prefix, value) {
2430
+ try {
2431
+ const payload = typeof value === "number" ? String(value) : JSON.stringify(value);
2432
+ process.stdout.write(`${prefix}${payload}
2433
+ `);
2434
+ } catch {
2435
+ }
2436
+ }
2437
+ function createProviderOutputForwarder(enabled) {
2438
+ if (!enabled) {
2439
+ return { close: () => {
2440
+ } };
2441
+ }
2442
+ const resultStreamer = new ResultStreamer();
2443
+ const listener = (event) => {
2444
+ try {
2445
+ process.stdout.write(`${PROVIDER_OUTPUT_WORKER_EVENT_PREFIX}${JSON.stringify(event)}
2446
+ `);
2447
+ } catch {
2448
+ }
2449
+ };
2450
+ const activityListener = (event) => {
2451
+ try {
2452
+ process.stdout.write(`${PROVIDER_ACTIVITY_WORKER_EVENT_PREFIX}${JSON.stringify(event)}
2453
+ `);
2454
+ } catch {
2455
+ }
2456
+ };
2457
+ resultStreamer.on("providerOutput", listener);
2458
+ resultStreamer.on("providerActivity", activityListener);
2459
+ return {
2460
+ resultStreamer,
2461
+ close: () => {
2462
+ resultStreamer.off("providerOutput", listener);
2463
+ resultStreamer.off("providerActivity", activityListener);
2464
+ resultStreamer.close();
2465
+ }
2466
+ };
2467
+ }
2468
+ async function tryLoadPackageJsonScripts(repoRoot) {
2469
+ try {
2470
+ const raw = await fs2.readFile(path2.join(repoRoot, "package.json"), "utf-8");
2471
+ const parsed = JSON.parse(raw);
2472
+ const scripts = parsed.scripts && typeof parsed.scripts === "object" ? parsed.scripts : {};
2473
+ return new Set(Object.keys(scripts));
2474
+ } catch {
2475
+ return void 0;
2476
+ }
2477
+ }
2478
+ function extractOriginalPrompt(fullPrompt) {
2479
+ const parts = fullPrompt.split(/\n\n---\n\n/);
2480
+ const first = parts[0];
2481
+ if (first?.trimStart().startsWith("[SPEC:") && parts.length > 1) {
2482
+ return parts.slice(1).join("\n\n---\n\n").trim();
2483
+ }
2484
+ return (first ?? fullPrompt).trim();
2485
+ }
2486
+ function toBaselineComparisonResult(comparison) {
2487
+ return {
2488
+ verdict: comparison.verdict,
2489
+ summary: comparison.summary,
2490
+ baselineRef: comparison.baselineRef,
2491
+ tests: {
2492
+ newFailures: comparison.tests.newFailures,
2493
+ fixedIssues: comparison.tests.fixedIssues,
2494
+ persistingIssues: comparison.tests.persistingIssues
2495
+ },
2496
+ types: {
2497
+ newFailures: comparison.types.newFailures,
2498
+ fixedIssues: comparison.types.fixedIssues,
2499
+ persistingIssues: comparison.types.persistingIssues
2500
+ },
2501
+ lint: {
2502
+ newFailures: comparison.lint.newFailures,
2503
+ fixedIssues: comparison.lint.fixedIssues,
2504
+ persistingIssues: comparison.lint.persistingIssues
2505
+ }
2506
+ };
2507
+ }
2508
+ function shouldTrustVerificationLoopBaseline(result) {
2509
+ const loop = result.verificationLoop;
2510
+ const last = latestVerificationIteration(loop);
2511
+ if (hasVerifiedTouchedTestFailure(result) && !repairOutcomeCanSupersedeRawTouchedFailure(result)) {
2512
+ return false;
2513
+ }
2514
+ return loop?.enabled === true && loop.passed === true && loop.passedBaseline === true && (last?.newIssueCount ?? 0) === 0;
2515
+ }
2516
+ function isValidationArtifactOnlyPrompt(prompt) {
2517
+ const hasValidationOnlyDirective = /\bvalidation(?:\s+run)?\s+only\b/i.test(prompt);
2518
+ const targetsValidationArtifact = /\bvalidation\s+artifact\b/i.test(prompt) || hasValidationArtifactTarget(prompt);
2519
+ const forbidsOtherFileChanges = /\b(?:do\s+not|don't)\s+modify\s+(?:any\s+)?other\s+files\b/i.test(prompt) || /\bmodify\s+no\s+other\s+files\b/i.test(prompt);
2520
+ return hasValidationOnlyDirective && targetsValidationArtifact && forbidsOtherFileChanges;
2521
+ }
2522
+ async function isValidationArtifactOnlyDiffSatisfied(input) {
2523
+ if (!input.worktreePath || !isValidationArtifactOnlyPrompt(input.prompt)) return false;
2524
+ try {
2525
+ const summary = await getGitChangeSummary(input.worktreePath, input.baselineRef, true);
2526
+ return summary.changedPaths.length > 0 && summary.changedPaths.every((changedPath) => isValidationArtifactEntry(changedPath));
2527
+ } catch {
2528
+ return false;
2529
+ }
2530
+ }
2531
+ async function resolveInitialVerificationDisposition(result, runFallbackVerification) {
2532
+ const dispositionOf = (fresh = false) => getVerificationResult({
2533
+ ...result,
2534
+ ...fresh ? { outcome: void 0 } : {},
2535
+ offScopeGateConfig: void 0
2536
+ });
2537
+ const provider = dispositionOf();
2538
+ if (provider.outcome !== "passed" || result.verificationLoop) return provider;
2539
+ await runFallbackVerification();
2540
+ const observed = dispositionOf(true);
2541
+ return observed.outcome === "failed" ? observed : provider;
2542
+ }
2543
+ function decideRepairAdmission(input) {
2544
+ const baseEvidence = {
2545
+ ...input.initialVerificationOutcome ? { initialVerificationOutcome: input.initialVerificationOutcome } : {},
2546
+ hasMissingFileTargets: input.hasMissingFileTargets,
2547
+ isClarifyingNoOp: input.isClarifyingNoOp,
2548
+ providerExecutionSucceeded: input.providerExecutionSucceeded,
2549
+ hasMaterializedDeliverable: input.hasMaterializedDeliverable,
2550
+ validationArtifactSatisfied: input.validationArtifactSatisfied,
2551
+ filesChanged: input.filesChanged
2552
+ };
2553
+ if (!input.repairLoopEnabled) {
2554
+ return {
2555
+ action: "skip",
2556
+ reason: "skip_disabled",
2557
+ summary: "Repair loop disabled",
2558
+ ...baseEvidence
2559
+ };
2560
+ }
2561
+ if (input.isAnalysisIntent) {
2562
+ return {
2563
+ action: "skip",
2564
+ reason: "skip_analysis_intent",
2565
+ summary: "Skipped repair loop for analysis intent",
2566
+ ...baseEvidence
2567
+ };
2568
+ }
2569
+ if (!input.hasRetainedWorktree || !input.hasBaselineRef) {
2570
+ return {
2571
+ action: "skip",
2572
+ reason: "skip_missing_worktree",
2573
+ summary: "Skipped repair loop because retained worktree or baseline ref is unavailable",
2574
+ ...baseEvidence
2575
+ };
2576
+ }
2577
+ if (!input.providerExecutionSucceeded) {
2578
+ return {
2579
+ action: "skip",
2580
+ reason: "skip_provider_failed",
2581
+ summary: "Skipped repair loop because provider execution failed",
2582
+ ...baseEvidence
2583
+ };
2584
+ }
2585
+ if (!input.hasMaterializedDeliverable) {
2586
+ return {
2587
+ action: "skip",
2588
+ reason: "skip_no_deliverable",
2589
+ summary: "Skipped repair loop because provider produced no materialized deliverable",
2590
+ ...baseEvidence
2591
+ };
2592
+ }
2593
+ if (input.validationArtifactSatisfied === true) {
2594
+ return {
2595
+ action: "skip",
2596
+ reason: "skip_validation_artifact_satisfied",
2597
+ summary: "Skipped repair loop because validation artifact target is already satisfied",
2598
+ ...baseEvidence
2599
+ };
2600
+ }
2601
+ if (input.providerGatesAlreadyPassed) {
2602
+ return {
2603
+ action: "skip",
2604
+ reason: "skip_passing_gates",
2605
+ summary: "Skipped repair loop: provider verification already passed",
2606
+ ...baseEvidence
2607
+ };
2608
+ }
2609
+ if (input.verificationUnavailable) {
2610
+ return {
2611
+ action: "skip",
2612
+ reason: "skip_verification_unavailable",
2613
+ summary: "Skipped repair loop: verification is unavailable in this environment",
2614
+ ...baseEvidence
2615
+ };
2616
+ }
2617
+ if (input.hasMissingFileTargets && input.isClarifyingNoOp) {
2618
+ return {
2619
+ action: "skip",
2620
+ reason: "skip_clarifying_noop",
2621
+ summary: "Skipped repair loop: missing FILE targets + clarifying no-op response",
2622
+ ...baseEvidence
2623
+ };
2624
+ }
2625
+ return {
2626
+ action: "run",
2627
+ reason: "run_gate_failure",
2628
+ summary: "Repair loop admitted for deterministic gate failure",
2629
+ ...baseEvidence
2630
+ };
2631
+ }
2632
+ function repairPolicyCompletionMode() {
2633
+ const raw = readEnv(BUILD_COMPLETION_MODE).value;
2634
+ return raw === "branch" || raw === "pr" || raw === "isolated" ? raw : "isolated";
2635
+ }
2636
+ function isOffScopeRepairOverrideEnabled() {
2637
+ return readEnv(BUILD_ALLOW_OFF_SCOPE_REPAIR).value === true;
2638
+ }
2639
+ function resolveRepairPromotionPolicy(input) {
2640
+ const outsideFiles = input.repairDelta?.filesOutsidePreRepairDiff ?? [];
2641
+ const mechanicalFiles = new Set(input.repairDelta?.mechanicalAllowlistMatches ?? []);
2642
+ const strictScopeExpansion = input.scopePolicy === "strict" && outsideFiles.some((file) => !mechanicalFiles.has(file));
2643
+ const classificationForPolicy = strictScopeExpansion && input.classification !== "off_scope" ? "off_scope" : input.classification;
2644
+ const policy = resolveRepairArtifactPolicy({
2645
+ classification: classificationForPolicy,
2646
+ effectiveMode: input.effectiveMode,
2647
+ allowOffScopeRepair: input.allowOffScopeRepair
2648
+ });
2649
+ return strictScopeExpansion ? {
2650
+ ...policy,
2651
+ reason: `${policy.reason}; strict repair scope forbids non-mechanical files outside the provider diff`
2652
+ } : policy;
2653
+ }
2654
+ async function readWorktreeHeadCommit(worktreePath) {
2655
+ const head = await execa3("git", ["rev-parse", "HEAD"], {
2656
+ cwd: worktreePath,
2657
+ stdio: "pipe",
2658
+ reject: false
2659
+ });
2660
+ if ((head.exitCode ?? 1) !== 0) return void 0;
2661
+ const commit = String(head.stdout ?? "").trim();
2662
+ return commit.length > 0 ? commit : void 0;
2663
+ }
2664
+ async function captureRepairDiffSnapshot(worktreePath, baselineRef) {
2665
+ try {
2666
+ const [commit, diff] = await Promise.all([
2667
+ readWorktreeHeadCommit(worktreePath),
2668
+ captureWorktreeDiff(worktreePath, baselineRef, true)
2669
+ ]);
2670
+ return buildRepairDiffSnapshot(diff, commit);
2671
+ } catch {
2672
+ return void 0;
2673
+ }
2674
+ }
2675
+ function buildRepairTriggerEvidence(repairOutcome) {
2676
+ const firstIteration = repairOutcome.verificationLoop?.iterations?.[0];
2677
+ const stopReason = typeof repairOutcome.verificationLoop?.stopReason === "string" ? repairOutcome.verificationLoop.stopReason : void 0;
2678
+ if (!firstIteration) {
2679
+ return {
2680
+ type: "unknown",
2681
+ gateId: "verification-loop",
2682
+ summary: stopReason ? `Verification-driven repair loop recorded no iterations; stopReason=${stopReason}` : "Verification-driven repair loop recorded no iterations"
2683
+ };
2684
+ }
2685
+ const failedGate = firstIteration.build?.status !== "passed" ? "build" : firstIteration.lint && firstIteration.lint.status !== "passed" ? "lint" : firstIteration.tests && firstIteration.tests.status !== "passed" ? "test" : void 0;
2686
+ if (!failedGate) {
2687
+ return {
2688
+ type: "policy",
2689
+ gateId: "verification-loop",
2690
+ summary: stopReason ? `Verification policy ran without an initial gate failure; stopReason=${stopReason}` : "Verification policy ran without an initial gate failure"
2691
+ };
2692
+ }
2693
+ const failedConstraintCheck = firstIteration.build?.command === "constraint-check" || firstIteration.lint?.command === "constraint-check" || firstIteration.tests?.command === "constraint-check";
2694
+ if (failedConstraintCheck) {
2695
+ return {
2696
+ type: "policy",
2697
+ gateId: "constraint-check",
2698
+ summary: stopReason ? `Verification repair was triggered by policy constraint failure; stopReason=${stopReason}` : "Verification repair was triggered by policy constraint failure"
2699
+ };
2700
+ }
2701
+ return {
2702
+ type: "gate_failure",
2703
+ gateId: failedGate,
2704
+ summary: stopReason ? `Verification repair was triggered by initial ${failedGate} gate failure; stopReason=${stopReason}` : `Verification repair was triggered by initial ${failedGate} gate failure`
2705
+ };
2706
+ }
2707
+ async function taskScopedChangedFiles(worktreePath, baselineRef) {
2708
+ try {
2709
+ const diff = await captureWorktreeDiff(worktreePath, baselineRef, true);
2710
+ if (!diff || diff.trim().length === 0) return [];
2711
+ return extractChangedFilesMeta(diff).map((meta) => meta.path).filter(Boolean);
2712
+ } catch {
2713
+ return [];
2714
+ }
2715
+ }
2716
+ function coerceComparisonGateStatus(status) {
2717
+ switch (status) {
2718
+ case "passed":
2719
+ case "failed":
2720
+ case "skipped":
2721
+ case "timeout":
2722
+ case "error":
2723
+ case "unavailable":
2724
+ case "not_run":
2725
+ return status;
2726
+ default:
2727
+ return void 0;
2728
+ }
2729
+ }
2730
+ function statusFromExitCode(exitCode) {
2731
+ return exitCode === 0 ? "passed" : "failed";
2732
+ }
2733
+ function toGateArtifactStatus(status) {
2734
+ return status === "not_run" ? "skipped" : status;
2735
+ }
2736
+ function verificationBaselineCacheDir() {
2737
+ return path2.join(resolveBuildDirFromContext(), "cache", "verification-baseline");
2738
+ }
2739
+ async function attachBaselineComparisonIfAvailable(result) {
2740
+ const baselineRef = typeof result.baselineRef === "string" ? result.baselineRef.trim() : "";
2741
+ if (!baselineRef) return;
2742
+ const last = latestVerificationIteration(result.verificationLoop);
2743
+ if (!last) return;
2744
+ if (shouldTrustVerificationLoopBaseline(result)) {
2745
+ result.baselineComparison = trustedLoopBaselineComparison(baselineRef, last);
2746
+ return;
2747
+ }
2748
+ const repoRoot = process.cwd();
2749
+ const cacheDir = verificationBaselineCacheDir();
2750
+ const changedFiles = typeof result.worktreeDiff === "string" && result.worktreeDiff.trim().length > 0 ? extractChangedFilesMeta(result.worktreeDiff).map((meta) => meta.path).filter(Boolean) : [];
2751
+ const baseline = await getOrCaptureVerificationBaseline({
2752
+ repoRoot,
2753
+ baselineRef,
2754
+ cacheDir,
2755
+ captureOptions: { changedFiles }
2756
+ });
2757
+ if (!baseline.metadata?.captureSucceeded) return;
2758
+ const currentArtifacts = {
2759
+ build: {
2760
+ exitCode: last.build.exitCode,
2761
+ outputTail: last.build.outputTail,
2762
+ command: last.build.command,
2763
+ durationMs: 0,
2764
+ stdoutTail: "",
2765
+ stderrTail: "",
2766
+ language: last.build.language,
2767
+ status: toGateArtifactStatus(
2768
+ coerceComparisonGateStatus(last.build.status) ?? statusFromExitCode(last.build.exitCode)
2769
+ )
2770
+ },
2771
+ lint: last.lint ? {
2772
+ exitCode: last.lint.exitCode,
2773
+ outputTail: last.lint.outputTail,
2774
+ command: last.lint.command,
2775
+ durationMs: 0,
2776
+ language: last.lint.language,
2777
+ status: toGateArtifactStatus(
2778
+ coerceComparisonGateStatus(last.lint.status) ?? statusFromExitCode(last.lint.exitCode)
2779
+ )
2780
+ } : void 0,
2781
+ tests: last.tests ? {
2782
+ exitCode: last.tests.exitCode,
2783
+ status: toGateArtifactStatus(
2784
+ coerceComparisonGateStatus(last.tests.status) ?? statusFromExitCode(last.tests.exitCode)
2785
+ ),
2786
+ failingTests: last.tests.failingTests,
2787
+ failingTestIdentities: last.tests.failingTestIdentities,
2788
+ outputTail: last.tests.outputTail,
2789
+ command: last.tests.command,
2790
+ durationMs: 0,
2791
+ language: last.tests.language
2792
+ } : void 0
2793
+ };
2794
+ const currentOutcomes = verificationOutcomesFromGateArtifacts(currentArtifacts, {
2795
+ cwd: repoRoot,
2796
+ source: "variant-worker"
2797
+ });
2798
+ const stableComparison = compareVerificationOutcomeToBaseline(baseline, currentOutcomes);
2799
+ result.baselineComparison = markLintIdenticalToBase(
2800
+ toBaselineComparisonResult(stableComparisonToBaselineComparison(stableComparison)),
2801
+ // Per-command lint results, so a lint gate of several commands is never matched.
2802
+ channelsFailingIdenticallyOnBase(
2803
+ baseline,
2804
+ {
2805
+ ...currentArtifacts,
2806
+ lint: currentArtifacts.lint && {
2807
+ ...currentArtifacts.lint,
2808
+ // The loop records the gate as run; its stored type lags the per-command field.
2809
+ commandResults: last.lint?.commandResults
2810
+ }
2811
+ },
2812
+ ["lint"],
2813
+ [repoRoot]
2814
+ )
2815
+ );
2816
+ }
2817
+ async function applyRegistryDowngradeIfApplicable(result) {
2818
+ const comparison = result.baselineComparison;
2819
+ if (!comparison || comparison.summary.shouldPenalize !== true) return;
2820
+ const testNewFailures = comparison.tests?.newFailures ?? [];
2821
+ if (testNewFailures.length === 0) return;
2822
+ if ((comparison.types?.newFailures?.length ?? 0) > 0) return;
2823
+ if ((comparison.lint?.newFailures?.length ?? 0) > 0) return;
2824
+ const last = latestVerificationIteration(result.verificationLoop);
2825
+ const testOutputTail = last?.tests?.outputTail ?? "";
2826
+ const registry = await loadKnownPreExistingFailures(process.cwd());
2827
+ const baselineRef = (result.baselineRef ?? comparison.baselineRef)?.trim().toLowerCase();
2828
+ const registryBaseCommit = registry.baseCommit?.trim().toLowerCase();
2829
+ const MIN_SHA_PREFIX_LEN = 7;
2830
+ if (!baselineRef || !registryBaseCommit || baselineRef.length < MIN_SHA_PREFIX_LEN || registryBaseCommit.length < MIN_SHA_PREFIX_LEN || !baselineRef.startsWith(registryBaseCommit) && !registryBaseCommit.startsWith(baselineRef)) {
2831
+ return;
2832
+ }
2833
+ if (!allFailuresAreRegistered(testNewFailures, registry, testOutputTail)) {
2834
+ return;
2835
+ }
2836
+ applyKnownFailureDowngrade(comparison, testNewFailures.length);
2837
+ const matchedNames = testNewFailures.join(", ");
2838
+ process.stderr.write(
2839
+ `[build:registry] Downgraded shouldPenalize=true \u2192 false for ${testNewFailures.length} registered failure(s): ${matchedNames}
2840
+ `
2841
+ );
2842
+ }
2843
+ function getWarningCodes(result) {
2844
+ const warnings = result.warnings;
2845
+ if (!Array.isArray(warnings)) return /* @__PURE__ */ new Set();
2846
+ return new Set(
2847
+ warnings.map((w) => w?.code).filter((code) => typeof code === "string" && code.trim().length > 0)
2848
+ );
2849
+ }
2850
+ function looksLikeClarifyingQuestion(text) {
2851
+ const lower = text.toLowerCase();
2852
+ if (lower.includes("?")) return true;
2853
+ return /(\bdoes(?:n't| not)\s+exist\b|\bnot\s+found\b|\bcannot\s+find\b|\bcan't\s+find\b|\bcould\s+you\s+clarify\b|\bplease\s+clarify\b|\bwhich\s+file\b|\bwhat\s+file\b)/i.test(
2854
+ lower
2855
+ );
2856
+ }
2857
+ initializeLabModeFromEnv("initializing-worker");
2858
+ function formatElapsedRuntime(elapsedMs) {
2859
+ const totalSeconds = Math.max(0, Math.floor(elapsedMs / 1e3));
2860
+ const minutes = Math.floor(totalSeconds / 60);
2861
+ const seconds = totalSeconds % 60;
2862
+ return `${minutes}m ${seconds}s`;
2863
+ }
2864
+ async function runWithTimeout(promise, timeoutMs, label) {
2865
+ let timeoutHandle;
2866
+ try {
2867
+ return await Promise.race([
2868
+ promise,
2869
+ new Promise((_, reject) => {
2870
+ timeoutHandle = setTimeout(() => {
2871
+ reject(new Error(`${label} timed out after ${timeoutMs}ms`));
2872
+ }, timeoutMs);
2873
+ })
2874
+ ]);
2875
+ } finally {
2876
+ if (timeoutHandle) {
2877
+ clearTimeout(timeoutHandle);
2878
+ }
2879
+ }
2880
+ }
2881
+ function parseRepairLoopConfig() {
2882
+ const enabledEnv = process.env.BUILD_REPAIR_LOOP_ENABLED;
2883
+ const enabled = enabledEnv === "1";
2884
+ const maxIterationsRaw = Number(process.env.BUILD_REPAIR_LOOP_MAX_ITERATIONS);
2885
+ const maxIterations = Number.isFinite(maxIterationsRaw) && maxIterationsRaw > 0 ? maxIterationsRaw : DEFAULT_REPAIR_LOOP_MAX_ITERATIONS;
2886
+ const iterationTimeoutMsRaw = Number(process.env.BUILD_REPAIR_LOOP_ITERATION_TIMEOUT_MS);
2887
+ const iterationTimeoutMs = Number.isFinite(iterationTimeoutMsRaw) && iterationTimeoutMsRaw > 0 ? iterationTimeoutMsRaw : DEFAULT_REPAIR_LOOP_ITERATION_TIMEOUT_MS;
2888
+ const abortIfRegression = process.env.BUILD_REPAIR_LOOP_ABORT_IF_REGRESSION !== "0";
2889
+ const allowApiBreak = process.env.BUILD_ALLOW_API_BREAK === "1";
2890
+ const repairModeEnv = process.env.BUILD_REPAIR_MODE;
2891
+ const repairMode = repairModeEnv === "strict" || repairModeEnv === "none" || repairModeEnv === "auto" ? repairModeEnv : "auto";
2892
+ const scopePolicyEnv = process.env.BUILD_REPAIR_SCOPE_POLICY;
2893
+ const scopePolicy = scopePolicyEnv === "expand" ? "expand" : "strict";
2894
+ const saveModesEnv = process.env.BUILD_REPAIR_SAVE_MODES;
2895
+ const repairSaveModes = (saveModesEnv?.trim().length ? saveModesEnv : "patch").split(",").map((m) => m.trim()).filter(Boolean).filter((m) => m === "patch" || m === "ref" || m === "branch");
2896
+ const normalizedRepairSaveModes = repairSaveModes.length > 0 ? repairSaveModes : ["patch"];
2897
+ return {
2898
+ enabled,
2899
+ maxIterations,
2900
+ iterationTimeoutMs,
2901
+ abortIfRegression,
2902
+ allowApiBreak,
2903
+ repairMode,
2904
+ scopePolicy,
2905
+ repairSaveModes: [...normalizedRepairSaveModes]
2906
+ };
2907
+ }
2908
+ async function tryCleanupRetainedWorktree(worktreePath, verbose) {
2909
+ const normalized = path2.resolve(worktreePath);
2910
+ const buildRoot = resolveBuildRoot();
2911
+ const allowedRoots = [
2912
+ path2.resolve(getWorktreeBaseDir(buildRoot)),
2913
+ path2.resolve(buildRoot, ".build-project", "tmp", "worktrees"),
2914
+ path2.resolve(buildRoot, "build-worktrees"),
2915
+ path2.join("/tmp", "build-worktrees"),
2916
+ path2.join(process.env.TMPDIR ?? "/tmp", "build-worktrees")
2917
+ ];
2918
+ const allowed = allowedRoots.some((root) => {
2919
+ const rootWithSep = root.endsWith(path2.sep) ? root : `${root}${path2.sep}`;
2920
+ return normalized === root || normalized.startsWith(rootWithSep);
2921
+ });
2922
+ if (!allowed) {
2923
+ if (verbose) {
2924
+ console.warn(
2925
+ chalk.yellow(`Refusing to cleanup retained worktree outside known roots: ${worktreePath}`)
2926
+ );
2927
+ }
2928
+ return;
2929
+ }
2930
+ try {
2931
+ await execa3("git", ["worktree", "remove", "--force", normalized], {
2932
+ cwd: buildRoot,
2933
+ stdio: "pipe",
2934
+ timeout: 3e4,
2935
+ reject: false
2936
+ });
2937
+ } catch (error) {
2938
+ if (verbose) {
2939
+ const msg = error instanceof Error ? error.message : String(error);
2940
+ console.warn(chalk.yellow(`Failed to cleanup retained worktree: ${msg}`));
2941
+ }
2942
+ }
2943
+ }
2944
+ async function ensureGitMetrics(result) {
2945
+ if (result.gitMetrics) return;
2946
+ const worktreePath = result.retainedWorktreePath;
2947
+ if (worktreePath) {
2948
+ const summary = await getGitChangeSummary(worktreePath, result.baselineRef, true);
2949
+ if (summary.filesChanged > 0) {
2950
+ result.gitMetrics = {
2951
+ filesChanged: summary.filesChanged,
2952
+ linesAdded: summary.linesAdded,
2953
+ linesDeleted: summary.linesRemoved,
2954
+ source: summary.source === "fallback" ? "unknown" : "worktree"
2955
+ };
2956
+ return;
2957
+ }
2958
+ }
2959
+ if (result.worktreeSummary) {
2960
+ result.gitMetrics = {
2961
+ filesChanged: result.worktreeSummary.filesChanged,
2962
+ linesAdded: result.worktreeSummary.insertions,
2963
+ linesDeleted: result.worktreeSummary.deletions,
2964
+ source: "unknown"
2965
+ };
2966
+ }
2967
+ }
2968
+ async function findVariantWorktreePathForTimeout(taskId, variant, repoRoot) {
2969
+ try {
2970
+ const listResult = await execa3("git", ["worktree", "list", "--porcelain"], {
2971
+ cwd: repoRoot,
2972
+ reject: false,
2973
+ timeout: PARTIAL_GIT_TIMEOUT_MS
2974
+ });
2975
+ if ((listResult.exitCode ?? 0) !== 0 || !listResult.stdout?.trim()) {
2976
+ return void 0;
2977
+ }
2978
+ const expectedBranch = generateBranchName(taskId, variant);
2979
+ return parseGitWorktreeBranches(listResult.stdout).find(
2980
+ (entry) => entry.branch === expectedBranch
2981
+ )?.path;
2982
+ } catch {
2983
+ return void 0;
2984
+ }
2985
+ }
2986
+ async function main() {
2987
+ const program = new Command();
2988
+ program.name("variant-worker").description("Execute a single variant task and write result to file").requiredOption("--task-id <id>", "Task identifier").requiredOption("--variant <json>", "Variant configuration as JSON string").requiredOption("--prompt-file <path>", "Path to file containing prompt text").option(
2989
+ "--original-task-file <path>",
2990
+ "Path to file containing the original task text before prompt injection"
2991
+ ).requiredOption("--result-file <path>", "Path to write result JSON").option(
2992
+ "--partial-result-file <path>",
2993
+ "Path to write timeout-partial result JSON (best-effort)"
2994
+ ).option("--timeout-minutes <minutes>", "Execution timeout in minutes", parseFloat).option("--deadline-at <epochMs>", "Absolute provider deadline (epoch ms)", parseFloat).option(
2995
+ "--idle-warn-minutes <minutes>",
2996
+ "Provider idle warning threshold in minutes",
2997
+ parseFloat
2998
+ ).option("--idle-kill-minutes <minutes>", "Provider idle stop threshold in minutes", parseFloat).option("--verbose", "Enable verbose logging", false).action(async (options) => {
2999
+ await executeWorker(options);
3000
+ });
3001
+ await program.parseAsync(process.argv);
3002
+ }
3003
+ async function warnOnce(message, state) {
3004
+ if (state.warned) return;
3005
+ state.warned = true;
3006
+ console.log(chalk.yellow(message));
3007
+ }
3008
+ var RESULT_PERSISTENCE_PATH_KEYS = /* @__PURE__ */ new Set([
3009
+ "artifactManifest",
3010
+ "resultFile",
3011
+ "resultPath",
3012
+ "retainedWorktreePath",
3013
+ "worktreePath"
3014
+ ]);
3015
+ function shouldPreserveResultPersistenceString(key) {
3016
+ return key !== void 0 && RESULT_PERSISTENCE_PATH_KEYS.has(key);
3017
+ }
3018
+ function serializeErrorForJson(error) {
3019
+ if (error instanceof Error) {
3020
+ const sanitized = sanitizeError(error);
3021
+ const serialized = {
3022
+ name: sanitized.name,
3023
+ message: sanitized.message,
3024
+ stack: sanitized.stack
3025
+ };
3026
+ if (error instanceof HostTimeoutError) {
3027
+ serialized.reason = "timeout";
3028
+ serialized.limitMs = error.limitMs;
3029
+ serialized.source = error.source;
3030
+ serialized.parsedError = createHostTerminationParsedError("timeout", sanitized.message, {
3031
+ limitMs: error.limitMs
3032
+ });
3033
+ }
3034
+ if (error instanceof ProviderExecutionError) {
3035
+ serialized.code = error.code;
3036
+ serialized.reason = sanitizeSynthesisArtifactForPersistence(error.reason);
3037
+ serialized.retryable = error.retryable;
3038
+ serialized.exitCode = error.exitCode;
3039
+ serialized.statusCode = error.statusCode;
3040
+ serialized.idleTerminated = error.idleTerminated;
3041
+ serialized.signal = sanitizeSynthesisArtifactForPersistence(error.signal);
3042
+ serialized.terminationSource = sanitizeSynthesisArtifactForPersistence(
3043
+ error.terminationSource
3044
+ );
3045
+ serialized.context = sanitizeSynthesisArtifactForPersistence(error.context);
3046
+ serialized.parsedError = sanitizeSynthesisArtifactForPersistence(error.parsedError);
3047
+ }
3048
+ return serialized;
3049
+ }
3050
+ return sanitizeSynthesisArtifactForPersistence(error);
3051
+ }
3052
+ function sanitizeResultPayloadForJson(value, seen = /* @__PURE__ */ new WeakSet(), key = void 0) {
3053
+ if (value instanceof Error) {
3054
+ return serializeErrorForJson(value);
3055
+ }
3056
+ if (typeof value === "string") {
3057
+ return shouldPreserveResultPersistenceString(key) ? value : sanitizeSynthesisStringForPersistence(value);
3058
+ }
3059
+ if (typeof value === "number") {
3060
+ return Number.isFinite(value) ? value : null;
3061
+ }
3062
+ if (typeof value === "boolean" || value === null) {
3063
+ return value;
3064
+ }
3065
+ if (typeof value === "bigint") {
3066
+ return value.toString();
3067
+ }
3068
+ if (typeof value === "symbol" || typeof value === "function" || value === void 0) {
3069
+ return void 0;
3070
+ }
3071
+ if (value instanceof Date) {
3072
+ return value.toISOString();
3073
+ }
3074
+ if (seen.has(value)) {
3075
+ return "[Circular]";
3076
+ }
3077
+ seen.add(value);
3078
+ try {
3079
+ if (Array.isArray(value)) {
3080
+ return value.map((entry) => sanitizeResultPayloadForJson(entry, seen, key));
3081
+ }
3082
+ const sanitized = {};
3083
+ for (const [entryKey, entry] of Object.entries(value)) {
3084
+ const sanitizedEntry = entryKey === "error" ? serializeErrorForJson(entry) : sanitizeResultPayloadForJson(entry, seen, entryKey);
3085
+ const finalValue = isSensitiveKey(entryKey) ? "[REDACTED]" : sanitizedEntry;
3086
+ if (finalValue !== void 0) {
3087
+ sanitized[entryKey] = finalValue;
3088
+ }
3089
+ }
3090
+ const original = value;
3091
+ if (typeof original.worktreeDiff === "string") {
3092
+ sanitized.worktreeDiffReplayable = original.worktreeDiffReplayable !== false && sanitized.worktreeDiff === original.worktreeDiff;
3093
+ }
3094
+ return sanitized;
3095
+ } finally {
3096
+ seen.delete(value);
3097
+ }
3098
+ }
3099
+ async function writeResultFileAtomically(resultPath, payload) {
3100
+ const resultJson = JSON.stringify(sanitizeResultPayloadForJson(payload), null, 2);
3101
+ const tmpFile = `${resultPath}.tmp.${randomBytes(4).toString("hex")}`;
3102
+ await fs2.writeFile(tmpFile, resultJson, "utf-8");
3103
+ const fd = openSync(tmpFile, "r+");
3104
+ try {
3105
+ fsyncSync(fd);
3106
+ } finally {
3107
+ closeSync(fd);
3108
+ }
3109
+ await fs2.rename(tmpFile, resultPath);
3110
+ }
3111
+ var __testOnlyWriteResultFileAtomically = writeResultFileAtomically;
3112
+ function formatVerboseWorkerCompletionMetric(result) {
3113
+ return `Completeness: ${result.completeness.toFixed(1)}%`;
3114
+ }
3115
+ function initializeWorkerExecutionContext(taskId) {
3116
+ const inheritedBuildDir = readEnv(BUILD_TELEMETRY_DIR).value?.trim();
3117
+ if (!inheritedBuildDir) return;
3118
+ setExecutionContext(
3119
+ createExecutionContext({
3120
+ repoRoot: resolveCliRepoRoot(process.cwd()),
3121
+ buildDir: inheritedBuildDir,
3122
+ taskId
3123
+ })
3124
+ );
3125
+ }
3126
+ async function executeWorker(options) {
3127
+ const {
3128
+ taskId,
3129
+ variant: variantJson,
3130
+ promptFile,
3131
+ originalTaskFile,
3132
+ resultFile,
3133
+ timeoutMinutes,
3134
+ deadlineAt,
3135
+ idleWarnMinutes,
3136
+ idleKillMinutes,
3137
+ verbose
3138
+ } = options;
3139
+ const repairLoopConfig = parseRepairLoopConfig();
3140
+ if (idleWarnMinutes == null !== (idleKillMinutes == null)) {
3141
+ throw new Error("--idle-warn-minutes and --idle-kill-minutes must be provided together");
3142
+ }
3143
+ initializeWorkerExecutionContext(taskId);
3144
+ initializeLabModeFromEnv(taskId);
3145
+ if (verbose) {
3146
+ console.log(chalk.blue("Variant Worker starting"));
3147
+ console.log(chalk.gray(` Task ID: ${taskId}`));
3148
+ console.log(chalk.gray(` Prompt: ${promptFile}`));
3149
+ console.log(chalk.gray(` Result: ${resultFile}`));
3150
+ console.log(
3151
+ chalk.gray(` Partial Result: ${options.partialResultFile ?? `${resultFile}.partial.json`}`)
3152
+ );
3153
+ }
3154
+ let variant;
3155
+ try {
3156
+ variant = parseJsonWithContext(
3157
+ variantJson,
3158
+ "[Variant Worker] variant configuration"
3159
+ );
3160
+ } catch (error) {
3161
+ throw new Error(
3162
+ `Invalid variant JSON: ${error instanceof Error ? error.message : String(error)}`
3163
+ );
3164
+ }
3165
+ const workerProcessLifecycle = new ProcessLifecycleManager({
3166
+ verbose: verbose === true,
3167
+ defaultTimeoutMinutes: timeoutMinutes ?? DEFAULT_PER_VARIANT_TIMEOUT_MINUTES,
3168
+ maxConcurrentProcesses: 10,
3169
+ cleanupOnTermination: true
3170
+ });
3171
+ setProcessLifecycleManager(workerProcessLifecycle);
3172
+ const processLifecycleSignalHandlerName = "variant-worker-process-lifecycle";
3173
+ const signalHandlerName = "variant-worker-timeout-partial-result";
3174
+ let postProviderSignalHandlersInstalled = false;
3175
+ const onPostProviderSigterm = () => {
3176
+ void postProviderShutdown?.("SIGTERM");
3177
+ };
3178
+ const onPostProviderSigint = () => {
3179
+ void postProviderShutdown?.("SIGINT");
3180
+ };
3181
+ let postProviderShutdown;
3182
+ const installPostProviderSignalHandlers = () => {
3183
+ if (postProviderSignalHandlersInstalled) return;
3184
+ signalCoordinator.suspendProcessSignalHandlers();
3185
+ process.on("SIGTERM", onPostProviderSigterm);
3186
+ process.on("SIGINT", onPostProviderSigint);
3187
+ postProviderSignalHandlersInstalled = true;
3188
+ };
3189
+ const uninstallPostProviderSignalHandlers = () => {
3190
+ if (!postProviderSignalHandlersInstalled) return;
3191
+ process.removeListener("SIGTERM", onPostProviderSigterm);
3192
+ process.removeListener("SIGINT", onPostProviderSigint);
3193
+ signalCoordinator.resumeProcessSignalHandlers();
3194
+ postProviderSignalHandlersInstalled = false;
3195
+ };
3196
+ signalCoordinator.register(
3197
+ processLifecycleSignalHandlerName,
3198
+ async (context) => {
3199
+ if (context.reason === "SIGTERM" || context.reason === "SIGINT") {
3200
+ await workerProcessLifecycle.handleSignal(context.reason);
3201
+ return;
3202
+ }
3203
+ await workerProcessLifecycle.close();
3204
+ },
3205
+ { priority: "critical", phase: "process-termination" }
3206
+ );
3207
+ try {
3208
+ variant.nativeWebSearch = isNativeResearchEnabledFor(variant.provider);
3209
+ const runMode = variant.isBasicCompetition ? "basic-cli-native" : "advanced";
3210
+ const partialResultFile = typeof options.partialResultFile === "string" && options.partialResultFile.trim().length > 0 ? options.partialResultFile.trim() : `${resultFile}.partial.json`;
3211
+ const workerStartMs = Date.now();
3212
+ const startTime = process.hrtime.bigint();
3213
+ const timeoutContext = {};
3214
+ let executorSettled = false;
3215
+ const persistTimeoutPartialResult = async (signal = "SIGTERM") => {
3216
+ const cancelled = signal === "SIGINT";
3217
+ const stopVerb = cancelled ? "Cancelled" : "Timed out";
3218
+ const timeoutWorktreeCandidate = timeoutContext.worktreePath ?? variant.workflowWorktreePath;
3219
+ let timeoutWorktreePath = typeof timeoutWorktreeCandidate === "string" && timeoutWorktreeCandidate.trim().length > 0 ? timeoutWorktreeCandidate.trim() : void 0;
3220
+ if (!timeoutWorktreePath) {
3221
+ timeoutWorktreePath = await findVariantWorktreePathForTimeout(
3222
+ taskId,
3223
+ variant,
3224
+ process.cwd()
3225
+ );
3226
+ if (!timeoutWorktreePath && verbose) {
3227
+ console.warn("[partial-save] Worktree context unavailable; needle discovery also failed");
3228
+ }
3229
+ }
3230
+ const elapsedText = formatElapsedRuntime(Date.now() - workerStartMs);
3231
+ let filesChanged = 0;
3232
+ let linesAdded = 0;
3233
+ let linesRemoved = 0;
3234
+ let statusLines = [];
3235
+ let partialEdits = false;
3236
+ let autoCommitFailed = false;
3237
+ let worktreeDiff;
3238
+ let baselineRef = typeof timeoutContext.baselineRef === "string" && timeoutContext.baselineRef.trim().length > 0 ? timeoutContext.baselineRef.trim() : void 0;
3239
+ let partialErrorDetail;
3240
+ if (timeoutWorktreePath) {
3241
+ try {
3242
+ const canMutateWorktreeForSnapshot = executorSettled;
3243
+ if (canMutateWorktreeForSnapshot) {
3244
+ await stageCommitEligibleChanges(timeoutWorktreePath);
3245
+ } else {
3246
+ partialErrorDetail = "executor still running during timeout; skipped git add/commit partial snapshot";
3247
+ }
3248
+ const [cachedStat, cachedShortStat, statusResult] = await Promise.all([
3249
+ execa3(
3250
+ "git",
3251
+ canMutateWorktreeForSnapshot ? ["diff", "--cached", "--stat"] : ["diff", "--stat"],
3252
+ {
3253
+ cwd: timeoutWorktreePath,
3254
+ stdio: "pipe",
3255
+ reject: false,
3256
+ timeout: 1200
3257
+ }
3258
+ ),
3259
+ execa3(
3260
+ "git",
3261
+ canMutateWorktreeForSnapshot ? ["diff", "--cached", "--shortstat"] : ["diff", "--shortstat"],
3262
+ {
3263
+ cwd: timeoutWorktreePath,
3264
+ stdio: "pipe",
3265
+ reject: false,
3266
+ timeout: 1200
3267
+ }
3268
+ ),
3269
+ execa3("git", ["status", "--porcelain", "--untracked-files=all"], {
3270
+ cwd: timeoutWorktreePath,
3271
+ stdio: "pipe",
3272
+ reject: false,
3273
+ timeout: 1200
3274
+ })
3275
+ ]);
3276
+ partialEdits = cachedStat.stdout.trim().length > 0;
3277
+ const parsedShortStat = parseShortStatSummary(cachedShortStat.stdout);
3278
+ filesChanged = parsedShortStat.filesChanged;
3279
+ linesAdded = parsedShortStat.linesAdded;
3280
+ linesRemoved = parsedShortStat.linesRemoved;
3281
+ statusLines = statusResult.stdout.split("\n").map((line) => line.trimEnd()).filter((line) => line.trim().length > 0);
3282
+ if (partialEdits && filesChanged === 0 && statusLines.length > 0) {
3283
+ filesChanged = statusLines.length;
3284
+ }
3285
+ if (partialEdits && canMutateWorktreeForSnapshot) {
3286
+ const commitMessage = `chore: partial work (${cancelled ? "cancelled" : "timeout"} at ${elapsedText})`;
3287
+ const commit = await execa3("git", ["commit", "--no-verify", "-m", commitMessage], {
3288
+ cwd: timeoutWorktreePath,
3289
+ stdio: "pipe",
3290
+ reject: false,
3291
+ timeout: 1500
3292
+ });
3293
+ ({ autoCommitFailed, baselineRef } = await resolveTimeoutSnapshotCommit(
3294
+ commit,
3295
+ baselineRef,
3296
+ async () => {
3297
+ const parent = await execa3("git", ["rev-parse", "HEAD~1"], {
3298
+ cwd: timeoutWorktreePath,
3299
+ stdio: "pipe",
3300
+ reject: false,
3301
+ timeout: 1200
3302
+ });
3303
+ return parent.exitCode === 0 && parent.stdout.trim().length > 0 ? parent.stdout.trim() : void 0;
3304
+ }
3305
+ ));
3306
+ try {
3307
+ const diffText = await captureWorktreeDiff(timeoutWorktreePath, baselineRef, true);
3308
+ if (diffText.trim().length > 0) {
3309
+ worktreeDiff = normalizeWorktreeDiff(diffText);
3310
+ }
3311
+ } catch {
3312
+ }
3313
+ }
3314
+ } catch (error) {
3315
+ partialErrorDetail = error instanceof Error ? error.message : String(error);
3316
+ }
3317
+ }
3318
+ if (!partialErrorDetail && partialEdits) {
3319
+ if (autoCommitFailed) {
3320
+ partialErrorDetail = "auto-commit failed";
3321
+ }
3322
+ }
3323
+ const completeness = partialEdits ? estimateTimeoutCompletenessFromScope({
3324
+ filesChanged,
3325
+ linesAdded,
3326
+ linesRemoved,
3327
+ statusEntries: statusLines.length
3328
+ }) : 0;
3329
+ const timeoutErrorMessage = (() => {
3330
+ if (partialErrorDetail) {
3331
+ if (partialEdits && !autoCommitFailed) {
3332
+ return `${stopVerb} at ${elapsedText}; partial edits detected (preservation warning: ${partialErrorDetail})`;
3333
+ }
3334
+ if (partialEdits && autoCommitFailed) {
3335
+ return `${stopVerb} at ${elapsedText}; partial edits detected but auto-commit failed`;
3336
+ }
3337
+ return `${stopVerb} at ${elapsedText}; partial preservation warning: ${partialErrorDetail}`;
3338
+ }
3339
+ if (partialEdits) {
3340
+ return `${stopVerb} at ${elapsedText}; partial edits preserved`;
3341
+ }
3342
+ return `${stopVerb} at ${elapsedText}; no staged edits detected`;
3343
+ })();
3344
+ const partialResult = {
3345
+ variant: formatVariantIdentifier(variant),
3346
+ provider: variant.provider,
3347
+ model: variant.model,
3348
+ executionMode: variant.executionMode,
3349
+ success: false,
3350
+ duration: Number(process.hrtime.bigint() - startTime) / 1e9,
3351
+ completeness,
3352
+ timedOut: !cancelled,
3353
+ partialEdits,
3354
+ terminationReason: cancelled ? "canceled_user" : "timeout",
3355
+ executionIntent: variant.executionIntent,
3356
+ isBasicCompetition: variant.isBasicCompetition,
3357
+ emptyChanges: !partialEdits,
3358
+ filesChanged,
3359
+ linesAdded,
3360
+ linesRemoved,
3361
+ worktreeDiff,
3362
+ gitMetrics: partialEdits ? {
3363
+ filesChanged,
3364
+ linesAdded,
3365
+ linesDeleted: linesRemoved,
3366
+ source: "worktree"
3367
+ } : void 0,
3368
+ worktreeSummary: timeoutWorktreePath ? {
3369
+ filesChanged,
3370
+ insertions: linesAdded,
3371
+ deletions: linesRemoved,
3372
+ statusLines
3373
+ } : void 0,
3374
+ retainedWorktreePath: timeoutWorktreePath,
3375
+ baselineRef,
3376
+ error: cancelled ? new Error(timeoutErrorMessage) : new HostTimeoutError(timeoutErrorMessage, {
3377
+ source: VARIANT_WORKER_SIGTERM_SOURCE
3378
+ })
3379
+ };
3380
+ partialResult.outcome = deriveVariantOutcome(partialResult);
3381
+ sanitizeVariantResult(partialResult);
3382
+ await writeResultFileAtomically(partialResultFile, partialResult);
3383
+ };
3384
+ const executionAbortController = new AbortController();
3385
+ let shutdownRequested = false;
3386
+ let shutdownRequestedAtMs;
3387
+ let shutdownSignal;
3388
+ const signalExitCode = (signal) => signal === "SIGINT" ? 130 : 143;
3389
+ const requestShutdown = async (signal, options2) => {
3390
+ if (shutdownRequested) {
3391
+ return;
3392
+ }
3393
+ shutdownRequested = true;
3394
+ shutdownRequestedAtMs = elapsedMsSince(startTime);
3395
+ shutdownSignal = signal;
3396
+ if (signal === "SIGINT") {
3397
+ mergeExecutionContextEnvOverrides({ BUILD_PRESERVE_WORKTREES: "1" });
3398
+ }
3399
+ if (!executionAbortController.signal.aborted) {
3400
+ executionAbortController.abort(buildShutdownAbortReason(signal));
3401
+ }
3402
+ const exitAfter = options2?.exitAfter ?? true;
3403
+ try {
3404
+ if (verbose) {
3405
+ console.log(chalk.yellow(`Received ${signal}; beginning timeout shutdown handling.`));
3406
+ }
3407
+ try {
3408
+ await runWithTimeout(persistTimeoutPartialResult(signal), 2500, "partial result save");
3409
+ if (verbose) {
3410
+ console.log(chalk.gray(` Partial timeout result written to ${partialResultFile}`));
3411
+ }
3412
+ } catch (error) {
3413
+ if (verbose) {
3414
+ const message = error instanceof Error ? error.message : String(error);
3415
+ console.warn(chalk.yellow(`Partial timeout preservation skipped: ${message}`));
3416
+ }
3417
+ }
3418
+ if (exitAfter) {
3419
+ try {
3420
+ await runWithTimeout(
3421
+ signalCoordinator.runCleanupHandlers(`variant-worker ${signal.toLowerCase()}`, {
3422
+ timeoutMs: SIGNAL_CLEANUP_TIMEOUT_MS
3423
+ }),
3424
+ SIGNAL_CLEANUP_WRAPPER_TIMEOUT_MS,
3425
+ "signal cleanup"
3426
+ );
3427
+ } catch {
3428
+ }
3429
+ }
3430
+ } catch (shutdownError) {
3431
+ console.error(
3432
+ `[variant-worker] Shutdown error (${signal}): ${shutdownError instanceof Error ? shutdownError.message : String(shutdownError)}`
3433
+ );
3434
+ } finally {
3435
+ if (exitAfter) {
3436
+ process.exit(signalExitCode(signal));
3437
+ }
3438
+ }
3439
+ };
3440
+ postProviderShutdown = async (signal) => {
3441
+ await requestShutdown(signal, { exitAfter: false });
3442
+ };
3443
+ signalCoordinator.register(
3444
+ signalHandlerName,
3445
+ async (context) => {
3446
+ if (context.reason === "SIGTERM" || context.reason === "SIGINT") {
3447
+ await requestShutdown(context.reason, { exitAfter: false });
3448
+ }
3449
+ },
3450
+ { priority: "critical", phase: "artifact-cleanup" }
3451
+ );
3452
+ if (variant.executionMode !== "local") {
3453
+ throw new Error(`Worker only supports local execution mode (got: ${variant.executionMode})`);
3454
+ }
3455
+ let prompt;
3456
+ try {
3457
+ prompt = await fs2.readFile(promptFile, "utf-8");
3458
+ } catch (error) {
3459
+ throw new Error(
3460
+ `Failed to read prompt file: ${error instanceof Error ? error.message : String(error)}`
3461
+ );
3462
+ }
3463
+ if (verbose) {
3464
+ console.log(chalk.blue(`Loaded prompt (${prompt.length} chars)`));
3465
+ console.log(chalk.blue(`Executing ${formatVariantIdentifier(variant)}...`));
3466
+ }
3467
+ const repoRoot = process.cwd();
3468
+ const packageJsonScripts = await tryLoadPackageJsonScripts(repoRoot);
3469
+ let originalPrompt;
3470
+ if (originalTaskFile) {
3471
+ try {
3472
+ originalPrompt = await fs2.readFile(originalTaskFile, "utf-8");
3473
+ } catch (error) {
3474
+ throw new Error(
3475
+ `Failed to read original task file: ${error instanceof Error ? error.message : String(error)}`
3476
+ );
3477
+ }
3478
+ } else {
3479
+ originalPrompt = extractOriginalPrompt(prompt);
3480
+ }
3481
+ const specInjectionUsed = /\[SPEC:/.test(prompt);
3482
+ const specSignal = evaluateExecutionSpec(originalPrompt);
3483
+ let guidanceTier;
3484
+ let specQualitySignals;
3485
+ if (specSignal) {
3486
+ guidanceTier = specSignal.guidanceTier;
3487
+ specQualitySignals = generateSpecQualitySignals(originalPrompt, repoRoot, packageJsonScripts);
3488
+ }
3489
+ const classification = classifyTask(prompt, { stripInjections: true });
3490
+ let telemetry = null;
3491
+ let telemetryEnabled = true;
3492
+ const telemetryWarning = { warned: false };
3493
+ const costTrackerWarning = { warned: false };
3494
+ const applyWorkerEnvOverrides = (overrides) => {
3495
+ mergeExecutionContextEnvOverrides(overrides);
3496
+ };
3497
+ const prevRetainBasicWorktree = getRuntimeEnv("BUILD_RETAIN_BASIC_WORKTREE");
3498
+ const prevPreserveWorktrees = getRuntimeEnv("BUILD_PRESERVE_WORKTREES");
3499
+ const preserveWorktreesForDebug = prevRetainBasicWorktree === "1" && getRuntimeEnv("BUILD_PRESERVE_WORKTREES") !== "1";
3500
+ if (preserveWorktreesForDebug) {
3501
+ applyWorkerEnvOverrides({ BUILD_PRESERVE_WORKTREES: "1" });
3502
+ }
3503
+ try {
3504
+ telemetry = TelemetryLogger.getInstance();
3505
+ telemetry.logVariantEvent(taskId, formatVariantIdentifier(variant), "started", {
3506
+ provider: variant.provider,
3507
+ model: variant.model,
3508
+ executionMode: variant.executionMode,
3509
+ runMode,
3510
+ executionIntent: variant.executionIntent,
3511
+ ...typeof guidanceTier === "number" ? { guidanceTier } : {},
3512
+ ...specInjectionUsed ? { specInjectionUsed: true } : {},
3513
+ ...Array.isArray(specQualitySignals) && specQualitySignals.length > 0 ? { specQualitySignals } : {},
3514
+ ...classification.drift ? { classificationDrift: classification.drift } : {}
3515
+ });
3516
+ } catch (_err) {
3517
+ await warnOnce(
3518
+ "Telemetry unavailable for worker; continuing with JSON output only.",
3519
+ telemetryWarning
3520
+ );
3521
+ telemetryEnabled = false;
3522
+ }
3523
+ let result;
3524
+ let cleanupWorktreeAfterRun = false;
3525
+ let executionResultSettledAtMs;
3526
+ const providerOutputForwarder = createProviderOutputForwarder(
3527
+ getRuntimeEnv("BUILD_PROVIDER_OUTPUT_EVENTS") === "1"
3528
+ );
3529
+ try {
3530
+ const { LocalExecutor } = await import("./local-executor-DCMDDRX2.js");
3531
+ if (repairLoopConfig.enabled && prevRetainBasicWorktree === void 0 && getRuntimeEnv("BUILD_RETAIN_BASIC_WORKTREE") !== "1") {
3532
+ applyWorkerEnvOverrides({ BUILD_RETAIN_BASIC_WORKTREE: "1" });
3533
+ cleanupWorktreeAfterRun = getRuntimeEnv("BUILD_PRESERVE_WORKTREES") !== "1";
3534
+ }
3535
+ let costTracker;
3536
+ if (telemetry) {
3537
+ try {
3538
+ const { UnifiedCostTracker } = await import("./unified-cost-tracker-5MTBJ2CL.js");
3539
+ const { UniversalCostCalculator } = await import("./universal-cost-calculator-JTFEJVWK.js");
3540
+ const costCalculator = new UniversalCostCalculator(telemetry);
3541
+ costTracker = new UnifiedCostTracker(costCalculator, telemetry, {
3542
+ enabled: true,
3543
+ budgetThresholds: {
3544
+ warning: 1,
3545
+ critical: 5,
3546
+ daily: 10,
3547
+ monthly: 100
3548
+ },
3549
+ optimization: {
3550
+ enableSuggestions: false,
3551
+ minSavingsThreshold: 1,
3552
+ maxSuggestionsPerHour: 0
3553
+ },
3554
+ updateIntervalMs: 6e4
3555
+ });
3556
+ } catch (costErr) {
3557
+ await warnOnce(
3558
+ "Cost tracking initialization failed in worker; continuing without a UnifiedCostTracker.",
3559
+ costTrackerWarning
3560
+ );
3561
+ if (verbose) {
3562
+ const message = costErr instanceof Error ? costErr.message : String(costErr);
3563
+ console.warn(chalk.yellow(` Cost tracking init error: ${message}`));
3564
+ }
3565
+ }
3566
+ }
3567
+ const executor = new LocalExecutor({
3568
+ repoRoot,
3569
+ verbose: verbose ?? false,
3570
+ executorTimeoutMs: timeoutMinutes != null ? timeoutMinutes * 6e4 : void 0,
3571
+ executorDeadlineAt: deadlineAt ?? (timeoutMinutes != null ? workerStartMs + timeoutMinutes * 6e4 : void 0),
3572
+ idleWarnMs: idleWarnMinutes != null ? idleWarnMinutes * 6e4 : void 0,
3573
+ idleKillMs: idleKillMinutes != null ? idleKillMinutes * 6e4 : void 0,
3574
+ costTracker,
3575
+ resultStreamer: providerOutputForwarder.resultStreamer,
3576
+ onWorktreeReady: ({ worktreePath, baselineRef }) => {
3577
+ timeoutContext.worktreePath = worktreePath;
3578
+ timeoutContext.baselineRef = baselineRef;
3579
+ }
3580
+ });
3581
+ const executionBreadcrumb = createCliBreadcrumb({
3582
+ label: `Variant ${formatVariantIdentifier(variant)}`,
3583
+ detail: "execution started; this step can stay quiet while the provider works."
3584
+ });
3585
+ let execResult;
3586
+ try {
3587
+ execResult = await executor.executeVariant(taskId, variant, prompt, {
3588
+ abortSignal: executionAbortController.signal
3589
+ });
3590
+ executionResultSettledAtMs = elapsedMsSince(startTime);
3591
+ installPostProviderSignalHandlers();
3592
+ executionBreadcrumb.complete();
3593
+ } finally {
3594
+ executorSettled = true;
3595
+ executionBreadcrumb.dispose();
3596
+ }
3597
+ result = execResult;
3598
+ const postProviderPhaseDurationsMs = {
3599
+ ...result.postProviderPhaseDurationsMs ?? {}
3600
+ };
3601
+ result.postProviderPhaseDurationsMs = postProviderPhaseDurationsMs;
3602
+ timeoutContext.worktreePath = result.retainedWorktreePath ?? timeoutContext.worktreePath;
3603
+ timeoutContext.baselineRef = result.baselineRef ?? timeoutContext.baselineRef;
3604
+ measurePostProviderPhaseSync(
3605
+ postProviderPhaseDurationsMs,
3606
+ "resultNormalization",
3607
+ verbose,
3608
+ () => {
3609
+ if (variant.executionIntent === "analysis" && result.success !== false && (result.completeness ?? 0) < MIN_ANALYSIS_COMPLETENESS) {
3610
+ const boosted = Math.max(result.completeness ?? 0, MIN_ANALYSIS_COMPLETENESS);
3611
+ result.completeness = boosted;
3612
+ result.completenessScore = {
3613
+ score: boosted,
3614
+ category: "analysis",
3615
+ fileTargetMatchRate: result.completenessScore?.fileTargetMatchRate
3616
+ };
3617
+ }
3618
+ if (result.completeness < 0) {
3619
+ result.completeness = 0;
3620
+ }
3621
+ }
3622
+ );
3623
+ const duration = Number(process.hrtime.bigint() - startTime) / 1e9;
3624
+ result.executionDurationMs = Math.round(duration * 1e3);
3625
+ await measurePostProviderPhase(
3626
+ postProviderPhaseDurationsMs,
3627
+ "gitMetrics",
3628
+ verbose,
3629
+ async () => ensureGitMetrics(result)
3630
+ );
3631
+ attachOffScopeConfigWarning(result, { taskId, prompt });
3632
+ const isAnalysisIntent = variant.executionIntent === "analysis";
3633
+ const hasRetainedRepairWorktree = typeof result.retainedWorktreePath === "string" && result.retainedWorktreePath.trim().length > 0;
3634
+ const hasRepairBaselineRef = typeof result.baselineRef === "string" && result.baselineRef.trim().length > 0;
3635
+ const warningCodes = getWarningCodes(result);
3636
+ const hasMissingFileTargets = warningCodes.has("WS-008");
3637
+ const filesChanged = result.gitMetrics?.filesChanged ?? result.filesChanged ?? 0;
3638
+ const hasMaterializedDeliverable = filesChanged > 0 || result.outcome?.delivery?.hasChanges === true;
3639
+ const outputText = `${result.result?.stdout ?? ""}
3640
+ ${result.result?.stderr ?? ""}`;
3641
+ const isClarifyingNoOp = filesChanged === 0 && looksLikeClarifyingQuestion(outputText);
3642
+ const exactArtifactGate = await measurePostProviderPhase(
3643
+ postProviderPhaseDurationsMs,
3644
+ "exactArtifactGoalGate",
3645
+ verbose,
3646
+ async () => {
3647
+ if (!hasRetainedRepairWorktree) {
3648
+ return { success: result.success === true };
3649
+ }
3650
+ return applyExactArtifactGoalSuccessGate({
3651
+ prompt,
3652
+ worktreePath: result.retainedWorktreePath,
3653
+ success: result.success === true
3654
+ });
3655
+ }
3656
+ );
3657
+ if (result.success === true && !exactArtifactGate.success) {
3658
+ result.success = false;
3659
+ result.completeness = 0;
3660
+ result.error = new Error(
3661
+ exactArtifactGate.failureReason ?? "Exact artifact content mismatch"
3662
+ );
3663
+ }
3664
+ const validationArtifactSatisfied = await measurePostProviderPhase(
3665
+ postProviderPhaseDurationsMs,
3666
+ "validationArtifactCheck",
3667
+ verbose,
3668
+ async () => {
3669
+ if (!hasRetainedRepairWorktree || result.success !== true) return false;
3670
+ const simpleArtifactGoal = parseSimpleArtifactGoal(prompt);
3671
+ if (simpleArtifactGoal) {
3672
+ return isSimpleArtifactGoalSatisfied(result.retainedWorktreePath, simpleArtifactGoal);
3673
+ }
3674
+ return isValidationArtifactOnlyDiffSatisfied({
3675
+ prompt,
3676
+ worktreePath: result.retainedWorktreePath,
3677
+ baselineRef: result.baselineRef
3678
+ });
3679
+ }
3680
+ );
3681
+ const runFallbackVerification = async () => {
3682
+ if (!result.verificationLoop && validationArtifactSatisfied !== true && !isAnalysisIntent && result.success === true && hasMaterializedDeliverable && typeof result.retainedWorktreePath === "string" && result.retainedWorktreePath.trim().length > 0 && typeof result.baselineRef === "string" && result.baselineRef.trim().length > 0) {
3683
+ const worktreePath = result.retainedWorktreePath.trim();
3684
+ const baselineRef = result.baselineRef.trim();
3685
+ const repoRoot2 = process.cwd();
3686
+ const cacheDir = verificationBaselineCacheDir();
3687
+ const verificationChangedFiles = await taskScopedChangedFiles(worktreePath, baselineRef);
3688
+ const testsProhibited = isTestRunProhibited(prompt);
3689
+ const baselineForVerification = await measurePostProviderPhase(
3690
+ postProviderPhaseDurationsMs,
3691
+ "verificationBaselineCapture",
3692
+ verbose,
3693
+ async () => getOrCaptureVerificationBaseline({
3694
+ repoRoot: repoRoot2,
3695
+ baselineRef,
3696
+ cacheDir,
3697
+ captureOptions: {
3698
+ changedFiles: verificationChangedFiles,
3699
+ skipTests: testsProhibited
3700
+ }
3701
+ }).catch(() => null)
3702
+ );
3703
+ const verificationOutcome = await measurePostProviderPhase(
3704
+ postProviderPhaseDurationsMs,
3705
+ "deterministicVerification",
3706
+ verbose,
3707
+ async () => runDeterministicVerificationOnce({
3708
+ worktreePath,
3709
+ baselineRef,
3710
+ // Same per-channel budget as the baseline capture above, not the
3711
+ // repair-iteration timebox, so a gate the baseline passed is not cut short.
3712
+ timeoutMs: resolveVerifyCommandTimeoutMs(),
3713
+ budget: "per-channel",
3714
+ baseline: baselineForVerification?.metadata?.captureSucceeded ? baselineForVerification : void 0,
3715
+ checkTestGate: !testsProhibited,
3716
+ // Same scope as the baseline capture above (symmetry invariant).
3717
+ changedFiles: verificationChangedFiles
3718
+ })
3719
+ );
3720
+ result.verification = verificationOutcome.verification;
3721
+ result.verificationLoop = verificationOutcome.verificationLoop;
3722
+ }
3723
+ };
3724
+ const initialVerificationDisposition = await resolveInitialVerificationDisposition(
3725
+ result,
3726
+ runFallbackVerification
3727
+ );
3728
+ const providerGatesAlreadyPassed = initialVerificationDisposition.outcome === "passed";
3729
+ const repairAdmission = measurePostProviderPhaseSync(
3730
+ postProviderPhaseDurationsMs,
3731
+ "repairAdmission",
3732
+ verbose,
3733
+ () => {
3734
+ return decideRepairAdmission({
3735
+ repairLoopEnabled: repairLoopConfig.enabled,
3736
+ isAnalysisIntent,
3737
+ hasRetainedWorktree: hasRetainedRepairWorktree,
3738
+ hasBaselineRef: hasRepairBaselineRef,
3739
+ initialVerificationOutcome: initialVerificationDisposition.outcome,
3740
+ providerGatesAlreadyPassed,
3741
+ verificationUnavailable: initialVerificationDisposition.outcome === "not_run" && hasUnavailableVerificationGateEvidence(result),
3742
+ hasMissingFileTargets,
3743
+ isClarifyingNoOp,
3744
+ providerExecutionSucceeded: result.success === true,
3745
+ hasMaterializedDeliverable,
3746
+ validationArtifactSatisfied,
3747
+ filesChanged
3748
+ });
3749
+ }
3750
+ );
3751
+ result.repairAdmission = repairAdmission;
3752
+ if (repairLoopConfig.enabled && result.repairAdmission.action === "skip" && (result.repairAdmission.reason === "skip_passing_gates" || result.repairAdmission.reason === "skip_clarifying_noop")) {
3753
+ emitWarning(
3754
+ "PERF-003",
3755
+ {
3756
+ taskId,
3757
+ subsystem: "repair-loop",
3758
+ executionPhase: "validation"
3759
+ },
3760
+ {
3761
+ metadata: {
3762
+ reason: result.repairAdmission.summary,
3763
+ admissionReason: result.repairAdmission.reason
3764
+ }
3765
+ }
3766
+ );
3767
+ }
3768
+ if (result.repairAdmission.action === "run") {
3769
+ let repairOutcome = null;
3770
+ let preRepairDiffSnapshot;
3771
+ {
3772
+ const worktreePath = result.retainedWorktreePath;
3773
+ const baselineRef = result.baselineRef;
3774
+ const initialCostUsd = result.costMetrics?.totalCost ?? result.result?.totalCostUsd ?? 0;
3775
+ preRepairDiffSnapshot = await measurePostProviderPhase(
3776
+ postProviderPhaseDurationsMs,
3777
+ "preRepairDiffSnapshot",
3778
+ verbose,
3779
+ async () => captureRepairDiffSnapshot(worktreePath, baselineRef)
3780
+ );
3781
+ if (!preRepairDiffSnapshot) {
3782
+ emitWarning(
3783
+ "PERF-003",
3784
+ {
3785
+ taskId,
3786
+ subsystem: "repair-loop",
3787
+ executionPhase: "validation"
3788
+ },
3789
+ {
3790
+ metadata: {
3791
+ reason: "pre-repair diff snapshot unavailable; repair-scope classification will be unknown",
3792
+ baselineRef,
3793
+ worktreePath
3794
+ }
3795
+ }
3796
+ );
3797
+ }
3798
+ const repoRoot2 = process.cwd();
3799
+ const cacheDir = verificationBaselineCacheDir();
3800
+ const repairChangedFiles = await taskScopedChangedFiles(worktreePath, baselineRef);
3801
+ const repairTestsProhibited = isTestRunProhibited(prompt);
3802
+ const baselineForRepair = await measurePostProviderPhase(
3803
+ postProviderPhaseDurationsMs,
3804
+ "verificationBaselineCapture",
3805
+ verbose,
3806
+ async () => getOrCaptureVerificationBaseline({
3807
+ repoRoot: repoRoot2,
3808
+ baselineRef,
3809
+ cacheDir,
3810
+ captureOptions: {
3811
+ changedFiles: repairChangedFiles,
3812
+ skipTests: repairTestsProhibited
3813
+ }
3814
+ }).catch(() => null)
3815
+ );
3816
+ const baselineSucceeded = !!baselineForRepair?.metadata?.captureSucceeded;
3817
+ const allowedFiles = (() => {
3818
+ try {
3819
+ const spec = parsePromptSpec(prompt);
3820
+ return Array.isArray(spec.fileConstraint.targets) ? spec.fileConstraint.targets : [];
3821
+ } catch {
3822
+ return [];
3823
+ }
3824
+ })();
3825
+ repairOutcome = await measurePostProviderPhase(
3826
+ postProviderPhaseDurationsMs,
3827
+ "repairLoop",
3828
+ verbose,
3829
+ async () => runVerificationDrivenRepairLoop({
3830
+ config: {
3831
+ enabled: true,
3832
+ maxIterations: Math.max(1, Math.floor(repairLoopConfig.maxIterations)),
3833
+ iterationTimeoutMs: Math.max(
3834
+ 1e3,
3835
+ Math.floor(repairLoopConfig.iterationTimeoutMs)
3836
+ ),
3837
+ abortIfRegression: repairLoopConfig.abortIfRegression,
3838
+ allowApiBreak: repairLoopConfig.allowApiBreak,
3839
+ repairMode: repairLoopConfig.repairMode,
3840
+ scopePolicy: repairLoopConfig.scopePolicy,
3841
+ repairSaveModes: repairLoopConfig.repairSaveModes,
3842
+ allowedFiles,
3843
+ // Default to true for the software-aware Multi-Lens judge.
3844
+ // This enables test failure detection in regression checks.
3845
+ checkTestGate: !repairTestsProhibited,
3846
+ skipTests: repairTestsProhibited
3847
+ },
3848
+ worktreePath,
3849
+ baselineRef,
3850
+ baseline: baselineSucceeded ? baselineForRepair : void 0,
3851
+ taskId,
3852
+ variantId: formatVariantIdentifier(variant),
3853
+ originalPrompt: prompt,
3854
+ initialCostUsd: Number.isFinite(initialCostUsd) && initialCostUsd > 0 ? initialCostUsd : 0,
3855
+ executeRepair: async (repairPrompt, iterationIndex, abortSignal) => {
3856
+ const repairTaskId = `${taskId}-verify-${iterationIndex + 1}`;
3857
+ const repairVariant = {
3858
+ ...variant,
3859
+ // Enforce same worktree + prevent auto-commit drift during repair loops.
3860
+ workflowWorktreePath: worktreePath,
3861
+ disableAutoCommit: true,
3862
+ isBasicCompetition: true
3863
+ };
3864
+ const repairResult = await executor.executeVariant(
3865
+ repairTaskId,
3866
+ repairVariant,
3867
+ repairPrompt,
3868
+ { abortSignal }
3869
+ );
3870
+ const costUsd = repairResult.costMetrics?.totalCost ?? repairResult.result?.totalCostUsd ?? 0;
3871
+ return { costUsd: Number.isFinite(costUsd) ? costUsd : 0 };
3872
+ }
3873
+ })
3874
+ );
3875
+ result.verification = repairOutcome.verification;
3876
+ result.verificationLoop = repairOutcome.verificationLoop;
3877
+ }
3878
+ if (repairOutcome) {
3879
+ const { verificationLoop } = repairOutcome;
3880
+ const shouldPromoteRepairs = verificationLoop.iterations.length > 0 && verificationLoop.bestIterationPromotable;
3881
+ if (!shouldPromoteRepairs) {
3882
+ } else {
3883
+ cleanupWorktreeAfterRun = false;
3884
+ try {
3885
+ const worktreePath = result.retainedWorktreePath;
3886
+ const baselineRef = result.baselineRef;
3887
+ const iterCount = verificationLoop.iterations.length;
3888
+ let commitSucceeded = false;
3889
+ const status = await measurePostProviderPhase(
3890
+ postProviderPhaseDurationsMs,
3891
+ "repairPromotionStatus",
3892
+ verbose,
3893
+ async () => execa3("git", ["status", "--porcelain"], {
3894
+ cwd: worktreePath,
3895
+ stdio: "pipe",
3896
+ reject: false
3897
+ })
3898
+ );
3899
+ const isDirty = String(status.stdout ?? "").trim().length > 0;
3900
+ const repairedSummary = await measurePostProviderPhase(
3901
+ postProviderPhaseDurationsMs,
3902
+ "repairPromotionChangeSummary",
3903
+ verbose,
3904
+ async () => getGitChangeSummary(worktreePath, baselineRef, true)
3905
+ );
3906
+ const finalDiffSnapshot = await measurePostProviderPhase(
3907
+ postProviderPhaseDurationsMs,
3908
+ "repairPromotionDiffSnapshot",
3909
+ verbose,
3910
+ async () => captureRepairDiffSnapshot(worktreePath, baselineRef)
3911
+ );
3912
+ if (!finalDiffSnapshot) {
3913
+ emitWarning(
3914
+ "PERF-003",
3915
+ {
3916
+ taskId,
3917
+ subsystem: "repair-loop",
3918
+ executionPhase: "validation"
3919
+ },
3920
+ {
3921
+ metadata: {
3922
+ reason: "post-repair diff snapshot unavailable; repair-scope classification will be unknown",
3923
+ baselineRef,
3924
+ worktreePath
3925
+ }
3926
+ }
3927
+ );
3928
+ }
3929
+ const repairScopeAnalysis = analyzeRepairScope({
3930
+ preRepairDiff: preRepairDiffSnapshot,
3931
+ finalDiff: finalDiffSnapshot
3932
+ });
3933
+ const repairPolicy = resolveRepairPromotionPolicy({
3934
+ classification: repairScopeAnalysis.classification,
3935
+ repairDelta: repairScopeAnalysis.repairDelta,
3936
+ scopePolicy: repairLoopConfig.scopePolicy,
3937
+ effectiveMode: repairPolicyCompletionMode(),
3938
+ allowOffScopeRepair: isOffScopeRepairOverrideEnabled()
3939
+ });
3940
+ const allowRepairCommit = repairPolicy.action === "allow" || repairPolicy.action === "warn";
3941
+ if (isDirty && !allowRepairCommit) {
3942
+ emitWarning(
3943
+ "PERF-003",
3944
+ {
3945
+ taskId,
3946
+ subsystem: "repair-loop",
3947
+ executionPhase: "validation"
3948
+ },
3949
+ {
3950
+ metadata: {
3951
+ reason: `Skipped repair commit: ${repairPolicy.reason}`,
3952
+ policyAction: repairPolicy.action,
3953
+ classification: repairScopeAnalysis.classification,
3954
+ finalArtifactTrust: repairPolicy.finalArtifactTrust,
3955
+ worktreePath
3956
+ }
3957
+ }
3958
+ );
3959
+ } else if (isDirty) {
3960
+ const stage = await measurePostProviderPhase(
3961
+ postProviderPhaseDurationsMs,
3962
+ "repairPromotionStage",
3963
+ verbose,
3964
+ async () => stageCommitEligibleChanges(worktreePath).then(
3965
+ (staged) => ({ staged, failure: void 0 }),
3966
+ (error) => ({
3967
+ staged: false,
3968
+ failure: error instanceof Error ? error.message : String(error)
3969
+ })
3970
+ )
3971
+ );
3972
+ if (stage.failure !== void 0 && verbose) {
3973
+ console.warn(
3974
+ chalk.yellow(
3975
+ `Failed to stage repairs (${stage.failure}); preserving worktree for manual commit.`
3976
+ )
3977
+ );
3978
+ }
3979
+ const isFullyClean = verificationLoop.passed;
3980
+ const commitMsg = isFullyClean ? `fix: repair-loop (${iterCount} iterations) - all gates pass` : `fix: repair-loop (${iterCount} iterations) - no new regressions vs baseline`;
3981
+ const commit = stage.staged ? await measurePostProviderPhase(
3982
+ postProviderPhaseDurationsMs,
3983
+ "repairPromotionCommit",
3984
+ verbose,
3985
+ async () => execa3("git", ["commit", "--no-verify", "-m", commitMsg], {
3986
+ cwd: worktreePath,
3987
+ stdio: "pipe",
3988
+ reject: false
3989
+ })
3990
+ ) : void 0;
3991
+ commitSucceeded = commit !== void 0 && (commit.exitCode ?? 0) === 0;
3992
+ if (commit !== void 0 && (commit.exitCode ?? 0) !== 0 && verbose) {
3993
+ const output = String(commit.stdout ?? commit.stderr ?? "").trim();
3994
+ console.warn(
3995
+ chalk.yellow(
3996
+ `Failed to commit repairs (exit ${commit.exitCode ?? "unknown"}); preserving worktree for manual commit.${output ? `
3997
+ ${output}` : ""}`
3998
+ )
3999
+ );
4000
+ }
4001
+ }
4002
+ let restoredBaseline = false;
4003
+ try {
4004
+ const baseTree = await execGit(["rev-parse", `${baselineRef}^{tree}`], {
4005
+ cwd: worktreePath
4006
+ });
4007
+ restoredBaseline = baseTree.exitCode === 0 && await captureCurrentWorkspaceTreeIdentity(worktreePath) === String(baseTree.stdout).trim();
4008
+ } catch {
4009
+ }
4010
+ result.repairOutcome = {
4011
+ attempted: true,
4012
+ passed: verificationLoop.passed,
4013
+ passedBaseline: verificationLoop.passedBaseline,
4014
+ iterations: verificationLoop.iterations.length,
4015
+ stopReason: verificationLoop.stopReason,
4016
+ filesChanged: repairedSummary.filesChanged,
4017
+ committed: commitSucceeded,
4018
+ repairTrigger: buildRepairTriggerEvidence(repairOutcome),
4019
+ ...repairScopeAnalysis.preRepairDiff ? { preRepairDiff: repairScopeAnalysis.preRepairDiff } : {},
4020
+ ...repairScopeAnalysis.finalDiff ? { finalDiff: repairScopeAnalysis.finalDiff } : {},
4021
+ ...repairScopeAnalysis.repairDelta ? { repairDelta: repairScopeAnalysis.repairDelta } : {},
4022
+ classification: repairScopeAnalysis.classification,
4023
+ judgeVerdictApplicability: repairScopeAnalysis.judgeVerdictApplicability,
4024
+ finalArtifactTrust: repairPolicy.finalArtifactTrust,
4025
+ policy: repairPolicy
4026
+ };
4027
+ if (!restoredBaseline && repairedSummary.filesChanged > 0) {
4028
+ result.gitMetrics = {
4029
+ filesChanged: repairedSummary.filesChanged,
4030
+ linesAdded: repairedSummary.linesAdded,
4031
+ linesDeleted: repairedSummary.linesRemoved,
4032
+ source: repairedSummary.source === "fallback" ? "unknown" : "worktree"
4033
+ };
4034
+ } else if (restoredBaseline) {
4035
+ result.gitMetrics = {
4036
+ filesChanged: 0,
4037
+ linesAdded: 0,
4038
+ linesDeleted: 0,
4039
+ source: "worktree"
4040
+ };
4041
+ result.filesChanged = result.linesAdded = result.linesRemoved = 0;
4042
+ result.emptyChanges = true;
4043
+ }
4044
+ if (!restoredBaseline && repairedSummary.filesChanged > 0)
4045
+ result.emptyChanges = false;
4046
+ if (repairedSummary.filesChanged > 0 || repairedSummary.source !== "fallback") {
4047
+ const repairedDiff = normalizeWorktreeDiff(
4048
+ await captureWorktreeDiff(worktreePath, baselineRef, true)
4049
+ );
4050
+ if (repairedDiff || restoredBaseline) {
4051
+ result.worktreeDiff = repairedDiff;
4052
+ }
4053
+ }
4054
+ if (verbose) {
4055
+ const baselineStatus = verificationLoop.passed ? "all gates pass" : "no new regressions";
4056
+ console.log(
4057
+ chalk.green(
4058
+ commitSucceeded ? `Verification repairs committed (${iterCount} iterations, ${repairedSummary.filesChanged} files, ${baselineStatus})` : `Verification repairs preserved (${iterCount} iterations, ${repairedSummary.filesChanged} files, ${baselineStatus})`
4059
+ )
4060
+ );
4061
+ }
4062
+ } catch (commitError) {
4063
+ if (verbose) {
4064
+ const msg = commitError instanceof Error ? commitError.message : String(commitError);
4065
+ console.warn(chalk.yellow(`Failed to commit repairs: ${msg}`));
4066
+ }
4067
+ }
4068
+ }
4069
+ }
4070
+ }
4071
+ if (result.gitMetrics && result.gitMetrics.filesChanged > 0) {
4072
+ result.filesChanged = result.gitMetrics.filesChanged;
4073
+ result.linesAdded = result.gitMetrics.linesAdded;
4074
+ result.linesRemoved = result.gitMetrics.linesDeleted;
4075
+ }
4076
+ const workspaceEditsApplied = result.workspaceEditsApplied ?? 0;
4077
+ if (result.gitMetrics && result.gitMetrics.filesChanged > 0 && (result.completeness ?? 0) === 0 && workspaceEditsApplied === 0) {
4078
+ console.warn(
4079
+ chalk.yellow(
4080
+ "[Telemetry] Git shows changes but completeness is 0 and no workspace edits were applied."
4081
+ ),
4082
+ {
4083
+ filesChanged: result.gitMetrics.filesChanged,
4084
+ linesAdded: result.gitMetrics.linesAdded,
4085
+ linesDeleted: result.gitMetrics.linesDeleted,
4086
+ provider: variant.provider,
4087
+ executionIntent: variant.executionIntent
4088
+ }
4089
+ );
4090
+ }
4091
+ await runFallbackVerification();
4092
+ try {
4093
+ await measurePostProviderPhase(
4094
+ postProviderPhaseDurationsMs,
4095
+ "baselineComparison",
4096
+ verbose,
4097
+ async () => attachBaselineComparisonIfAvailable(result)
4098
+ );
4099
+ } catch {
4100
+ }
4101
+ try {
4102
+ await measurePostProviderPhase(
4103
+ postProviderPhaseDurationsMs,
4104
+ "registryDowngrade",
4105
+ verbose,
4106
+ async () => applyRegistryDowngradeIfApplicable(result)
4107
+ );
4108
+ } catch {
4109
+ }
4110
+ const repairedFiles = result.repairOutcome?.finalDiff?.files;
4111
+ attachOffScopeConfigWarning(result, {
4112
+ taskId,
4113
+ prompt,
4114
+ ...repairedFiles ? { changedPaths: repairedFiles } : {}
4115
+ });
4116
+ measurePostProviderPhaseSync(
4117
+ postProviderPhaseDurationsMs,
4118
+ "outcomeDerivation",
4119
+ verbose,
4120
+ () => {
4121
+ result.outcome = deriveVariantOutcome(result);
4122
+ }
4123
+ );
4124
+ if (specSignal) {
4125
+ result.inputSpecWarning = {
4126
+ completenessScore: specSignal.completenessScore,
4127
+ guidanceTier: specSignal.guidanceTier,
4128
+ missingFields: [...specSignal.missingFields],
4129
+ hasFillPlaceholders: specSignal.hasFillPlaceholders
4130
+ };
4131
+ }
4132
+ if (verbose) {
4133
+ console.log(
4134
+ chalk.green(`Execution completed in ${duration.toFixed(2)}s (success: ${result.success})`)
4135
+ );
4136
+ console.log(chalk.gray(` ${formatVerboseWorkerCompletionMetric(result)}`));
4137
+ if (specSignal) {
4138
+ const missingNames = specSignal.missingFields.map(
4139
+ (field) => FIELD_DISPLAY_NAMES[field] ?? field
4140
+ );
4141
+ console.log(
4142
+ chalk.yellow(
4143
+ ` Note: execution started from an incomplete spec (${Math.round(specSignal.completenessScore * 100)}% complete; missing: ${missingNames.join(", ")})`
4144
+ )
4145
+ );
4146
+ }
4147
+ }
4148
+ if (telemetryEnabled && telemetry) {
4149
+ try {
4150
+ const processReliability = computeProcessReliabilityMetrics({
4151
+ success: result.success,
4152
+ result: result.result
4153
+ });
4154
+ let terminationReason;
4155
+ if (result.terminationReason) {
4156
+ terminationReason = result.terminationReason;
4157
+ } else if (result.success) {
4158
+ terminationReason = "completed";
4159
+ } else if (result.timedOut) {
4160
+ terminationReason = "timeout";
4161
+ } else {
4162
+ terminationReason = "failed_error";
4163
+ }
4164
+ telemetry.logVariantEvent(taskId, formatVariantIdentifier(variant), "completed", {
4165
+ success: result.success,
4166
+ completeness: result.completeness,
4167
+ duration,
4168
+ provider: variant.provider,
4169
+ model: variant.model,
4170
+ executionMode: variant.executionMode,
4171
+ runMode,
4172
+ executionIntent: variant.executionIntent,
4173
+ behavioralMetrics: { processReliability },
4174
+ terminationReason
4175
+ });
4176
+ telemetry.logVariantEvent(taskId, formatVariantIdentifier(variant), "evaluated", {
4177
+ ...resolveVariantEvaluation(result),
4178
+ completeness: result.completeness,
4179
+ provider: variant.provider,
4180
+ model: variant.model,
4181
+ executionMode: variant.executionMode,
4182
+ runMode,
4183
+ executionIntent: variant.executionIntent
4184
+ });
4185
+ await measurePostProviderPhase(
4186
+ postProviderPhaseDurationsMs,
4187
+ "telemetryArtifactWrite",
4188
+ verbose,
4189
+ async () => {
4190
+ const artifactResult = await telemetry.logVariantResultWithArtifact(
4191
+ taskId,
4192
+ formatVariantIdentifier(variant),
4193
+ result,
4194
+ {
4195
+ provider: variant.provider,
4196
+ model: variant.model,
4197
+ executionMode: variant.executionMode,
4198
+ runMode,
4199
+ executionIntent: variant.executionIntent
4200
+ }
4201
+ );
4202
+ if (artifactResult?.success && artifactResult.manifestPath) {
4203
+ result.artifactManifest = artifactResult.manifestPath;
4204
+ }
4205
+ }
4206
+ );
4207
+ } catch (_err) {
4208
+ await warnOnce(
4209
+ "Telemetry logging failed mid-run; disabling telemetry for this worker.",
4210
+ telemetryWarning
4211
+ );
4212
+ telemetryEnabled = false;
4213
+ }
4214
+ }
4215
+ } catch (error) {
4216
+ const duration = Number(process.hrtime.bigint() - startTime) / 1e9;
4217
+ const errorObj = error instanceof Error ? error : new Error(String(error));
4218
+ result = {
4219
+ variant: formatVariantIdentifier(variant),
4220
+ provider: variant.provider,
4221
+ model: variant.model,
4222
+ executionMode: variant.executionMode,
4223
+ success: false,
4224
+ error: errorObj,
4225
+ duration,
4226
+ completeness: 0,
4227
+ executionIntent: variant.executionIntent,
4228
+ isBasicCompetition: variant.isBasicCompetition,
4229
+ // Record requested prompt mode even on failure
4230
+ promptModeRequested: variant.promptMode,
4231
+ ...specSignal ? {
4232
+ inputSpecWarning: {
4233
+ completenessScore: specSignal.completenessScore,
4234
+ guidanceTier: specSignal.guidanceTier,
4235
+ missingFields: [...specSignal.missingFields],
4236
+ hasFillPlaceholders: specSignal.hasFillPlaceholders
4237
+ }
4238
+ } : {}
4239
+ };
4240
+ const hostTerminationMetadata = hostTerminationMetadataFromUnknown(errorObj);
4241
+ if (hostTerminationMetadata && classifyHostTermination(hostTerminationMetadata) === "timeout") {
4242
+ result.timedOut = true;
4243
+ }
4244
+ const errorTerminationReason = result.terminationReason || (result.timedOut ? "timeout" : "failed_crash");
4245
+ result.terminationReason = errorTerminationReason;
4246
+ result.outcome = deriveVariantOutcome(result);
4247
+ if (telemetryEnabled && telemetry) {
4248
+ try {
4249
+ const processReliability = computeProcessReliabilityMetrics({
4250
+ success: false,
4251
+ result: result.result
4252
+ });
4253
+ telemetry.logVariantEvent(taskId, formatVariantIdentifier(variant), "completed", {
4254
+ success: false,
4255
+ completeness: 0,
4256
+ duration,
4257
+ provider: variant.provider,
4258
+ model: variant.model,
4259
+ executionMode: variant.executionMode,
4260
+ runMode,
4261
+ executionIntent: variant.executionIntent,
4262
+ behavioralMetrics: { processReliability },
4263
+ terminationReason: errorTerminationReason
4264
+ });
4265
+ telemetry.logVariantEvent(taskId, formatVariantIdentifier(variant), "evaluated", {
4266
+ verdict: "failure",
4267
+ completeness: 0,
4268
+ codeDelivered: false,
4269
+ provider: variant.provider,
4270
+ model: variant.model,
4271
+ executionMode: variant.executionMode,
4272
+ runMode,
4273
+ executionIntent: variant.executionIntent
4274
+ });
4275
+ const artifactResult = await telemetry.logVariantResultWithArtifact(
4276
+ taskId,
4277
+ formatVariantIdentifier(variant),
4278
+ result,
4279
+ {
4280
+ provider: variant.provider,
4281
+ model: variant.model,
4282
+ executionMode: variant.executionMode,
4283
+ runMode,
4284
+ executionIntent: variant.executionIntent
4285
+ }
4286
+ );
4287
+ if (artifactResult?.success && artifactResult.manifestPath) {
4288
+ result.artifactManifest = artifactResult.manifestPath;
4289
+ }
4290
+ } catch (_err) {
4291
+ await warnOnce(
4292
+ "Telemetry logging failed mid-run; disabling telemetry for this worker.",
4293
+ telemetryWarning
4294
+ );
4295
+ telemetryEnabled = false;
4296
+ }
4297
+ }
4298
+ if (verbose) {
4299
+ console.error(chalk.red(`Execution failed: ${errorObj.message}`));
4300
+ if (specSignal) {
4301
+ const missingNames = specSignal.missingFields.map(
4302
+ (field) => FIELD_DISPLAY_NAMES[field] ?? field
4303
+ );
4304
+ console.error(
4305
+ chalk.yellow(
4306
+ ` Note: execution started from an incomplete spec (${Math.round(specSignal.completenessScore * 100)}% complete; missing: ${missingNames.join(", ")})`
4307
+ )
4308
+ );
4309
+ }
4310
+ }
4311
+ }
4312
+ providerOutputForwarder.close();
4313
+ if (!result.postProviderPhaseDurationsMs) {
4314
+ result.postProviderPhaseDurationsMs = {};
4315
+ }
4316
+ const finalPostProviderPhaseDurationsMs = result.postProviderPhaseDurationsMs;
4317
+ if (result.success === true && shouldDowngradeSuccessfulResultForShutdown({
4318
+ shutdownRequested,
4319
+ shutdownRequestedAtMs,
4320
+ executionResultSettledAtMs
4321
+ })) {
4322
+ const signal = shutdownSignal ?? "SIGTERM";
4323
+ result.success = false;
4324
+ result.timedOut = signal === "SIGTERM";
4325
+ result.terminationReason = signal === "SIGINT" ? "canceled_user" : "timeout";
4326
+ result.error = buildShutdownAbortReason(signal);
4327
+ }
4328
+ measurePostProviderPhaseSync(
4329
+ finalPostProviderPhaseDurationsMs,
4330
+ "finalOutcomeDerivation",
4331
+ verbose,
4332
+ () => {
4333
+ result.outcome = deriveVariantOutcome(result);
4334
+ }
4335
+ );
4336
+ const worktreePathForCleanup = cleanupWorktreeAfterRun && result.success === true && typeof result.retainedWorktreePath === "string" ? result.retainedWorktreePath.trim() : void 0;
4337
+ if (worktreePathForCleanup) {
4338
+ result.retainedWorktreePath = void 0;
4339
+ }
4340
+ measurePostProviderPhaseSync(
4341
+ finalPostProviderPhaseDurationsMs,
4342
+ "resultFinalize",
4343
+ verbose,
4344
+ () => {
4345
+ if (result.result) {
4346
+ if (isNativeResearchEnabledFor(variant.provider)) {
4347
+ const rawTranscript = `${result.result.rawStdout ?? ""}
4348
+ ${result.result.rawStderr ?? ""}`;
4349
+ if (rawTranscript.trim().length > 0) {
4350
+ const scan = scanWebToolEvents(rawTranscript);
4351
+ if (scan.corroboratedUrls.size > 0) {
4352
+ result.result.researchCorroboratedUrls = Array.from(scan.corroboratedUrls);
4353
+ }
4354
+ if (scan.observedWebToolEvent) {
4355
+ result.result.researchObservedWebToolEvent = true;
4356
+ }
4357
+ }
4358
+ }
4359
+ result.result.rawStdout = void 0;
4360
+ result.result.rawStderr = void 0;
4361
+ if (result.result.stdout && Buffer.byteLength(result.result.stdout, "utf8") > 2e5) {
4362
+ result.result.stdout = truncateToByteLimit(result.result.stdout, 2e5);
4363
+ }
4364
+ if (result.result.stderr && Buffer.byteLength(result.result.stderr, "utf8") > 2e5) {
4365
+ result.result.stderr = truncateToByteLimit(result.result.stderr, 2e5);
4366
+ }
4367
+ }
4368
+ }
4369
+ );
4370
+ sanitizeVariantResult(result);
4371
+ try {
4372
+ await measurePostProviderPhase(
4373
+ finalPostProviderPhaseDurationsMs,
4374
+ "resultWrite",
4375
+ verbose,
4376
+ async () => writeResultFileAtomically(resultFile, result)
4377
+ );
4378
+ emitWorkerLifecycleMarker(RESULT_WRITTEN_MARKER_PREFIX, elapsedMsSince(startTime));
4379
+ emitWorkerLifecycleMarker(
4380
+ POST_PROVIDER_PHASES_MARKER_PREFIX,
4381
+ finalPostProviderPhaseDurationsMs
4382
+ );
4383
+ if (verbose) {
4384
+ console.log(chalk.green(`Result written to ${resultFile}`));
4385
+ }
4386
+ if (telemetryEnabled && telemetry) {
4387
+ try {
4388
+ TelemetryLogger.disposeShared();
4389
+ } catch (_err) {
4390
+ }
4391
+ }
4392
+ if (worktreePathForCleanup && worktreePathForCleanup.length > 0) {
4393
+ await measurePostProviderPhase(
4394
+ finalPostProviderPhaseDurationsMs,
4395
+ "cleanup",
4396
+ verbose,
4397
+ async () => tryCleanupRetainedWorktree(worktreePathForCleanup, verbose)
4398
+ );
4399
+ }
4400
+ applyWorkerEnvOverrides({
4401
+ BUILD_RETAIN_BASIC_WORKTREE: prevRetainBasicWorktree
4402
+ });
4403
+ emitWorkerLifecycleMarker(CLEANUP_START_MARKER_PREFIX, elapsedMsSince(startTime));
4404
+ await measurePostProviderPhase(
4405
+ finalPostProviderPhaseDurationsMs,
4406
+ "cleanup",
4407
+ verbose,
4408
+ async () => signalCoordinator.runCleanupHandlers("variant-worker exit", {
4409
+ timeoutMs: SIGNAL_CLEANUP_TIMEOUT_MS
4410
+ })
4411
+ );
4412
+ emitWorkerLifecycleMarker(CLEANUP_COMPLETE_MARKER_PREFIX, elapsedMsSince(startTime));
4413
+ emitWorkerLifecycleMarker(
4414
+ POST_PROVIDER_PHASES_MARKER_PREFIX,
4415
+ finalPostProviderPhaseDurationsMs
4416
+ );
4417
+ emitWorkerLifecycleMarker(ACTIVE_HANDLES_MARKER_PREFIX, activeHandleSummary());
4418
+ if (preserveWorktreesForDebug) {
4419
+ applyWorkerEnvOverrides({
4420
+ BUILD_PRESERVE_WORKTREES: prevPreserveWorktrees
4421
+ });
4422
+ }
4423
+ return;
4424
+ } catch (error) {
4425
+ const message = error instanceof Error ? error.message : String(error);
4426
+ console.error(chalk.red(`Failed to write result: ${message}`));
4427
+ if (telemetryEnabled && telemetry) {
4428
+ try {
4429
+ TelemetryLogger.disposeShared();
4430
+ } catch (_err) {
4431
+ }
4432
+ }
4433
+ applyWorkerEnvOverrides({
4434
+ BUILD_RETAIN_BASIC_WORKTREE: prevRetainBasicWorktree
4435
+ });
4436
+ await signalCoordinator.runCleanupHandlers("variant-worker fatal-exit", {
4437
+ timeoutMs: SIGNAL_CLEANUP_TIMEOUT_MS
4438
+ });
4439
+ if (preserveWorktreesForDebug) {
4440
+ applyWorkerEnvOverrides({
4441
+ BUILD_PRESERVE_WORKTREES: prevPreserveWorktrees
4442
+ });
4443
+ }
4444
+ throw new ExitCodeError(1, message);
4445
+ }
4446
+ } finally {
4447
+ uninstallPostProviderSignalHandlers();
4448
+ signalCoordinator.unregister(signalHandlerName);
4449
+ signalCoordinator.unregister(processLifecycleSignalHandlerName);
4450
+ setProcessLifecycleManager(void 0);
4451
+ }
4452
+ }
4453
+ var workerEntrypoint = fileURLToPath(import.meta.url);
4454
+ var invokedScript = process.argv[1] ? path2.resolve(process.argv[1]) : null;
4455
+ var isDirectInvocation = invokedScript !== null && path2.resolve(workerEntrypoint) === invokedScript;
4456
+ async function runVariantWorkerEntrypoint(entryOptions = {}) {
4457
+ if (!entryOptions.runtimeAlreadyChecked) {
4458
+ assertBuildRuntimeReady({ command: "variant-worker" });
4459
+ }
4460
+ try {
4461
+ await main();
4462
+ return 0;
4463
+ } catch (error) {
4464
+ const message = error instanceof Error ? error.message : String(error);
4465
+ console.error(chalk.red(`Unhandled error: ${message}`));
4466
+ try {
4467
+ const argv = process.argv;
4468
+ const flagIdx = argv.indexOf("--result-file");
4469
+ const resultFile = flagIdx !== -1 && flagIdx + 1 < argv.length ? argv[flagIdx + 1] : void 0;
4470
+ if (resultFile) {
4471
+ const payload = {
4472
+ success: false,
4473
+ error: { message, stage: "bootstrap" },
4474
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
4475
+ };
4476
+ await writeResultFileAtomically(resultFile, payload);
4477
+ }
4478
+ } catch {
4479
+ }
4480
+ return error instanceof ExitCodeError ? error.exitCode : 1;
4481
+ }
4482
+ }
4483
+ if (process.env.VITEST !== "1" && isDirectInvocation) {
4484
+ runVariantWorkerEntrypoint().then((exitCode) => {
4485
+ if (exitCode === 0) {
4486
+ process.exitCode = 0;
4487
+ } else {
4488
+ process.exit(exitCode);
4489
+ }
4490
+ }).catch((error) => {
4491
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}
4492
+ `);
4493
+ process.exit(1);
4494
+ });
4495
+ }
4496
+ export {
4497
+ __testOnlyWriteResultFileAtomically,
4498
+ attachBaselineComparisonIfAvailable,
4499
+ buildRepairTriggerEvidence,
4500
+ buildShutdownAbortReason,
4501
+ createProviderOutputForwarder,
4502
+ decideRepairAdmission,
4503
+ executeWorker,
4504
+ extractOriginalPrompt,
4505
+ findVariantWorktreePathForTimeout,
4506
+ formatVerboseWorkerCompletionMetric,
4507
+ initializeWorkerExecutionContext,
4508
+ isValidationArtifactOnlyPrompt,
4509
+ resolveInitialVerificationDisposition,
4510
+ resolveRepairPromotionPolicy,
4511
+ runVariantWorkerEntrypoint,
4512
+ serializeErrorForJson,
4513
+ shouldDowngradeSuccessfulResultForShutdown,
4514
+ shouldTrustVerificationLoopBaseline,
4515
+ tryCleanupRetainedWorktree
4516
+ };
4517
+ //# sourceMappingURL=variant-worker-COB5YTJX.js.map