agentic-qe 3.8.14 → 3.9.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 (451) hide show
  1. package/.claude/skills/skills-manifest.json +1 -1
  2. package/CHANGELOG.md +60 -0
  3. package/dist/adapters/a2ui/integration/agui-sync.js +2 -1
  4. package/dist/audit/witness-chain.d.ts +1 -1
  5. package/dist/boot/fast-paths.d.ts +24 -0
  6. package/dist/boot/fast-paths.js +43 -0
  7. package/dist/boot/parallel-prefetch.d.ts +26 -0
  8. package/dist/boot/parallel-prefetch.js +36 -0
  9. package/dist/cli/bundle.js +12 -9431
  10. package/dist/cli/chunks/adapter-NTM4ZH3P.js +2 -0
  11. package/dist/cli/chunks/agent-booster-wasm-UH2J6BNA.js +2 -0
  12. package/dist/cli/chunks/agent-handler-ZCBWQE3X.js +33 -0
  13. package/dist/cli/chunks/agent-memory-branch-2BAVI7UW.js +2 -0
  14. package/dist/cli/chunks/aqe-learning-engine-RVX6MPYK.js +2 -0
  15. package/dist/cli/chunks/audit-G5UIJBSQ.js +3 -0
  16. package/dist/cli/chunks/base-7HKNQ6UP.js +2 -0
  17. package/dist/cli/chunks/better-sqlite3-YHIAPPVT.js +2 -0
  18. package/dist/cli/chunks/brain-handler-5EE3J5PR.js +68 -0
  19. package/dist/cli/chunks/branch-enumerator-OV54PID5.js +7 -0
  20. package/dist/cli/chunks/browser-7RZGKOEO.js +4 -0
  21. package/dist/cli/chunks/browser-workflow-UOFSQK7X.js +2 -0
  22. package/dist/cli/chunks/chunk-24E47G3D.js +604 -0
  23. package/dist/cli/chunks/chunk-35H73OPP.js +2 -0
  24. package/dist/cli/chunks/chunk-36X2O3BL.js +3 -0
  25. package/dist/cli/chunks/chunk-3JESHZQM.js +2 -0
  26. package/dist/cli/chunks/chunk-3VAKR43Z.js +2 -0
  27. package/dist/cli/chunks/chunk-3WQNW6CH.js +2 -0
  28. package/dist/cli/chunks/chunk-43M6Y6VF.js +15 -0
  29. package/dist/cli/chunks/chunk-4BHOAQJH.js +2 -0
  30. package/dist/cli/chunks/chunk-4LWXZCSD.js +146 -0
  31. package/dist/cli/chunks/chunk-4TNXEANY.js +2 -0
  32. package/dist/cli/chunks/chunk-4XBY5JDT.js +4 -0
  33. package/dist/cli/chunks/chunk-4XREPCBZ.js +2 -0
  34. package/dist/cli/chunks/chunk-5GPTM2RV.js +2 -0
  35. package/dist/cli/chunks/chunk-5KBQQP3X.js +7 -0
  36. package/dist/cli/chunks/chunk-5LDBKZ6P.js +2 -0
  37. package/dist/cli/chunks/chunk-6BSJNG2S.js +2 -0
  38. package/dist/cli/chunks/chunk-6YC24TPL.js +27 -0
  39. package/dist/cli/chunks/chunk-7ATLJCSG.js +2 -0
  40. package/dist/cli/chunks/chunk-7JQTHPCD.js +2 -0
  41. package/dist/cli/chunks/chunk-7YUOUVN7.js +2 -0
  42. package/dist/cli/chunks/chunk-7ZNINH6J.js +59 -0
  43. package/dist/cli/chunks/chunk-A57BEPL7.js +3 -0
  44. package/dist/cli/chunks/chunk-AFPMCMVX.js +45 -0
  45. package/dist/cli/chunks/chunk-AREIP4FX.js +3 -0
  46. package/dist/cli/chunks/chunk-B2I7BJLL.js +3 -0
  47. package/dist/cli/chunks/chunk-BEHP3DEF.js +66 -0
  48. package/dist/cli/chunks/chunk-C24ZDUCM.js +30 -0
  49. package/dist/cli/chunks/chunk-D4PSFWND.js +2 -0
  50. package/dist/cli/chunks/chunk-D55PSO5D.js +81 -0
  51. package/dist/cli/chunks/chunk-DC3HPOOJ.js +2 -0
  52. package/dist/cli/chunks/chunk-DMGLX76J.js +180 -0
  53. package/dist/cli/chunks/chunk-E33KQBMW.js +2 -0
  54. package/dist/cli/chunks/chunk-EQFZQPFN.js +2 -0
  55. package/dist/cli/chunks/chunk-FPRL6UDF.js +2 -0
  56. package/dist/cli/chunks/chunk-FRNB4CH2.js +2 -0
  57. package/dist/cli/chunks/chunk-FWDKVTK4.js +2 -0
  58. package/dist/cli/chunks/chunk-GFNUESMU.js +2 -0
  59. package/dist/cli/chunks/chunk-GJW6V35N.js +2 -0
  60. package/dist/cli/chunks/chunk-GLIFZWV2.js +2 -0
  61. package/dist/cli/chunks/chunk-GNUUBTSX.js +14 -0
  62. package/dist/cli/chunks/chunk-HAUXLXKZ.js +2 -0
  63. package/dist/cli/chunks/chunk-HTXSUTWL.js +9 -0
  64. package/dist/cli/chunks/chunk-I5WZ2NM2.js +95 -0
  65. package/dist/cli/chunks/chunk-I7TA453K.js +2 -0
  66. package/dist/cli/chunks/chunk-IF6GW6IY.js +27 -0
  67. package/dist/cli/chunks/chunk-IHWSNYL2.js +5 -0
  68. package/dist/cli/chunks/chunk-IJKYJGJL.js +2 -0
  69. package/dist/cli/chunks/chunk-IQPXANCE.js +14 -0
  70. package/dist/cli/chunks/chunk-JCEY7RLP.js +2 -0
  71. package/dist/cli/chunks/chunk-JSOBRKMA.js +2 -0
  72. package/dist/cli/chunks/chunk-KIGRLIU4.js +2 -0
  73. package/dist/cli/chunks/chunk-L4H54Z27.js +21 -0
  74. package/dist/cli/chunks/chunk-LCOEBFAB.js +2 -0
  75. package/dist/cli/chunks/chunk-MZ54VM6A.js +2 -0
  76. package/dist/cli/chunks/chunk-NB47YT6A.js +167 -0
  77. package/dist/cli/chunks/chunk-NG3BKE7V.js +2 -0
  78. package/dist/cli/chunks/chunk-NG4TE3OW.js +2 -0
  79. package/dist/cli/chunks/chunk-O636JKJR.js +18 -0
  80. package/dist/cli/chunks/chunk-O6QQ4HLS.js +2 -0
  81. package/dist/cli/chunks/chunk-OFNIQCGX.js +2 -0
  82. package/dist/cli/chunks/chunk-OTSJU5LH.js +2 -0
  83. package/dist/cli/chunks/chunk-POLFT2PQ.js +15 -0
  84. package/dist/cli/chunks/chunk-QAYTL6KC.js +2 -0
  85. package/dist/cli/chunks/chunk-QMFP5OKH.js +2 -0
  86. package/dist/cli/chunks/chunk-RAJO7VML.js +2 -0
  87. package/dist/cli/chunks/chunk-RKIGOARX.js +2 -0
  88. package/dist/cli/chunks/chunk-RU6Q5HOC.js +3 -0
  89. package/dist/cli/chunks/chunk-RV6SGDET.js +2 -0
  90. package/dist/cli/chunks/chunk-RWXI7XAR.js +2 -0
  91. package/dist/cli/chunks/chunk-RXVYOXDB.js +2 -0
  92. package/dist/cli/chunks/chunk-SGRN6JFB.js +2 -0
  93. package/dist/cli/chunks/chunk-SVNX4UWR.js +3029 -0
  94. package/dist/cli/chunks/chunk-TL7ABIMP.js +2 -0
  95. package/dist/cli/chunks/chunk-TOLYWONQ.js +2 -0
  96. package/dist/cli/chunks/chunk-TPXYS3WG.js +3 -0
  97. package/dist/cli/chunks/chunk-U5JQGRHZ.js +2 -0
  98. package/dist/cli/chunks/chunk-UB7RGVKO.js +2 -0
  99. package/dist/cli/chunks/chunk-UBKK7KCR.js +70 -0
  100. package/dist/cli/chunks/chunk-UMGWGX7C.js +2 -0
  101. package/dist/cli/chunks/chunk-UN4PA4M2.js +2 -0
  102. package/dist/cli/chunks/chunk-US7INRP2.js +314 -0
  103. package/dist/cli/chunks/chunk-UWDBFPHQ.js +750 -0
  104. package/dist/cli/chunks/chunk-UZZCWWIG.js +2 -0
  105. package/dist/cli/chunks/chunk-V4HM4QAO.js +24 -0
  106. package/dist/cli/chunks/chunk-V4U3CTS2.js +180 -0
  107. package/dist/cli/chunks/chunk-VCCMCFDU.js +2 -0
  108. package/dist/cli/chunks/chunk-VEWIT6VN.js +4 -0
  109. package/dist/cli/chunks/chunk-VNYGVG4Y.js +2 -0
  110. package/dist/cli/chunks/chunk-VO3OVD5D.js +4 -0
  111. package/dist/cli/chunks/chunk-VY74OMGQ.js +6 -0
  112. package/dist/cli/chunks/chunk-WDJBGXC2.js +2 -0
  113. package/dist/cli/chunks/chunk-WDV6TN7E.js +65 -0
  114. package/dist/cli/chunks/chunk-WLXEDOG4.js +2 -0
  115. package/dist/cli/chunks/chunk-WXXAAXNS.js +12 -0
  116. package/dist/cli/chunks/chunk-X4MZYBOU.js +256 -0
  117. package/dist/cli/chunks/chunk-XE2YAYU5.js +12 -0
  118. package/dist/cli/chunks/chunk-XP6XKBNW.js +2 -0
  119. package/dist/cli/chunks/chunk-XPB6ZVQY.js +2 -0
  120. package/dist/cli/chunks/chunk-XRVUSKQV.js +1 -0
  121. package/dist/cli/chunks/chunk-XSITQBYB.js +20 -0
  122. package/dist/cli/chunks/chunk-XTLA4F5Z.js +91 -0
  123. package/dist/cli/chunks/chunk-XU6L2VJY.js +2 -0
  124. package/dist/cli/chunks/chunk-XUFHYPZK.js +2 -0
  125. package/dist/cli/chunks/chunk-Y2ZEDXTV.js +16 -0
  126. package/dist/cli/chunks/chunk-YQWB4QUP.js +316 -0
  127. package/dist/cli/chunks/chunk-YUQIXT3G.js +79 -0
  128. package/dist/cli/chunks/chunk-YYYB2JN5.js +2 -0
  129. package/dist/cli/chunks/chunk-ZEUVPLGX.js +2 -0
  130. package/dist/cli/chunks/chunk-ZSRQHJEW.js +3 -0
  131. package/dist/cli/chunks/ci-N4NTYAAI.js +81 -0
  132. package/dist/cli/chunks/ci-output-XYR2PSYH.js +2 -0
  133. package/dist/cli/chunks/claude-flow-setup-FX7PRBJV.js +2 -0
  134. package/dist/cli/chunks/client-CRRENRK4.js +2 -0
  135. package/dist/cli/chunks/cline-installer-GTHQOK7U.js +4 -0
  136. package/dist/cli/chunks/code-4G6ZHVNI.js +38 -0
  137. package/dist/cli/chunks/code-index-extractor-MKJTP5AK.js +3 -0
  138. package/dist/cli/chunks/codex-installer-UGS773DT.js +8 -0
  139. package/dist/cli/chunks/completions-B3BXNXAU.js +1364 -0
  140. package/dist/cli/chunks/complexity-analyzer-PMN77CUP.js +2 -0
  141. package/dist/cli/chunks/continuedev-installer-3DYKSIP3.js +14 -0
  142. package/dist/cli/chunks/copilot-installer-IUC5HDHD.js +3 -0
  143. package/dist/cli/chunks/cost-tracker-GSGQ7O5T.js +2 -0
  144. package/dist/cli/chunks/coverage-PO72QC3P.js +27 -0
  145. package/dist/cli/chunks/cross-domain-router-FSCGJG3B.js +2 -0
  146. package/dist/cli/chunks/cursor-installer-FK53S3ZL.js +3 -0
  147. package/dist/cli/chunks/daemon-4UIQTQ73.js +19 -0
  148. package/dist/cli/chunks/dag-attention-scheduler-ZGIMLECE.js +2 -0
  149. package/dist/cli/chunks/detect-XXHLTLL7.js +2 -0
  150. package/dist/cli/chunks/domain-handler-PPGFP7P4.js +25 -0
  151. package/dist/cli/chunks/domain-transfer-Q5UAE65W.js +2 -0
  152. package/dist/cli/chunks/dream-PONKQULG.js +2 -0
  153. package/dist/cli/chunks/esm-node-XLWDJRBX.js +2 -0
  154. package/dist/cli/chunks/eval-JVJKHSTQ.js +15 -0
  155. package/dist/cli/chunks/fast-paths-3KX4ZV66.js +2 -0
  156. package/dist/cli/chunks/feature-flags-2NOVE7DL.js +2 -0
  157. package/dist/cli/chunks/feature-flags-GKHHG2I2.js +2 -0
  158. package/dist/cli/chunks/file-discovery-XFSGQNM3.js +2 -0
  159. package/dist/cli/chunks/fleet-FOIDAXLR.js +43 -0
  160. package/dist/cli/chunks/gnn-wrapper-HPCQREKP.js +2 -0
  161. package/dist/cli/chunks/heartbeat-handler-HTR3EFFV.js +48 -0
  162. package/dist/cli/chunks/heartbeat-scheduler-NZQWN7CH.js +2 -0
  163. package/dist/cli/chunks/hnsw-adapter-BNA5WUAB.js +2 -0
  164. package/dist/cli/chunks/hnsw-index-RQIIAE7S.js +2 -0
  165. package/dist/cli/chunks/hnsw-legacy-bridge-H6OA3AA3.js +2 -0
  166. package/dist/cli/chunks/hnswlib-node-FF27BDMD.js +2 -0
  167. package/dist/cli/chunks/hooks-63NZQ7NH.js +101 -0
  168. package/dist/cli/chunks/hypergraph-engine-XMSLA4XH.js +2 -0
  169. package/dist/cli/chunks/hypergraph-handler-ID6J6GS2.js +35 -0
  170. package/dist/cli/chunks/impact-analyzer-FS2UNVP4.js +2 -0
  171. package/dist/cli/chunks/init-handler-CIKZGGAY.js +68 -0
  172. package/dist/cli/chunks/init-wizard-TUU5PPY6.js +2 -0
  173. package/dist/cli/chunks/kernel-XFG42WAG.js +2 -0
  174. package/dist/cli/chunks/kilocode-installer-N7NLISYY.js +4 -0
  175. package/dist/cli/chunks/kiro-installer-U6XIPAT3.js +74 -0
  176. package/dist/cli/chunks/knowledge-graph-XV7FPU2T.js +2 -0
  177. package/dist/cli/chunks/learning-NKOF7KDJ.js +107 -0
  178. package/dist/cli/chunks/llm-router-34WHT3PH.js +30 -0
  179. package/dist/cli/chunks/load-ZW4Z3YLT.js +2 -0
  180. package/dist/cli/chunks/load-test-F4L7RTXJ.js +2 -0
  181. package/dist/cli/chunks/mcp-6R7SVGKO.js +2 -0
  182. package/dist/cli/chunks/memory-OUYCBU4M.js +32 -0
  183. package/dist/cli/chunks/memory-backend-DTJD2DWF.js +2 -0
  184. package/dist/cli/chunks/memory-handlers-WNXKZRNM.js +2 -0
  185. package/dist/cli/chunks/opencode-installer-FR75GHFU.js +3 -0
  186. package/dist/cli/chunks/orchestrator-AK7ZMVNH.js +371 -0
  187. package/dist/cli/chunks/pipeline-CFOPG7EM.js +19 -0
  188. package/dist/cli/chunks/platform-NY3ULBR7.js +2 -0
  189. package/dist/cli/chunks/plugin-LRANQYUR.js +27 -0
  190. package/dist/cli/chunks/prime-radiant-advanced-wasm-6KEIU55P.js +2 -0
  191. package/dist/cli/chunks/protocol-executor-6W4PS2D4.js +2 -0
  192. package/dist/cli/chunks/protocol-handler-ESSZGJ7R.js +20 -0
  193. package/dist/cli/chunks/prove-EF2PPY65.js +3 -0
  194. package/dist/cli/chunks/qe-reasoning-bank-7G3TZLEA.js +2 -0
  195. package/dist/cli/chunks/quality-AYBXB635.js +7 -0
  196. package/dist/cli/chunks/queen-coordinator-NFPKGMQN.js +2 -0
  197. package/dist/cli/chunks/real-embeddings-QPBXE7MA.js +2 -0
  198. package/dist/cli/chunks/roocode-installer-UF6MMBH6.js +4 -0
  199. package/dist/cli/chunks/router-F4B7Q66G.js +2 -0
  200. package/dist/cli/chunks/routing-feedback-5CIDDW7P.js +2 -0
  201. package/dist/cli/chunks/routing-handler-5TVKFU7V.js +20 -0
  202. package/dist/cli/chunks/ruvector-commands-E33VXFIA.js +8 -0
  203. package/dist/cli/chunks/rvf-dual-writer-O3AZKD24.js +2 -0
  204. package/dist/cli/chunks/rvf-migration-adapter-IKEUZ2HX.js +2 -0
  205. package/dist/cli/chunks/rvf-migration-coordinator-M4H7W4RN.js +2 -0
  206. package/dist/cli/chunks/rvf-native-adapter-UX3WAPIP.js +2 -0
  207. package/dist/cli/chunks/safe-db-QBBNXEVK.js +2 -0
  208. package/dist/cli/chunks/schedule-GFT4NN6Z.js +2 -0
  209. package/dist/cli/chunks/scheduler-CQ56T7DB.js +2 -0
  210. package/dist/cli/chunks/security-ZLWT7IU3.js +14 -0
  211. package/dist/cli/chunks/shared-rvf-adapter-EXACQ2PT.js +2 -0
  212. package/dist/cli/chunks/shared-rvf-dual-writer-G43LQDIV.js +2 -0
  213. package/dist/cli/chunks/sqlite-persistence-JHSUZPAW.js +2 -0
  214. package/dist/cli/chunks/status-handler-7P23CXUI.js +45 -0
  215. package/dist/cli/chunks/structural-health-SCNBNL7K.js +2 -0
  216. package/dist/cli/chunks/sync-BYZBBH65.js +23 -0
  217. package/dist/cli/chunks/task-handler-DWJQXZ2K.js +49 -0
  218. package/dist/cli/chunks/task-handlers-35JIXVRW.js +2 -0
  219. package/dist/cli/chunks/test-2JSS4XW7.js +33 -0
  220. package/dist/cli/chunks/test-scheduling-TWJ5I7N3.js +15 -0
  221. package/dist/cli/chunks/token-bootstrap-LLLNJT5V.js +2 -0
  222. package/dist/cli/chunks/token-usage-EQ4HM4EZ.js +25 -0
  223. package/dist/cli/chunks/transformers-PBIR5U5S.js +2 -0
  224. package/dist/cli/chunks/tree-sitter-wasm-parser-X3L2GXUX.js +2 -0
  225. package/dist/cli/chunks/types-OD43K2NP.js +2 -0
  226. package/dist/cli/chunks/unified-memory-YPHONR2T.js +2 -0
  227. package/dist/cli/chunks/unified-memory-hnsw-HJS4OXWM.js +2 -0
  228. package/dist/cli/chunks/unified-persistence-EFZRO6AW.js +2 -0
  229. package/dist/cli/chunks/validate-POMLT2KU.js +21 -0
  230. package/dist/cli/chunks/validate-swarm-UOC4JGZT.js +14 -0
  231. package/dist/cli/chunks/vibium-5JF6LAXI.js +2 -0
  232. package/dist/cli/chunks/visual-security-7KWFLYNB.js +2 -0
  233. package/dist/cli/chunks/web-tree-sitter-R7WR7J7B.js +2 -0
  234. package/dist/cli/chunks/windsurf-installer-ZSPEUBKR.js +7 -0
  235. package/dist/cli/chunks/witness-chain-CFSPCXHG.js +2 -0
  236. package/dist/cli/chunks/witness-chain-RWU6WT37.js +2 -0
  237. package/dist/cli/chunks/workflow-YNQT3OW2.js +51 -0
  238. package/dist/cli/chunks/workflow-orchestrator-Z6TAVMQP.js +2 -0
  239. package/dist/cli/chunks/wrappers-BP4FODVH.js +2 -0
  240. package/dist/cli/commands/daemon.d.ts +13 -0
  241. package/dist/cli/commands/daemon.js +224 -0
  242. package/dist/cli/commands/hooks-handlers/hooks-shared.js +2 -1
  243. package/dist/cli/commands/plugin.d.ts +12 -0
  244. package/dist/cli/commands/plugin.js +135 -0
  245. package/dist/cli/commands/ruvector-commands.js +14 -2
  246. package/dist/cli/commands/workflow.d.ts +10 -0
  247. package/dist/cli/commands/workflow.js +587 -0
  248. package/dist/cli/handlers/brain-handler.js +13 -8
  249. package/dist/cli/handlers/heartbeat-handler.d.ts +1 -0
  250. package/dist/cli/handlers/heartbeat-handler.js +20 -10
  251. package/dist/cli/handlers/hypergraph-handler.js +3 -3
  252. package/dist/cli/handlers/init-handler.js +10 -9
  253. package/dist/cli/handlers/interfaces.d.ts +4 -4
  254. package/dist/cli/index.js +159 -638
  255. package/dist/cli/lazy-registry.d.ts +27 -0
  256. package/dist/cli/lazy-registry.js +70 -0
  257. package/dist/context/compaction/context-budget.d.ts +71 -0
  258. package/dist/context/compaction/context-budget.js +120 -0
  259. package/dist/context/compaction/index.d.ts +96 -0
  260. package/dist/context/compaction/index.js +259 -0
  261. package/dist/context/compaction/llm-caller-adapter.d.ts +14 -0
  262. package/dist/context/compaction/llm-caller-adapter.js +47 -0
  263. package/dist/context/compaction/tier1-microcompact.d.ts +33 -0
  264. package/dist/context/compaction/tier1-microcompact.js +47 -0
  265. package/dist/context/compaction/tier2-session-summary.d.ts +72 -0
  266. package/dist/context/compaction/tier2-session-summary.js +172 -0
  267. package/dist/context/compaction/tier3-llm-compact.d.ts +65 -0
  268. package/dist/context/compaction/tier3-llm-compact.js +166 -0
  269. package/dist/context/compaction/tier4-reactive.d.ts +54 -0
  270. package/dist/context/compaction/tier4-reactive.js +129 -0
  271. package/dist/coordination/agent-memory-branch.d.ts +117 -0
  272. package/dist/coordination/agent-memory-branch.js +213 -0
  273. package/dist/coordination/agent-teams/mailbox.d.ts +43 -0
  274. package/dist/coordination/agent-teams/mailbox.js +130 -4
  275. package/dist/coordination/consensus/providers/claude-provider.d.ts +1 -0
  276. package/dist/coordination/consensus/providers/claude-provider.js +23 -3
  277. package/dist/coordination/handlers/handler-utils.d.ts +1 -0
  278. package/dist/coordination/handlers/handler-utils.js +9 -2
  279. package/dist/coordination/handlers/quality-handlers.js +7 -1
  280. package/dist/domains/contract-testing/coordinator.js +11 -0
  281. package/dist/domains/quality-assessment/coherence/gate-controller.d.ts +20 -1
  282. package/dist/domains/quality-assessment/coherence/gate-controller.js +64 -0
  283. package/dist/domains/quality-assessment/coherence/index.d.ts +3 -3
  284. package/dist/domains/quality-assessment/coherence/index.js +2 -2
  285. package/dist/domains/quality-assessment/coherence/types.d.ts +39 -0
  286. package/dist/domains/quality-assessment/coherence/types.js +11 -0
  287. package/dist/domains/quality-assessment/coordinator.d.ts +14 -0
  288. package/dist/domains/quality-assessment/coordinator.js +92 -0
  289. package/dist/domains/test-execution/coordinator.d.ts +19 -0
  290. package/dist/domains/test-execution/coordinator.js +102 -5
  291. package/dist/domains/test-generation/coordinator.js +11 -0
  292. package/dist/domains/test-generation/interfaces.d.ts +2 -0
  293. package/dist/domains/test-generation/services/test-generator.d.ts +9 -0
  294. package/dist/domains/test-generation/services/test-generator.js +37 -0
  295. package/dist/hooks/cross-phase-hooks.d.ts +11 -0
  296. package/dist/hooks/cross-phase-hooks.js +73 -9
  297. package/dist/hooks/security/config-snapshot.d.ts +21 -0
  298. package/dist/hooks/security/config-snapshot.js +33 -0
  299. package/dist/hooks/security/exit-codes.d.ts +28 -0
  300. package/dist/hooks/security/exit-codes.js +33 -0
  301. package/dist/hooks/security/index.d.ts +15 -0
  302. package/dist/hooks/security/index.js +15 -0
  303. package/dist/hooks/security/ssrf-guard.d.ts +25 -0
  304. package/dist/hooks/security/ssrf-guard.js +69 -0
  305. package/dist/init/agents-installer.d.ts +5 -3
  306. package/dist/init/agents-installer.js +17 -43
  307. package/dist/init/find-package-root.d.ts +22 -0
  308. package/dist/init/find-package-root.js +46 -0
  309. package/dist/init/n8n-installer.d.ts +4 -2
  310. package/dist/init/n8n-installer.js +23 -23
  311. package/dist/init/opencode-installer.d.ts +0 -5
  312. package/dist/init/opencode-installer.js +12 -39
  313. package/dist/init/skills-installer.d.ts +5 -2
  314. package/dist/init/skills-installer.js +15 -37
  315. package/dist/integrations/embeddings/index/HNSWIndex.d.ts +9 -2
  316. package/dist/integrations/embeddings/index/HNSWIndex.js +110 -35
  317. package/dist/integrations/ruvector/cognitive-routing.d.ts +67 -0
  318. package/dist/integrations/ruvector/cognitive-routing.js +208 -0
  319. package/dist/integrations/ruvector/feature-flags.d.ts +84 -0
  320. package/dist/integrations/ruvector/feature-flags.js +59 -0
  321. package/dist/integrations/ruvector/hdc-fingerprint.d.ts +76 -0
  322. package/dist/integrations/ruvector/hdc-fingerprint.js +217 -0
  323. package/dist/integrations/ruvector/hyperbolic-hnsw.d.ts +59 -0
  324. package/dist/integrations/ruvector/hyperbolic-hnsw.js +194 -0
  325. package/dist/integrations/ruvector/index.d.ts +5 -2
  326. package/dist/integrations/ruvector/index.js +13 -2
  327. package/dist/integrations/ruvector/shared-rvf-adapter.d.ts +24 -0
  328. package/dist/integrations/ruvector/shared-rvf-adapter.js +55 -0
  329. package/dist/integrations/ruvector/shared-rvf-dual-writer.d.ts +6 -0
  330. package/dist/integrations/ruvector/shared-rvf-dual-writer.js +38 -0
  331. package/dist/integrations/ruvector/sona-persistence.d.ts +8 -0
  332. package/dist/integrations/ruvector/sona-persistence.js +10 -0
  333. package/dist/integrations/ruvector/vector-delta-tracker.d.ts +96 -0
  334. package/dist/integrations/ruvector/vector-delta-tracker.js +226 -0
  335. package/dist/kernel/agent-coordinator.d.ts +75 -1
  336. package/dist/kernel/agent-coordinator.js +250 -1
  337. package/dist/kernel/hnsw-legacy-bridge.d.ts +38 -0
  338. package/dist/kernel/hnsw-legacy-bridge.js +88 -0
  339. package/dist/kernel/hnsw-shadow-validator.d.ts +91 -0
  340. package/dist/kernel/hnsw-shadow-validator.js +139 -0
  341. package/dist/kernel/index.d.ts +1 -1
  342. package/dist/kernel/index.js +1 -1
  343. package/dist/kernel/interfaces.d.ts +39 -0
  344. package/dist/kernel/kernel.d.ts +23 -0
  345. package/dist/kernel/kernel.js +141 -1
  346. package/dist/kernel/memory-backend.js +3 -1
  347. package/dist/kernel/unified-memory.d.ts +1 -1
  348. package/dist/kernel/unified-memory.js +7 -3
  349. package/dist/learning/aqe-learning-engine.d.ts +65 -0
  350. package/dist/learning/aqe-learning-engine.js +134 -0
  351. package/dist/learning/dream/dream-engine.d.ts +6 -1
  352. package/dist/learning/dream/dream-engine.js +37 -2
  353. package/dist/learning/dream/dream-scheduler.d.ts +25 -0
  354. package/dist/learning/dream/dream-scheduler.js +120 -0
  355. package/dist/learning/dream/rvcow-branch-manager.d.ts +6 -3
  356. package/dist/learning/dream/rvcow-branch-manager.js +60 -5
  357. package/dist/learning/experience-capture.d.ts +3 -3
  358. package/dist/learning/hyperbolic-pattern-index.d.ts +82 -0
  359. package/dist/learning/hyperbolic-pattern-index.js +142 -0
  360. package/dist/learning/index.d.ts +3 -3
  361. package/dist/learning/index.js +1 -1
  362. package/dist/learning/metrics-tracker.d.ts +44 -0
  363. package/dist/learning/metrics-tracker.js +37 -0
  364. package/dist/learning/pattern-promotion.d.ts +3 -3
  365. package/dist/learning/pattern-store.d.ts +45 -2
  366. package/dist/learning/pattern-store.js +217 -4
  367. package/dist/learning/qe-patterns.d.ts +1 -1
  368. package/dist/learning/qe-reasoning-bank.js +1 -1
  369. package/dist/learning/rvf-pattern-migration.d.ts +50 -0
  370. package/dist/learning/rvf-pattern-migration.js +106 -0
  371. package/dist/learning/rvf-pattern-store.d.ts +66 -0
  372. package/dist/learning/rvf-pattern-store.js +447 -0
  373. package/dist/mcp/bundle.js +1937 -1793
  374. package/dist/mcp/entry.js +132 -77
  375. package/dist/mcp/handlers/index.d.ts +1 -0
  376. package/dist/mcp/handlers/index.js +2 -0
  377. package/dist/mcp/handlers/migration-handlers.d.ts +52 -0
  378. package/dist/mcp/handlers/migration-handlers.js +85 -0
  379. package/dist/mcp/middleware/batch-executor.d.ts +46 -0
  380. package/dist/mcp/middleware/batch-executor.js +150 -0
  381. package/dist/mcp/middleware/microcompact.d.ts +97 -0
  382. package/dist/mcp/middleware/microcompact.js +179 -0
  383. package/dist/mcp/middleware/middleware-chain.d.ts +37 -0
  384. package/dist/mcp/middleware/middleware-chain.js +60 -0
  385. package/dist/mcp/protocol-server.d.ts +12 -0
  386. package/dist/mcp/protocol-server.js +192 -36
  387. package/dist/mcp/services/session-durability-middleware.d.ts +22 -0
  388. package/dist/mcp/services/session-durability-middleware.js +64 -0
  389. package/dist/mcp/services/session-resume.d.ts +29 -0
  390. package/dist/mcp/services/session-resume.js +221 -0
  391. package/dist/mcp/services/session-store.d.ts +84 -0
  392. package/dist/mcp/services/session-store.js +163 -0
  393. package/dist/mcp/tool-registry.d.ts +9 -0
  394. package/dist/mcp/tool-registry.js +30 -1
  395. package/dist/mcp/types.d.ts +2 -1
  396. package/dist/optimization/early-exit-token-optimizer.d.ts +7 -7
  397. package/dist/optimization/early-exit-token-optimizer.js +3 -3
  398. package/dist/persistence/rvf-consistency-validator.d.ts +85 -0
  399. package/dist/persistence/rvf-consistency-validator.js +182 -0
  400. package/dist/persistence/rvf-migration-adapter.d.ts +125 -0
  401. package/dist/persistence/rvf-migration-adapter.js +303 -0
  402. package/dist/persistence/rvf-migration-coordinator.d.ts +115 -0
  403. package/dist/persistence/rvf-migration-coordinator.js +224 -0
  404. package/dist/persistence/rvf-stage-gate.d.ts +70 -0
  405. package/dist/persistence/rvf-stage-gate.js +163 -0
  406. package/dist/plugins/cache.d.ts +44 -0
  407. package/dist/plugins/cache.js +149 -0
  408. package/dist/plugins/index.d.ts +15 -0
  409. package/dist/plugins/index.js +15 -0
  410. package/dist/plugins/lifecycle.d.ts +67 -0
  411. package/dist/plugins/lifecycle.js +175 -0
  412. package/dist/plugins/manifest.d.ts +45 -0
  413. package/dist/plugins/manifest.js +173 -0
  414. package/dist/plugins/resolver.d.ts +37 -0
  415. package/dist/plugins/resolver.js +80 -0
  416. package/dist/plugins/security.d.ts +23 -0
  417. package/dist/plugins/security.js +125 -0
  418. package/dist/plugins/sources/github.d.ts +17 -0
  419. package/dist/plugins/sources/github.js +77 -0
  420. package/dist/plugins/sources/local.d.ts +20 -0
  421. package/dist/plugins/sources/local.js +32 -0
  422. package/dist/plugins/sources/npm.d.ts +18 -0
  423. package/dist/plugins/sources/npm.js +82 -0
  424. package/dist/shared/llm/retry.d.ts +5 -2
  425. package/dist/shared/llm/retry.js +7 -3
  426. package/dist/shared/prompt-cache-latch.d.ts +41 -0
  427. package/dist/shared/prompt-cache-latch.js +63 -0
  428. package/dist/shared/retry-engine.d.ts +77 -0
  429. package/dist/shared/retry-engine.js +194 -0
  430. package/dist/workers/daemon.d.ts +8 -0
  431. package/dist/workers/daemon.js +13 -0
  432. package/dist/workers/quality-daemon/ci-monitor.d.ts +55 -0
  433. package/dist/workers/quality-daemon/ci-monitor.js +147 -0
  434. package/dist/workers/quality-daemon/coverage-delta.d.ts +72 -0
  435. package/dist/workers/quality-daemon/coverage-delta.js +135 -0
  436. package/dist/workers/quality-daemon/git-watcher.d.ts +51 -0
  437. package/dist/workers/quality-daemon/git-watcher.js +209 -0
  438. package/dist/workers/quality-daemon/index.d.ts +119 -0
  439. package/dist/workers/quality-daemon/index.js +343 -0
  440. package/dist/workers/quality-daemon/nightly-consolidation.d.ts +74 -0
  441. package/dist/workers/quality-daemon/nightly-consolidation.js +136 -0
  442. package/dist/workers/quality-daemon/notification-service.d.ts +67 -0
  443. package/dist/workers/quality-daemon/notification-service.js +178 -0
  444. package/dist/workers/quality-daemon/persistent-memory.d.ts +31 -0
  445. package/dist/workers/quality-daemon/persistent-memory.js +30 -0
  446. package/dist/workers/quality-daemon/priority-queue.d.ts +97 -0
  447. package/dist/workers/quality-daemon/priority-queue.js +126 -0
  448. package/dist/workers/quality-daemon/test-suggester.d.ts +50 -0
  449. package/dist/workers/quality-daemon/test-suggester.js +121 -0
  450. package/dist/workers/worker-manager.js +2 -1
  451. package/package.json +10 -10
