agentic-qe 3.12.3 → 3.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/.agents/skills/aqe-plan-quality/SKILL.md +25 -0
  2. package/.agents/skills/aqe-plan-quality/agents/openai.yaml +4 -0
  3. package/.agents/skills/aqe-plan-quality/references/qe-routing.md +22 -0
  4. package/.agents/skills/aqe-review-quality/SKILL.md +24 -0
  5. package/.agents/skills/aqe-review-quality/agents/openai.yaml +4 -0
  6. package/.agents/skills/aqe-review-quality/references/quality-gates.md +20 -0
  7. package/.agents/skills/aqe-test-change/SKILL.md +26 -0
  8. package/.agents/skills/aqe-test-change/agents/openai.yaml +4 -0
  9. package/.agents/skills/aqe-test-change/references/test-specialties.md +23 -0
  10. package/.claude/helpers/.helpers-version +1 -1
  11. package/.claude/helpers/auto-memory-hook.mjs +430 -430
  12. package/.claude/helpers/helpers.manifest.json +6 -5
  13. package/.claude/helpers/hook-handler.cjs +565 -311
  14. package/.claude/helpers/intelligence.cjs +1058 -1058
  15. package/.claude/helpers/ruflo-hook.cjs +5 -1
  16. package/.claude/helpers/statusline.cjs +995 -682
  17. package/.claude/skills/qe-court/SKILL.md +186 -0
  18. package/.claude/skills/qe-court/config.json +27 -0
  19. package/.claude/skills/qe-court/evals/fixtures/seeded-mutant-delivery/README.md +38 -0
  20. package/.claude/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.test.ts +21 -0
  21. package/.claude/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.ts +25 -0
  22. package/.claude/skills/qe-court/evals/qe-court.yaml +70 -0
  23. package/.claude/skills/qe-court/schemas/output.json +92 -0
  24. package/.claude/skills/qe-court/scripts/validate-config.json +30 -0
  25. package/.claude/skills/skills-manifest.json +9 -8
  26. package/.codex/hooks/aqe-codex-hook.cjs +69 -0
  27. package/.codex/hooks/ruflo-codex-hook.cjs +94 -0
  28. package/.codex/hooks.json +169 -0
  29. package/CHANGELOG.md +159 -0
  30. package/README.md +3 -3
  31. package/assets/skills/qe-court/SKILL.md +186 -0
  32. package/assets/skills/qe-court/config.json +27 -0
  33. package/assets/skills/qe-court/evals/fixtures/seeded-mutant-delivery/README.md +38 -0
  34. package/assets/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.test.ts +21 -0
  35. package/assets/skills/qe-court/evals/fixtures/seeded-mutant-delivery/budget.ts +25 -0
  36. package/assets/skills/qe-court/evals/qe-court.yaml +70 -0
  37. package/assets/skills/qe-court/schemas/output.json +92 -0
  38. package/assets/skills/qe-court/scripts/validate-config.json +30 -0
  39. package/assets/skills/skills-manifest.json +9 -8
  40. package/dist/cli/bundle.js +5 -5
  41. package/dist/cli/chunks/adapter-VRZNL53W.js +2 -0
  42. package/dist/cli/chunks/{agent-booster-wasm-XFAQATTH.js → agent-booster-wasm-4VM3DE42.js} +2 -2
  43. package/dist/cli/chunks/{agent-handler-2ZV4CA3U.js → agent-handler-ZDLMZQQX.js} +2 -2
  44. package/dist/cli/chunks/{agent-memory-branch-6WGP7F5T.js → agent-memory-branch-P72MDHHV.js} +2 -2
  45. package/dist/cli/chunks/aqe-learning-engine-XCNMNERX.js +2 -0
  46. package/dist/cli/chunks/{arena-FWX7XZAE.js → arena-55FZGKEV.js} +4 -4
  47. package/dist/cli/chunks/{arena-KJUNQK4N.js → arena-GCRBQ26R.js} +2 -2
  48. package/dist/cli/chunks/{audit-YFUDEOKN.js → audit-VYAYVLIV.js} +3 -3
  49. package/dist/cli/chunks/base-VZZNR4UR.js +2 -0
  50. package/dist/cli/chunks/{hnswlib-node-SKTT5KIH.js → better-sqlite3-JDDFYVCX.js} +2 -2
  51. package/dist/cli/chunks/{brain-handler-ZCK4WTPK.js → brain-handler-IUKMRGWO.js} +3 -3
  52. package/dist/cli/chunks/{branch-enumerator-HTVINRYG.js → branch-enumerator-TUI3RWLX.js} +2 -2
  53. package/dist/cli/chunks/{browser-WUL2B77M.js → browser-NBQTZYX2.js} +2 -2
  54. package/dist/cli/chunks/browser-workflow-5DZNIFUY.js +2 -0
  55. package/dist/cli/chunks/{chunk-IWQHQLT6.js → chunk-23MT7OBY.js} +2 -2
  56. package/dist/cli/chunks/{chunk-KE3RK35K.js → chunk-2CQAWYYE.js} +1 -1
  57. package/dist/cli/chunks/{chunk-ADQFQBFJ.js → chunk-2D2XFUKI.js} +2 -2
  58. package/dist/cli/chunks/{chunk-2YDZXFO2.js → chunk-2G2QWV7B.js} +2 -2
  59. package/dist/cli/chunks/{chunk-HGJQSTQD.js → chunk-2ISLQU3G.js} +1 -1
  60. package/dist/cli/chunks/{chunk-6E47R27C.js → chunk-2OM3TDC4.js} +1 -1
  61. package/dist/cli/chunks/{chunk-WQASUQ5P.js → chunk-2XZ4BHWS.js} +1 -1
  62. package/dist/cli/chunks/{chunk-E2U3LTGM.js → chunk-3F4XH4ZA.js} +1 -1
  63. package/dist/cli/chunks/{chunk-YUDGQZJN.js → chunk-3K4YC3GC.js} +2 -2
  64. package/dist/cli/chunks/chunk-3KGCBAUH.js +2 -0
  65. package/dist/cli/chunks/{chunk-PXCJDB7J.js → chunk-3Y6CHW67.js} +1 -1
  66. package/dist/cli/chunks/{chunk-MOX25RZQ.js → chunk-4QMWWYNU.js} +2 -2
  67. package/dist/cli/chunks/{chunk-XZGOXLZH.js → chunk-4WGSMODQ.js} +1 -1
  68. package/dist/cli/chunks/{chunk-2CPJCXV6.js → chunk-55WDVSCM.js} +2 -2
  69. package/dist/cli/chunks/{chunk-EHO52NKU.js → chunk-5BB5DUL4.js} +2 -2
  70. package/dist/cli/chunks/{chunk-BEPP57C2.js → chunk-6C3MZLYW.js} +2 -2
  71. package/dist/cli/chunks/{chunk-DTZFZ5M7.js → chunk-6QKQFHS7.js} +2 -2
  72. package/dist/cli/chunks/{chunk-KXKACV3E.js → chunk-6XZXMEK4.js} +3 -3
  73. package/dist/cli/chunks/{chunk-L6GZGEFQ.js → chunk-7D7XFZZI.js} +2 -2
  74. package/dist/cli/chunks/{chunk-NLDLUHOF.js → chunk-7WEHZCSK.js} +2 -2
  75. package/dist/cli/chunks/{chunk-TXLPOXAN.js → chunk-A2MG3YXO.js} +1 -1
  76. package/dist/cli/chunks/{chunk-HJ2LG5IH.js → chunk-AHTOWWSE.js} +1 -1
  77. package/dist/cli/chunks/{chunk-GV2BS5NC.js → chunk-AOMXMFDH.js} +2 -2
  78. package/dist/cli/chunks/{chunk-EH7TSJPS.js → chunk-ARTLSAXO.js} +2 -2
  79. package/dist/cli/chunks/{chunk-CXMOIE7D.js → chunk-AY7S7AWN.js} +2 -2
  80. package/dist/cli/chunks/{chunk-2LNDU7AW.js → chunk-AYYDO52G.js} +2 -2
  81. package/dist/cli/chunks/chunk-BBLWZT5I.js +2 -0
  82. package/dist/cli/chunks/{chunk-KRS4KGX5.js → chunk-BF5BKSDU.js} +2 -2
  83. package/dist/cli/chunks/{chunk-BQ2K4BPD.js → chunk-BOCEOLLJ.js} +2 -2
  84. package/dist/cli/chunks/{chunk-KKOFH26C.js → chunk-CE6LYEHT.js} +1 -1
  85. package/dist/cli/chunks/{chunk-GS6G7AVS.js → chunk-CWP4RMOM.js} +2 -2
  86. package/dist/cli/chunks/{chunk-DCYBV6HV.js → chunk-CWXDL7AH.js} +1 -1
  87. package/dist/cli/chunks/{chunk-KGHSKDC7.js → chunk-DTRFZD7N.js} +2 -2
  88. package/dist/cli/chunks/{chunk-CYSBM52D.js → chunk-DVPGQG4W.js} +2 -2
  89. package/dist/cli/chunks/{chunk-MSDIIRLM.js → chunk-E4D47QTF.js} +2 -2
  90. package/dist/cli/chunks/{chunk-MB7TZQW3.js → chunk-EAKHU5YX.js} +3 -3
  91. package/dist/cli/chunks/{chunk-TP3UAWMB.js → chunk-EGMGOWCE.js} +2 -2
  92. package/dist/cli/chunks/{chunk-4EHW4TNA.js → chunk-ELMUHNXN.js} +2 -2
  93. package/dist/cli/chunks/chunk-EVDYFGVH.js +2 -0
  94. package/dist/cli/chunks/{chunk-D4GMAUTP.js → chunk-FDUSWM6O.js} +98 -88
  95. package/dist/cli/chunks/{chunk-YEC55GO5.js → chunk-FM272B4O.js} +2 -2
  96. package/dist/cli/chunks/{chunk-DMD6WVJ2.js → chunk-FQUUMC57.js} +2 -2
  97. package/dist/cli/chunks/{chunk-Y625LP6K.js → chunk-FQXQJMSF.js} +2 -2
  98. package/dist/cli/chunks/{chunk-Z3SXMYVI.js → chunk-FRAGSKXQ.js} +3 -3
  99. package/dist/cli/chunks/{chunk-MOXKKY5Q.js → chunk-GASOBSNB.js} +4 -4
  100. package/dist/cli/chunks/{chunk-PTPN6HQ7.js → chunk-GJEEPKAT.js} +2 -2
  101. package/dist/cli/chunks/{chunk-WFPGIP4N.js → chunk-GOV2MHLV.js} +2 -2
  102. package/dist/cli/chunks/{chunk-NKTLKMUB.js → chunk-GTPZVLL6.js} +1 -1
  103. package/dist/cli/chunks/chunk-H7YZ2YF2.js +3 -0
  104. package/dist/cli/chunks/{chunk-WKE6WL5C.js → chunk-HFI5PHG5.js} +3 -3
  105. package/dist/cli/chunks/chunk-HUMQU4ES.js +153 -0
  106. package/dist/cli/chunks/{chunk-5FAWIIWF.js → chunk-HYIRFJDB.js} +2 -2
  107. package/dist/cli/chunks/{chunk-DZ775UGW.js → chunk-IBSBOHUX.js} +2 -2
  108. package/dist/cli/chunks/{chunk-NAMJGRGC.js → chunk-IJA4WS7B.js} +2 -2
  109. package/dist/cli/chunks/{chunk-XUUVAAHV.js → chunk-IJP42OGW.js} +2 -2
  110. package/dist/cli/chunks/{chunk-UZ7FXVH5.js → chunk-IMQKEFW6.js} +1 -1
  111. package/dist/cli/chunks/{chunk-MZ7SIO6R.js → chunk-INYS35DV.js} +2 -2
  112. package/dist/cli/chunks/{chunk-MS6VOSPY.js → chunk-IV2VCR75.js} +5 -5
  113. package/dist/cli/chunks/{chunk-UAPUA6OY.js → chunk-IZO6TPGX.js} +2 -2
  114. package/dist/cli/chunks/{chunk-XBOCRCC6.js → chunk-J45DX3IK.js} +1 -1
  115. package/dist/cli/chunks/{chunk-RE42RJYR.js → chunk-J4T6D2OQ.js} +2 -2
  116. package/dist/cli/chunks/{chunk-Y5L37K7X.js → chunk-JAPOMPFD.js} +2 -2
  117. package/dist/cli/chunks/{chunk-M7W6VJ65.js → chunk-JELNVHBF.js} +1 -1
  118. package/dist/cli/chunks/{chunk-YDYKFSD2.js → chunk-JOTNKZ7A.js} +87 -87
  119. package/dist/cli/chunks/{chunk-VUCVSKJC.js → chunk-KNWDXI3I.js} +2 -2
  120. package/dist/cli/chunks/{chunk-SPI4LUJ6.js → chunk-KW5NBORV.js} +2 -2
  121. package/dist/cli/chunks/{chunk-2OX74DOO.js → chunk-L7IOTWWY.js} +1 -1
  122. package/dist/cli/chunks/{chunk-VFYMWDSJ.js → chunk-LJQ27PUE.js} +1 -1
  123. package/dist/cli/chunks/{chunk-NT66CT73.js → chunk-LSKQUUUN.js} +2 -2
  124. package/dist/cli/chunks/{chunk-ROFCS47F.js → chunk-LSZZQ7H6.js} +1 -1
  125. package/dist/cli/chunks/{chunk-Y6XNISHP.js → chunk-LTKNCYMO.js} +2 -2
  126. package/dist/cli/chunks/{chunk-7WF3TW3G.js → chunk-LTWT4GZD.js} +4 -4
  127. package/dist/cli/chunks/chunk-LVHMXGDI.js +29 -0
  128. package/dist/cli/chunks/{chunk-3YC4YUGB.js → chunk-M3T6FB54.js} +2 -2
  129. package/dist/cli/chunks/{chunk-M32DTUZM.js → chunk-MAYZTGJ2.js} +3 -3
  130. package/dist/cli/chunks/{chunk-RLBNAB6Y.js → chunk-MCIO7BDK.js} +1 -1
  131. package/dist/cli/chunks/{chunk-SFS3UHNF.js → chunk-MPD7RR4P.js} +1 -1
  132. package/dist/cli/chunks/{chunk-DDYP6FBC.js → chunk-MUFYDKVC.js} +2 -2
  133. package/dist/cli/chunks/{chunk-ZFLE4D4X.js → chunk-MX5ZDKRR.js} +2 -2
  134. package/dist/cli/chunks/{chunk-WBZNLFTV.js → chunk-MXKHIZVM.js} +5 -5
  135. package/dist/cli/chunks/chunk-MY47CR27.js +2 -0
  136. package/dist/cli/chunks/chunk-N7WAZ2Y6.js +2 -0
  137. package/dist/cli/chunks/{chunk-2HCMRGMO.js → chunk-NHV4PTG6.js} +2 -2
  138. package/dist/cli/chunks/{chunk-HJ4U64BL.js → chunk-NP4CP3LR.js} +2 -2
  139. package/dist/cli/chunks/{chunk-UIHZ34SJ.js → chunk-OCKTPTQ7.js} +2 -2
  140. package/dist/cli/chunks/{chunk-SGMJ277D.js → chunk-OE4B6LDZ.js} +1 -1
  141. package/dist/cli/chunks/{chunk-SV7J5FDW.js → chunk-OPQY2333.js} +2 -2
  142. package/dist/cli/chunks/{chunk-FTM562PF.js → chunk-ORDH4VPL.js} +1 -1
  143. package/dist/cli/chunks/{chunk-YOG5KQZF.js → chunk-P4Y3G6OB.js} +2 -2
  144. package/dist/cli/chunks/{chunk-LHAUFY4Y.js → chunk-PIOO2M4W.js} +2 -2
  145. package/dist/cli/chunks/{chunk-UGW23T6S.js → chunk-PKMCZFET.js} +2 -2
  146. package/dist/cli/chunks/{chunk-OPG2HV2W.js → chunk-QES4QHQW.js} +1 -1
  147. package/dist/cli/chunks/{chunk-BDGKB2PT.js → chunk-QG6BXSNJ.js} +2 -2
  148. package/dist/cli/chunks/{chunk-BSNNTOHY.js → chunk-QLOOW23R.js} +3 -3
  149. package/dist/cli/chunks/{chunk-AIWRYWK2.js → chunk-RSCGBHLM.js} +2 -2
  150. package/dist/cli/chunks/{chunk-LCM7TY76.js → chunk-RZ6CO3RZ.js} +2 -2
  151. package/dist/cli/chunks/chunk-S6F3IJMK.js +2 -0
  152. package/dist/cli/chunks/{chunk-WUE53ZPH.js → chunk-S6VNPKHO.js} +1 -1
  153. package/dist/cli/chunks/{chunk-L2X3BWMN.js → chunk-SHWXADCI.js} +2 -2
  154. package/dist/cli/chunks/{chunk-GMFFMJD6.js → chunk-SPJQJWGK.js} +2 -2
  155. package/dist/cli/chunks/{chunk-KVHCWH4H.js → chunk-SS6K4FBH.js} +2 -2
  156. package/dist/cli/chunks/{chunk-ZGKQCUPB.js → chunk-SXADKQJN.js} +2 -2
  157. package/dist/cli/chunks/{chunk-LGYEOYQJ.js → chunk-TBQTGQ75.js} +2 -2
  158. package/dist/cli/chunks/{chunk-J2RJOJ5Q.js → chunk-TDGE52HJ.js} +1 -1
  159. package/dist/cli/chunks/chunk-THFLRJT6.js +54 -0
  160. package/dist/cli/chunks/{chunk-GGTCD4MA.js → chunk-TQ2MA3SR.js} +1 -1
  161. package/dist/cli/chunks/{chunk-NOSQI2OW.js → chunk-UCQ66N6M.js} +3 -3
  162. package/dist/cli/chunks/{chunk-CL6SNCFF.js → chunk-UHGMS2PJ.js} +1 -1
  163. package/dist/cli/chunks/{chunk-XDHGCBTS.js → chunk-UHKXKWMD.js} +2 -2
  164. package/dist/cli/chunks/{chunk-PEHEANAM.js → chunk-UJ6TMZC6.js} +2 -2
  165. package/dist/cli/chunks/{chunk-PSDH7CIL.js → chunk-UKBDH27A.js} +1 -1
  166. package/dist/cli/chunks/{chunk-ZTKCGEB6.js → chunk-UMCEEXQN.js} +1 -1
  167. package/dist/cli/chunks/{chunk-KA4EAMMQ.js → chunk-USUFTHHT.js} +3 -3
  168. package/dist/cli/chunks/{chunk-QILF6BZH.js → chunk-V32MDID3.js} +2 -2
  169. package/dist/cli/chunks/{chunk-6SUSRXXF.js → chunk-VAJT6QWX.js} +1 -1
  170. package/dist/cli/chunks/{chunk-7Q74K3HZ.js → chunk-VLUJWI56.js} +1 -1
  171. package/dist/cli/chunks/{chunk-DW7OI5IF.js → chunk-WINA3XUT.js} +2 -2
  172. package/dist/cli/chunks/{chunk-S47YGWXK.js → chunk-WWCH5SSF.js} +2 -2
  173. package/dist/cli/chunks/{chunk-FJACKKRL.js → chunk-WWP2VXYJ.js} +2 -2
  174. package/dist/cli/chunks/{chunk-N4ML23ZG.js → chunk-WZROSTQZ.js} +1 -1
  175. package/dist/cli/chunks/{chunk-FXOOOJQD.js → chunk-XFUF654L.js} +1 -1
  176. package/dist/cli/chunks/{chunk-PDX7IYTJ.js → chunk-XN2CD5S6.js} +2 -2
  177. package/dist/cli/chunks/{chunk-DHUZHT5D.js → chunk-XOQQGZFY.js} +1 -1
  178. package/dist/cli/chunks/{chunk-4HP7N6SP.js → chunk-XSCOEY4C.js} +2 -2
  179. package/dist/cli/chunks/{chunk-KNWBRMLL.js → chunk-Y734CWHJ.js} +2 -2
  180. package/dist/cli/chunks/{chunk-NJDLJ3KD.js → chunk-YBPCBFEE.js} +2 -2
  181. package/dist/cli/chunks/{chunk-67BCEHU5.js → chunk-YLAEIS6F.js} +1 -1
  182. package/dist/cli/chunks/{chunk-E53UR2EW.js → chunk-YMMVCOPF.js} +3 -3
  183. package/dist/cli/chunks/{chunk-VSD6JE2H.js → chunk-YQCAXYBF.js} +2 -2
  184. package/dist/cli/chunks/{chunk-32L7DKNQ.js → chunk-YRVUYM62.js} +2 -2
  185. package/dist/cli/chunks/{chunk-LNIHLNW4.js → chunk-YVKMHXQK.js} +3 -3
  186. package/dist/cli/chunks/{chunk-CHFTHSMM.js → chunk-ZCLFAOVT.js} +2 -2
  187. package/dist/cli/chunks/{chunk-AZ24ONMX.js → chunk-ZH6ZBDVV.js} +1 -1
  188. package/dist/cli/chunks/{chunk-R6WMGSEK.js → chunk-ZHEKGB4A.js} +2 -2
  189. package/dist/cli/chunks/{chunk-EOUJ6X5H.js → chunk-ZIBW7CB4.js} +1 -1
  190. package/dist/cli/chunks/{chunk-OBL6W4Z5.js → chunk-ZLCATRXI.js} +2 -2
  191. package/dist/cli/chunks/{chunk-UGXHMQ6P.js → chunk-ZXX2VFMA.js} +2 -2
  192. package/dist/cli/chunks/{chunk-72QQDR3Y.js → chunk-ZYPESQ4M.js} +2 -2
  193. package/dist/cli/chunks/{ci-MMLUV6L6.js → ci-HHL5WQXQ.js} +2 -2
  194. package/dist/cli/chunks/{ci-output-25GS6RXR.js → ci-output-HVOJC2KN.js} +2 -2
  195. package/dist/cli/chunks/{circuit-breaker-4OWAN6R6.js → circuit-breaker-HRXMIY2G.js} +2 -2
  196. package/dist/cli/chunks/{claude-flow-setup-LR3SRBX6.js → claude-flow-setup-3I7WVMZN.js} +2 -2
  197. package/dist/cli/chunks/client-EY2IYQDL.js +2 -0
  198. package/dist/cli/chunks/{cline-installer-YSZWRZUI.js → cline-installer-NBREL4QT.js} +2 -2
  199. package/dist/cli/chunks/{code-UUWUIXI7.js → code-TX4E2RWU.js} +2 -2
  200. package/dist/cli/chunks/{code-index-extractor-2LSPQORU.js → code-index-extractor-YELOFLSL.js} +2 -2
  201. package/dist/cli/chunks/codex-installer-HEX3KFRB.js +10 -0
  202. package/dist/cli/chunks/{completions-YKXBKZSO.js → completions-72GGFRGG.js} +2 -2
  203. package/dist/cli/chunks/{complexity-analyzer-HNT2QRWB.js → complexity-analyzer-WRAKDYUK.js} +2 -2
  204. package/dist/cli/chunks/{continuedev-installer-AW5VCB66.js → continuedev-installer-UGYKSKTI.js} +2 -2
  205. package/dist/cli/chunks/{copilot-installer-B6SVZXQT.js → copilot-installer-RPCRUKIJ.js} +2 -2
  206. package/dist/cli/chunks/core-handlers-G4GLA4DT.js +2 -0
  207. package/dist/cli/chunks/{cost-tracker-POZMBN2V.js → cost-tracker-CNHJ7G4M.js} +2 -2
  208. package/dist/cli/chunks/{coverage-V5BGPN5Q.js → coverage-RHIQ4XEX.js} +3 -3
  209. package/dist/cli/chunks/cross-domain-router-P3K4IH5H.js +2 -0
  210. package/dist/cli/chunks/{cursor-installer-EYBI4QVK.js → cursor-installer-KSRVA4V2.js} +2 -2
  211. package/dist/cli/chunks/{daemon-CF6ENQB2.js → daemon-IT4AAFBW.js} +3 -3
  212. package/dist/cli/chunks/{daemon-HKARXY2W.js → daemon-QBXSJABV.js} +4 -4
  213. package/dist/cli/chunks/{dag-attention-scheduler-XIL5IAP7.js → dag-attention-scheduler-F7WCQTLY.js} +2 -2
  214. package/dist/cli/chunks/{detect-RRX2U2KK.js → detect-2IYU332U.js} +2 -2
  215. package/dist/cli/chunks/{dist-node-DOANNRCS.js → dist-node-CIYNYCYN.js} +2 -2
  216. package/dist/cli/chunks/{domain-handler-QMTJV5OR.js → domain-handler-QRYQO2QK.js} +2 -2
  217. package/dist/cli/chunks/{domain-transfer-FSNH75XW.js → domain-transfer-2OQDOD3G.js} +2 -2
  218. package/dist/cli/chunks/dream-IT4ZQGEO.js +2 -0
  219. package/dist/cli/chunks/{embed-and-insert-pattern-NI7PGONV.js → embed-and-insert-pattern-P2IFC7JL.js} +2 -2
  220. package/dist/cli/chunks/{eval-6ZAF2RY3.js → eval-SBPK37IB.js} +2 -2
  221. package/dist/cli/chunks/{experience-capture-middleware-JMXR7N5G.js → experience-capture-middleware-3GMFND3F.js} +3 -3
  222. package/dist/cli/chunks/{fast-paths-YB7XZZ76.js → fast-paths-4OYYII2F.js} +2 -2
  223. package/dist/cli/chunks/{feature-flags-2RC4GFC4.js → feature-flags-BM6QTMMC.js} +2 -2
  224. package/dist/cli/chunks/{feature-flags-KJSP7KR6.js → feature-flags-NFCAYUWO.js} +2 -2
  225. package/dist/cli/chunks/{file-discovery-SUPBXFYI.js → file-discovery-2M3ZUAGC.js} +2 -2
  226. package/dist/cli/chunks/{fleet-KSXFOLFW.js → fleet-QMGGVIDV.js} +3 -3
  227. package/dist/cli/chunks/{gnn-wrapper-DFZ5KPPK.js → gnn-wrapper-WGMAGZMO.js} +2 -2
  228. package/dist/cli/chunks/{heartbeat-handler-G3EADK2H.js → heartbeat-handler-5RSMEZGG.js} +4 -4
  229. package/dist/cli/chunks/heartbeat-scheduler-UUWSPHF2.js +2 -0
  230. package/dist/cli/chunks/hnsw-adapter-YUJVSFPD.js +2 -0
  231. package/dist/cli/chunks/hnsw-index-FQZ47RSJ.js +2 -0
  232. package/dist/cli/chunks/{hnsw-legacy-bridge-MA676GER.js → hnsw-legacy-bridge-TYPQ2T6P.js} +2 -2
  233. package/dist/cli/chunks/{better-sqlite3-FE55OGYB.js → hnswlib-node-GMRPPMDM.js} +2 -2
  234. package/dist/cli/chunks/{hooks-HTCPMZNZ.js → hooks-NUC5P3OJ.js} +10 -10
  235. package/dist/cli/chunks/hybrid-router-T5MF73NF.js +2 -0
  236. package/dist/cli/chunks/{hypergraph-engine-QPB3IH4A.js → hypergraph-engine-OIB7WK54.js} +2 -2
  237. package/dist/cli/chunks/{hypergraph-handler-GBFSVD7N.js → hypergraph-handler-XX2N75QC.js} +3 -3
  238. package/dist/cli/chunks/impact-analyzer-AEGELYMD.js +2 -0
  239. package/dist/cli/chunks/{init-handler-XYBTBCPD.js → init-handler-AKSTJMZY.js} +6 -6
  240. package/dist/cli/chunks/init-wizard-WKX3OGWM.js +2 -0
  241. package/dist/cli/chunks/kernel-5CVWFIGR.js +2 -0
  242. package/dist/cli/chunks/{kilocode-installer-LY6JOBFY.js → kilocode-installer-375V5ZZB.js} +2 -2
  243. package/dist/cli/chunks/{kiro-installer-JF6NXTJL.js → kiro-installer-GKY5GB5Q.js} +2 -2
  244. package/dist/cli/chunks/knowledge-graph-EGPMNDMT.js +2 -0
  245. package/dist/cli/chunks/{learning-BIISN67N.js → learning-2CQE3QP6.js} +3 -3
  246. package/dist/cli/chunks/{llm-router-YZUNVZQE.js → llm-router-FTQNRF45.js} +5 -5
  247. package/dist/cli/chunks/llm-router-service-H4LXOARB.js +2 -0
  248. package/dist/cli/chunks/{load-MTWNBNLL.js → load-3DBAO5ZG.js} +2 -2
  249. package/dist/cli/chunks/load-test-OOOGITSN.js +2 -0
  250. package/dist/cli/chunks/{mcp-37PYMNHQ.js → mcp-AWR6TDXM.js} +2 -2
  251. package/dist/cli/chunks/{memory-IXUUDCI3.js → memory-GI4LCNXY.js} +5 -5
  252. package/dist/cli/chunks/memory-backend-O2YOT4LW.js +2 -0
  253. package/dist/cli/chunks/{memory-handlers-RM2VOFJX.js → memory-handlers-MALKG7GP.js} +2 -2
  254. package/dist/cli/chunks/{multi-model-executor-RKKS5XYG.js → multi-model-executor-SWFT5U72.js} +2 -2
  255. package/dist/cli/chunks/{opencode-installer-3VXI5MTR.js → opencode-installer-EYXGYJX5.js} +2 -2
  256. package/dist/cli/chunks/{orchestrator-UO3ZOGFZ.js → orchestrator-MP3EAZVC.js} +5 -5
  257. package/dist/cli/chunks/pattern-null-store-WBOHE2XL.js +2 -0
  258. package/dist/cli/chunks/{pattern-usage-recorder-YJKRL2GI.js → pattern-usage-recorder-25P3R3W7.js} +2 -2
  259. package/dist/cli/chunks/{pipeline-GJQJKXWX.js → pipeline-LSAFL25D.js} +2 -2
  260. package/dist/cli/chunks/{platform-RHVCZK6C.js → platform-IJ6DJ2PG.js} +2 -2
  261. package/dist/cli/chunks/{plugin-ZKAIW7O6.js → plugin-OXOZRZW2.js} +2 -2
  262. package/dist/cli/chunks/{prime-radiant-advanced-wasm-4X3DSKQV.js → prime-radiant-advanced-wasm-HJNJQQ3R.js} +2 -2
  263. package/dist/cli/chunks/protocol-executor-JCNTPW5J.js +2 -0
  264. package/dist/cli/chunks/{protocol-handler-KKYQZMB2.js → protocol-handler-TCMUH2HL.js} +2 -2
  265. package/dist/cli/chunks/{prove-OD6RPKWX.js → prove-ADXQ2GOX.js} +2 -2
  266. package/dist/cli/chunks/provider-manager-LPGQ5GOO.js +2 -0
  267. package/dist/cli/chunks/qe-reasoning-bank-FWVYVSPP.js +2 -0
  268. package/dist/cli/chunks/{quality-ZRWBXCKO.js → quality-EWP36ORX.js} +2 -2
  269. package/dist/cli/chunks/{quality-gate-Y6BWQV7J.js → quality-gate-3BIG7PVU.js} +3 -3
  270. package/dist/cli/chunks/queen-coordinator-UXNALRVD.js +2 -0
  271. package/dist/cli/chunks/{real-embeddings-YYEUO4P2.js → real-embeddings-D4NBT7W5.js} +2 -2
  272. package/dist/cli/chunks/{roocode-installer-JBCPS3FK.js → roocode-installer-DOPWH6YV.js} +2 -2
  273. package/dist/cli/chunks/router-C6LUIQYY.js +2 -0
  274. package/dist/cli/chunks/routing-feedback-KMSGGDVD.js +2 -0
  275. package/dist/cli/chunks/{routing-handler-KTPJOSBJ.js → routing-handler-5ADEFOHS.js} +2 -2
  276. package/dist/cli/chunks/{ruvector-commands-SCZZVRE7.js → ruvector-commands-PLMEIHSN.js} +2 -2
  277. package/dist/cli/chunks/{rvf-dual-writer-IP7GELQJ.js → rvf-dual-writer-EQWKVNQB.js} +2 -2
  278. package/dist/cli/chunks/{rvf-migration-adapter-WLFTDARU.js → rvf-migration-adapter-2OWFUUCG.js} +2 -2
  279. package/dist/cli/chunks/{rvf-migration-coordinator-MGFDQ5WD.js → rvf-migration-coordinator-URAETAPU.js} +2 -2
  280. package/dist/cli/chunks/rvf-native-adapter-K54BELUE.js +2 -0
  281. package/dist/cli/chunks/{rvf-store-integrity-OTOAGT5W.js → rvf-store-integrity-4AWPW4TF.js} +2 -2
  282. package/dist/cli/chunks/safe-db-NGOZWF2D.js +2 -0
  283. package/dist/cli/chunks/schedule-B3Y5P64E.js +2 -0
  284. package/dist/cli/chunks/scheduler-Z6QVRMTB.js +2 -0
  285. package/dist/cli/chunks/{security-B2CLZKRB.js → security-HDLZVM62.js} +3 -3
  286. package/dist/cli/chunks/{shared-rvf-adapter-2PMFAQMN.js → shared-rvf-adapter-YQT7PF7X.js} +2 -2
  287. package/dist/cli/chunks/{shared-rvf-dual-writer-B6P732AV.js → shared-rvf-dual-writer-N5D3NSJ7.js} +2 -2
  288. package/dist/cli/chunks/sqlite-persistence-PLOUGATS.js +2 -0
  289. package/dist/cli/chunks/{status-handler-M6SN2W2D.js → status-handler-KLYRJ2MR.js} +2 -2
  290. package/dist/cli/chunks/{structural-health-YCCTGI3K.js → structural-health-6LKVRP6Y.js} +2 -2
  291. package/dist/cli/chunks/sync-7VMFPBVB.js +2 -0
  292. package/dist/cli/chunks/{sync-KSRF77ID.js → sync-YYOW6L6W.js} +2 -2
  293. package/dist/cli/chunks/{task-handler-MIKRB2SL.js → task-handler-RKQDGFN2.js} +2 -2
  294. package/dist/cli/chunks/{task-handlers-YXKRUBQ4.js → task-handlers-6YJ4QTEP.js} +3 -3
  295. package/dist/cli/chunks/{test-MLOLQCB7.js → test-ASPUIUJH.js} +4 -4
  296. package/dist/cli/chunks/{test-scheduling-3KXESUZS.js → test-scheduling-I7ABQBBU.js} +3 -3
  297. package/dist/cli/chunks/{token-bootstrap-6V2PMDBJ.js → token-bootstrap-2XZBTODN.js} +2 -2
  298. package/dist/cli/chunks/{token-usage-DP6THJ3I.js → token-usage-TMUE6PTF.js} +2 -2
  299. package/dist/cli/chunks/transformers-FDHHH4SL.js +2 -0
  300. package/dist/cli/chunks/{tree-sitter-wasm-parser-COK2XERS.js → tree-sitter-wasm-parser-G7PGZA5C.js} +2 -2
  301. package/dist/cli/chunks/{types-PYHUCVOZ.js → types-JGT57UFP.js} +2 -2
  302. package/dist/cli/chunks/unified-memory-P5YVLMFI.js +2 -0
  303. package/dist/cli/chunks/unified-memory-hnsw-7HI43A2O.js +2 -0
  304. package/dist/cli/chunks/unified-persistence-U26YP3N3.js +2 -0
  305. package/dist/cli/chunks/{upgrade-ONP2HNGL.js → upgrade-V6UQODJF.js} +2 -2
  306. package/dist/cli/chunks/{validate-NWSICDAY.js → validate-UBZAE5RW.js} +2 -2
  307. package/dist/cli/chunks/{validate-swarm-KXS5P3U7.js → validate-swarm-TSO2MI5X.js} +2 -2
  308. package/dist/cli/chunks/{vibium-TZSGZRCQ.js → vibium-7G3VYSQA.js} +2 -2
  309. package/dist/cli/chunks/visual-security-6FCDY5FF.js +2 -0
  310. package/dist/cli/chunks/{web-tree-sitter-V2FADNRA.js → web-tree-sitter-MIYJSF2L.js} +2 -2
  311. package/dist/cli/chunks/{windsurf-installer-GQM7KWDC.js → windsurf-installer-5TLZSQIJ.js} +2 -2
  312. package/dist/cli/chunks/witness-chain-I3K3WQID.js +2 -0
  313. package/dist/cli/chunks/{witness-chain-GTITDIA2.js → witness-chain-LTV7H2HM.js} +2 -2
  314. package/dist/cli/chunks/{witness-key-manager-AHRM2M52.js → witness-key-manager-PAJ2J4AL.js} +2 -2
  315. package/dist/cli/chunks/{workflow-XCGHEL3I.js → workflow-DL3ESR2H.js} +4 -4
  316. package/dist/cli/chunks/workflow-orchestrator-MAALP4WA.js +2 -0
  317. package/dist/cli/chunks/{wrappers-VGO2GO4J.js → wrappers-5HSU665E.js} +2 -2
  318. package/dist/cli/commands/llm-router.js +1 -0
  319. package/dist/cli/handlers/init-handler.js +1 -1
  320. package/dist/coordination/handlers/coverage-collection.d.ts +161 -0
  321. package/dist/coordination/handlers/coverage-collection.js +639 -0
  322. package/dist/coordination/handlers/coverage-handlers.js +199 -146
  323. package/dist/coordination/handlers/handler-types.d.ts +6 -1
  324. package/dist/coordination/handlers/handler-utils.js +10 -3
  325. package/dist/coordination/handlers/security-handlers.js +17 -2
  326. package/dist/coordination/handlers/test-execution-handlers.js +16 -1
  327. package/dist/coordination/result-saver.js +119 -97
  328. package/dist/coordination/task-executor.d.ts +26 -1
  329. package/dist/coordination/task-executor.js +52 -4
  330. package/dist/domains/code-intelligence/services/knowledge-graph.js +8 -0
  331. package/dist/domains/coverage-analysis/services/coverage-analyzer.js +4 -0
  332. package/dist/domains/coverage-analysis/services/gap-detector.js +4 -0
  333. package/dist/domains/defect-intelligence/services/defect-predictor.js +4 -0
  334. package/dist/domains/defect-intelligence/services/root-cause-analyzer.js +4 -0
  335. package/dist/domains/quality-assessment/services/deployment-advisor.js +4 -0
  336. package/dist/domains/quality-assessment/services/quality-analyzer.js +4 -0
  337. package/dist/domains/security-compliance/services/scanners/sast-scanner.js +4 -0
  338. package/dist/domains/test-generation/index.js +17 -2
  339. package/dist/domains/test-generation/services/test-generator.js +31 -9
  340. package/dist/init/codex-installer.d.ts +13 -0
  341. package/dist/init/codex-installer.js +122 -1
  342. package/dist/init/phases/09-assets.js +4 -0
  343. package/dist/init/phases/phase-interface.d.ts +1 -1
  344. package/dist/init/skills-installer.js +1 -0
  345. package/dist/integrations/embeddings/base/EmbeddingGenerator.js +13 -1
  346. package/dist/kernel/unified-memory.js +4 -0
  347. package/dist/learning/qe-flywheel/corpus-scorer.js +10 -7
  348. package/dist/learning/qe-flywheel/generation.d.ts +7 -0
  349. package/dist/learning/qe-flywheel/generation.js +5 -0
  350. package/dist/learning/qe-flywheel/witness-verify.d.ts +86 -0
  351. package/dist/learning/qe-flywheel/witness-verify.js +156 -0
  352. package/dist/learning/real-embeddings.js +15 -1
  353. package/dist/mcp/bundle.js +455 -434
  354. package/dist/mcp/handlers/domain-handler-configs.js +79 -14
  355. package/dist/mcp/types.d.ts +42 -4
  356. package/dist/optimization/session-cache.d.ts +13 -1
  357. package/dist/optimization/session-cache.js +27 -2
  358. package/dist/shared/db-recovery.d.ts +55 -0
  359. package/dist/shared/db-recovery.js +184 -0
  360. package/dist/shared/llm/billing-modes.js +5 -2
  361. package/dist/shared/llm/cost-tracker.js +1 -0
  362. package/dist/shared/llm/interfaces.d.ts +14 -1
  363. package/dist/shared/llm/llm-router-service.js +59 -4
  364. package/dist/shared/llm/provider-manager.d.ts +1 -1
  365. package/dist/shared/llm/provider-manager.js +7 -3
  366. package/dist/shared/llm/providers/claude-code.js +12 -3
  367. package/dist/shared/llm/providers/codex.d.ts +58 -0
  368. package/dist/shared/llm/providers/codex.js +305 -0
  369. package/dist/shared/llm/providers/index.d.ts +1 -0
  370. package/dist/shared/llm/providers/index.js +1 -0
  371. package/dist/shared/llm/router/agent-router-config.d.ts +46 -2
  372. package/dist/shared/llm/router/agent-router-config.js +124 -2
  373. package/dist/shared/llm/router/config-store.d.ts +17 -1
  374. package/dist/shared/llm/router/config-store.js +108 -0
  375. package/dist/shared/llm/router/hybrid-router.js +2 -2
  376. package/dist/shared/llm/router/index.d.ts +2 -2
  377. package/dist/shared/llm/router/index.js +2 -0
  378. package/dist/shared/llm/router/types.d.ts +44 -0
  379. package/dist/shared/llm/router/types.js +1 -0
  380. package/dist/shared/llm/spend-ledger.d.ts +24 -0
  381. package/dist/shared/llm/spend-ledger.js +86 -15
  382. package/dist/shared/llm/translation/message-formatter.js +1 -0
  383. package/dist/shared/safe-db.d.ts +10 -0
  384. package/dist/shared/safe-db.js +17 -0
  385. package/dist/skills/qe-court/referee.d.ts +62 -0
  386. package/dist/skills/qe-court/referee.js +78 -0
  387. package/dist/validation/gate-reexecute.d.ts +9 -0
  388. package/dist/validation/gate-reexecute.js +61 -0
  389. package/dist/validation/paired-bootstrap.d.ts +36 -0
  390. package/dist/validation/paired-bootstrap.js +58 -0
  391. package/package.json +9 -2
  392. package/dist/cli/chunks/adapter-D657MKZY.js +0 -2
  393. package/dist/cli/chunks/aqe-learning-engine-AFR6OZJK.js +0 -2
  394. package/dist/cli/chunks/base-K5QRGZWE.js +0 -2
  395. package/dist/cli/chunks/browser-workflow-ZMMKCGYW.js +0 -2
  396. package/dist/cli/chunks/chunk-6HQDPDN5.js +0 -2
  397. package/dist/cli/chunks/chunk-6SQ72FG7.js +0 -2
  398. package/dist/cli/chunks/chunk-7XUM4LBC.js +0 -2
  399. package/dist/cli/chunks/chunk-FHHCH7WL.js +0 -2
  400. package/dist/cli/chunks/chunk-G5OGKVLO.js +0 -2
  401. package/dist/cli/chunks/chunk-ILRKO6A5.js +0 -43
  402. package/dist/cli/chunks/chunk-NX522PRH.js +0 -153
  403. package/dist/cli/chunks/chunk-PPUDKQ4X.js +0 -29
  404. package/dist/cli/chunks/chunk-RSZOCQOL.js +0 -2
  405. package/dist/cli/chunks/chunk-ULQCEM7K.js +0 -2
  406. package/dist/cli/chunks/chunk-XQ5JT7KM.js +0 -3
  407. package/dist/cli/chunks/client-WI7RRUZO.js +0 -2
  408. package/dist/cli/chunks/codex-installer-E5BVXZVA.js +0 -8
  409. package/dist/cli/chunks/core-handlers-T6URR57V.js +0 -2
  410. package/dist/cli/chunks/cross-domain-router-WHTTKHWM.js +0 -2
  411. package/dist/cli/chunks/dream-QUL6SURC.js +0 -2
  412. package/dist/cli/chunks/heartbeat-scheduler-VZNKE33K.js +0 -2
  413. package/dist/cli/chunks/hnsw-adapter-LGWLDZLC.js +0 -2
  414. package/dist/cli/chunks/hnsw-index-66FOOI7U.js +0 -2
  415. package/dist/cli/chunks/hybrid-router-I5MEVQDF.js +0 -2
  416. package/dist/cli/chunks/impact-analyzer-K6ANYIY3.js +0 -2
  417. package/dist/cli/chunks/init-wizard-URHGXJ32.js +0 -2
  418. package/dist/cli/chunks/kernel-OKI5ZY5P.js +0 -2
  419. package/dist/cli/chunks/knowledge-graph-VQQSK7T5.js +0 -2
  420. package/dist/cli/chunks/llm-router-service-TISH33SY.js +0 -2
  421. package/dist/cli/chunks/load-test-KWKWC4Q7.js +0 -2
  422. package/dist/cli/chunks/memory-backend-JSQQMXVS.js +0 -2
  423. package/dist/cli/chunks/pattern-null-store-SXBIUKE5.js +0 -2
  424. package/dist/cli/chunks/protocol-executor-D3Q5P3WY.js +0 -2
  425. package/dist/cli/chunks/provider-manager-2EIX7E5Q.js +0 -2
  426. package/dist/cli/chunks/qe-reasoning-bank-ITOW2ZHC.js +0 -2
  427. package/dist/cli/chunks/queen-coordinator-TO5X2EXL.js +0 -2
  428. package/dist/cli/chunks/router-GZJQEJU3.js +0 -2
  429. package/dist/cli/chunks/routing-feedback-CRXSKFNS.js +0 -2
  430. package/dist/cli/chunks/rvf-native-adapter-WHADT5HX.js +0 -2
  431. package/dist/cli/chunks/safe-db-MIZ2OFWC.js +0 -2
  432. package/dist/cli/chunks/schedule-XFILYTYC.js +0 -2
  433. package/dist/cli/chunks/scheduler-EIPJ777A.js +0 -2
  434. package/dist/cli/chunks/sqlite-persistence-PFU3GSRD.js +0 -2
  435. package/dist/cli/chunks/sync-3SDMVAIU.js +0 -2
  436. package/dist/cli/chunks/transformers-QFOBOP2Y.js +0 -2
  437. package/dist/cli/chunks/unified-memory-OUVCMFGK.js +0 -2
  438. package/dist/cli/chunks/unified-memory-hnsw-YGQPOHXB.js +0 -2
  439. package/dist/cli/chunks/unified-persistence-GFRZVDOW.js +0 -2
  440. package/dist/cli/chunks/visual-security-LVOOYQ64.js +0 -2
  441. package/dist/cli/chunks/witness-chain-QNFPV4UL.js +0 -2
  442. package/dist/cli/chunks/workflow-orchestrator-MIVBCALG.js +0 -2
