agentic-qe 3.15.3 → 3.15.5

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 (420) hide show
  1. package/.claude/skills/skills-manifest.json +1 -1
  2. package/CHANGELOG.md +139 -0
  3. package/assets/skills/skills-manifest.json +1 -1
  4. package/dist/bridge/captured-experience-bridge.js +7 -9
  5. package/dist/cli/bundle.js +5 -5
  6. package/dist/cli/chunks/adapter-EGIPTX5H.js +2 -0
  7. package/dist/cli/chunks/{agent-booster-wasm-CYG3PKHH.js → agent-booster-wasm-CCTTGCQS.js} +2 -2
  8. package/dist/cli/chunks/{agent-handler-WTFYFZKL.js → agent-handler-DHYUF3NX.js} +2 -2
  9. package/dist/cli/chunks/{agent-memory-branch-G6WE3ZXU.js → agent-memory-branch-642W7CYX.js} +2 -2
  10. package/dist/cli/chunks/aqe-learning-engine-WP4GCBDT.js +2 -0
  11. package/dist/cli/chunks/{arena-S72QW44C.js → arena-MUCC7UUN.js} +4 -4
  12. package/dist/cli/chunks/{arena-ZFXQEVUQ.js → arena-NW2JVAFY.js} +2 -2
  13. package/dist/cli/chunks/{audit-KPYIEQJ3.js → audit-VKQTZJAA.js} +3 -3
  14. package/dist/cli/chunks/base-6ORFD62I.js +2 -0
  15. package/dist/cli/chunks/{better-sqlite3-L2M3TI5D.js → better-sqlite3-7ZUFVWLQ.js} +2 -2
  16. package/dist/cli/chunks/{brain-handler-FHKLQTB4.js → brain-handler-7LKAWSBI.js} +3 -3
  17. package/dist/cli/chunks/{branch-enumerator-3BSHOPOK.js → branch-enumerator-HUNXJKM4.js} +2 -2
  18. package/dist/cli/chunks/{browser-JUIJPL6Y.js → browser-ZSZEYUDP.js} +2 -2
  19. package/dist/cli/chunks/browser-workflow-PIXGERWP.js +2 -0
  20. package/dist/cli/chunks/{chunk-VHBZADYK.js → chunk-2KWI3MT3.js} +2 -2
  21. package/dist/cli/chunks/{chunk-35VDOH4Y.js → chunk-2WFTZSRT.js} +1 -1
  22. package/dist/cli/chunks/{chunk-UTALYUMW.js → chunk-2XYTS2WY.js} +2 -2
  23. package/dist/cli/chunks/{chunk-OTTTHNIT.js → chunk-35MDATQE.js} +1 -1
  24. package/dist/cli/chunks/{chunk-Z7UGEQ4G.js → chunk-3AYYGR6W.js} +1 -1
  25. package/dist/cli/chunks/{chunk-LPZAB3N2.js → chunk-3DTEQHFB.js} +3 -3
  26. package/dist/cli/chunks/{chunk-YHZGFWJE.js → chunk-3OAQPN2N.js} +2 -2
  27. package/dist/cli/chunks/{chunk-PUPEKA2J.js → chunk-3QD7U3FY.js} +2 -2
  28. package/dist/cli/chunks/{chunk-3Y4GX5FL.js → chunk-3SH23PS3.js} +2 -2
  29. package/dist/cli/chunks/{chunk-NT6FYFJA.js → chunk-3YASZPLO.js} +2 -2
  30. package/dist/cli/chunks/{chunk-QVNMTMDJ.js → chunk-3YNP33GB.js} +2 -2
  31. package/dist/cli/chunks/{chunk-AQTQ24SK.js → chunk-47GEI2LT.js} +3 -3
  32. package/dist/cli/chunks/{chunk-JJBTM4JO.js → chunk-4AZP7ZCW.js} +2 -2
  33. package/dist/cli/chunks/{chunk-6W6GZHQA.js → chunk-4PT5KNXL.js} +4 -4
  34. package/dist/cli/chunks/{chunk-EQGT4VLC.js → chunk-4UXPDV7E.js} +1 -1
  35. package/dist/cli/chunks/{chunk-SP2JO53K.js → chunk-4XSCZVON.js} +2 -2
  36. package/dist/cli/chunks/{chunk-DWG4TN6A.js → chunk-5BOZCMXZ.js} +1 -1
  37. package/dist/cli/chunks/{chunk-PBUWNMZ2.js → chunk-644DFAGS.js} +1 -1
  38. package/dist/cli/chunks/{chunk-6EQDA4EC.js → chunk-663ZFPUL.js} +2 -2
  39. package/dist/cli/chunks/{chunk-HU474NXP.js → chunk-6JFGB2JB.js} +1 -1
  40. package/dist/cli/chunks/{chunk-AS54N3H7.js → chunk-6LG5UEQE.js} +2 -2
  41. package/dist/cli/chunks/{chunk-3UUMGWHW.js → chunk-6UYN5PHA.js} +4 -4
  42. package/dist/cli/chunks/{chunk-RQUSJEON.js → chunk-6ZIDZ4TJ.js} +2 -2
  43. package/dist/cli/chunks/{chunk-P36IODAM.js → chunk-7BIYJRQJ.js} +2 -2
  44. package/dist/cli/chunks/{chunk-5LEUEWJY.js → chunk-7EZLOC4K.js} +2 -2
  45. package/dist/cli/chunks/{chunk-EBIMVSPH.js → chunk-7YB2KELI.js} +2 -2
  46. package/dist/cli/chunks/{chunk-YCGU2LI7.js → chunk-A2WOQO2N.js} +2 -2
  47. package/dist/cli/chunks/{chunk-HSR53REE.js → chunk-A337MD3C.js} +2 -2
  48. package/dist/cli/chunks/{chunk-ZJW4HRUA.js → chunk-A5J4XJS6.js} +1 -1
  49. package/dist/cli/chunks/{chunk-POTVF6BY.js → chunk-AQN5EDBM.js} +1 -1
  50. package/dist/cli/chunks/{chunk-X335K4SU.js → chunk-AUZXRFOX.js} +2 -2
  51. package/dist/cli/chunks/{chunk-WI7I6LMM.js → chunk-B2UHTA4Q.js} +1 -1
  52. package/dist/cli/chunks/{chunk-W7EHNX3Y.js → chunk-BBL6YXD3.js} +2 -2
  53. package/dist/cli/chunks/chunk-BJ5P4IV2.js +2 -0
  54. package/dist/cli/chunks/{chunk-RDTR43YN.js → chunk-BMWAWZAN.js} +2 -2
  55. package/dist/cli/chunks/chunk-BO4PKNYP.js +102 -0
  56. package/dist/cli/chunks/{chunk-KGS6H2HB.js → chunk-BY646JOM.js} +2 -2
  57. package/dist/cli/chunks/{chunk-PPA53NJB.js → chunk-BYXNHGQC.js} +2 -2
  58. package/dist/cli/chunks/{chunk-RRSZ27A7.js → chunk-BZFT4QDQ.js} +2 -2
  59. package/dist/cli/chunks/{chunk-M3ACHBC7.js → chunk-CFPR24YK.js} +2 -2
  60. package/dist/cli/chunks/{chunk-SRDECRTL.js → chunk-CQMHDAJS.js} +2 -2
  61. package/dist/cli/chunks/{chunk-WW4RJ6BH.js → chunk-CR2JUANW.js} +2 -2
  62. package/dist/cli/chunks/{chunk-QSVNVDA5.js → chunk-CXOXUBYU.js} +1 -1
  63. package/dist/cli/chunks/chunk-D3G2NN7F.js +741 -0
  64. package/dist/cli/chunks/{chunk-RGD2CG23.js → chunk-DEGWCUMY.js} +2 -2
  65. package/dist/cli/chunks/{chunk-AEL4XJGJ.js → chunk-DFPL5N3Q.js} +2 -2
  66. package/dist/cli/chunks/{chunk-FTUNC4EI.js → chunk-DL5JENWD.js} +3 -3
  67. package/dist/cli/chunks/{chunk-DH5NWHH2.js → chunk-DLY4YEN3.js} +2 -2
  68. package/dist/cli/chunks/{chunk-V5NYGDSX.js → chunk-DPV33C77.js} +2 -2
  69. package/dist/cli/chunks/{chunk-A5H7TF7C.js → chunk-DPYDUKVZ.js} +2 -2
  70. package/dist/cli/chunks/{chunk-4JVVVKAX.js → chunk-DTJODGCE.js} +2 -2
  71. package/dist/cli/chunks/{chunk-6AKJ73X3.js → chunk-DWZI3IVB.js} +2 -2
  72. package/dist/cli/chunks/{chunk-7UUSV2SK.js → chunk-DXVZBJE4.js} +1 -1
  73. package/dist/cli/chunks/{chunk-FPFGN2Z5.js → chunk-E4VIVMDL.js} +2 -2
  74. package/dist/cli/chunks/{chunk-GPZH6OPP.js → chunk-EAYQCBXL.js} +3 -3
  75. package/dist/cli/chunks/{chunk-7SWHW5AC.js → chunk-EOR3RECZ.js} +20 -20
  76. package/dist/cli/chunks/chunk-ERGWWI4Y.js +3 -0
  77. package/dist/cli/chunks/{chunk-XXW4KFBB.js → chunk-EUEHBERE.js} +1 -1
  78. package/dist/cli/chunks/{chunk-VUBLJBHQ.js → chunk-EVCFUYYK.js} +2 -2
  79. package/dist/cli/chunks/{chunk-YQ3ZW47V.js → chunk-FBEXG4HD.js} +2 -2
  80. package/dist/cli/chunks/{chunk-HV3ZVUHO.js → chunk-FE3AIZI6.js} +1 -1
  81. package/dist/cli/chunks/{chunk-TBVPNN65.js → chunk-FHUJCVT3.js} +2 -2
  82. package/dist/cli/chunks/{chunk-3ZTBV6M3.js → chunk-FNAYDITO.js} +1 -1
  83. package/dist/cli/chunks/{chunk-JVQK6NGI.js → chunk-FQKEZVN6.js} +2 -2
  84. package/dist/cli/chunks/{chunk-MUSYQF53.js → chunk-FWYJ6UDX.js} +2 -2
  85. package/dist/cli/chunks/{chunk-QUXX2DP7.js → chunk-GGDKOJVF.js} +2 -2
  86. package/dist/cli/chunks/{chunk-VRT736E3.js → chunk-GKPRECLL.js} +2 -2
  87. package/dist/cli/chunks/{chunk-3MNKYCLH.js → chunk-GRIPCYW5.js} +1 -1
  88. package/dist/cli/chunks/{chunk-DE3QNPTG.js → chunk-GTSOFCMQ.js} +1 -1
  89. package/dist/cli/chunks/{chunk-2MEWIXW4.js → chunk-HBYQYGXP.js} +2 -2
  90. package/dist/cli/chunks/{chunk-RWLOERKK.js → chunk-HGBJ2QQ4.js} +2 -2
  91. package/dist/cli/chunks/{chunk-4IYHYHTG.js → chunk-HIUNCO2W.js} +2 -2
  92. package/dist/cli/chunks/{chunk-WSUYEVSY.js → chunk-HLFDC4SF.js} +1 -1
  93. package/dist/cli/chunks/{chunk-OKNMZLGB.js → chunk-HPLMX62I.js} +2 -2
  94. package/dist/cli/chunks/{chunk-Z7JPWXW2.js → chunk-IHFUEPZH.js} +2 -2
  95. package/dist/cli/chunks/{chunk-2TBHPYOU.js → chunk-IJ2EXSMO.js} +2 -2
  96. package/dist/cli/chunks/{chunk-SKHP5WUP.js → chunk-IJOFZBXD.js} +2 -2
  97. package/dist/cli/chunks/{chunk-YW4GM36K.js → chunk-JANLATHN.js} +2 -2
  98. package/dist/cli/chunks/{chunk-BDKQSEEY.js → chunk-JCC7QEKZ.js} +1 -1
  99. package/dist/cli/chunks/{chunk-7PDC4SKR.js → chunk-JI77KJP7.js} +1 -1
  100. package/dist/cli/chunks/{chunk-LEB6O2IN.js → chunk-JNMUVBAJ.js} +2 -2
  101. package/dist/cli/chunks/{chunk-ZI6NJEBY.js → chunk-JYY7AYGA.js} +1 -1
  102. package/dist/cli/chunks/{chunk-ASUXS4N4.js → chunk-KHCALIFP.js} +2 -2
  103. package/dist/cli/chunks/{chunk-ED5HUPUR.js → chunk-KJ3KBP24.js} +2 -2
  104. package/dist/cli/chunks/{chunk-YTRGMILO.js → chunk-KZVJW2SD.js} +2 -2
  105. package/dist/cli/chunks/chunk-L336HFFE.js +2 -0
  106. package/dist/cli/chunks/{chunk-GJB3LPCS.js → chunk-L375O3CZ.js} +2 -2
  107. package/dist/cli/chunks/{chunk-WQZBKLAG.js → chunk-L6SVCNXK.js} +1 -1
  108. package/dist/cli/chunks/{chunk-YGKU2QRC.js → chunk-LNO5IWGH.js} +1 -1
  109. package/dist/cli/chunks/{chunk-APV5UWTU.js → chunk-LRASYSGV.js} +2 -2
  110. package/dist/cli/chunks/{chunk-HW4V7BVV.js → chunk-MB4VFAJC.js} +2 -2
  111. package/dist/cli/chunks/{chunk-366IBPZB.js → chunk-MNQ36MAF.js} +2 -2
  112. package/dist/cli/chunks/{chunk-7TW5UGDP.js → chunk-MQGEZA2A.js} +2 -2
  113. package/dist/cli/chunks/{chunk-CFXROOIU.js → chunk-MS3Z2CP5.js} +2 -2
  114. package/dist/cli/chunks/{chunk-4TM5K6EZ.js → chunk-N2TJNIHA.js} +2 -2
  115. package/dist/cli/chunks/{chunk-DLA3EHKJ.js → chunk-NF6AFIAX.js} +1 -1
  116. package/dist/cli/chunks/{chunk-2GJJGO5D.js → chunk-NLDFNAOS.js} +2 -2
  117. package/dist/cli/chunks/{chunk-UCSGZVJX.js → chunk-NMJVG22Z.js} +1 -1
  118. package/dist/cli/chunks/{chunk-WSND64RL.js → chunk-OGYWWZU7.js} +2 -2
  119. package/dist/cli/chunks/{chunk-FXTZXZCU.js → chunk-ONCH5AXU.js} +3 -3
  120. package/dist/cli/chunks/{chunk-M3ONCPSU.js → chunk-OQDC7GCM.js} +2 -2
  121. package/dist/cli/chunks/{chunk-P6EGRAQG.js → chunk-ORTBRO7F.js} +2 -2
  122. package/dist/cli/chunks/{chunk-D6PUDLJ4.js → chunk-OU4ZAWCC.js} +2 -2
  123. package/dist/cli/chunks/{chunk-AOZJ6UUZ.js → chunk-OW42F2TX.js} +2 -2
  124. package/dist/cli/chunks/{chunk-4N7YXTV3.js → chunk-PCCIZFD7.js} +1 -1
  125. package/dist/cli/chunks/{chunk-OT6SOPAL.js → chunk-PDPEMBFV.js} +2 -2
  126. package/dist/cli/chunks/{chunk-A3IQU2ND.js → chunk-PHAQWAEV.js} +2 -2
  127. package/dist/cli/chunks/{chunk-XV2TIODR.js → chunk-PHP4UJYP.js} +1 -1
  128. package/dist/cli/chunks/{chunk-POVP6O6K.js → chunk-PURHGLEC.js} +1 -1
  129. package/dist/cli/chunks/{chunk-5QUOM357.js → chunk-PVAE65B4.js} +1 -1
  130. package/dist/cli/chunks/{chunk-ZL2GYU7H.js → chunk-QPV3OKX2.js} +2 -2
  131. package/dist/cli/chunks/{chunk-B23ROYST.js → chunk-QXY3IRBW.js} +21 -21
  132. package/dist/cli/chunks/chunk-RCXMUEZN.js +3 -0
  133. package/dist/cli/chunks/{chunk-HVIFA73X.js → chunk-RMJ7PJOS.js} +2 -2
  134. package/dist/cli/chunks/{chunk-OGARNKLS.js → chunk-RUJLVJDE.js} +2 -2
  135. package/dist/cli/chunks/{chunk-UGNTLSBL.js → chunk-RUSLEOMC.js} +2 -2
  136. package/dist/cli/chunks/chunk-SAPIRK2G.js +3 -0
  137. package/dist/cli/chunks/{chunk-F5BREV2Q.js → chunk-SDWMLT7B.js} +5 -5
  138. package/dist/cli/chunks/{chunk-A6PII4R4.js → chunk-SEZLYRCS.js} +1 -1
  139. package/dist/cli/chunks/{chunk-RWQDRPN5.js → chunk-TDLKXLJC.js} +2 -2
  140. package/dist/cli/chunks/{chunk-YJH7UFA2.js → chunk-U4TV75AC.js} +2 -2
  141. package/dist/cli/chunks/{chunk-34Y4CIHD.js → chunk-U6OVPMQX.js} +2 -2
  142. package/dist/cli/chunks/{chunk-L6OSEWOS.js → chunk-UE22ODHN.js} +1 -1
  143. package/dist/cli/chunks/{chunk-IARE5VGI.js → chunk-UXZEVIFX.js} +1 -1
  144. package/dist/cli/chunks/{chunk-OMHISPPF.js → chunk-V7GNUVYI.js} +1 -1
  145. package/dist/cli/chunks/{chunk-HR7RL4PB.js → chunk-VCKDVOPD.js} +2 -2
  146. package/dist/cli/chunks/{chunk-UZDTRCVU.js → chunk-VH3EB6ZG.js} +2 -2
  147. package/dist/cli/chunks/{chunk-6V6XVGCL.js → chunk-VLOIEVER.js} +3 -3
  148. package/dist/cli/chunks/{chunk-XTGVGZ4J.js → chunk-VML4SG3X.js} +3 -3
  149. package/dist/cli/chunks/{chunk-6TYTBQPV.js → chunk-VRJPH3LG.js} +2 -2
  150. package/dist/cli/chunks/{chunk-5WOBFN2T.js → chunk-VYDNLQJN.js} +2 -2
  151. package/dist/cli/chunks/{chunk-U5AVZ3T2.js → chunk-W3ZGNNDV.js} +1 -1
  152. package/dist/cli/chunks/{chunk-YGEC3PSD.js → chunk-WC47GICZ.js} +2 -2
  153. package/dist/cli/chunks/{chunk-WLOHTLHO.js → chunk-WLIYWBQR.js} +2 -2
  154. package/dist/cli/chunks/{chunk-I5VJ3FBC.js → chunk-WN55MNZ2.js} +2 -2
  155. package/dist/cli/chunks/chunk-WOZIXXY5.js +7 -0
  156. package/dist/cli/chunks/{chunk-X33LID2T.js → chunk-WR64BKUE.js} +1 -1
  157. package/dist/cli/chunks/{chunk-VGN46ZT4.js → chunk-WT3JC4A6.js} +2 -2
  158. package/dist/cli/chunks/{chunk-VOKIUF7I.js → chunk-X52TMBHU.js} +1 -1
  159. package/dist/cli/chunks/{chunk-ZATQLTYL.js → chunk-XIE7OHML.js} +1 -1
  160. package/dist/cli/chunks/{chunk-BO43BGHX.js → chunk-XNEEYXR2.js} +2 -2
  161. package/dist/cli/chunks/{chunk-KCBCYF7M.js → chunk-XNHB6TLC.js} +2 -2
  162. package/dist/cli/chunks/{chunk-VX7CQUO7.js → chunk-XQRE2HWM.js} +2 -2
  163. package/dist/cli/chunks/{chunk-CNQUU6CF.js → chunk-Y2E3IJ53.js} +2 -2
  164. package/dist/cli/chunks/{chunk-2M75CW5Q.js → chunk-Y2WMPEUP.js} +2 -2
  165. package/dist/cli/chunks/{chunk-WTMLRMKW.js → chunk-Y7GPLOXB.js} +2 -2
  166. package/dist/cli/chunks/{chunk-O66D4NEJ.js → chunk-YINFES3E.js} +2 -2
  167. package/dist/cli/chunks/{chunk-CF3BPD2R.js → chunk-ZLBBX24Q.js} +163 -164
  168. package/dist/cli/chunks/{chunk-S7D4GD7H.js → chunk-ZT3GUYM5.js} +2 -2
  169. package/dist/cli/chunks/{chunk-D5V6C3XG.js → chunk-ZTC5FBL6.js} +3 -3
  170. package/dist/cli/chunks/ci-KP4GZKJ7.js +81 -0
  171. package/dist/cli/chunks/ci-config-XDDZOOEI.js +2 -0
  172. package/dist/cli/chunks/{ci-output-DPHTFIGX.js → ci-output-7ZUQI4U6.js} +2 -2
  173. package/dist/cli/chunks/{circuit-breaker-PQ65VU2M.js → circuit-breaker-ALXKCFAL.js} +2 -2
  174. package/dist/cli/chunks/{claude-flow-setup-GKHVO7AD.js → claude-flow-setup-RL7K2NI2.js} +2 -2
  175. package/dist/cli/chunks/client-C3KHVRM6.js +2 -0
  176. package/dist/cli/chunks/{cline-installer-HWMQZJ64.js → cline-installer-2Z2QQKC3.js} +2 -2
  177. package/dist/cli/chunks/{code-OTY7BF3D.js → code-QSZTDINQ.js} +4 -4
  178. package/dist/cli/chunks/{code-index-extractor-FG3TMHHR.js → code-index-extractor-5CGR5D3Y.js} +2 -2
  179. package/dist/cli/chunks/{codex-installer-63JARKKS.js → codex-installer-7JLSEDE5.js} +2 -2
  180. package/dist/cli/chunks/{completions-4ZHONFML.js → completions-U4NBSXEB.js} +2 -2
  181. package/dist/cli/chunks/{complexity-analyzer-FYHTJW5Y.js → complexity-analyzer-WYZD2YSY.js} +2 -2
  182. package/dist/cli/chunks/{continuedev-installer-ZAWDSUR3.js → continuedev-installer-UPXINJFT.js} +2 -2
  183. package/dist/cli/chunks/{copilot-installer-5QK565JX.js → copilot-installer-WIVYQRIF.js} +2 -2
  184. package/dist/cli/chunks/core-handlers-KSQM6Q6S.js +2 -0
  185. package/dist/cli/chunks/{cost-tracker-AWWMPPBJ.js → cost-tracker-RIN4JDDM.js} +2 -2
  186. package/dist/cli/chunks/coverage-SPFVHRRU.js +43 -0
  187. package/dist/cli/chunks/coverage-target-GSRBNHXE.js +2 -0
  188. package/dist/cli/chunks/cross-domain-router-CTGNOVCF.js +2 -0
  189. package/dist/cli/chunks/{cursor-installer-3BL7JACV.js → cursor-installer-POM7NGCC.js} +2 -2
  190. package/dist/cli/chunks/{daemon-R6ULBHHF.js → daemon-HFGKQ6LB.js} +3 -3
  191. package/dist/cli/chunks/{daemon-OJ624POF.js → daemon-M5TD5Y6T.js} +4 -4
  192. package/dist/cli/chunks/{dag-attention-scheduler-J6I3LTMY.js → dag-attention-scheduler-HJXM7Q5P.js} +2 -2
  193. package/dist/cli/chunks/{detect-5Q5W33UR.js → detect-XKQGLZYN.js} +2 -2
  194. package/dist/cli/chunks/{dist-node-GJNW56NA.js → dist-node-SSKB53QL.js} +2 -2
  195. package/dist/cli/chunks/{domain-handler-IZQY2G44.js → domain-handler-6BNDHATU.js} +2 -2
  196. package/dist/cli/chunks/{domain-plugins-PIGO3KI2.js → domain-plugins-DOX54YE3.js} +2 -2
  197. package/dist/cli/chunks/{domain-transfer-NU3B4FQG.js → domain-transfer-FW4ZX3Z7.js} +2 -2
  198. package/dist/cli/chunks/dream-MIK2E4UL.js +2 -0
  199. package/dist/cli/chunks/{embed-and-insert-pattern-5QDDRPWV.js → embed-and-insert-pattern-QST77T2B.js} +2 -2
  200. package/dist/cli/chunks/{eval-TB5HOAUY.js → eval-K7E4XXBS.js} +2 -2
  201. package/dist/cli/chunks/{experience-capture-middleware-SIYVLKDE.js → experience-capture-middleware-X66IYSRV.js} +3 -3
  202. package/dist/cli/chunks/{fast-paths-T7QELS6D.js → fast-paths-5JXXTYAG.js} +2 -2
  203. package/dist/cli/chunks/{feature-flags-TNZ7ZAJV.js → feature-flags-2CR3CO23.js} +2 -2
  204. package/dist/cli/chunks/{feature-flags-T3CNNYMJ.js → feature-flags-RB72LHOJ.js} +2 -2
  205. package/dist/cli/chunks/{file-discovery-M45P2ZCY.js → file-discovery-3NHRUQQB.js} +2 -2
  206. package/dist/cli/chunks/{fleet-DSBZPHBZ.js → fleet-SDU7QEOA.js} +3 -3
  207. package/dist/cli/chunks/{gnn-wrapper-EHODCF32.js → gnn-wrapper-AWCFODUV.js} +2 -2
  208. package/dist/cli/chunks/{heartbeat-handler-V5DBVF7V.js → heartbeat-handler-A4PJ3NFP.js} +4 -4
  209. package/dist/cli/chunks/heartbeat-scheduler-OCKRACUW.js +2 -0
  210. package/dist/cli/chunks/hnsw-adapter-X67XG73C.js +2 -0
  211. package/dist/cli/chunks/hnsw-index-I7KCQBQR.js +2 -0
  212. package/dist/cli/chunks/{hnsw-legacy-bridge-IYKDYA2F.js → hnsw-legacy-bridge-KRS7SSFM.js} +2 -2
  213. package/dist/cli/chunks/{hnswlib-node-DKG4LW3X.js → hnswlib-node-OGGCPKPO.js} +2 -2
  214. package/dist/cli/chunks/{hooks-VKNMAILY.js → hooks-XNRNMUBW.js} +10 -10
  215. package/dist/cli/chunks/hybrid-backend-FOUHTKAK.js +2 -0
  216. package/dist/cli/chunks/{hypergraph-engine-AXZVP7A7.js → hypergraph-engine-X35LTXYT.js} +2 -2
  217. package/dist/cli/chunks/{hypergraph-handler-6EO6JN4Z.js → hypergraph-handler-M6THKAG6.js} +3 -3
  218. package/dist/cli/chunks/impact-analyzer-GXYVX46O.js +2 -0
  219. package/dist/cli/chunks/{init-handler-N3NG3RHN.js → init-handler-2AXMXHYF.js} +6 -6
  220. package/dist/cli/chunks/init-wizard-C2MRX2QG.js +2 -0
  221. package/dist/cli/chunks/kernel-Q2IUDIDC.js +2 -0
  222. package/dist/cli/chunks/{kilocode-installer-JICGAHLM.js → kilocode-installer-TEPR2ZJD.js} +2 -2
  223. package/dist/cli/chunks/{kiro-installer-VYBFP6ZH.js → kiro-installer-RUKHGDEE.js} +2 -2
  224. package/dist/cli/chunks/knowledge-graph-E2Z6K5EE.js +2 -0
  225. package/dist/cli/chunks/{learning-3BHEZEPK.js → learning-BEA26RNA.js} +3 -3
  226. package/dist/cli/chunks/{llm-router-GPTEZCUN.js → llm-router-7GECMDCP.js} +4 -4
  227. package/dist/cli/chunks/llm-router-service-YATYFEDD.js +2 -0
  228. package/dist/cli/chunks/{load-W5BIRPU4.js → load-NTJ4Y4ZR.js} +2 -2
  229. package/dist/cli/chunks/load-test-LV77JXWA.js +2 -0
  230. package/dist/cli/chunks/{mcp-EBV4DZPG.js → mcp-4335GTTG.js} +2 -2
  231. package/dist/cli/chunks/{memory-7F6YYKNL.js → memory-HYC4M4XS.js} +5 -5
  232. package/dist/cli/chunks/memory-backend-XME3X3QX.js +2 -0
  233. package/dist/cli/chunks/memory-handlers-VG47X5DX.js +2 -0
  234. package/dist/cli/chunks/{multi-model-executor-3ZIA2YOL.js → multi-model-executor-T7FYKM6T.js} +2 -2
  235. package/dist/cli/chunks/{opencode-installer-2XRZUTLR.js → opencode-installer-3USXVT5M.js} +2 -2
  236. package/dist/cli/chunks/{orchestrator-VSZVJUJW.js → orchestrator-VHUXUYIM.js} +5 -5
  237. package/dist/cli/chunks/pattern-null-store-TAXMLENP.js +2 -0
  238. package/dist/cli/chunks/{pattern-usage-recorder-I2IGVHRL.js → pattern-usage-recorder-CMZLPX2K.js} +2 -2
  239. package/dist/cli/chunks/{pipeline-5G3O6WBY.js → pipeline-BTRZOVSL.js} +2 -2
  240. package/dist/cli/chunks/{platform-6GUFDIA3.js → platform-2MCRKC25.js} +2 -2
  241. package/dist/cli/chunks/{plugin-GYXE4CIC.js → plugin-2VAYWAO3.js} +2 -2
  242. package/dist/cli/chunks/{prime-radiant-advanced-wasm-THX6JLGZ.js → prime-radiant-advanced-wasm-TXFEMBP6.js} +2 -2
  243. package/dist/cli/chunks/{project-root-QJRBKZQU.js → project-root-CFFPBGPX.js} +2 -2
  244. package/dist/cli/chunks/protocol-executor-ML76QAVQ.js +2 -0
  245. package/dist/cli/chunks/{protocol-handler-B54LRU26.js → protocol-handler-DZ26OYVZ.js} +2 -2
  246. package/dist/cli/chunks/{prove-PCY2WQOD.js → prove-QWONEJWX.js} +2 -2
  247. package/dist/cli/chunks/qe-reasoning-bank-LUZH6RYV.js +2 -0
  248. package/dist/cli/chunks/quality-WFH54FY7.js +8 -0
  249. package/dist/cli/chunks/{quality-gate-L3KXL6WE.js → quality-gate-ONJB7XU7.js} +3 -3
  250. package/dist/cli/chunks/queen-coordinator-EWXNIXB6.js +2 -0
  251. package/dist/cli/chunks/{real-embeddings-N3H523PJ.js → real-embeddings-GZV4VKK4.js} +2 -2
  252. package/dist/cli/chunks/{ref-validation-6BKDPHZ7.js → ref-validation-HW5Y55ZC.js} +2 -2
  253. package/dist/cli/chunks/{roocode-installer-NSGGTWXE.js → roocode-installer-5OABDNZT.js} +2 -2
  254. package/dist/cli/chunks/router-MXOBVEBF.js +2 -0
  255. package/dist/cli/chunks/routing-feedback-T6CCRUEK.js +2 -0
  256. package/dist/cli/chunks/{routing-handler-SRQNUBG3.js → routing-handler-CVHVOQTC.js} +2 -2
  257. package/dist/cli/chunks/{ruvector-commands-2IGULGDE.js → ruvector-commands-KKDKFGIQ.js} +2 -2
  258. package/dist/cli/chunks/rvf-dual-writer-WHXVT3V3.js +2 -0
  259. package/dist/cli/chunks/rvf-migration-adapter-JFPWIRCG.js +2 -0
  260. package/dist/cli/chunks/{rvf-migration-coordinator-ZD6WK5CK.js → rvf-migration-coordinator-D4KUBNRZ.js} +2 -2
  261. package/dist/cli/chunks/rvf-native-adapter-KOXR7TJL.js +2 -0
  262. package/dist/cli/chunks/{rvf-store-integrity-QULKUBBI.js → rvf-store-integrity-UGUXKIFX.js} +2 -2
  263. package/dist/cli/chunks/safe-db-CI6IPSIN.js +2 -0
  264. package/dist/cli/chunks/schedule-X4HW6TVJ.js +2 -0
  265. package/dist/cli/chunks/scheduler-KCNJ2ON3.js +2 -0
  266. package/dist/cli/chunks/{security-JW4EBARW.js → security-7723AZZ4.js} +3 -3
  267. package/dist/cli/chunks/{shared-rvf-adapter-VQ7NJTGY.js → shared-rvf-adapter-KEQ5CLNI.js} +2 -2
  268. package/dist/cli/chunks/{shared-rvf-dual-writer-SKTS52HK.js → shared-rvf-dual-writer-ZSHYG5IA.js} +2 -2
  269. package/dist/cli/chunks/sqlite-persistence-PGHU6VUR.js +2 -0
  270. package/dist/cli/chunks/{standalone-memory-3N4YJCSY.js → standalone-memory-MHZEEYMK.js} +2 -2
  271. package/dist/cli/chunks/{status-handler-5BQ2IIDG.js → status-handler-JKXPJ22K.js} +2 -2
  272. package/dist/cli/chunks/{structural-health-WGYR2RJB.js → structural-health-J4RKCYWF.js} +2 -2
  273. package/dist/cli/chunks/{sync-R5OKUBTQ.js → sync-EFWXMA2H.js} +2 -2
  274. package/dist/cli/chunks/{sync-DLKSXTIR.js → sync-PDPORHVN.js} +2 -2
  275. package/dist/cli/chunks/{task-handler-Z5KNTSUX.js → task-handler-VERADM44.js} +2 -2
  276. package/dist/cli/chunks/{task-handlers-RZFMYFSC.js → task-handlers-4RUCWUR2.js} +3 -3
  277. package/dist/cli/chunks/{test-LHWKZJRN.js → test-DMBJFQNL.js} +4 -4
  278. package/dist/cli/chunks/{test-scheduling-EN7WXUMS.js → test-scheduling-LUPTVGCD.js} +3 -3
  279. package/dist/cli/chunks/{token-bootstrap-4V3OO4EC.js → token-bootstrap-S346YBVO.js} +2 -2
  280. package/dist/cli/chunks/{token-usage-PFC2BYBS.js → token-usage-VOA34IKM.js} +2 -2
  281. package/dist/cli/chunks/{transformers-VZCC4SHC.js → transformers-GU4TYAN5.js} +2 -2
  282. package/dist/cli/chunks/{tree-sitter-wasm-parser-ZYDQXGKN.js → tree-sitter-wasm-parser-MZPXAH7C.js} +2 -2
  283. package/dist/cli/chunks/{types-I6AWHZZQ.js → types-K4FLXR2K.js} +2 -2
  284. package/dist/cli/chunks/unified-memory-6CK3TUNQ.js +2 -0
  285. package/dist/cli/chunks/unified-memory-hnsw-A7BWBGYN.js +2 -0
  286. package/dist/cli/chunks/unified-persistence-GEPMDBQZ.js +2 -0
  287. package/dist/cli/chunks/{upgrade-T7SG75PA.js → upgrade-M3ATDRMK.js} +2 -2
  288. package/dist/cli/chunks/{validate-YLYEHTY3.js → validate-AAP773B3.js} +2 -2
  289. package/dist/cli/chunks/{validate-swarm-VTLTRUE3.js → validate-swarm-7RGAZX5F.js} +2 -2
  290. package/dist/cli/chunks/visual-security-L4J7LQWT.js +2 -0
  291. package/dist/cli/chunks/{web-tree-sitter-JUM7ZY5M.js → web-tree-sitter-GQMRHGGI.js} +2 -2
  292. package/dist/cli/chunks/{windsurf-installer-4KS2466T.js → windsurf-installer-HG6HF2GF.js} +2 -2
  293. package/dist/cli/chunks/witness-chain-CDUMX623.js +2 -0
  294. package/dist/cli/chunks/{witness-chain-E4X6TOCT.js → witness-chain-WKU3ZIBQ.js} +2 -2
  295. package/dist/cli/chunks/{witness-chain-repair-MB53OZO6.js → witness-chain-repair-WNYH6O4L.js} +2 -2
  296. package/dist/cli/chunks/{witness-chain-verifier-LBWJHO7Y.js → witness-chain-verifier-Q2KW3QEQ.js} +2 -2
  297. package/dist/cli/chunks/{witness-key-manager-5IHVMXHJ.js → witness-key-manager-NQ5DAAC4.js} +2 -2
  298. package/dist/cli/chunks/{workflow-XUQXIRNE.js → workflow-CX6SHFBW.js} +5 -5
  299. package/dist/cli/chunks/workflow-orchestrator-USJDWVDR.js +2 -0
  300. package/dist/cli/chunks/{wrappers-YVF5SQUN.js → wrappers-CZDI6Z3X.js} +2 -2
  301. package/dist/cli/commands/ci.js +14 -6
  302. package/dist/cli/commands/code.js +1 -0
  303. package/dist/cli/commands/coverage.d.ts +28 -0
  304. package/dist/cli/commands/coverage.js +258 -143
  305. package/dist/cli/commands/quality.d.ts +12 -1
  306. package/dist/cli/commands/quality.js +51 -3
  307. package/dist/cli/commands/workflow.js +3 -0
  308. package/dist/cli/scheduler/persistent-scheduler.d.ts +2 -0
  309. package/dist/cli/scheduler/persistent-scheduler.js +12 -2
  310. package/dist/cli/utils/ci-output.d.ts +14 -4
  311. package/dist/cli/utils/ci-output.js +21 -4
  312. package/dist/cli/utils/coverage-data.d.ts +7 -0
  313. package/dist/cli/utils/coverage-data.js +21 -27
  314. package/dist/contracts/verdicts.d.ts +14 -0
  315. package/dist/contracts/verdicts.js +44 -3
  316. package/dist/coordination/handlers/coverage-handlers.js +121 -120
  317. package/dist/coordination/handlers/coverage-runner.d.ts +121 -0
  318. package/dist/coordination/handlers/coverage-runner.js +367 -0
  319. package/dist/coordination/handlers/coverage-target.d.ts +144 -0
  320. package/dist/coordination/handlers/coverage-target.js +311 -0
  321. package/dist/coordination/handlers/handler-utils.d.ts +9 -0
  322. package/dist/coordination/handlers/handler-utils.js +44 -1
  323. package/dist/coordination/handlers/quality-handlers.js +101 -15
  324. package/dist/coordination/result-saver.js +17 -3
  325. package/dist/coordination/task-executor.d.ts +5 -0
  326. package/dist/coordination/task-executor.js +7 -0
  327. package/dist/domains/code-intelligence/coordinator.d.ts +2 -1
  328. package/dist/domains/code-intelligence/coordinator.js +10 -32
  329. package/dist/domains/code-intelligence/interfaces.d.ts +5 -0
  330. package/dist/domains/code-intelligence/plugin.js +1 -0
  331. package/dist/domains/code-intelligence/project-root-resolver.d.ts +50 -0
  332. package/dist/domains/code-intelligence/project-root-resolver.js +121 -0
  333. package/dist/domains/code-intelligence/services/metric-collector/listing-process-owner.d.ts +3 -0
  334. package/dist/domains/code-intelligence/services/metric-collector/listing-process-owner.js +57 -0
  335. package/dist/domains/code-intelligence/services/metric-collector/test-counter.js +124 -36
  336. package/dist/domains/coverage-analysis/coordinator.js +4 -1
  337. package/dist/domains/coverage-analysis/interfaces.d.ts +15 -0
  338. package/dist/domains/coverage-analysis/plugin.js +7 -1
  339. package/dist/domains/coverage-analysis/services/coverage-analyzer.d.ts +7 -0
  340. package/dist/domains/coverage-analysis/services/coverage-analyzer.js +29 -9
  341. package/dist/domains/quality-assessment/coordinator-claim-verifier.js +2 -1
  342. package/dist/domains/quality-assessment/coordinator.js +8 -8
  343. package/dist/domains/quality-assessment/coverage-report-event.d.ts +25 -0
  344. package/dist/domains/quality-assessment/coverage-report-event.js +36 -0
  345. package/dist/domains/quality-assessment/evidence-sufficiency.d.ts +57 -0
  346. package/dist/domains/quality-assessment/evidence-sufficiency.js +97 -0
  347. package/dist/domains/quality-assessment/index.d.ts +1 -1
  348. package/dist/domains/quality-assessment/index.js +1 -1
  349. package/dist/domains/quality-assessment/plugin.js +8 -8
  350. package/dist/domains/quality-assessment/quality-evidence.d.ts +50 -2
  351. package/dist/domains/quality-assessment/quality-evidence.js +90 -8
  352. package/dist/domains/quality-assessment/services/quality-analyzer.js +13 -9
  353. package/dist/mcp/bundle.js +457 -453
  354. package/dist/mcp/handlers/domain-handler-configs.d.ts +60 -1
  355. package/dist/mcp/handlers/domain-handler-configs.js +42 -4
  356. package/dist/mcp/handlers/handler-factory.js +3 -0
  357. package/dist/mcp/handlers/wrapped-domain-handlers.js +7 -1
  358. package/dist/mcp/protocol-server.js +3 -2
  359. package/dist/mcp/services/session-store.js +11 -1
  360. package/dist/mcp/tools/coverage-analysis/index.js +1 -0
  361. package/dist/mcp/types.d.ts +24 -0
  362. package/dist/memory/crdt/convergence-tracker.js +14 -24
  363. package/dist/memory/crdt/crdt-store.js +15 -0
  364. package/dist/memory/crdt/lww-register.js +3 -3
  365. package/dist/memory/crdt/or-set.js +18 -0
  366. package/dist/planning/goap-planner.js +18 -10
  367. package/dist/shared/embeddings/embedding-cache.d.ts +3 -3
  368. package/dist/shared/embeddings/embedding-cache.js +8 -8
  369. package/dist/shared/embeddings/nomic-embedder.js +9 -6
  370. package/dist/shared/events/domain-events.d.ts +2 -0
  371. package/dist/shared/llm/cache.js +1 -1
  372. package/package.json +1 -1
  373. package/dist/cli/chunks/adapter-WQSFQES5.js +0 -2
  374. package/dist/cli/chunks/aqe-learning-engine-TDHBBADE.js +0 -2
  375. package/dist/cli/chunks/base-CZSB27VO.js +0 -2
  376. package/dist/cli/chunks/browser-workflow-AEMIS6PA.js +0 -2
  377. package/dist/cli/chunks/chunk-7IJVCDDC.js +0 -96
  378. package/dist/cli/chunks/chunk-INVDDFJC.js +0 -2
  379. package/dist/cli/chunks/chunk-K65X6CQA.js +0 -4
  380. package/dist/cli/chunks/chunk-MZDUBFLP.js +0 -2
  381. package/dist/cli/chunks/chunk-QDQLL2QB.js +0 -3
  382. package/dist/cli/chunks/chunk-QZBFMXO5.js +0 -742
  383. package/dist/cli/chunks/ci-JPISJ25U.js +0 -82
  384. package/dist/cli/chunks/client-BS7I637W.js +0 -2
  385. package/dist/cli/chunks/core-handlers-UG7RMTK5.js +0 -2
  386. package/dist/cli/chunks/coverage-SMFQEGKE.js +0 -27
  387. package/dist/cli/chunks/cross-domain-router-NX7F6TOF.js +0 -2
  388. package/dist/cli/chunks/dream-GYEH57FW.js +0 -2
  389. package/dist/cli/chunks/heartbeat-scheduler-4TJ3T7LR.js +0 -2
  390. package/dist/cli/chunks/hnsw-adapter-PHFK4EAP.js +0 -2
  391. package/dist/cli/chunks/hnsw-index-434XDDBH.js +0 -2
  392. package/dist/cli/chunks/hybrid-backend-DYVJQENQ.js +0 -2
  393. package/dist/cli/chunks/impact-analyzer-CBAST6M2.js +0 -2
  394. package/dist/cli/chunks/init-wizard-DWIJW7HY.js +0 -2
  395. package/dist/cli/chunks/kernel-AQGCS4X2.js +0 -2
  396. package/dist/cli/chunks/knowledge-graph-2ICXFUUV.js +0 -2
  397. package/dist/cli/chunks/llm-router-service-C47RGTH6.js +0 -2
  398. package/dist/cli/chunks/load-test-LRDAW3N6.js +0 -2
  399. package/dist/cli/chunks/memory-backend-UFBAYPQ6.js +0 -2
  400. package/dist/cli/chunks/memory-handlers-OGLJHAAJ.js +0 -2
  401. package/dist/cli/chunks/pattern-null-store-27FCITT3.js +0 -2
  402. package/dist/cli/chunks/protocol-executor-XWXXTMEW.js +0 -2
  403. package/dist/cli/chunks/qe-reasoning-bank-3RMYXENE.js +0 -2
  404. package/dist/cli/chunks/quality-LPVDZC7U.js +0 -7
  405. package/dist/cli/chunks/queen-coordinator-AS6DZ7UJ.js +0 -2
  406. package/dist/cli/chunks/router-OVNLNGHO.js +0 -2
  407. package/dist/cli/chunks/routing-feedback-TBOWEB6H.js +0 -2
  408. package/dist/cli/chunks/rvf-dual-writer-YJYRCYGT.js +0 -2
  409. package/dist/cli/chunks/rvf-migration-adapter-VMRQ2SFO.js +0 -2
  410. package/dist/cli/chunks/rvf-native-adapter-B75L3ALW.js +0 -2
  411. package/dist/cli/chunks/safe-db-CRQHMCV6.js +0 -2
  412. package/dist/cli/chunks/schedule-L3DKJRXU.js +0 -2
  413. package/dist/cli/chunks/scheduler-VRHYUGY5.js +0 -2
  414. package/dist/cli/chunks/sqlite-persistence-JVAZETTL.js +0 -2
  415. package/dist/cli/chunks/unified-memory-WOOCCIUM.js +0 -2
  416. package/dist/cli/chunks/unified-memory-hnsw-PDDHFLUB.js +0 -2
  417. package/dist/cli/chunks/unified-persistence-6ETD3JSC.js +0 -2
  418. package/dist/cli/chunks/visual-security-O4OT2YPY.js +0 -2
  419. package/dist/cli/chunks/witness-chain-67JHPDCN.js +0 -2
  420. package/dist/cli/chunks/workflow-orchestrator-ZVFSNRYZ.js +0 -2