@@ -26,6 +26,9 @@ import * as ReportHelpers from './coordinator-reports.js';
26
26
  import * as RLIntegration from './coordinator-rl-integration.js';
27
27
  import * as ClaimVerifierHelpers from './coordinator-claim-verifier.js';
28
28
  import * as GateEvalHelpers from './coordinator-gate-evaluation.js';
29
+ // ADR-062: Gate ratcheting
30
+ import { checkRatchet, } from './coherence/gate-controller.js';
31
+ import { DEFAULT_RATCHET_CONFIG, } from './coherence/types.js';
29
32
  // ADR-070: Witness Chain audit trail
30
33
  import { getWitnessChain } from '../../audit/witness-chain.js';
31
34
  // Three-loop feature flag for instantAdapt protocol
@@ -85,6 +88,13 @@ export class QualityAssessmentCoordinator extends BaseDomainCoordinator {
85
88
  domain = 'quality-assessment';
86
89
  // Cache of recent dream insights for quality assessment enhancement
87
90
  recentDreamInsights = [];
91
+ // ADR-062: Monotonic gate threshold ratcheting state
92
+ ratchetState = {
93
+ currentThreshold: 70,
94
+ consecutivePasses: 0,
95
+ lastRatchetTime: 0,
96
+ history: [],
97
+ };
88
98
  constructor(eventBus, memory, agentCoordinator, config = {}) {
89
99
  const fullConfig = { ...DEFAULT_CONFIG, ...config };
90
100
  super(eventBus, 'quality-assessment', fullConfig, {
@@ -116,6 +126,9 @@ export class QualityAssessmentCoordinator extends BaseDomainCoordinator {
116
126
  this.subscribeToEvents();
117
127
  // Load any persisted workflow state
118
128
  await this.loadWorkflowState();
129
+ // ADR-062: Restore persisted ratchet state so the monotonic invariant
130
+ // survives coordinator restarts.
131
+ await this.loadRatchetState();
119
132
  // Initialize Actor-Critic RL for threshold tuning
120
133
  if (this.config.enableRLThresholdTuning) {
121
134
  await this.initializeActorCritic();
@@ -242,6 +255,17 @@ export class QualityAssessmentCoordinator extends BaseDomainCoordinator {
242
255
  m.duplications / 100,
243
256
  finalResult.overallScore / 100,
244
257
  ]);
258
+ // EWC++ outcome recording: reward scaled by gate score
259
+ try {
260
+ this.qesona.recordOutcome(finalResult.overallScore / 100);
261
+ if (this.qesona.shouldConsolidate()) {
262
+ try {
263
+ this.qesona.backgroundConsolidate();
264
+ }
265
+ catch { /* best-effort */ }
266
+ }
267
+ }
268
+ catch { /* must not break main flow */ }
245
269
  }
246
270
  // Store quality pattern in SONA if enabled
247
271
  if (this.config.enableSONAPatternLearning && this.qesona) {
@@ -257,6 +281,26 @@ export class QualityAssessmentCoordinator extends BaseDomainCoordinator {
257
281
  wc.append(finalResult.passed ? 'QUALITY_GATE_PASS' : 'QUALITY_GATE_FAIL', { gateName: request.gateName, passed: finalResult.passed, score: finalResult.overallScore, failedChecks: finalResult.failedChecks }, 'quality-gate');
258
282
  }
259
283
  catch (_wcErr) { /* non-critical */ }
284
+ // ADR-062: Monotonic gate threshold ratcheting
285
+ // After gate decision is final, check if threshold should ratchet upward
286
+ if (process.env.AQE_GATE_RATCHETING_ENABLED === 'true') {
287
+ try {
288
+ const prevThreshold = this.ratchetState.currentThreshold;
289
+ this.ratchetState = checkRatchet(finalResult.passed, DEFAULT_RATCHET_CONFIG, this.ratchetState);
290
+ if (this.ratchetState.currentThreshold > prevThreshold) {
291
+ logger.info(`Gate threshold ratcheted: ${prevThreshold} -> ${this.ratchetState.currentThreshold}`);
292
+ // ADR-062: Persist updated ratchet state so the monotonic invariant
293
+ // survives coordinator restarts.
294
+ await this.saveRatchetState();
295
+ }
296
+ }
297
+ catch (ratchetErr) {
298
+ // Ratcheting failure must never break gate evaluation
299
+ logger.warn('Gate ratcheting failed (non-critical)', {
300
+ error: ratchetErr instanceof Error ? ratchetErr.message : String(ratchetErr),
301
+ });
302
+ }
303
+ }
260
304
  // Publish event
261
305
  if (this.config.publishEvents) {
262
306
  await this.publishQualityGateEvaluated(finalResult);
@@ -347,6 +391,17 @@ export class QualityAssessmentCoordinator extends BaseDomainCoordinator {
347
391
  result.value.trends.length / 10,
348
392
  result.value.recommendations.length / 10,
349
393
  ]);
394
+ // EWC++ outcome recording: reward scaled by analysis score
395
+ try {
396
+ this.qesona.recordOutcome(score.overall / 100);
397
+ if (this.qesona.shouldConsolidate()) {
398
+ try {
399
+ this.qesona.backgroundConsolidate();
400
+ }
401
+ catch { /* best-effort */ }
402
+ }
403
+ }
404
+ catch { /* must not break main flow */ }
350
405
  }
351
406
  // Store quality pattern in SONA
352
407
  if (this.config.enableSONAPatternLearning && this.qesona) {
@@ -798,6 +853,43 @@ export class QualityAssessmentCoordinator extends BaseDomainCoordinator {
798
853
  const workflows = Array.from(this.workflows.values());
799
854
  await this.memory.set('quality-assessment:coordinator:workflows', workflows, { namespace: 'quality-assessment', persist: true });
800
855
  }
856
+ /**
857
+ * ADR-062: Load persisted ratchet state from MemoryBackend.
858
+ * If no saved state exists the in-memory default (threshold 70) is kept.
859
+ * Persistence failures are logged but never propagated — the coordinator
860
+ * must remain functional even when the memory backend is degraded.
861
+ */
862
+ async loadRatchetState() {
863
+ try {
864
+ const saved = await this.memory.get('quality-assessment:ratchet-state');
865
+ if (saved) {
866
+ this.ratchetState = saved;
867
+ logger.info(`Restored ratchet state (threshold=${saved.currentThreshold}, passes=${saved.consecutivePasses})`);
868
+ }
869
+ }
870
+ catch (loadErr) {
871
+ // Non-critical: default ratchet state is safe
872
+ logger.warn('Failed to load ratchet state (using default)', {
873
+ error: loadErr instanceof Error ? loadErr.message : String(loadErr),
874
+ });
875
+ }
876
+ }
877
+ /**
878
+ * ADR-062: Persist current ratchet state to MemoryBackend.
879
+ * Called after checkRatchet() when the threshold actually ratcheted upward.
880
+ * Persistence failures are logged but never propagated.
881
+ */
882
+ async saveRatchetState() {
883
+ try {
884
+ await this.memory.set('quality-assessment:ratchet-state', this.ratchetState, { namespace: 'quality-assessment', persist: true });
885
+ }
886
+ catch (saveErr) {
887
+ // Non-critical: next restart will use the previous persisted value
888
+ logger.warn('Failed to persist ratchet state', {
889
+ error: saveErr instanceof Error ? saveErr.message : String(saveErr),
890
+ });
891
+ }
892
+ }
801
893
  // ============================================================================
802
894
  // Ruvector Integration Methods (ADR-040)
803
895
  // ============================================================================
@@ -98,6 +98,7 @@ export interface ITestExecutionCoordinator extends TestExecutionAPI {
98
98
  isConsensusAvailable(): boolean;
99
99
  }
100
100
  export declare class TestExecutionCoordinator extends BaseDomainCoordinator<TestExecutionCoordinatorConfig> implements ITestExecutionCoordinator {
101
+ private readonly memory;
101
102
  private readonly executor;
102
103
  private readonly flakyDetector;
103
104
  private readonly retryHandler;
@@ -186,6 +187,24 @@ export declare class TestExecutionCoordinator extends BaseDomainCoordinator<Test
186
187
  * Extract test name from file path
187
188
  */
188
189
  private extractTestName;
190
+ /**
191
+ * ADR-062: Partition test files into normal and holdout sets.
192
+ *
193
+ * When AQE_HOLDOUT_TESTING_ENABLED is 'true', holdout test file paths are
194
+ * looked up from memory (stored by the test-generation domain when a test
195
+ * is created with `holdout: true`).
196
+ *
197
+ * - Normal runs execute only non-holdout tests.
198
+ * - Holdout runs (AQE_RUN_HOLDOUT_TESTS === 'true' or runHoldout flag)
199
+ * execute only holdout tests.
200
+ *
201
+ * If the feature flag is disabled, all tests are returned as normal tests.
202
+ * Failures in holdout lookup are logged and treated as "no holdout tests"
203
+ * so that normal execution is never blocked.
204
+ *
205
+ * @returns Object with testsToRun and holdoutCount.
206
+ */
207
+ private partitionHoldoutTests;
189
208
  /**
190
209
  * Execute E2E test case
191
210
  */
@@ -37,6 +37,7 @@ const DEFAULT_COORDINATOR_CONFIG = {
37
37
  // ============================================================================
38
38
  const logger = LoggerFactory.create('test-execution');
39
39
  export class TestExecutionCoordinator extends BaseDomainCoordinator {
40
+ memory;
40
41
  executor;
41
42
  flakyDetector;
42
43
  retryHandler;
@@ -52,6 +53,7 @@ export class TestExecutionCoordinator extends BaseDomainCoordinator {
52
53
  verifyFindingTypes: ['flaky-test-detection', 'test-failure-analysis', 'retry-strategy'],
53
54
  ...fullConfig.consensusConfig,
54
55
  });
56
+ this.memory = memory;
55
57
  // Create services with appropriate configuration
56
58
  this.executor = new TestExecutorService({ memory }, {
57
59
  simulateForTesting: fullConfig.simulateForTesting,
@@ -116,13 +118,21 @@ export class TestExecutionCoordinator extends BaseDomainCoordinator {
116
118
  * Auto-detects framework and uses sensible defaults
117
119
  */
118
120
  async runTests(request) {
119
- const framework = this.detectFramework(request.testFiles);
120
- const workers = request.workers ?? Math.min(4, Math.max(1, request.testFiles.length));
121
+ // ADR-062: Filter holdout tests before execution
122
+ const { testsToRun } = await this.partitionHoldoutTests(request.testFiles);
123
+ if (testsToRun.length === 0) {
124
+ return ok({
125
+ runId: uuidv4(), status: 'passed', total: 0, passed: 0,
126
+ failed: 0, skipped: 0, duration: 0, failedTests: [],
127
+ });
128
+ }
129
+ const framework = this.detectFramework(testsToRun);
130
+ const workers = request.workers ?? Math.min(4, Math.max(1, testsToRun.length));
121
131
  const timeout = request.timeout ?? 60000;
122
132
  // Use parallel execution by default (unless explicitly disabled)
123
- if (request.parallel !== false && request.testFiles.length > 1) {
133
+ if (request.parallel !== false && testsToRun.length > 1) {
124
134
  const result = await this.executeParallel({
125
- testFiles: request.testFiles,
135
+ testFiles: testsToRun,
126
136
  framework,
127
137
  workers,
128
138
  timeout,
@@ -141,7 +151,7 @@ export class TestExecutionCoordinator extends BaseDomainCoordinator {
141
151
  }
142
152
  // Sequential execution
143
153
  const result = await this.execute({
144
- testFiles: request.testFiles,
154
+ testFiles: testsToRun,
145
155
  framework,
146
156
  timeout,
147
157
  });
@@ -181,6 +191,17 @@ export class TestExecutionCoordinator extends BaseDomainCoordinator {
181
191
  // ADR-057: Reset recovery attempt counter for each top-level execution
182
192
  this.infraRecoveryAttempts = 0;
183
193
  try {
194
+ // ADR-062: Filter holdout tests before execution
195
+ const { testsToRun } = await this.partitionHoldoutTests(request.testFiles);
196
+ if (testsToRun.length === 0) {
197
+ this.activeRuns.delete(runId);
198
+ return ok({
199
+ runId, status: 'passed', total: 0, passed: 0,
200
+ failed: 0, skipped: 0, duration: 0, failedTests: [],
201
+ });
202
+ }
203
+ // Replace testFiles with filtered set for the remainder of execution
204
+ request = { ...request, testFiles: testsToRun };
184
205
  // Prioritize tests if enabled
185
206
  let orderedTestFiles = request.testFiles;
186
207
  let prioritizationResult = null;
@@ -273,6 +294,16 @@ export class TestExecutionCoordinator extends BaseDomainCoordinator {
273
294
  // ADR-057: Reset recovery attempt counter for each top-level execution
274
295
  this.infraRecoveryAttempts = 0;
275
296
  try {
297
+ // ADR-062: Filter holdout tests before execution
298
+ const { testsToRun } = await this.partitionHoldoutTests(request.testFiles);
299
+ if (testsToRun.length === 0) {
300
+ this.activeRuns.delete(runId);
301
+ return ok({
302
+ runId, status: 'passed', total: 0, passed: 0,
303
+ failed: 0, skipped: 0, duration: 0, failedTests: [],
304
+ });
305
+ }
306
+ request = { ...request, testFiles: testsToRun };
276
307
  // ADR-047: Check topology health before expensive parallel operations
277
308
  if (this.config.enableMinCutAwareness && !this.isTopologyHealthy()) {
278
309
  logger.warn(`Topology degraded, reducing parallel workers`);
@@ -677,6 +708,72 @@ export class TestExecutionCoordinator extends BaseDomainCoordinator {
677
708
  return parts[parts.length - 1] || filePath;
678
709
  }
679
710
  // ============================================================================
711
+ // ADR-062: Holdout Test Filtering
712
+ // ============================================================================
713
+ /**
714
+ * ADR-062: Partition test files into normal and holdout sets.
715
+ *
716
+ * When AQE_HOLDOUT_TESTING_ENABLED is 'true', holdout test file paths are
717
+ * looked up from memory (stored by the test-generation domain when a test
718
+ * is created with `holdout: true`).
719
+ *
720
+ * - Normal runs execute only non-holdout tests.
721
+ * - Holdout runs (AQE_RUN_HOLDOUT_TESTS === 'true' or runHoldout flag)
722
+ * execute only holdout tests.
723
+ *
724
+ * If the feature flag is disabled, all tests are returned as normal tests.
725
+ * Failures in holdout lookup are logged and treated as "no holdout tests"
726
+ * so that normal execution is never blocked.
727
+ *
728
+ * @returns Object with testsToRun and holdoutCount.
729
+ */
730
+ async partitionHoldoutTests(testFiles, runHoldout) {
731
+ const holdoutEnabled = process.env.AQE_HOLDOUT_TESTING_ENABLED === 'true';
732
+ if (!holdoutEnabled) {
733
+ return { testsToRun: testFiles, holdoutCount: 0 };
734
+ }
735
+ try {
736
+ // Retrieve the set of holdout test file paths stored by test-generation
737
+ const holdoutSet = await this.memory.get('test-generation:holdout-test-files');
738
+ if (!holdoutSet || holdoutSet.length === 0) {
739
+ return { testsToRun: testFiles, holdoutCount: 0 };
740
+ }
741
+ const holdoutPaths = new Set(holdoutSet);
742
+ const normalTests = [];
743
+ const holdoutTests = [];
744
+ for (const file of testFiles) {
745
+ if (holdoutPaths.has(file)) {
746
+ holdoutTests.push(file);
747
+ }
748
+ else {
749
+ normalTests.push(file);
750
+ }
751
+ }
752
+ // Determine if this is a holdout-only run
753
+ const isHoldoutRun = runHoldout === true ||
754
+ process.env.AQE_RUN_HOLDOUT_TESTS === 'true';
755
+ if (isHoldoutRun) {
756
+ logger.info(`Holdout run: executing ${holdoutTests.length} holdout tests, skipping ${normalTests.length} normal tests`);
757
+ // Store metadata about the holdout run
758
+ await this.memory.set(`test-execution:holdout-run:${Date.now()}`, { holdoutCount: holdoutTests.length, holdoutFiles: holdoutTests }, { namespace: 'test-execution', ttl: 86400 });
759
+ return { testsToRun: holdoutTests, holdoutCount: holdoutTests.length };
760
+ }
761
+ if (holdoutTests.length > 0) {
762
+ logger.info(`Normal run: filtered out ${holdoutTests.length} holdout test(s), running ${normalTests.length} normal tests`);
763
+ // Store metadata for visibility
764
+ await this.memory.set(`test-execution:holdout-filtered:${Date.now()}`, { holdoutCount: holdoutTests.length, holdoutFiles: holdoutTests }, { namespace: 'test-execution', ttl: 86400 });
765
+ }
766
+ return { testsToRun: normalTests, holdoutCount: holdoutTests.length };
767
+ }
768
+ catch (partitionErr) {
769
+ // Non-critical: if holdout lookup fails, run all tests
770
+ logger.warn('Holdout test partitioning failed (running all tests)', {
771
+ error: partitionErr instanceof Error ? partitionErr.message : String(partitionErr),
772
+ });
773
+ return { testsToRun: testFiles, holdoutCount: 0 };
774
+ }
775
+ }
776
+ // ============================================================================
680
777
  // E2E Test Execution Methods
681
778
  // ============================================================================
682
779
  /**
@@ -320,6 +320,17 @@ export class TestGenerationCoordinator extends BaseDomainCoordinator {
320
320
  (request.coverageTarget ?? 80) / 100,
321
321
  tests.tests.filter(t => t.type === 'unit').length / 20,
322
322
  ]);
323
+ // EWC++ outcome recording: close the feedback loop
324
+ try {
325
+ this.qesona.recordOutcome(1.0);
326
+ if (this.qesona.shouldConsolidate()) {
327
+ try {
328
+ this.qesona.backgroundConsolidate();
329
+ }
330
+ catch { /* best-effort */ }
331
+ }
332
+ }
333
+ catch { /* must not break main flow */ }
323
334
  }
324
335
  // Learn from successful generation using QESONA
325
336
  if (this.config.enableQESONA && this.qesona) {
@@ -48,6 +48,8 @@ export interface IGeneratedTest {
48
48
  llmEnhanced?: boolean;
49
49
  /** Test quality gate validation result (loki-mode Gates 8 & 9) */
50
50
  qualityGateResult?: TestQualityGateResult;
51
+ /** ADR-062: Whether this test is a holdout test (not shown to developer, runs in CI only) */
52
+ holdout?: boolean;
51
53
  }
52
54
  export interface ITDDRequest {
53
55
  feature: string;
@@ -15,6 +15,15 @@ import { type ITDDGeneratorService } from './tdd-generator';
15
15
  import { type IPropertyTestGeneratorService } from './property-test-generator';
16
16
  import { type ITestDataGeneratorService } from './test-data-generator';
17
17
  import type { HybridRouter } from '../../../shared/llm';
18
+ /**
19
+ * Deterministically decide whether a test ID should be a holdout test.
20
+ * Uses FNV-1a hash of the testId to select ~10% of tests as holdout.
21
+ *
22
+ * @param testId - Unique identifier for the test
23
+ * @param seed - Optional seed for the hash (default: 0)
24
+ * @returns true if this test should be flagged as holdout
25
+ */
26
+ export declare function isHoldoutTest(testId: string, seed?: number): boolean;
18
27
  /**
19
28
  * Interface for the test generation service
20
29
  */
@@ -27,6 +27,35 @@ import { resolveRequest } from '../../../shared/language-detector.js';
27
27
  import { compilationValidator } from './compilation-validator.js';
28
28
  import { resolveTestFilePath } from './test-file-resolver.js';
29
29
  import { getPromptConfig } from '../prompts/language-prompts.js';
30
+ // ============================================================================
31
+ // ADR-062 Tier 2: Holdout Test Selection
32
+ // ============================================================================
33
+ /**
34
+ * FNV-1a hash of a string, returning a 32-bit unsigned integer.
35
+ * Deterministic: same input always produces the same output.
36
+ */
37
+ function fnv1aHashU32(input, seed = 0) {
38
+ let hash = (0x811c9dc5 ^ seed) >>> 0; // FNV offset basis, XOR with seed
39
+ for (let i = 0; i < input.length; i++) {
40
+ hash ^= input.charCodeAt(i);
41
+ hash = Math.imul(hash, 0x01000193); // FNV prime
42
+ hash = hash >>> 0; // Force unsigned 32-bit
43
+ }
44
+ return hash;
45
+ }
46
+ /**
47
+ * Deterministically decide whether a test ID should be a holdout test.
48
+ * Uses FNV-1a hash of the testId to select ~10% of tests as holdout.
49
+ *
50
+ * @param testId - Unique identifier for the test
51
+ * @param seed - Optional seed for the hash (default: 0)
52
+ * @returns true if this test should be flagged as holdout
53
+ */
54
+ export function isHoldoutTest(testId, seed = 0) {
55
+ const hash = fnv1aHashU32(testId, seed);
56
+ // Select bottom 10% of the hash space (0 to 0xFFFFFFFF)
57
+ return (hash % 100) < 10;
58
+ }
30
59
  const DEFAULT_CONFIG = {
31
60
  defaultFramework: 'vitest',
32
61
  maxTestsPerFile: 50,
@@ -280,6 +309,14 @@ Return a JSON array of test suggestions, each with: { "name": "test name", "desc
280
309
  patternsUsed.push(...fileTests.value.patternsUsed);
281
310
  }
282
311
  }
312
+ // ADR-062 Tier 2: Mark holdout tests when feature flag is enabled
313
+ if (process.env.AQE_HOLDOUT_TESTING_ENABLED === 'true') {
314
+ for (const test of tests) {
315
+ if (isHoldoutTest(test.id)) {
316
+ test.holdout = true;
317
+ }
318
+ }
319
+ }
283
320
  const coverageEstimate = this.estimateCoverage(tests, coverageTarget);
284
321
  await this.storeGenerationMetadata(tests, patternsUsed);
285
322
  return ok({
@@ -26,6 +26,17 @@ export declare class CrossPhaseHookExecutor {
26
26
  private querySignalsForInjection;
27
27
  formatSignalsForInjection(signals: CrossPhaseSignal[]): string;
28
28
  private getRecommendations;
29
+ /**
30
+ * IMP-07: When AQE_HOOKS_MANAGED_ONLY is set, only hooks whose names start
31
+ * with "managed:" are allowed to execute. All other hooks are filtered out.
32
+ */
33
+ private filterManagedHooks;
34
+ /**
35
+ * IMP-07: SSRF guard — if a target string looks like a URL (has a scheme),
36
+ * validate it against the SSRF blocklist. Returns true when the URL is
37
+ * blocked and the caller should abort the action.
38
+ */
39
+ private isBlockedUrl;
29
40
  private checkConditions;
30
41
  private evaluateCondition;
31
42
  private getValueFromPath;
@@ -11,6 +11,7 @@ import { readFileSync, existsSync } from 'fs';
11
11
  import { join } from 'path';
12
12
  import { parse as parseYaml } from 'yaml';
13
13
  import { getCrossPhaseMemory, } from '../memory/cross-phase-memory.js';
14
+ import { captureHooksConfigSnapshot, validateHookUrl, classifyHookExit, } from './security/index.js';
14
15
  // =============================================================================
15
16
  // Hook Executor
16
17
  // =============================================================================
@@ -27,17 +28,24 @@ export class CrossPhaseHookExecutor {
27
28
  // Initialization
28
29
  // ---------------------------------------------------------------------------
29
30
  async initialize() {
31
+ // IMP-07: Policy flag — globally disable all hook execution
32
+ if (process.env.AQE_HOOKS_DISABLED === 'true') {
33
+ console.log('[CrossPhaseHooks] All hooks disabled via AQE_HOOKS_DISABLED');
34
+ return false;
35
+ }
30
36
  if (!existsSync(this.configPath)) {
31
37
  console.warn(`[CrossPhaseHooks] Config not found: ${this.configPath}`);
32
38
  return false;
33
39
  }
34
40
  try {
35
41
  const content = readFileSync(this.configPath, 'utf-8');
36
- this.config = parseYaml(content);
37
- if (!this.config.enabled) {
42
+ const parsed = parseYaml(content);
43
+ if (!parsed.enabled) {
38
44
  console.log('[CrossPhaseHooks] Hooks disabled in config');
39
45
  return false;
40
46
  }
47
+ // IMP-07: Deep-freeze config so it cannot be mutated at runtime
48
+ this.config = captureHooksConfigSnapshot(parsed);
41
49
  await this.memory.initialize();
42
50
  console.log(`[CrossPhaseHooks] Initialized with ${Object.keys(this.config.hooks).length} hooks`);
43
51
  return true;
@@ -53,8 +61,11 @@ export class CrossPhaseHookExecutor {
53
61
  async onAgentComplete(agentName, result) {
54
62
  if (!this.config)
55
63
  return;
56
- const matchingHooks = Object.entries(this.config.hooks).filter(([_, hook]) => hook.trigger.event === 'agent-complete' &&
57
- hook.trigger.agent === agentName);
64
+ // IMP-07: Runtime kill-switch check
65
+ if (process.env.AQE_HOOKS_DISABLED === 'true')
66
+ return;
67
+ const matchingHooks = this.filterManagedHooks(Object.entries(this.config.hooks).filter(([_, hook]) => hook.trigger.event === 'agent-complete' &&
68
+ hook.trigger.agent === agentName));
58
69
  for (const [hookName, hook] of matchingHooks) {
59
70
  if (this.checkConditions(hook.trigger.conditions, result)) {
60
71
  console.log(`[CrossPhaseHooks] Executing hook: ${hookName}`);
@@ -65,9 +76,12 @@ export class CrossPhaseHookExecutor {
65
76
  async onPhaseStart(phaseName, context = {}) {
66
77
  if (!this.config)
67
78
  return {};
79
+ // IMP-07: Runtime kill-switch check
80
+ if (process.env.AQE_HOOKS_DISABLED === 'true')
81
+ return {};
68
82
  const injectedSignals = {};
69
- const matchingHooks = Object.entries(this.config.hooks).filter(([_, hook]) => hook.trigger.event === 'phase-start' &&
70
- hook.trigger.phase === phaseName);
83
+ const matchingHooks = this.filterManagedHooks(Object.entries(this.config.hooks).filter(([_, hook]) => hook.trigger.event === 'phase-start' &&
84
+ hook.trigger.phase === phaseName));
71
85
  for (const [hookName, hook] of matchingHooks) {
72
86
  console.log(`[CrossPhaseHooks] Executing phase-start hook: ${hookName}`);
73
87
  for (const action of hook.actions) {
@@ -87,8 +101,11 @@ export class CrossPhaseHookExecutor {
87
101
  async onPhaseEnd(phaseName, result) {
88
102
  if (!this.config)
89
103
  return;
90
- const matchingHooks = Object.entries(this.config.hooks).filter(([_, hook]) => hook.trigger.event === 'phase-end' &&
91
- hook.trigger.phase === phaseName);
104
+ // IMP-07: Runtime kill-switch check
105
+ if (process.env.AQE_HOOKS_DISABLED === 'true')
106
+ return;
107
+ const matchingHooks = this.filterManagedHooks(Object.entries(this.config.hooks).filter(([_, hook]) => hook.trigger.event === 'phase-end' &&
108
+ hook.trigger.phase === phaseName));
92
109
  for (const [hookName, hook] of matchingHooks) {
93
110
  console.log(`[CrossPhaseHooks] Executing phase-end hook: ${hookName}`);
94
111
  await this.executeActions(hook.actions, result);
@@ -103,7 +120,19 @@ export class CrossPhaseHookExecutor {
103
120
  await this.executeAction(action, context);
104
121
  }
105
122
  catch (err) {
106
- console.error(`[CrossPhaseHooks] Action failed:`, err);
123
+ // IMP-07: Classify exit codes when error carries one
124
+ const exitCode = err?.exitCode;
125
+ if (typeof exitCode === 'number') {
126
+ const classification = classifyHookExit(exitCode);
127
+ if (classification === 'model_blocking') {
128
+ console.error(`[CrossPhaseHooks] Model-blocking hook failure (exit ${exitCode}):`, err);
129
+ throw err; // Propagate blocking failures
130
+ }
131
+ console.warn(`[CrossPhaseHooks] Hook ${classification} (exit ${exitCode}):`, err);
132
+ }
133
+ else {
134
+ console.error(`[CrossPhaseHooks] Action failed:`, err);
135
+ }
107
136
  }
108
137
  }
109
138
  }
@@ -158,6 +187,9 @@ export class CrossPhaseHookExecutor {
158
187
  async executeNotifyAgent(action, context) {
159
188
  if (!action.target || !action.message)
160
189
  return;
190
+ // IMP-07: SSRF guard — block if target looks like a URL pointing to private IP
191
+ if (await this.isBlockedUrl(action.target))
192
+ return;
161
193
  console.log(`[CrossPhaseHooks] Notify ${action.target}: ${action.message}`);
162
194
  this.emit('agent-notification', {
163
195
  target: action.target,
@@ -169,6 +201,9 @@ export class CrossPhaseHookExecutor {
169
201
  async executeInvokeAgent(action, context) {
170
202
  if (!action.target)
171
203
  return;
204
+ // IMP-07: SSRF guard — block if target looks like a URL pointing to private IP
205
+ if (await this.isBlockedUrl(action.target))
206
+ return;
172
207
  console.log(`[CrossPhaseHooks] Invoke agent: ${action.target}`);
173
208
  this.emit('agent-invocation', {
174
209
  agent: action.target,
@@ -235,6 +270,35 @@ export class CrossPhaseHookExecutor {
235
270
  // ---------------------------------------------------------------------------
236
271
  // Helpers
237
272
  // ---------------------------------------------------------------------------
273
+ /**
274
+ * IMP-07: When AQE_HOOKS_MANAGED_ONLY is set, only hooks whose names start
275
+ * with "managed:" are allowed to execute. All other hooks are filtered out.
276
+ */
277
+ filterManagedHooks(hooks) {
278
+ if (process.env.AQE_HOOKS_MANAGED_ONLY !== 'true')
279
+ return hooks;
280
+ const filtered = hooks.filter(([name]) => name.startsWith('managed:'));
281
+ if (filtered.length < hooks.length) {
282
+ console.log(`[CrossPhaseHooks] AQE_HOOKS_MANAGED_ONLY: filtered ${hooks.length - filtered.length} non-managed hooks`);
283
+ }
284
+ return filtered;
285
+ }
286
+ /**
287
+ * IMP-07: SSRF guard — if a target string looks like a URL (has a scheme),
288
+ * validate it against the SSRF blocklist. Returns true when the URL is
289
+ * blocked and the caller should abort the action.
290
+ */
291
+ async isBlockedUrl(target) {
292
+ // Only validate strings that look like URLs (contain "://")
293
+ if (!target.includes('://'))
294
+ return false;
295
+ const result = await validateHookUrl(target);
296
+ if (!result.safe) {
297
+ console.warn(`[CrossPhaseHooks] SSRF blocked: ${result.reason}`);
298
+ return true;
299
+ }
300
+ return false;
301
+ }
238
302
  checkConditions(conditions, context) {
239
303
  if (!conditions || conditions.length === 0)
240
304
  return true;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Hook Configuration Snapshot
3
+ *
4
+ * Deep-freezes hook configuration at startup so it cannot be mutated
5
+ * at runtime. Uses structuredClone to detach from the original, then
6
+ * recursively freezes every nested object and array.
7
+ *
8
+ * @module hooks/security/config-snapshot
9
+ * @see IMP-07 Hook Security Hardening
10
+ */
11
+ /**
12
+ * Deep-freeze an object and all nested objects.
13
+ * Returns a Readonly<T> that throws on mutation attempts.
14
+ */
15
+ export declare function deepFreeze<T extends object>(obj: T): Readonly<T>;
16
+ /**
17
+ * Capture an immutable snapshot of hook configuration.
18
+ * Uses structuredClone to detach from original, then deep-freezes.
19
+ */
20
+ export declare function captureHooksConfigSnapshot<T extends object>(config: T): Readonly<T>;
21
+ //# sourceMappingURL=config-snapshot.d.ts.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Hook Configuration Snapshot
3
+ *
4
+ * Deep-freezes hook configuration at startup so it cannot be mutated
5
+ * at runtime. Uses structuredClone to detach from the original, then
6
+ * recursively freezes every nested object and array.
7
+ *
8
+ * @module hooks/security/config-snapshot
9
+ * @see IMP-07 Hook Security Hardening
10
+ */
11
+ /**
12
+ * Deep-freeze an object and all nested objects.
13
+ * Returns a Readonly<T> that throws on mutation attempts.
14
+ */
15
+ export function deepFreeze(obj) {
16
+ const props = Object.getOwnPropertyNames(obj);
17
+ for (const prop of props) {
18
+ const val = obj[prop];
19
+ if (val && typeof val === 'object' && !Object.isFrozen(val)) {
20
+ deepFreeze(val);
21
+ }
22
+ }
23
+ return Object.freeze(obj);
24
+ }
25
+ /**
26
+ * Capture an immutable snapshot of hook configuration.
27
+ * Uses structuredClone to detach from original, then deep-freezes.
28
+ */
29
+ export function captureHooksConfigSnapshot(config) {
30
+ const snapshot = structuredClone(config);
31
+ return deepFreeze(snapshot);
32
+ }
33
+ //# sourceMappingURL=config-snapshot.js.map