@@ -108,6 +108,9 @@ export const testGenerateConfig = {
108
108
  const domainTests = data.tests;
109
109
  const hasRealTests = Array.isArray(domainTests) && domainTests.length > 0
110
110
  && domainTests[0].testCode;
111
+ // #567: did the ADR-051 LLM branch actually run? Report it instead of
112
+ // asserting `aiGenerated: true` unconditionally.
113
+ const llmEnhanced = data.llmEnhanced === true;
111
114
  const tests = hasRealTests
112
115
  ? domainTests.map((t, i) => ({
113
116
  id: generateTestId(),
@@ -119,7 +122,7 @@ export const testGenerateConfig = {
119
122
  : [`test assertion ${i}`],
120
123
  expectedResult: null,
121
124
  estimatedDuration: t.type === 'integration' ? 2000 : 1000,
122
- aiGenerated: true,
125
+ aiGenerated: llmEnhanced,
123
126
  testCode: t.testCode,
124
127
  sourceFile: t.sourceFile,
125
128
  testFile: t.testFile || t.file,
@@ -133,7 +136,9 @@ export const testGenerateConfig = {
133
136
  aiInsights,
134
137
  coverage: {
135
138
  predicted: data.coverageEstimate || params?.coverageGoal || 80,
136
- confidence: 0.9,
139
+ // #567: a template scaffold's coverage prediction is a guess, not a
140
+ // 0.9-confidence estimate. Don't dress it up as one.
141
+ confidence: llmEnhanced ? 0.9 : 0.3,
137
142
  achievable: true,
138
143
  },
139
144
  properties: tests.filter(t => t.type === 'property').map(t => ({
@@ -151,6 +156,10 @@ export const testGenerateConfig = {
151
156
  patternsUsed: data.patternsUsed || ['assertion-patterns', 'mock-generation', 'edge-case-detection'],
152
157
  duration,
153
158
  savedFiles,
159
+ // #567: propagate the LLM-enhancement signal to the MCP caller.
160
+ llmEnhanced,
161
+ ...(data.generationMode ? { generationMode: data.generationMode } : {}),
162
+ ...(data.note ? { note: data.note } : {}),
154
163
  };
155
164
  },
156
165
  };
@@ -253,12 +262,40 @@ export const coverageAnalyzeConfig = {
253
262
  // The domain returns CoverageReport { summary: { line, branch, function, statement, files }, ... }
254
263
  // Map from both nested (domain) and flat (legacy) field shapes.
255
264
  const summary = data.summary;
256
- const lineCoverage = summary?.line ?? data.lineCoverage ?? 0;
257
- const branchCoverage = summary?.branch ?? data.branchCoverage ?? 0;
258
- const functionCoverage = summary?.function ?? data.functionCoverage ?? 0;
259
- const statementCoverage = summary?.statement ?? data.statementCoverage ?? lineCoverage;
260
265
  const totalFiles = summary?.files ?? data.totalFiles ?? 0;
261
266
  const gaps = data.gaps || [];
267
+ // #569/ADR-126: an ABSENT provenance flag means "unknown", never "collected".
268
+ //
269
+ // Defaulting these to `true` (`!== false`) meant any producer that supplies
270
+ // no provenance at all — notably the coverage-analysis domain plugin, whose
271
+ // handler returns a nested-`summary` CoverageReport — surfaced the exact
272
+ // impossible pair from the issue: 100% branch coverage alongside 0% function
273
+ // coverage, labelled `measured: true` with `confidence: 0.7` on its gaps.
274
+ // Requiring an explicit `true` makes an unprovenanced result honest (`null`)
275
+ // instead of confidently wrong.
276
+ const branchDataCollected = data.branchDataCollected === true;
277
+ const functionDataCollected = data.functionDataCollected === true;
278
+ const branchCoverage = branchDataCollected
279
+ ? (summary?.branch ?? data.branchCoverage ?? null)
280
+ : null;
281
+ const functionCoverage = functionDataCollected
282
+ ? (summary?.function ?? data.functionCoverage ?? null)
283
+ : null;
284
+ // #569: is this a measurement or a static estimate? Everything downstream —
285
+ // gap confidence, AI insights, risk assessment — must be qualified by it.
286
+ const estimated = data.estimated === true;
287
+ // #569/ADR-126: `measured` is NOT the complement of `estimated` — there is a
288
+ // third state where nothing was collected at all. Deriving it as `!estimated`
289
+ // reported an empty project (no sources, no coverage report, nothing run) as
290
+ // `lineCoverage: 0, measured: true` — "we measured 0%" when the truth is "we
291
+ // measured nothing". Trust only an explicit claim from the producer.
292
+ const measured = data.measured === true;
293
+ // Likewise, a `null` line/statement figure must survive as `null`. `?? 0`
294
+ // turns "no data" into a plottable 0%.
295
+ const rawLine = summary?.line ?? data.lineCoverage;
296
+ const lineCoverage = rawLine ?? null;
297
+ const rawStatement = summary?.statement ?? data.statementCoverage;
298
+ const statementCoverage = rawStatement ?? lineCoverage;
262
299
  const learning = generateV2LearningFeedback('coverage-analyzer');
263
300
  // Map gap analysis from real data — never fabricate file paths
264
301
  const detailedGaps = gaps.map((gap, i) => {
@@ -278,7 +315,12 @@ export const coverageAnalyzeConfig = {
278
315
  suggestion: g.suggestedTest || 'Add test coverage',
279
316
  suggestedTest: g.suggestedTest || 'Add test coverage',
280
317
  riskScore: g.riskScore || 0.5,
281
- confidence: g.confidence || 0.7,
318
+ // #569: the 0.7 default confidence is only defensible for a gap derived
319
+ // from a real measurement. An estimated gap carries its own low
320
+ // confidence from the handler; a gap with no provenance at all is not
321
+ // known to be measured either, so it gets the cautious value too.
322
+ confidence: g.confidence ?? (measured ? 0.7 : 0.2),
323
+ estimated: g.estimated === true || estimated,
282
324
  };
283
325
  }).filter((g) => g !== null);
284
326
  // Use real file data from the analyzer if available, never fabricate file paths
@@ -287,8 +329,9 @@ export const coverageAnalyzeConfig = {
287
329
  ? coverageByFileData.map(f => ({
288
330
  file: f.file,
289
331
  lineCoverage: f.lineCoverage || 0,
290
- branchCoverage: f.branchCoverage || 0,
291
- functionCoverage: f.functionCoverage || 0,
332
+ // #569: preserve null (metric not collected) instead of collapsing to 0.
333
+ branchCoverage: f.branchCoverage ?? null,
334
+ functionCoverage: f.functionCoverage ?? null,
292
335
  }))
293
336
  : [];
294
337
  return {
@@ -305,11 +348,25 @@ export const coverageAnalyzeConfig = {
305
348
  weeklyChange: 0,
306
349
  },
307
350
  aiInsights: totalFiles > 0 ? {
308
- recommendations: data.recommendations || [
309
- 'Run tests with coverage enabled to get accurate metrics',
310
- ],
311
- riskAssessment: lineCoverage < 70 ? 'high' : lineCoverage < 85 ? 'medium' : 'low',
312
- confidence: 0.88,
351
+ recommendations: estimated
352
+ // #569: the reported insights ("Coverage is 15.9% below threshold",
353
+ // "Function coverage is below 70%") were all derived from estimated
354
+ // numbers and presented as findings. Lead with the caveat.
355
+ ? [
356
+ 'ESTIMATED RESULT — no instrumentation ran. The figures below are a ' +
357
+ 'static guess from source shape, not measured coverage. Do not act on ' +
358
+ 'individual gaps without running real instrumentation first.',
359
+ ...(data.recommendations || []),
360
+ ]
361
+ : (data.recommendations || [
362
+ 'Run tests with coverage enabled to get accurate metrics',
363
+ ]),
364
+ // #569: risk can only be graded off a real number. `null < 70` is
365
+ // `false` in JS, which would have silently graded "no data" as 'low'.
366
+ riskAssessment: (estimated || !measured || lineCoverage === null)
367
+ ? 'unknown'
368
+ : (lineCoverage < 70 ? 'high' : lineCoverage < 85 ? 'medium' : 'low'),
369
+ confidence: estimated ? 0.2 : (measured ? 0.88 : 0),
313
370
  } : {
314
371
  recommendations: [
315
372
  'No coverage data found. Run tests with coverage first (e.g., npm test -- --coverage, or pytest --cov)',
@@ -329,6 +386,14 @@ export const coverageAnalyzeConfig = {
329
386
  gaps: detailedGaps,
330
387
  duration,
331
388
  savedFiles,
389
+ // #569: provenance travels with the numbers so a caller can never mistake
390
+ // a static estimate for a measurement.
391
+ estimated,
392
+ measured,
393
+ coverageMethod: data.coverageMethod ?? 'unknown',
394
+ branchDataCollected,
395
+ functionDataCollected,
396
+ ...(data.warning ? { warning: data.warning } : {}),
332
397
  };
333
398
  },
334
399
  };
@@ -446,6 +446,15 @@ export interface TestGenerateResult {
446
446
  suggestions?: string[];
447
447
  savedFiles?: string[];
448
448
  patternsUsed?: string[];
449
+ /**
450
+ * #567: true when the ADR-051 LLM branch actually ran. When false the tests
451
+ * are deterministic template scaffolding — see `generationMode`/`note`.
452
+ */
453
+ llmEnhanced?: boolean;
454
+ /** #567: set to 'deterministic-template' when no LLM enhancement was applied. */
455
+ generationMode?: string;
456
+ /** #567: human-readable reason the LLM branch did not run. */
457
+ note?: string;
449
458
  tests?: unknown[];
450
459
  antiPatterns?: unknown[];
451
460
  aiInsights?: Record<string, unknown>;
@@ -462,19 +471,46 @@ export interface CoverageAnalyzeResult {
462
471
  taskId: string;
463
472
  status: string;
464
473
  duration: number;
465
- lineCoverage: number;
466
- branchCoverage: number;
467
- functionCoverage: number;
474
+ /**
475
+ * #569: `null` when no coverage figure was produced at all (no report, no
476
+ * instrumentation run, nothing to estimate from). `0` means a measured zero;
477
+ * `null` means "we don't know" — the two must not be conflated.
478
+ */
479
+ lineCoverage: number | null;
480
+ /**
481
+ * #569: `null` when branch data was not collected. Never report a branch
482
+ * percentage — least of all 100% — that no instrumentation produced.
483
+ */
484
+ branchCoverage: number | null;
485
+ /** #569: `null` when function-level data was not collected. */
486
+ functionCoverage: number | null;
468
487
  gaps?: CoverageGap[];
469
488
  riskScore?: number;
470
489
  savedFiles?: string[];
471
- statementCoverage?: number;
490
+ /** #569: `null` when no figure was produced — see `lineCoverage`. */
491
+ statementCoverage?: number | null;
472
492
  totalFiles?: number;
473
493
  coverageByFile?: unknown[];
474
494
  gapAnalysis?: Record<string, unknown>;
475
495
  trends?: Record<string, unknown>;
476
496
  aiInsights?: Record<string, unknown>;
477
497
  learning?: Record<string, unknown>;
498
+ /**
499
+ * #569 provenance. `true` means the figures are a STATIC ESTIMATE derived
500
+ * from source shape, not measured coverage. Callers must not present an
501
+ * estimated result as a measurement.
502
+ */
503
+ estimated?: boolean;
504
+ /** Inverse of `estimated`: real instrumentation produced these numbers. */
505
+ measured?: boolean;
506
+ /** How the numbers were obtained: instrumented-report | cargo-llvm-cov | static-estimation | none. */
507
+ coverageMethod?: string;
508
+ /** Whether branch data was actually collected. */
509
+ branchDataCollected?: boolean;
510
+ /** Whether function-level data was actually collected. */
511
+ functionDataCollected?: boolean;
512
+ /** Caveats the caller should surface (e.g. "no instrumentation ran"). */
513
+ warning?: string;
478
514
  }
479
515
  /**
480
516
  * Coverage gap
@@ -492,6 +528,8 @@ export interface CoverageGap {
492
528
  priority?: string;
493
529
  suggestedTest?: string;
494
530
  riskScore?: number;
531
+ /** #569: true when this gap came from a static estimate, not a measurement. */
532
+ estimated?: boolean;
495
533
  }
496
534
  /**
497
535
  * Memory store result
@@ -47,8 +47,20 @@ export declare class SessionOperationCache {
47
47
  private misses;
48
48
  constructor(config?: Partial<SessionCacheConfig>);
49
49
  /**
50
- * Compute a deterministic fingerprint from domain + action + input.
50
+ * Compute a deterministic fingerprint from build + domain + action + input.
51
51
  * Uses SHA-256 of the canonicalized JSON (recursively sorted keys), truncated to 16 hex chars.
52
+ *
53
+ * The build identity is part of the key on purpose. Entries are persisted to
54
+ * `kv_store` and survive process restarts *and package upgrades*, so a
55
+ * fingerprint over inputs alone means an upgraded install keeps replaying the
56
+ * previous version's answers until the TTL lapses — the fix looks like it did
57
+ * not work. That is exactly what happened while verifying issue #569: a
58
+ * project analyzed before the fix kept returning the old fabricated coverage
59
+ * numbers (`lineCoverage: 0, measured: true`) from cache, while an untouched
60
+ * project returned the corrected result.
61
+ *
62
+ * Including the version means an upgrade misses cleanly rather than serving
63
+ * stale answers; entries from the old build simply age out.
52
64
  */
53
65
  computeFingerprint(domain: string, action: string, input: Record<string, unknown>): string;
54
66
  /**
@@ -13,6 +13,19 @@
13
13
  * - TTL-based expiry, LRU-ish eviction at capacity
14
14
  */
15
15
  import { createHash } from 'crypto';
16
+ /**
17
+ * Build identity mixed into every cache fingerprint so persisted entries never
18
+ * outlive the code that produced them. `__CLI_VERSION__` is substituted at bundle
19
+ * time; in source/test runs it is undefined and we fall back to a dev marker.
20
+ *
21
+ * `AQE_SESSION_CACHE_SALT` lets an operator force a cold cache without deleting
22
+ * anything (e.g. after a local rebuild that keeps the same version string).
23
+ */
24
+ function getBuildIdentity() {
25
+ const version = typeof __CLI_VERSION__ !== 'undefined' ? __CLI_VERSION__ : 'dev';
26
+ const salt = (process.env.AQE_SESSION_CACHE_SALT ?? '').trim();
27
+ return salt ? `${version}+${salt}` : version;
28
+ }
16
29
  export const DEFAULT_SESSION_CACHE_CONFIG = {
17
30
  enabled: true,
18
31
  maxEntries: 500,
@@ -51,11 +64,23 @@ export class SessionOperationCache {
51
64
  this.config = { ...DEFAULT_SESSION_CACHE_CONFIG, ...config };
52
65
  }
53
66
  /**
54
- * Compute a deterministic fingerprint from domain + action + input.
67
+ * Compute a deterministic fingerprint from build + domain + action + input.
55
68
  * Uses SHA-256 of the canonicalized JSON (recursively sorted keys), truncated to 16 hex chars.
69
+ *
70
+ * The build identity is part of the key on purpose. Entries are persisted to
71
+ * `kv_store` and survive process restarts *and package upgrades*, so a
72
+ * fingerprint over inputs alone means an upgraded install keeps replaying the
73
+ * previous version's answers until the TTL lapses — the fix looks like it did
74
+ * not work. That is exactly what happened while verifying issue #569: a
75
+ * project analyzed before the fix kept returning the old fabricated coverage
76
+ * numbers (`lineCoverage: 0, measured: true`) from cache, while an untouched
77
+ * project returned the corrected result.
78
+ *
79
+ * Including the version means an upgrade misses cleanly rather than serving
80
+ * stale answers; entries from the old build simply age out.
56
81
  */
57
82
  computeFingerprint(domain, action, input) {
58
- const canonical = canonicalStringify({ action, domain, input });
83
+ const canonical = canonicalStringify({ action, build: getBuildIdentity(), domain, input });
59
84
  return createHash('sha256').update(canonical).digest('hex').slice(0, 16);
60
85
  }
61
86
  /**
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Auto-restore for the unified `memory.db` (M3.2, inspired by ruflo v3.25.2's
3
+ * backup-auto-restore, adapted to better-sqlite3).
4
+ *
5
+ * Hardened after a qe-court review (ADR-124) surfaced three data-loss risks in
6
+ * the first cut:
7
+ * F3 — `isDbHealthy` via a readonly open + integrity_check FALSE-NEGATIVES a
8
+ * HEALTHY WAL db when `-shm` is zeroed/inaccessible over virtiofs (the
9
+ * exact documented failure mode), which would have parked a good DB and
10
+ * reverted to an older backup. FIX: the live-corruption signal is now the
11
+ * SQLite HEADER — a `-wal`/`-shm` problem does not corrupt the main file,
12
+ * so we only treat a missing/garbage header (zeroed/not-a-db) as corrupt.
13
+ * F2 — non-atomic `copyFileSync` + no lock let concurrent hook processes tear
14
+ * the restored image. FIX: copy to a temp in the same dir → atomic rename,
15
+ * under a best-effort exclusive lock so only one process restores.
16
+ * backup trust — a backup we are about to promote to the LIVE db still gets a
17
+ * FULL `integrity_check` (it is a static file, safe to open readonly).
18
+ *
19
+ * DATA-PROTECTION INVARIANTS (this file must never make things worse):
20
+ * - The corrupt original is RENAMED to `<db>.corrupt-<ts>`, NEVER deleted.
21
+ * - A header-valid main file is treated as HEALTHY — we never park a DB that
22
+ * might just have a transient `-wal`/`-shm` issue (a writable open rebuilds
23
+ * `-shm`). We prefer "manual restore" over "auto-destroy a healthy DB".
24
+ * - A backup is used only if it passes `PRAGMA integrity_check`.
25
+ * - If no verified backup exists, we do NOTHING (leave the DB for inspection).
26
+ */
27
+ /**
28
+ * True if the main DB file is structurally a database (or absent/empty = a fresh
29
+ * DB the caller will create). LIVE-corruption signal only: it deliberately does
30
+ * NOT open the DB or run integrity_check, because a `-wal`/`-shm` fault over
31
+ * virtiofs makes a HEALTHY db unreadable and we must not mistake that for
32
+ * corruption (F3). Only a missing/garbage header — the zeroed/not-a-db case —
33
+ * is "corrupt". A header-valid-but-page-corrupt file is left for MANUAL restore
34
+ * rather than risk auto-parking a healthy DB.
35
+ */
36
+ export declare function isDbHealthy(dbPath: string): boolean;
37
+ export interface RestoreResult {
38
+ restored: boolean;
39
+ reason: 'healthy' | 'no-verified-backup' | 'restored-from-backup' | 'restore-in-progress' | 'park-failed' | 'copy-failed';
40
+ backupUsed?: string;
41
+ parkedTo?: string;
42
+ }
43
+ /** Default verified-backup directory (matches `scripts/aqe-db-backup.sh`). */
44
+ export declare function defaultBackupDir(dbPath: string): string;
45
+ /**
46
+ * If `dbPath`'s main file is unambiguously corrupt (bad SQLite header), park it
47
+ * and atomically restore the newest verified backup. No-op (and non-destructive)
48
+ * when the DB is healthy, when no good backup exists, or when another process is
49
+ * already restoring.
50
+ */
51
+ export declare function attemptAutoRestore(dbPath: string, opts?: {
52
+ backupDir?: string;
53
+ now?: number;
54
+ }): RestoreResult;
55
+ //# sourceMappingURL=db-recovery.d.ts.map
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Auto-restore for the unified `memory.db` (M3.2, inspired by ruflo v3.25.2's
3
+ * backup-auto-restore, adapted to better-sqlite3).
4
+ *
5
+ * Hardened after a qe-court review (ADR-124) surfaced three data-loss risks in
6
+ * the first cut:
7
+ * F3 — `isDbHealthy` via a readonly open + integrity_check FALSE-NEGATIVES a
8
+ * HEALTHY WAL db when `-shm` is zeroed/inaccessible over virtiofs (the
9
+ * exact documented failure mode), which would have parked a good DB and
10
+ * reverted to an older backup. FIX: the live-corruption signal is now the
11
+ * SQLite HEADER — a `-wal`/`-shm` problem does not corrupt the main file,
12
+ * so we only treat a missing/garbage header (zeroed/not-a-db) as corrupt.
13
+ * F2 — non-atomic `copyFileSync` + no lock let concurrent hook processes tear
14
+ * the restored image. FIX: copy to a temp in the same dir → atomic rename,
15
+ * under a best-effort exclusive lock so only one process restores.
16
+ * backup trust — a backup we are about to promote to the LIVE db still gets a
17
+ * FULL `integrity_check` (it is a static file, safe to open readonly).
18
+ *
19
+ * DATA-PROTECTION INVARIANTS (this file must never make things worse):
20
+ * - The corrupt original is RENAMED to `<db>.corrupt-<ts>`, NEVER deleted.
21
+ * - A header-valid main file is treated as HEALTHY — we never park a DB that
22
+ * might just have a transient `-wal`/`-shm` issue (a writable open rebuilds
23
+ * `-shm`). We prefer "manual restore" over "auto-destroy a healthy DB".
24
+ * - A backup is used only if it passes `PRAGMA integrity_check`.
25
+ * - If no verified backup exists, we do NOTHING (leave the DB for inspection).
26
+ */
27
+ import { existsSync, renameSync, copyFileSync, readdirSync, statSync, openSync, readSync, closeSync, writeFileSync, rmSync, } from 'node:fs';
28
+ import { join, dirname } from 'node:path';
29
+ import Database from 'better-sqlite3';
30
+ /** The 16-byte magic every valid SQLite database file starts with. */
31
+ const SQLITE_MAGIC = Buffer.concat([Buffer.from('SQLite format 3', 'latin1'), Buffer.from([0])]);
32
+ /**
33
+ * True if the main DB file is structurally a database (or absent/empty = a fresh
34
+ * DB the caller will create). LIVE-corruption signal only: it deliberately does
35
+ * NOT open the DB or run integrity_check, because a `-wal`/`-shm` fault over
36
+ * virtiofs makes a HEALTHY db unreadable and we must not mistake that for
37
+ * corruption (F3). Only a missing/garbage header — the zeroed/not-a-db case —
38
+ * is "corrupt". A header-valid-but-page-corrupt file is left for MANUAL restore
39
+ * rather than risk auto-parking a healthy DB.
40
+ */
41
+ export function isDbHealthy(dbPath) {
42
+ if (!existsSync(dbPath))
43
+ return true;
44
+ let size;
45
+ try {
46
+ size = statSync(dbPath).size;
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ if (size === 0)
52
+ return true; // freshly-created, not yet written — not corrupt
53
+ if (size < SQLITE_MAGIC.length)
54
+ return false; // too small to be a real db
55
+ let fd;
56
+ try {
57
+ fd = openSync(dbPath, 'r');
58
+ const header = Buffer.alloc(SQLITE_MAGIC.length);
59
+ readSync(fd, header, 0, SQLITE_MAGIC.length, 0);
60
+ return header.equals(SQLITE_MAGIC);
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ finally {
66
+ if (fd !== undefined) {
67
+ try {
68
+ closeSync(fd);
69
+ }
70
+ catch {
71
+ /* ignore */
72
+ }
73
+ }
74
+ }
75
+ }
76
+ /** Full integrity check for a backup we are about to promote to the live DB. */
77
+ function backupIsRestorable(path) {
78
+ let db;
79
+ try {
80
+ db = new Database(path, { readonly: true, fileMustExist: true });
81
+ return db.pragma('integrity_check', { simple: true }) === 'ok';
82
+ }
83
+ catch {
84
+ return false;
85
+ }
86
+ finally {
87
+ try {
88
+ db?.close();
89
+ }
90
+ catch {
91
+ /* ignore */
92
+ }
93
+ }
94
+ }
95
+ /** Default verified-backup directory (matches `scripts/aqe-db-backup.sh`). */
96
+ export function defaultBackupDir(dbPath) {
97
+ return join(dirname(dbPath), 'backups', 'verified');
98
+ }
99
+ /** Newest `memory-*.db` in the backup dir that passes a full integrity_check, or null. */
100
+ function newestVerifiedBackup(backupDir) {
101
+ if (!existsSync(backupDir))
102
+ return null;
103
+ const candidates = readdirSync(backupDir)
104
+ .filter((f) => f.startsWith('memory-') && f.endsWith('.db'))
105
+ .map((f) => {
106
+ const path = join(backupDir, f);
107
+ return { path, mtime: statSync(path).mtimeMs };
108
+ })
109
+ .sort((a, b) => b.mtime - a.mtime);
110
+ for (const c of candidates) {
111
+ if (backupIsRestorable(c.path))
112
+ return c.path;
113
+ }
114
+ return null;
115
+ }
116
+ /**
117
+ * If `dbPath`'s main file is unambiguously corrupt (bad SQLite header), park it
118
+ * and atomically restore the newest verified backup. No-op (and non-destructive)
119
+ * when the DB is healthy, when no good backup exists, or when another process is
120
+ * already restoring.
121
+ */
122
+ export function attemptAutoRestore(dbPath, opts) {
123
+ if (isDbHealthy(dbPath))
124
+ return { restored: false, reason: 'healthy' };
125
+ const backupDir = opts?.backupDir ?? defaultBackupDir(dbPath);
126
+ const good = newestVerifiedBackup(backupDir);
127
+ if (!good)
128
+ return { restored: false, reason: 'no-verified-backup' };
129
+ // F2: best-effort exclusive lock so concurrent processes don't both restore.
130
+ const lockPath = `${dbPath}.restore.lock`;
131
+ try {
132
+ writeFileSync(lockPath, String(process.pid), { flag: 'wx' });
133
+ }
134
+ catch {
135
+ return { restored: false, reason: 'restore-in-progress' };
136
+ }
137
+ try {
138
+ // Re-check under the lock: a peer may have just restored a healthy DB.
139
+ if (isDbHealthy(dbPath))
140
+ return { restored: false, reason: 'healthy' };
141
+ const ts = opts?.now ?? Date.now();
142
+ const parked = `${dbPath}.corrupt-${ts}`;
143
+ // Park the corrupt original + any stale WAL/shm. NEVER delete.
144
+ try {
145
+ if (existsSync(dbPath))
146
+ renameSync(dbPath, parked);
147
+ for (const suffix of ['-wal', '-shm']) {
148
+ if (existsSync(dbPath + suffix))
149
+ renameSync(dbPath + suffix, parked + suffix);
150
+ }
151
+ }
152
+ catch {
153
+ return { restored: false, reason: 'park-failed' };
154
+ }
155
+ // F2: restore atomically — copy to a temp on the same filesystem, then rename.
156
+ const tmp = `${dbPath}.restoring-${ts}`;
157
+ try {
158
+ copyFileSync(good, tmp);
159
+ renameSync(tmp, dbPath); // atomic on the same fs
160
+ }
161
+ catch {
162
+ try {
163
+ if (existsSync(tmp))
164
+ rmSync(tmp, { force: true });
165
+ if (!existsSync(dbPath) && existsSync(parked))
166
+ renameSync(parked, dbPath);
167
+ }
168
+ catch {
169
+ /* leave parked copy for manual recovery */
170
+ }
171
+ return { restored: false, reason: 'copy-failed' };
172
+ }
173
+ return { restored: true, reason: 'restored-from-backup', backupUsed: good, parkedTo: parked };
174
+ }
175
+ finally {
176
+ try {
177
+ rmSync(lockPath, { force: true });
178
+ }
179
+ catch {
180
+ /* ignore */
181
+ }
182
+ }
183
+ }
184
+ //# sourceMappingURL=db-recovery.js.map
@@ -10,6 +10,7 @@
10
10
  const BILLING_MODE_BY_TYPE = {
11
11
  claude: 'metered-api',
12
12
  'claude-code': 'subscription',
13
+ codex: 'subscription',
13
14
  openai: 'metered-api',
14
15
  openrouter: 'metered-api',
15
16
  gemini: 'metered-api',
@@ -45,10 +46,12 @@ export function billingNotice(provider, mode) {
45
46
  case 'metered-capped':
46
47
  return (`ℹ️ LLM provider "${provider}" bills per-token but enforces a server-side ` +
47
48
  `hard spend cap; it will pause at the cap rather than overspend.`);
48
- case 'subscription':
49
- return (`ℹ️ LLM provider "${provider}" runs on your Claude Code subscription ` +
49
+ case 'subscription': {
50
+ const sub = provider === 'codex' ? 'ChatGPT' : 'Claude Code';
51
+ return (`ℹ️ LLM provider "${provider}" runs on your ${sub} subscription ` +
50
52
  `(shared plan usage). Worst case is hitting your plan's rate limit and pausing — ` +
51
53
  `no per-token API charges.`);
54
+ }
52
55
  case 'local':
53
56
  return undefined;
54
57
  }
@@ -177,6 +177,7 @@ export class CostTracker {
177
177
  const byProvider = {
178
178
  claude: 0,
179
179
  'claude-code': 0,
180
+ codex: 0,
180
181
  openai: 0,
181
182
  ollama: 0,
182
183
  openrouter: 0,
@@ -11,7 +11,7 @@
11
11
  /**
12
12
  * Supported LLM provider types
13
13
  */
14
- export type LLMProviderType = 'claude' | 'claude-code' | 'openai' | 'ollama' | 'openrouter' | 'bedrock' | 'azure-openai' | 'gemini' | 'cognitum';
14
+ export type LLMProviderType = 'claude' | 'claude-code' | 'codex' | 'openai' | 'ollama' | 'openrouter' | 'bedrock' | 'azure-openai' | 'gemini' | 'cognitum';
15
15
  /**
16
16
  * Message role in a conversation
17
17
  */
@@ -273,6 +273,18 @@ export interface ClaudeCodeConfig extends LLMConfig {
273
273
  /** Tools to disallow in the headless session (safety). */
274
274
  disallowedTools?: string[];
275
275
  }
276
+ /**
277
+ * Codex CLI (subscription) provider configuration (ADR-123 / ADR-124 M3.5).
278
+ * Runs on the user's ChatGPT subscription by shelling out to `codex exec`,
279
+ * mirroring the claude-code provider. Gives AQE a cross-vendor (GPT-family)
280
+ * engine for provider fallback and qe-court prosecutor/juror diversity.
281
+ */
282
+ export interface CodexConfig extends LLMConfig {
283
+ /** Path to the `codex` binary (default: 'codex' on PATH). */
284
+ binaryPath?: string;
285
+ /** Max concurrent `codex exec` subprocesses. */
286
+ maxConcurrency?: number;
287
+ }
276
288
  /**
277
289
  * Cognitum provider configuration (ADR-123). OpenAI-compatible gateway with
278
290
  * per-request cost receipts and a server-side hard spend cap.
@@ -294,6 +306,7 @@ export interface ProviderManagerConfig {
294
306
  providers: {
295
307
  claude?: ClaudeConfig;
296
308
  'claude-code'?: ClaudeCodeConfig;
309
+ codex?: CodexConfig;
297
310
  openai?: OpenAIConfig;
298
311
  ollama?: OllamaConfig;
299
312
  openrouter?: OpenRouterConfig;