@@ -10,6 +10,17 @@ import { toError } from '../../../shared/error-utils.js';
10
10
  import { safeJsonParse } from '../../../shared/safe-json.js';
11
11
  import { writeQualityEvidence } from '../../quality-assessment/quality-evidence.js';
12
12
  import { getClaudeModelForTier } from '../../../shared/llm/model-registry.js';
13
+ /**
14
+ * Whether an analyze request carries instrumented (measured) coverage (#1008).
15
+ * Fail-closed: an explicit `request.measured` wins; otherwise only data a
16
+ * producer marked `instrumented: true` is measured. Anything without
17
+ * provenance is analyzed and returned, but never persisted as evidence.
18
+ */
19
+ export function isMeasuredCoverage(request) {
20
+ if (typeof request.measured === 'boolean')
21
+ return request.measured;
22
+ return request.coverageData.instrumented === true;
23
+ }
13
24
  const DEFAULT_CONFIG = {
14
25
  defaultThreshold: 80,
15
26
  enableLLMAnalysis: true, // On by default - opt-out
@@ -66,22 +77,30 @@ export class CoverageAnalyzerService {
66
77
  // Check if coverage meets threshold
67
78
  const overallCoverage = this.calculateOverallCoverage(summary);
68
79
  const meetsThreshold = overallCoverage >= threshold;
80
+ // #1008: only instrumented coverage is evidence. A static estimate is
81
+ // analyzed and returned to the caller, but never compared against or
82
+ // written over a measurement, and never stored where a quality gate,
83
+ // quality_assess or another reader would take it as measured.
84
+ const measured = isMeasuredCoverage(request);
69
85
  // Calculate delta from previous coverage (if stored)
70
- const delta = await this.calculateDelta(summary);
86
+ const delta = measured ? await this.calculateDelta(summary) : undefined;
71
87
  // Generate recommendations based on analysis
72
88
  const recommendations = this.generateRecommendations(coverageData, summary, threshold);
73
- // Store current coverage for future delta calculations
74
- await this.storeCoverageSnapshot(summary);
75
- // Store coverage vectors for similarity search + KV for quality-analyzer
76
- if (request.includeFileDetails) {
77
- await this.indexFileCoverageVectors(coverageData.files);
78
- await this.storeFileCoverageKV(coverageData.files);
89
+ if (measured) {
90
+ // Store current coverage for future delta calculations
91
+ await this.storeCoverageSnapshot(summary);
92
+ // Store coverage vectors for similarity search + KV for quality-analyzer
93
+ if (request.includeFileDetails) {
94
+ await this.indexFileCoverageVectors(coverageData.files);
95
+ await this.storeFileCoverageKV(coverageData.files);
96
+ }
79
97
  }
80
98
  return ok({
81
99
  summary,
82
100
  meetsThreshold,
83
101
  delta,
84
102
  recommendations,
103
+ measured,
85
104
  });
86
105
  }
87
106
  catch (error) {
@@ -440,8 +459,9 @@ Provide thoughtful, specific analysis based on the coverage data. Do not include
440
459
  if (existing) {
441
460
  await this.memory.set('coverage:previous', existing, { persist: true });
442
461
  }
443
- // Store latest snapshot
444
- await this.memory.set('coverage:latest', summary, { persist: true });
462
+ // Store latest snapshot, stamped with its provenance (#1008). Only
463
+ // measured coverage reaches this method.
464
+ await this.memory.set('coverage:latest', { ...summary, measured: true }, { persist: true });
445
465
  await writeQualityEvidence(this.memory, { coverage: summary.line }, {
446
466
  measuredAt: new Date().toISOString(),
447
467
  source: 'coverage-analysis',
@@ -104,7 +104,8 @@ export function convertToQEReport(report, type) {
104
104
  },
105
105
  });
106
106
  }
107
- if (report.score.coverage < 80) {
107
+ // #996: -1 means coverage was not measured; it is not a "-1%" coverage claim.
108
+ if (report.score.coverage >= 0 && report.score.coverage < 80) {
108
109
  claims.push({
109
110
  id: `coverage-${Date.now()}`,
110
111
  type: 'coverage-claim',
@@ -33,6 +33,7 @@ import { DEFAULT_RATCHET_CONFIG, } from './coherence/types.js';
33
33
  import { getWitnessChain } from '../../audit/witness-chain.js';
34
34
  // Three-loop feature flag for instantAdapt protocol
35
35
  import { isSONAThreeLoopEnabled } from '../../integrations/ruvector/feature-flags.js';
36
+ import { measuredCoverageSummary } from './coverage-report-event.js';
36
37
  // CQ-002: Base domain coordinator
37
38
  import { BaseDomainCoordinator, } from '../base-domain-coordinator.js';
38
39
  const DEFAULT_CONFIG = {
@@ -819,15 +820,14 @@ export class QualityAssessmentCoordinator extends BaseDomainCoordinator {
819
820
  }
820
821
  async handleCoverageReportCreated(event) {
821
822
  // Store coverage data for quality assessment
822
- const payload = event.payload;
823
+ // #1008: only a report explicitly marked measured is coverage evidence.
824
+ // Estimates and look-alike events with no coverage figures (e.g. bridged
825
+ // captured experiences) must never touch `coverage:latest`.
826
+ const summary = measuredCoverageSummary(event.payload);
827
+ if (!summary)
828
+ return;
823
829
  // Store under the canonical coverage key so quality-analyzer can read it
824
- await this.memory.set('coverage:latest', {
825
- line: payload.line,
826
- branch: payload.branch,
827
- function: 0,
828
- statement: 0,
829
- files: 0,
830
- }, { persist: true });
830
+ await this.memory.set('coverage:latest', summary, { persist: true });
831
831
  }
832
832
  async handleSecurityAuditCompleted(event) {
833
833
  // Store security findings for deployment decisions
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Validation of `coverage-analysis.CoverageReportCreated` payloads before the
3
+ * quality-assessment domain stores them as `coverage:latest` (#1008).
4
+ *
5
+ * Only a report its producer explicitly marked `measured: true`, carrying
6
+ * finite coverage figures, is coverage evidence. Anything else — a static
7
+ * estimate, a legacy event without provenance, or a look-alike event with no
8
+ * coverage figures at all — is ignored rather than written as zeros.
9
+ */
10
+ /** The `coverage:latest` record written from a measured coverage report. */
11
+ export interface MeasuredCoverageSummary {
12
+ line: number;
13
+ branch: number;
14
+ function: number;
15
+ statement: number;
16
+ files: number;
17
+ /** Provenance stamp: this record came from instrumented coverage. */
18
+ measured: true;
19
+ }
20
+ /**
21
+ * Return the measured summary to store, or `null` when the payload is not
22
+ * measured coverage evidence.
23
+ */
24
+ export declare function measuredCoverageSummary(payload: unknown): MeasuredCoverageSummary | null;
25
+ //# sourceMappingURL=coverage-report-event.d.ts.map
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Validation of `coverage-analysis.CoverageReportCreated` payloads before the
3
+ * quality-assessment domain stores them as `coverage:latest` (#1008).
4
+ *
5
+ * Only a report its producer explicitly marked `measured: true`, carrying
6
+ * finite coverage figures, is coverage evidence. Anything else — a static
7
+ * estimate, a legacy event without provenance, or a look-alike event with no
8
+ * coverage figures at all — is ignored rather than written as zeros.
9
+ */
10
+ const isPercent = (v) => typeof v === 'number' && Number.isFinite(v) && v >= 0 && v <= 100;
11
+ /**
12
+ * Return the measured summary to store, or `null` when the payload is not
13
+ * measured coverage evidence.
14
+ */
15
+ export function measuredCoverageSummary(payload) {
16
+ if (!payload || typeof payload !== 'object')
17
+ return null;
18
+ const p = payload;
19
+ if (p.measured !== true)
20
+ return null;
21
+ if (!isPercent(p.line) || !isPercent(p.branch) || !isPercent(p.function) || !isPercent(p.statement)) {
22
+ return null;
23
+ }
24
+ const files = typeof p.files === 'number' && Number.isInteger(p.files) && p.files >= 0 ? p.files : null;
25
+ if (files === null)
26
+ return null;
27
+ return {
28
+ line: p.line,
29
+ branch: p.branch,
30
+ function: p.function,
31
+ statement: p.statement,
32
+ files,
33
+ measured: true,
34
+ };
35
+ }
36
+ //# sourceMappingURL=coverage-report-event.js.map
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Evidence sufficiency for static quality analysis (#996).
3
+ *
4
+ * The static analyzer marks metrics it could not measure with the `-1`
5
+ * sentinel (or omits them). Such metrics must never be read as numbers that
6
+ * support a verdict: a pass computed without them is a pass on missing data.
7
+ */
8
+ import { INSUFFICIENT_EVIDENCE, type QualityThresholdOverrides } from './quality-evidence.js';
9
+ /** `measured`: every requested metric has data. Otherwise no verdict may approve. */
10
+ export type StaticEvidenceStatus = 'measured' | typeof INSUFFICIENT_EVIDENCE;
11
+ /** Metric names the static quality analysis understands. */
12
+ export declare const STATIC_QUALITY_METRICS: readonly ["coverage", "complexity", "maintainability", "duplication", "testability", "security"];
13
+ /**
14
+ * #996: the coverage threshold that applies to a static assessment — the
15
+ * request's threshold, else the user-configured gate threshold, else the
16
+ * canonical default (undefined = use the default).
17
+ */
18
+ export declare function resolveCoverageOverride(requested: number | undefined, configured: number | undefined): number | undefined;
19
+ export interface MeasuredFailure {
20
+ metric: string;
21
+ value: number;
22
+ threshold: number;
23
+ direction: 'min' | 'max';
24
+ }
25
+ export interface EvidenceSufficiency {
26
+ evidenceStatus: StaticEvidenceStatus;
27
+ /** Requested metrics backed by measured data. */
28
+ measured: string[];
29
+ /** Requested metrics with no measured data (missing, `-1`, or non-finite). */
30
+ unmeasured: string[];
31
+ /** Share of requested metrics that were measured, in [0, 1], two decimals. */
32
+ confidence: number;
33
+ }
34
+ /** A metric value is measured only if it is a finite, non-negative number. */
35
+ export declare function isMeasuredMetricValue(value: unknown): value is number;
36
+ /**
37
+ * #996 (N3): `metrics` must be a non-empty string[] of known names. A bare
38
+ * string would otherwise be spread into characters. Returns the de-duplicated
39
+ * list, or throws a caller-facing validation error.
40
+ */
41
+ export declare function validateRequestedMetrics(metrics: unknown): string[];
42
+ /**
43
+ * Decide whether static analysis measured every requested metric.
44
+ *
45
+ * @param requested - metric names the caller asked to assess; when empty,
46
+ * the measured values themselves define the scope.
47
+ * @param values - metric values produced by the analyzer (`-1` = unmeasured).
48
+ */
49
+ export declare function assessEvidenceSufficiency(requested: readonly string[], values: Readonly<Record<string, number | undefined>>): EvidenceSufficiency;
50
+ /**
51
+ * #996 (N2): measured metrics that already fail their own limit. Such a
52
+ * failure is conclusive — no unmeasured metric can turn it into a pass.
53
+ */
54
+ export declare function findMeasuredFailures(measured: readonly string[], values: Readonly<Record<string, number | undefined>>, overrides?: QualityThresholdOverrides): MeasuredFailure[];
55
+ /** Plain-language recommendation for one measured failure. */
56
+ export declare function describeMeasuredFailure(failure: MeasuredFailure): string;
57
+ //# sourceMappingURL=evidence-sufficiency.d.ts.map
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Evidence sufficiency for static quality analysis (#996).
3
+ *
4
+ * The static analyzer marks metrics it could not measure with the `-1`
5
+ * sentinel (or omits them). Such metrics must never be read as numbers that
6
+ * support a verdict: a pass computed without them is a pass on missing data.
7
+ */
8
+ import { INSUFFICIENT_EVIDENCE, resolveQualityThresholds, } from './quality-evidence.js';
9
+ /** Metric names the static quality analysis understands. */
10
+ export const STATIC_QUALITY_METRICS = [
11
+ 'coverage', 'complexity', 'maintainability', 'duplication', 'testability', 'security',
12
+ ];
13
+ /**
14
+ * Static metrics that a measured value can fail on its own, mapped to the
15
+ * canonical gate metric whose effective threshold applies (by default
16
+ * coverage >= 80, duplication <= 5; see resolveQualityThresholds).
17
+ */
18
+ const STATIC_TO_GATE_METRIC = {
19
+ coverage: 'coverage',
20
+ duplication: 'duplications',
21
+ };
22
+ /**
23
+ * #996: the coverage threshold that applies to a static assessment — the
24
+ * request's threshold, else the user-configured gate threshold, else the
25
+ * canonical default (undefined = use the default).
26
+ */
27
+ export function resolveCoverageOverride(requested, configured) {
28
+ return requested ?? configured;
29
+ }
30
+ /** A metric value is measured only if it is a finite, non-negative number. */
31
+ export function isMeasuredMetricValue(value) {
32
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
33
+ }
34
+ /**
35
+ * #996 (N3): `metrics` must be a non-empty string[] of known names. A bare
36
+ * string would otherwise be spread into characters. Returns the de-duplicated
37
+ * list, or throws a caller-facing validation error.
38
+ */
39
+ export function validateRequestedMetrics(metrics) {
40
+ const known = STATIC_QUALITY_METRICS;
41
+ const message = `metrics must be a non-empty array of metric names (${known.join(', ')}).`;
42
+ if (!Array.isArray(metrics) || metrics.length === 0)
43
+ throw new Error(message);
44
+ const unknown = metrics.filter((m) => typeof m !== 'string' || !known.includes(m));
45
+ if (unknown.length > 0) {
46
+ throw new Error(`${message} Unknown: ${unknown.map((m) => JSON.stringify(m)).join(', ')}.`);
47
+ }
48
+ return [...new Set(metrics)];
49
+ }
50
+ /**
51
+ * Decide whether static analysis measured every requested metric.
52
+ *
53
+ * @param requested - metric names the caller asked to assess; when empty,
54
+ * the measured values themselves define the scope.
55
+ * @param values - metric values produced by the analyzer (`-1` = unmeasured).
56
+ */
57
+ export function assessEvidenceSufficiency(requested, values) {
58
+ const scope = requested.length > 0
59
+ ? [...new Set(requested)]
60
+ : Object.keys(values).filter((name) => isMeasuredMetricValue(values[name]));
61
+ const measured = scope.filter((name) => isMeasuredMetricValue(values[name]));
62
+ const unmeasured = scope.filter((name) => !isMeasuredMetricValue(values[name]));
63
+ const confidence = scope.length === 0
64
+ ? 0
65
+ : Math.round((measured.length / scope.length) * 100) / 100;
66
+ return {
67
+ evidenceStatus: unmeasured.length === 0 && measured.length > 0 ? 'measured' : INSUFFICIENT_EVIDENCE,
68
+ measured,
69
+ unmeasured,
70
+ confidence,
71
+ };
72
+ }
73
+ /**
74
+ * #996 (N2): measured metrics that already fail their own limit. Such a
75
+ * failure is conclusive — no unmeasured metric can turn it into a pass.
76
+ */
77
+ export function findMeasuredFailures(measured, values, overrides = {}) {
78
+ const thresholds = resolveQualityThresholds(overrides);
79
+ const failures = [];
80
+ for (const metric of measured) {
81
+ const gateMetric = STATIC_TO_GATE_METRIC[metric];
82
+ const limit = gateMetric ? thresholds[gateMetric] : undefined;
83
+ const value = values[metric];
84
+ if (!limit || !isMeasuredMetricValue(value))
85
+ continue;
86
+ const fails = limit.direction === 'min' ? value < limit.value : value > limit.value;
87
+ if (fails)
88
+ failures.push({ metric, value, threshold: limit.value, direction: limit.direction });
89
+ }
90
+ return failures;
91
+ }
92
+ /** Plain-language recommendation for one measured failure. */
93
+ export function describeMeasuredFailure(failure) {
94
+ const bound = failure.direction === 'min' ? 'at least' : 'at most';
95
+ return `${failure.metric} measured at ${failure.value} fails its threshold (${bound} ${failure.threshold}).`;
96
+ }
97
+ //# sourceMappingURL=evidence-sufficiency.js.map
@@ -9,7 +9,7 @@ export { QualityAssessmentCoordinator, type IQualityAssessmentCoordinator, type
9
9
  export { QualityGateService, type IQualityGateService, type QualityGateConfig, } from './services/quality-gate';
10
10
  export { QualityAnalyzerService, type IQualityAnalyzerService, type QualityAnalyzerConfig, } from './services/quality-analyzer';
11
11
  export { DeploymentAdvisorService, type IDeploymentAdvisorService, type DeploymentAdvisorConfig, type DeploymentAccuracy, } from './services/deployment-advisor';
12
- export { DEFAULT_QUALITY_EVIDENCE_MAX_AGE_MS, DEFAULT_QUALITY_THRESHOLDS, QUALITY_EVIDENCE_NAMESPACE, QUALITY_METRICS, evaluateQualityEvidence, loadQualityEvidence, writeQualityEvidence, type EvaluatedQualityCheck, type QualityEvidenceRecord, type QualityEvidenceValues, type QualityMetricName, type QualityThreshold, } from './quality-evidence.js';
12
+ export { DEFAULT_QUALITY_EVIDENCE_MAX_AGE_MS, DEFAULT_QUALITY_THRESHOLDS, QUALITY_EVIDENCE_NAMESPACE, QUALITY_METRICS, INSUFFICIENT_EVIDENCE, InsufficientQualityEvidenceError, evaluateQualityEvidence, inspectQualityEvidence, loadQualityEvidence, writeQualityEvidence, type EvaluatedQualityCheck, type QualityEvidenceRecord, type QualityEvidenceValues, type QualityMetricName, type QualityThreshold, } from './quality-evidence.js';
13
13
  export { CoherenceGateService, createCoherenceGateService, type CoherenceGateResult, type CoherenceGateServiceConfig, } from './services/coherence-gate';
14
14
  export * from './coherence';
15
15
  export type { QualityAssessmentAPI, GateEvaluationRequest, QualityAnalysisRequest, DeploymentRequest, ComplexityRequest, GateResult, GateCheck, QualityReport, QualityMetricDetail, QualityTrend, Recommendation, DeploymentAdvice, ComplexityReport, FileComplexity, ComplexitySummary, ComplexityHotspot, QualityMetrics, GateThresholds, } from './interfaces';
@@ -18,7 +18,7 @@ export { QualityAssessmentCoordinator, } from './coordinator.js';
18
18
  export { QualityGateService, } from './services/quality-gate.js';
19
19
  export { QualityAnalyzerService, } from './services/quality-analyzer.js';
20
20
  export { DeploymentAdvisorService, } from './services/deployment-advisor.js';
21
- export { DEFAULT_QUALITY_EVIDENCE_MAX_AGE_MS, DEFAULT_QUALITY_THRESHOLDS, QUALITY_EVIDENCE_NAMESPACE, QUALITY_METRICS, evaluateQualityEvidence, loadQualityEvidence, writeQualityEvidence, } from './quality-evidence.js';
21
+ export { DEFAULT_QUALITY_EVIDENCE_MAX_AGE_MS, DEFAULT_QUALITY_THRESHOLDS, QUALITY_EVIDENCE_NAMESPACE, QUALITY_METRICS, INSUFFICIENT_EVIDENCE, InsufficientQualityEvidenceError, evaluateQualityEvidence, inspectQualityEvidence, loadQualityEvidence, writeQualityEvidence, } from './quality-evidence.js';
22
22
  // ============================================================================
23
23
  // Coherence-Gated Quality Gates (ADR-030)
24
24
  // ============================================================================
@@ -8,6 +8,7 @@ import { QualityAssessmentCoordinator, } from './coordinator.js';
8
8
  import { QualityGateService, } from './services/quality-gate.js';
9
9
  import { QualityAnalyzerService, } from './services/quality-analyzer.js';
10
10
  import { toError } from '../../shared/error-utils.js';
11
+ import { measuredCoverageSummary } from './coverage-report-event.js';
11
12
  import { DeploymentAdvisorService, } from './services/deployment-advisor.js';
12
13
  /**
13
14
  * Quality Assessment Domain Plugin
@@ -285,15 +286,14 @@ export class QualityAssessmentPlugin extends BaseDomainPlugin {
285
286
  }
286
287
  }
287
288
  async handleCoverageReport(event) {
288
- const payload = event.payload;
289
+ // #1008: only a report explicitly marked measured is coverage evidence.
290
+ // Estimates and look-alike events with no coverage figures (e.g. bridged
291
+ // captured experiences) must never touch `coverage:latest`.
292
+ const summary = measuredCoverageSummary(event.payload);
293
+ if (!summary)
294
+ return;
289
295
  // Store under the canonical coverage key so quality-analyzer can read it
290
- await this.memory.set('coverage:latest', {
291
- line: payload.line,
292
- branch: payload.branch,
293
- function: payload.function,
294
- statement: payload.statement,
295
- files: 0,
296
- }, { persist: true });
296
+ await this.memory.set('coverage:latest', summary, { persist: true });
297
297
  }
298
298
  async handleDefectPrediction(event) {
299
299
  const payload = event.payload;
@@ -29,13 +29,61 @@ export declare function writeQualityEvidence(memory: MemoryBackend, values: Part
29
29
  measuredAt: string;
30
30
  source: string;
31
31
  }): Promise<void>;
32
+ /** #996: the single status word for "a verdict cannot be reached on this evidence". */
33
+ export declare const INSUFFICIENT_EVIDENCE: "insufficient-evidence";
34
+ /** #996: one recommendation per unmeasured metric, naming what to run. */
35
+ export declare function describeMissingMetrics(unmeasured: readonly string[]): string[];
36
+ /** Why a canonical metric has no usable evidence. */
37
+ export interface UnusableQualityEvidence {
38
+ metric: QualityMetricName;
39
+ reason: string;
40
+ }
41
+ /**
42
+ * #996: thrown when the measured gate cannot be evaluated. The message is the
43
+ * first problem found (unchanged wording); `unmeasured` names every metric
44
+ * whose record is absent, stale, future-dated or malformed.
45
+ */
46
+ export declare class InsufficientQualityEvidenceError extends Error {
47
+ readonly status: "insufficient-evidence";
48
+ readonly unmeasured: QualityMetricName[];
49
+ readonly problems: UnusableQualityEvidence[];
50
+ constructor(problems: UnusableQualityEvidence[]);
51
+ /** Structured, non-passing description of the gate that could not run. */
52
+ toDetails(): {
53
+ passed: false;
54
+ status: typeof INSUFFICIENT_EVIDENCE;
55
+ evidenceStatus: typeof INSUFFICIENT_EVIDENCE;
56
+ unmeasured: QualityMetricName[];
57
+ gateEvaluated: false;
58
+ recommendations: string[];
59
+ };
60
+ }
61
+ /**
62
+ * Inspect every canonical metric with the same validation, collecting each
63
+ * absent, stale, future-dated or malformed record instead of stopping at the first.
64
+ */
65
+ export declare function inspectQualityEvidence(memory: MemoryBackend, options?: {
66
+ now?: number;
67
+ maxAgeMs?: number;
68
+ }): Promise<{
69
+ values: Partial<QualityEvidenceValues>;
70
+ problems: UnusableQualityEvidence[];
71
+ }>;
32
72
  export declare function loadQualityEvidence(memory: MemoryBackend, options?: {
33
73
  now?: number;
34
74
  maxAgeMs?: number;
35
75
  }): Promise<QualityEvidenceValues>;
36
- export declare function evaluateQualityEvidence(values: QualityEvidenceValues, thresholds?: {
76
+ /** Threshold overrides a caller or user configuration may apply to the canonical defaults. */
77
+ export interface QualityThresholdOverrides {
37
78
  coverage?: number;
38
- }): {
79
+ }
80
+ /**
81
+ * The single source of effective quality thresholds: canonical defaults with
82
+ * any override applied. Used by the measured gate and by static analysis
83
+ * (#996) so the two never disagree.
84
+ */
85
+ export declare function resolveQualityThresholds(overrides?: QualityThresholdOverrides): Record<QualityMetricName, QualityThreshold>;
86
+ export declare function evaluateQualityEvidence(values: QualityEvidenceValues, thresholds?: QualityThresholdOverrides): {
39
87
  passed: boolean;
40
88
  checks: EvaluatedQualityCheck[];
41
89
  recommendations: string[];
@@ -78,27 +78,109 @@ export async function writeQualityEvidence(memory, values, metadata) {
78
78
  });
79
79
  }
80
80
  }
81
- export async function loadQualityEvidence(memory, options = {}) {
81
+ /** #996: the single status word for "a verdict cannot be reached on this evidence". */
82
+ export const INSUFFICIENT_EVIDENCE = 'insufficient-evidence';
83
+ /** #996: what to run to measure a metric that has no usable evidence. */
84
+ // Advice names only producers a user can actually run. Metrics with no
85
+ // exposed producer say so instead of pointing at an unreachable tool.
86
+ const NO_EXPOSED_PRODUCER = 'no MCP tool or CLI command records it yet, so supply it from your own measurement';
87
+ const MISSING_METRIC_ADVICE = {
88
+ coverage: 'run the tests with coverage instrumentation enabled so measured line coverage is recorded '
89
+ + '(a static estimate is not measured coverage)',
90
+ testsPassing: 'run the test suite (test_execute_parallel, or `aqe test execute`)',
91
+ // The static analyzer has no security measurement; a scan reports findings separately.
92
+ security: 'static analysis never measures security; drop it from metrics and use '
93
+ + 'security_scan_comprehensive (or `aqe security`) for findings',
94
+ securityVulnerabilities: `a measured vulnerability count is required; ${NO_EXPOSED_PRODUCER}`,
95
+ criticalBugs: `a measured critical-bug count is required; ${NO_EXPOSED_PRODUCER}`,
96
+ codeSmells: `a measured code-smell count is required; ${NO_EXPOSED_PRODUCER}`,
97
+ technicalDebt: `a measured technical-debt ratio is required; ${NO_EXPOSED_PRODUCER}`,
98
+ duplications: `a measured duplication percentage is required; ${NO_EXPOSED_PRODUCER}`,
99
+ complexity: 'make sure the target contains readable TypeScript/JavaScript source the analyzer can parse',
100
+ maintainability: 'make sure the target contains readable TypeScript/JavaScript source the analyzer can parse',
101
+ testability: 'make sure the target contains readable TypeScript/JavaScript source the analyzer can parse',
102
+ duplication: 'make sure the target contains readable TypeScript/JavaScript source the analyzer can parse',
103
+ };
104
+ /** #996: one recommendation per unmeasured metric, naming what to run. */
105
+ export function describeMissingMetrics(unmeasured) {
106
+ return unmeasured.map((metric) => `Insufficient evidence: ${metric} not measured — ${MISSING_METRIC_ADVICE[metric] ?? 'measure it'}.`);
107
+ }
108
+ /**
109
+ * #996: thrown when the measured gate cannot be evaluated. The message is the
110
+ * first problem found (unchanged wording); `unmeasured` names every metric
111
+ * whose record is absent, stale, future-dated or malformed.
112
+ */
113
+ export class InsufficientQualityEvidenceError extends Error {
114
+ status = INSUFFICIENT_EVIDENCE;
115
+ unmeasured;
116
+ problems;
117
+ constructor(problems) {
118
+ super(problems[0]?.reason ?? 'Measured quality evidence is unavailable.');
119
+ this.name = 'InsufficientQualityEvidenceError';
120
+ this.problems = problems;
121
+ this.unmeasured = problems.map((p) => p.metric);
122
+ }
123
+ /** Structured, non-passing description of the gate that could not run. */
124
+ toDetails() {
125
+ return {
126
+ passed: false,
127
+ status: INSUFFICIENT_EVIDENCE,
128
+ evidenceStatus: INSUFFICIENT_EVIDENCE,
129
+ unmeasured: this.unmeasured,
130
+ gateEvaluated: false,
131
+ recommendations: describeMissingMetrics(this.unmeasured),
132
+ };
133
+ }
134
+ }
135
+ /**
136
+ * Inspect every canonical metric with the same validation, collecting each
137
+ * absent, stale, future-dated or malformed record instead of stopping at the first.
138
+ */
139
+ export async function inspectQualityEvidence(memory, options = {}) {
82
140
  const now = options.now ?? Date.now();
83
141
  const maxAgeMs = options.maxAgeMs ?? DEFAULT_QUALITY_EVIDENCE_MAX_AGE_MS;
84
142
  const values = {};
143
+ const problems = [];
85
144
  for (const metric of QUALITY_METRICS) {
86
145
  const record = await memory.get(evidenceKey(metric), {
87
146
  namespace: QUALITY_EVIDENCE_NAMESPACE,
88
147
  });
89
- validateRecord(record, metric, now, maxAgeMs);
90
- values[metric] = record.value;
148
+ try {
149
+ validateRecord(record, metric, now, maxAgeMs);
150
+ values[metric] = record.value;
151
+ }
152
+ catch (error) {
153
+ problems.push({ metric, reason: error instanceof Error ? error.message : String(error) });
154
+ }
91
155
  }
156
+ return { values, problems };
157
+ }
158
+ export async function loadQualityEvidence(memory, options = {}) {
159
+ const { values, problems } = await inspectQualityEvidence(memory, options);
160
+ if (problems.length > 0)
161
+ throw new InsufficientQualityEvidenceError(problems);
92
162
  return values;
93
163
  }
94
- export function evaluateQualityEvidence(values, thresholds = {}) {
95
- if (thresholds.coverage !== undefined && (!Number.isFinite(thresholds.coverage) || thresholds.coverage < 0 || thresholds.coverage > 100)) {
164
+ /**
165
+ * The single source of effective quality thresholds: canonical defaults with
166
+ * any override applied. Used by the measured gate and by static analysis
167
+ * (#996) so the two never disagree.
168
+ */
169
+ export function resolveQualityThresholds(overrides = {}) {
170
+ if (overrides.coverage !== undefined && (!Number.isFinite(overrides.coverage) || overrides.coverage < 0 || overrides.coverage > 100)) {
96
171
  throw new Error('Coverage quality threshold must be a finite number between 0 and 100.');
97
172
  }
173
+ return {
174
+ ...DEFAULT_QUALITY_THRESHOLDS,
175
+ ...(overrides.coverage !== undefined
176
+ ? { coverage: { ...DEFAULT_QUALITY_THRESHOLDS.coverage, value: overrides.coverage } }
177
+ : {}),
178
+ };
179
+ }
180
+ export function evaluateQualityEvidence(values, thresholds = {}) {
181
+ const effective = resolveQualityThresholds(thresholds);
98
182
  const checks = QUALITY_METRICS.map((name) => {
99
- const threshold = name === 'coverage' && thresholds.coverage !== undefined
100
- ? { ...DEFAULT_QUALITY_THRESHOLDS[name], value: thresholds.coverage }
101
- : DEFAULT_QUALITY_THRESHOLDS[name];
183
+ const threshold = effective[name];
102
184
  const value = values[name];
103
185
  return {
104
186
  name,
@@ -152,11 +152,13 @@ Focus on:
152
152
  prompt += `- **${metric.name}**: ${metric.value} (Rating: ${metric.rating}, Trend: ${metric.trend})\n`;
153
153
  }
154
154
  prompt += `\n`;
155
+ // #996: -1 means "not measured"; never present it to the model as a value.
156
+ const show = (value, unit = '') => (value >= 0 ? `${value}${unit}` : 'not measured');
155
157
  prompt += `### Score Breakdown:\n`;
156
- prompt += `- Coverage: ${score.coverage}%\n`;
157
- prompt += `- Complexity: ${score.complexity}\n`;
158
- prompt += `- Maintainability: ${score.maintainability}\n`;
159
- prompt += `- Security: ${score.security}\n\n`;
158
+ prompt += `- Coverage: ${show(score.coverage, '%')}\n`;
159
+ prompt += `- Complexity: ${show(score.complexity)}\n`;
160
+ prompt += `- Maintainability: ${show(score.maintainability)}\n`;
161
+ prompt += `- Security: ${show(score.security)}\n\n`;
160
162
  if (codeContext) {
161
163
  prompt += `### Code Context:\n\`\`\`\n${codeContext.slice(0, 2000)}\n\`\`\`\n\n`;
162
164
  }
@@ -480,13 +482,15 @@ Focus on:
480
482
  }
481
483
  const overall = totalWeight > 0 ? Math.round(weightedSum / totalWeight) : 0;
482
484
  // Use -1 to signal "no data available" rather than 0 which implies "0% coverage"
483
- const coverageMetric = metrics.find((m) => m.name === 'coverage');
485
+ // (#996: the same holds for every score field — never fabricate a value).
486
+ const valueOf = (name) => metrics.find((m) => m.name === name)?.value ?? -1;
484
487
  return {
485
488
  overall,
486
- coverage: coverageMetric ? coverageMetric.value : -1,
487
- complexity: metrics.find((m) => m.name === 'complexity')?.value || 0,
488
- maintainability: metrics.find((m) => m.name === 'maintainability')?.value || 0,
489
- security: 85, // Placeholder - would come from security analysis
489
+ coverage: valueOf('coverage'),
490
+ complexity: valueOf('complexity'),
491
+ maintainability: valueOf('maintainability'),
492
+ // No security analysis runs here; -1 = not measured (was a fixed 85 placeholder).
493
+ security: -1,
490
494
  };
491
495
  }
492
496
  async generateTrends(currentMetrics, _compareBaseline) {