agentic-qe 3.10.0 → 3.10.2
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.
- package/.claude/hooks/README.txt +17 -0
- package/.claude/hooks/aqe-hook.cjs +98 -0
- package/.claude/hooks/cross-phase-memory.yaml +296 -0
- package/.claude/hooks/post-task-sync.sh +113 -0
- package/.claude/hooks/v3-domain-workers.json +121 -0
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +148 -0
- package/README.md +35 -8
- package/dist/cli/bundle.js +5 -5
- package/dist/cli/chunks/adapter-CR6J5C76.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-5UDM2PWG.js → agent-booster-wasm-DHSIPFTH.js} +2 -2
- package/dist/cli/chunks/{agent-handler-JSYER5YC.js → agent-handler-FPQVHGGT.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-T2SAHI4F.js → agent-memory-branch-OLOF5ZHV.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-2MNTHMB6.js +2 -0
- package/dist/cli/chunks/{audit-HIBRVGXG.js → audit-ALRYPHGP.js} +2 -2
- package/dist/cli/chunks/base-AOQNGMTL.js +2 -0
- package/dist/cli/chunks/{hnswlib-node-TA4DZV62.js → better-sqlite3-5BT5FO64.js} +2 -2
- package/dist/cli/chunks/{brain-handler-N6AWIMXG.js → brain-handler-ROZUHCOT.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-VYQGBVEJ.js → branch-enumerator-VK7G4NKJ.js} +2 -2
- package/dist/cli/chunks/{browser-2X4WKZPT.js → browser-Q2S75M2F.js} +2 -2
- package/dist/cli/chunks/browser-workflow-UJ4A2ZXO.js +2 -0
- package/dist/cli/chunks/{chunk-BQX5QDU5.js → chunk-2244IFZA.js} +1 -1
- package/dist/cli/chunks/{chunk-S33246T4.js → chunk-22D6VBPD.js} +1 -1
- package/dist/cli/chunks/{chunk-UGX4EHT5.js → chunk-24LUQICS.js} +2 -2
- package/dist/cli/chunks/{chunk-6HCHW5TS.js → chunk-2EDWGHDA.js} +2 -2
- package/dist/cli/chunks/{chunk-4WYGUTSF.js → chunk-2JDLQWSV.js} +2 -2
- package/dist/cli/chunks/{chunk-3QULDB7K.js → chunk-2OH3ALYB.js} +1 -1
- package/dist/cli/chunks/chunk-3RHHKYUR.js +2 -0
- package/dist/cli/chunks/{chunk-Z6JLPPAY.js → chunk-3Z4FHA2E.js} +1 -1
- package/dist/cli/chunks/{chunk-ZYZWBNKT.js → chunk-4BXGVM2C.js} +1 -1
- package/dist/cli/chunks/{chunk-6F3WJOU2.js → chunk-4F3ZTXHP.js} +2 -2
- package/dist/cli/chunks/{chunk-CU4IUJ2K.js → chunk-4GTDW2XL.js} +2 -2
- package/dist/cli/chunks/{chunk-4UUDFWOP.js → chunk-5HB54RUS.js} +2 -2
- package/dist/cli/chunks/{chunk-YHNEBCYQ.js → chunk-5PL7WTCU.js} +2 -2
- package/dist/cli/chunks/{chunk-MF3XRML3.js → chunk-5PRFFHFV.js} +2 -2
- package/dist/cli/chunks/{chunk-TEJPHJMW.js → chunk-5QHSLWLP.js} +2 -2
- package/dist/cli/chunks/{chunk-ZFBMBCKN.js → chunk-5WJ3FWL4.js} +2 -2
- package/dist/cli/chunks/{chunk-V5TRAL57.js → chunk-6KSCXPPL.js} +2 -2
- package/dist/cli/chunks/{chunk-P6XYFDXN.js → chunk-6NZHEM4V.js} +1 -1
- package/dist/cli/chunks/{chunk-HD6CZBZV.js → chunk-6ZFHIKQG.js} +2 -2
- package/dist/cli/chunks/{chunk-VEOQH4W6.js → chunk-7DKYCVJI.js} +2 -2
- package/dist/cli/chunks/{chunk-Y4I5JBOL.js → chunk-7IVQ6OVR.js} +2 -2
- package/dist/cli/chunks/chunk-7IZ2OPC2.js +2 -0
- package/dist/cli/chunks/{chunk-AFFYJSW2.js → chunk-7QRMARM7.js} +2 -2
- package/dist/cli/chunks/{chunk-L2AIES7X.js → chunk-7SJX4CFK.js} +1 -1
- package/dist/cli/chunks/{chunk-UCIJCRPB.js → chunk-7SWD3D6Y.js} +2 -2
- package/dist/cli/chunks/{chunk-FCSJ7GIZ.js → chunk-7V5UHLNY.js} +4 -4
- package/dist/cli/chunks/{chunk-5QJDH4Z5.js → chunk-7Z46RDDV.js} +2 -2
- package/dist/cli/chunks/{chunk-5RQT7EJP.js → chunk-A5RMQG4N.js} +3 -3
- package/dist/cli/chunks/{chunk-3BO7EKGO.js → chunk-AH7FXNFE.js} +3 -3
- package/dist/cli/chunks/chunk-AIUSZC6K.js +3 -0
- package/dist/cli/chunks/{chunk-MJBXQXSX.js → chunk-AOI67HA3.js} +1 -1
- package/dist/cli/chunks/{chunk-6H5MRVJS.js → chunk-AV7KYE5P.js} +7 -7
- package/dist/cli/chunks/{chunk-OGT45MZN.js → chunk-AWFIEGR3.js} +2 -2
- package/dist/cli/chunks/{chunk-J5RJYFRM.js → chunk-BQCSCAUC.js} +2 -2
- package/dist/cli/chunks/{chunk-OUJJ34JH.js → chunk-C2M74HCN.js} +1 -1
- package/dist/cli/chunks/{chunk-G2HA2O3R.js → chunk-CIRPP7RQ.js} +2 -2
- package/dist/cli/chunks/{chunk-LXHA55EB.js → chunk-CMACGG4Z.js} +1 -1
- package/dist/cli/chunks/{chunk-LRISVDVO.js → chunk-CTDLI2ON.js} +1 -1
- package/dist/cli/chunks/{chunk-DXV6NRG3.js → chunk-CV2SBMBW.js} +2 -2
- package/dist/cli/chunks/{chunk-WLLE54TA.js → chunk-DMQPO43S.js} +1 -1
- package/dist/cli/chunks/{chunk-I4E6CLC4.js → chunk-DRWGK3YO.js} +2 -2
- package/dist/cli/chunks/{chunk-Z2SCTEZD.js → chunk-DZZEHPSJ.js} +2 -2
- package/dist/cli/chunks/{chunk-DY7IRNE2.js → chunk-EA7ZSN3V.js} +1 -1
- package/dist/cli/chunks/{chunk-M4HDBRVJ.js → chunk-EQBEGDTG.js} +1 -1
- package/dist/cli/chunks/{chunk-HZPXOAFW.js → chunk-ETN5563K.js} +2 -2
- package/dist/cli/chunks/{chunk-OWMGD7FO.js → chunk-EVCOCGVJ.js} +3 -3
- package/dist/cli/chunks/{chunk-27ACATRH.js → chunk-FO43SQXP.js} +2 -2
- package/dist/cli/chunks/{chunk-DQJJS4AX.js → chunk-FO73PZVU.js} +2 -2
- package/dist/cli/chunks/{chunk-FEBXP74Y.js → chunk-FPAW77XV.js} +1 -1
- package/dist/cli/chunks/{chunk-KYLJERZ3.js → chunk-FY3CUPNN.js} +20 -17
- package/dist/cli/chunks/{chunk-LQ3TA22E.js → chunk-G5U6Q42D.js} +2 -2
- package/dist/cli/chunks/{chunk-JCKX2LEJ.js → chunk-HA63NBFK.js} +49 -49
- package/dist/cli/chunks/{chunk-NT4PI5HI.js → chunk-HHCYSAH3.js} +2 -2
- package/dist/cli/chunks/{chunk-GPKZ4MMH.js → chunk-HJME6G5M.js} +1 -1
- package/dist/cli/chunks/{chunk-TR7BZLB6.js → chunk-HJORBNXW.js} +1 -1
- package/dist/cli/chunks/{chunk-BXCS55GB.js → chunk-HO37VP4O.js} +1 -1
- package/dist/cli/chunks/{chunk-FX4SYT6Y.js → chunk-I677W5BT.js} +3 -3
- package/dist/cli/chunks/chunk-IAZEDWRX.js +2 -0
- package/dist/cli/chunks/{chunk-5UOV7T36.js → chunk-IICTTDAA.js} +2 -2
- package/dist/cli/chunks/{chunk-BQT4J3BD.js → chunk-JF53LRBL.js} +2 -2
- package/dist/cli/chunks/{chunk-S4CNA6Z5.js → chunk-KB5L5TTF.js} +3 -3
- package/dist/cli/chunks/{chunk-UE3XXKLN.js → chunk-L7VIX22Y.js} +2 -2
- package/dist/cli/chunks/{chunk-C5QESAYA.js → chunk-LQTWPSYL.js} +1 -1
- package/dist/cli/chunks/{chunk-2GL4GH52.js → chunk-LZCBSFAU.js} +4 -4
- package/dist/cli/chunks/{chunk-LDMG4372.js → chunk-MCOFJHSJ.js} +2 -2
- package/dist/cli/chunks/{chunk-ZCNVFULO.js → chunk-MCZHKXB4.js} +2 -2
- package/dist/cli/chunks/{chunk-VTIXFHZR.js → chunk-MEY43PIQ.js} +2 -2
- package/dist/cli/chunks/{chunk-PNDO4W4L.js → chunk-MMIQ5DMA.js} +2 -2
- package/dist/cli/chunks/{chunk-NWHSEXHA.js → chunk-MNUTRAUV.js} +1 -1
- package/dist/cli/chunks/{chunk-XFUU2RCA.js → chunk-MNV3E5KY.js} +2 -2
- package/dist/cli/chunks/{chunk-WVCIZIKH.js → chunk-MYWQTCS4.js} +1 -1
- package/dist/cli/chunks/{chunk-T7DLX3LS.js → chunk-NZO4WUSO.js} +3 -3
- package/dist/cli/chunks/{chunk-RF6QKV7M.js → chunk-OIEQF7PG.js} +2 -2
- package/dist/cli/chunks/{chunk-NLCUQMUR.js → chunk-OIRZJCZY.js} +2 -2
- package/dist/cli/chunks/{chunk-KOSKGZK4.js → chunk-ON4D4TJ4.js} +2 -2
- package/dist/cli/chunks/chunk-OPFN5LFT.js +95 -0
- package/dist/cli/chunks/{chunk-55JPAF56.js → chunk-ORF2UKQH.js} +1 -1
- package/dist/cli/chunks/{chunk-M73IL7FA.js → chunk-OWQ6HEYI.js} +2 -2
- package/dist/cli/chunks/{chunk-O3NAUNFC.js → chunk-OXCEUR5F.js} +2 -2
- package/dist/cli/chunks/{chunk-BTIVIWIG.js → chunk-PEK6NGVJ.js} +1 -1
- package/dist/cli/chunks/{chunk-ALCQRJDY.js → chunk-PIZYRPMT.js} +2 -2
- package/dist/cli/chunks/{chunk-L3IFZ4IX.js → chunk-PXTDEO65.js} +2 -2
- package/dist/cli/chunks/{chunk-3U77XX6J.js → chunk-PYIHZXCI.js} +12 -12
- package/dist/cli/chunks/{chunk-FQ5FT7IE.js → chunk-QBRHKTFT.js} +1 -1
- package/dist/cli/chunks/{chunk-I4T4JPR2.js → chunk-QEPFXY6G.js} +1 -1
- package/dist/cli/chunks/{chunk-X4U5NYB6.js → chunk-QJ2EHLJ2.js} +1 -1
- package/dist/cli/chunks/{chunk-JKVNZASH.js → chunk-QQNCSEZG.js} +2 -2
- package/dist/cli/chunks/{chunk-URVDWF2Y.js → chunk-QSE67XJO.js} +2 -2
- package/dist/cli/chunks/{chunk-RARSTEUO.js → chunk-R2O6OKT2.js} +1 -1
- package/dist/cli/chunks/{chunk-RGONSQ44.js → chunk-RLXTBL3H.js} +210 -210
- package/dist/cli/chunks/{chunk-RH3PHCJT.js → chunk-RNREAOY4.js} +2 -2
- package/dist/cli/chunks/{chunk-2POXDKUB.js → chunk-S3OZ7XSY.js} +1 -1
- package/dist/cli/chunks/{provider-manager-HV55NIIO.js → chunk-S3ZO7JXS.js} +13 -13
- package/dist/cli/chunks/{chunk-QWBO76AU.js → chunk-SJH3HYNC.js} +2 -2
- package/dist/cli/chunks/{chunk-WC6KZDPM.js → chunk-STEGWLH5.js} +2 -2
- package/dist/cli/chunks/{chunk-KCHFF4IE.js → chunk-SVYTN2GT.js} +2 -2
- package/dist/cli/chunks/{chunk-OKGK7DBT.js → chunk-SW4OKUTC.js} +2 -2
- package/dist/cli/chunks/{chunk-3OSCWD7Z.js → chunk-THRTUW4Z.js} +1 -1
- package/dist/cli/chunks/{chunk-U56TIYGP.js → chunk-TJKDATEU.js} +2 -2
- package/dist/cli/chunks/{chunk-4NQ6KANC.js → chunk-U3EUH6LX.js} +2 -2
- package/dist/cli/chunks/{chunk-7Y54QZKF.js → chunk-UUFOHMUG.js} +2 -2
- package/dist/cli/chunks/{chunk-W6U7SIIK.js → chunk-UVU7XLJY.js} +3 -3
- package/dist/cli/chunks/chunk-UWXH2UQK.js +2 -0
- package/dist/cli/chunks/{chunk-YYDHTBHE.js → chunk-UYYBPWU3.js} +1 -1
- package/dist/cli/chunks/{chunk-LYVFC7C7.js → chunk-VSUTI4G6.js} +2 -2
- package/dist/cli/chunks/{chunk-SGONA5GS.js → chunk-WDMPJ2M2.js} +2 -2
- package/dist/cli/chunks/{chunk-66GIKUI2.js → chunk-WNR2KAUH.js} +2 -2
- package/dist/cli/chunks/{chunk-M3M7HXDH.js → chunk-WSVUSIAZ.js} +2 -2
- package/dist/cli/chunks/{chunk-SCYF5CQA.js → chunk-WZJUMJ2S.js} +1 -1
- package/dist/cli/chunks/{chunk-WG6I7YF3.js → chunk-X2VAOIUY.js} +1 -1
- package/dist/cli/chunks/{chunk-7ZIRDBXH.js → chunk-XDSA7YUQ.js} +1 -1
- package/dist/cli/chunks/{chunk-HIWBW4IQ.js → chunk-XDU624HU.js} +1 -1
- package/dist/cli/chunks/{chunk-JUICZG3T.js → chunk-XGBAHAGC.js} +2 -2
- package/dist/cli/chunks/{chunk-DQLEZBWV.js → chunk-XMJTTF5N.js} +2 -2
- package/dist/cli/chunks/{chunk-KNL3QWVA.js → chunk-XPCNUX2U.js} +2 -2
- package/dist/cli/chunks/{chunk-VTO5O7DA.js → chunk-XRJECWZE.js} +1 -1
- package/dist/cli/chunks/{chunk-HD5NQDOL.js → chunk-XTCUN36Z.js} +2 -2
- package/dist/cli/chunks/{chunk-KDFW7MVM.js → chunk-Y63MBMOV.js} +2 -2
- package/dist/cli/chunks/{chunk-L4N6PTIC.js → chunk-YACT5WFC.js} +2 -2
- package/dist/cli/chunks/{chunk-QU54GUEA.js → chunk-YI6GNRQM.js} +2 -2
- package/dist/cli/chunks/chunk-YNNOY3XN.js +62 -0
- package/dist/cli/chunks/{chunk-GXCD7GNH.js → chunk-YWZHMXTO.js} +2 -2
- package/dist/cli/chunks/{chunk-XFMSHTXG.js → chunk-ZDHMZPSL.js} +1 -1
- package/dist/cli/chunks/{chunk-F363JJUI.js → chunk-ZGNZJJFF.js} +1 -1
- package/dist/cli/chunks/{chunk-UCXQQCIP.js → chunk-ZK2BH23O.js} +2 -2
- package/dist/cli/chunks/{chunk-IQNR662U.js → chunk-ZQUXNG5X.js} +2 -2
- package/dist/cli/chunks/{chunk-IBXNBLGM.js → chunk-ZXTO4C7R.js} +2 -2
- package/dist/cli/chunks/{ci-7TR4NQ5I.js → ci-PYCRCL7G.js} +2 -2
- package/dist/cli/chunks/{ci-output-SLTICF3O.js → ci-output-EKQQFE2D.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-7GVVTMBY.js → circuit-breaker-RH3Q2MJO.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-TYCWYEMM.js → claude-flow-setup-DUDXB4VV.js} +2 -2
- package/dist/cli/chunks/client-RDPWGOSA.js +2 -0
- package/dist/cli/chunks/{cline-installer-ESIAJOLK.js → cline-installer-3Q4WIWUG.js} +2 -2
- package/dist/cli/chunks/{code-I42JGOVI.js → code-E4Q6DGOO.js} +2 -2
- package/dist/cli/chunks/{code-index-extractor-2CCXPCQW.js → code-index-extractor-2PCISUOW.js} +2 -2
- package/dist/cli/chunks/{codex-installer-HEZRDNUT.js → codex-installer-YNNNOLJ6.js} +2 -2
- package/dist/cli/chunks/{completions-44HLIZGI.js → completions-2F7TUFBD.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-SOCSFDVO.js → complexity-analyzer-2B6MHO7W.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-Q7O4HLIM.js → continuedev-installer-ENOKRU5M.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-GIWCVLCS.js → copilot-installer-6YD2KM5F.js} +2 -2
- package/dist/cli/chunks/{cost-tracker-G7BONKEV.js → cost-tracker-FCH4QOEA.js} +2 -2
- package/dist/cli/chunks/{coverage-5TWVP7KY.js → coverage-JTOXZE3T.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-4K5ZVZEZ.js +2 -0
- package/dist/cli/chunks/{cursor-installer-43EQZSB5.js → cursor-installer-QZFBUGLQ.js} +2 -2
- package/dist/cli/chunks/{daemon-ZXHFRDKG.js → daemon-K4QFB5FQ.js} +3 -3
- package/dist/cli/chunks/{daemon-QQZE4BU2.js → daemon-M422U3ZA.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-GOZAVAZQ.js → dag-attention-scheduler-BXAAW33V.js} +2 -2
- package/dist/cli/chunks/{detect-X777GVJ4.js → detect-UGSWIOAD.js} +2 -2
- package/dist/cli/chunks/{dist-node-EZZK46TB.js → dist-node-FN3HX3OK.js} +2 -2
- package/dist/cli/chunks/{domain-handler-ZT32DKYY.js → domain-handler-7PP7VYA7.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-LHQVSLJW.js → domain-transfer-XZM44W7I.js} +2 -2
- package/dist/cli/chunks/dream-RPNWM7VS.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-XFYPPWG7.js → embed-and-insert-pattern-JZVERJ5L.js} +2 -2
- package/dist/cli/chunks/{eval-V4NYJZUZ.js → eval-466NFF2D.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-HXX2W4GL.js → experience-capture-middleware-I7IQCC7V.js} +3 -3
- package/dist/cli/chunks/{fast-paths-RBPWQSFJ.js → fast-paths-34OICNZA.js} +2 -2
- package/dist/cli/chunks/{feature-flags-NX5EXRO3.js → feature-flags-6UBIVTAD.js} +2 -2
- package/dist/cli/chunks/{feature-flags-INJJZBMN.js → feature-flags-X5WBBWSO.js} +2 -2
- package/dist/cli/chunks/{file-discovery-SNFSG6NK.js → file-discovery-NLMDBWXX.js} +2 -2
- package/dist/cli/chunks/{fleet-6SDN4UWE.js → fleet-W7CYCHDI.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-2JDRTDDK.js → gnn-wrapper-K4VTAG5X.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-QLK6E7KA.js → heartbeat-handler-ZGKF2Z6T.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-JBCXMMZO.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-3SC2HZIG.js +2 -0
- package/dist/cli/chunks/hnsw-index-FQORAR6K.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-Q2ZEZQKB.js → hnsw-legacy-bridge-ELDRLKK5.js} +2 -2
- package/dist/cli/chunks/{better-sqlite3-Y6GX6CGB.js → hnswlib-node-ZGSUMHDC.js} +2 -2
- package/dist/cli/chunks/{hooks-D4YENHO2.js → hooks-T4CBINAV.js} +13 -13
- package/dist/cli/chunks/hybrid-router-6CBFDXPR.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-G72U446M.js → hypergraph-engine-UWFW3XP5.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-TRZ5FDRH.js → hypergraph-handler-PK2BI46K.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-SOEFVZWG.js +2 -0
- package/dist/cli/chunks/{init-handler-3ZD4GCT4.js → init-handler-HNG6KJOU.js} +6 -6
- package/dist/cli/chunks/init-wizard-3E4IU5M4.js +2 -0
- package/dist/cli/chunks/kernel-GFZP4G5J.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-AXSIW3XW.js → kilocode-installer-25V7FEJ4.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-JQGIFWBK.js → kiro-installer-7RMTTCQB.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-BKRKBU26.js +2 -0
- package/dist/cli/chunks/{learning-SPO7TGWX.js → learning-XQC2MG2R.js} +3 -3
- package/dist/cli/chunks/llm-router-6KTTONH4.js +36 -0
- package/dist/cli/chunks/llm-router-service-KE4IGZPP.js +2 -0
- package/dist/cli/chunks/{load-XIDDK64U.js → load-BV64P3AL.js} +2 -2
- package/dist/cli/chunks/load-test-VSYJV2AO.js +2 -0
- package/dist/cli/chunks/{mcp-3JXRGXO4.js → mcp-U5ZN77TA.js} +2 -2
- package/dist/cli/chunks/{memory-A66KRS2P.js → memory-WB5BNBK7.js} +5 -5
- package/dist/cli/chunks/memory-backend-B72RGHRF.js +2 -0
- package/dist/cli/chunks/memory-handlers-NWCH7AUO.js +2 -0
- package/dist/cli/chunks/{multi-model-executor-XCDGUVCE.js → multi-model-executor-3X3W3UTY.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-GELXWLF2.js → opencode-installer-TTTMG7ZZ.js} +2 -2
- package/dist/cli/chunks/{orchestrator-CCS3K6NH.js → orchestrator-BLCGSHMZ.js} +18 -18
- package/dist/cli/chunks/{pipeline-Z5C72H5S.js → pipeline-DZPGMRG7.js} +2 -2
- package/dist/cli/chunks/{platform-4AK7XJ3Y.js → platform-EVMZAUNV.js} +2 -2
- package/dist/cli/chunks/{plugin-7RYBIZI7.js → plugin-OR55K4HT.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-E5PARKRX.js → prime-radiant-advanced-wasm-4ODV27HD.js} +2 -2
- package/dist/cli/chunks/protocol-executor-V3F37FPO.js +2 -0
- package/dist/cli/chunks/{protocol-handler-R6QJQFNL.js → protocol-handler-ZOTI5PID.js} +2 -2
- package/dist/cli/chunks/{prove-7ESQ2YAL.js → prove-DIMBYJ7V.js} +2 -2
- package/dist/cli/chunks/provider-manager-2PN72TT6.js +2 -0
- package/dist/cli/chunks/qe-reasoning-bank-P665QNIR.js +2 -0
- package/dist/cli/chunks/{quality-4UE345QA.js → quality-7MX4VL6M.js} +2 -2
- package/dist/cli/chunks/queen-coordinator-XD4F7BGB.js +2 -0
- package/dist/cli/chunks/{real-embeddings-TYIVN3N5.js → real-embeddings-YPUHWRN2.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-2KOANC47.js → roocode-installer-WG5AU4QM.js} +2 -2
- package/dist/cli/chunks/router-4SSNWDJC.js +2 -0
- package/dist/cli/chunks/routing-feedback-O2JSIBW6.js +2 -0
- package/dist/cli/chunks/{routing-handler-JFEYTN7T.js → routing-handler-LZB4MN2K.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-KSLSZRJX.js → ruvector-commands-YE4ADBMC.js} +2 -2
- package/dist/cli/chunks/{rvf-dual-writer-EPBL226J.js → rvf-dual-writer-QS5ATW4C.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-adapter-25KSI6SF.js → rvf-migration-adapter-YIGKSBD3.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-coordinator-2XBYHPZP.js → rvf-migration-coordinator-2NDCWP7F.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-WIUHYXRB.js +2 -0
- package/dist/cli/chunks/safe-db-WL5Y7ZNS.js +2 -0
- package/dist/cli/chunks/schedule-U7QDGU5A.js +2 -0
- package/dist/cli/chunks/scheduler-LXKGQYXA.js +2 -0
- package/dist/cli/chunks/{security-4XWYKI4O.js → security-HT4SUT24.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-WRZ3HGDQ.js → shared-rvf-adapter-4IZOJL33.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-DX2N5STR.js → shared-rvf-dual-writer-ZKFO7CBY.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-4KFO3SEB.js +2 -0
- package/dist/cli/chunks/{status-handler-V75OSXMQ.js → status-handler-AMEMKBI4.js} +2 -2
- package/dist/cli/chunks/{structural-health-TLX3JHZ6.js → structural-health-RBADRLC3.js} +2 -2
- package/dist/cli/chunks/{sync-KGBEXUF7.js → sync-ARDDLQBS.js} +2 -2
- package/dist/cli/chunks/{sync-DXZFMVZQ.js → sync-PCB23M4K.js} +2 -2
- package/dist/cli/chunks/{task-handler-T3OJ6R7H.js → task-handler-J26FSCH5.js} +2 -2
- package/dist/cli/chunks/{task-handlers-NJYR54AS.js → task-handlers-AQRLR6BL.js} +3 -3
- package/dist/cli/chunks/{test-KMVDNNQA.js → test-YXWSIOSB.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-R5EQ2XGV.js → test-scheduling-XY532GI4.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-PFKVV3RO.js → token-bootstrap-KL2QIQ36.js} +2 -2
- package/dist/cli/chunks/{token-usage-ZLOGA6LR.js → token-usage-2MJVE4DT.js} +2 -2
- package/dist/cli/chunks/{transformers-TNPSPQI3.js → transformers-QSNTOD2Z.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-A2EEB5BF.js → tree-sitter-wasm-parser-QJOKHOIW.js} +2 -2
- package/dist/cli/chunks/{types-DIXPI4NR.js → types-RNKRSYMO.js} +2 -2
- package/dist/cli/chunks/unified-memory-7AS4LIEF.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-GREESNJX.js +2 -0
- package/dist/cli/chunks/unified-persistence-BPJOMZOA.js +2 -0
- package/dist/cli/chunks/{upgrade-LX5KP6VO.js → upgrade-EKJHIFWP.js} +2 -2
- package/dist/cli/chunks/{validate-3L6F7M36.js → validate-KS4T7LWC.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-FD42ZKAQ.js → validate-swarm-SKKWRP2H.js} +2 -2
- package/dist/cli/chunks/{vibium-GSBSJR53.js → vibium-FLUQO4IF.js} +2 -2
- package/dist/cli/chunks/visual-security-BW662FHQ.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-TXHMO4BW.js → web-tree-sitter-UMC63DWD.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-3EUZ6RD3.js → windsurf-installer-V3FQGJIQ.js} +2 -2
- package/dist/cli/chunks/{witness-chain-ONAUEJ4M.js → witness-chain-GE74TLSO.js} +2 -2
- package/dist/cli/chunks/witness-chain-OXVDLNVT.js +2 -0
- package/dist/cli/chunks/{workflow-E7A6BV4C.js → workflow-4YZ2RPWA.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-KKNR46XV.js +2 -0
- package/dist/cli/chunks/{wrappers-AHHAQJM3.js → wrappers-37NLMKPE.js} +2 -2
- package/dist/cli/commands/hooks-handlers/command-hooks.js +1 -1
- package/dist/cli/commands/hooks-handlers/routing-hooks.js +1 -1
- package/dist/cli/commands/hooks-handlers/task-hooks.js +1 -1
- package/dist/cli/commands/llm-router.js +83 -26
- package/dist/domains/chaos-resilience/coordinator.d.ts +2 -1
- package/dist/domains/chaos-resilience/coordinator.js +3 -2
- package/dist/domains/chaos-resilience/plugin.d.ts +4 -2
- package/dist/domains/chaos-resilience/plugin.js +8 -5
- package/dist/domains/code-intelligence/coordinator.d.ts +2 -1
- package/dist/domains/code-intelligence/coordinator.js +3 -2
- package/dist/domains/code-intelligence/plugin.d.ts +4 -2
- package/dist/domains/code-intelligence/plugin.js +8 -5
- package/dist/domains/contract-testing/coordinator.d.ts +2 -1
- package/dist/domains/contract-testing/coordinator.js +3 -2
- package/dist/domains/contract-testing/plugin.d.ts +4 -2
- package/dist/domains/contract-testing/plugin.js +8 -5
- package/dist/domains/coverage-analysis/coordinator.d.ts +2 -1
- package/dist/domains/coverage-analysis/coordinator.js +4 -3
- package/dist/domains/coverage-analysis/plugin.d.ts +3 -2
- package/dist/domains/coverage-analysis/plugin.js +4 -4
- package/dist/domains/defect-intelligence/coordinator.d.ts +2 -1
- package/dist/domains/defect-intelligence/coordinator.js +4 -3
- package/dist/domains/defect-intelligence/plugin.d.ts +4 -2
- package/dist/domains/defect-intelligence/plugin.js +9 -6
- package/dist/domains/learning-optimization/coordinator.d.ts +2 -1
- package/dist/domains/learning-optimization/coordinator.js +3 -2
- package/dist/domains/learning-optimization/plugin.d.ts +4 -2
- package/dist/domains/learning-optimization/plugin.js +8 -5
- package/dist/domains/quality-assessment/coordinator.d.ts +2 -1
- package/dist/domains/quality-assessment/coordinator.js +4 -3
- package/dist/domains/quality-assessment/plugin.d.ts +4 -2
- package/dist/domains/quality-assessment/plugin.js +10 -6
- package/dist/domains/requirements-validation/coordinator.d.ts +2 -1
- package/dist/domains/requirements-validation/coordinator.js +3 -2
- package/dist/domains/requirements-validation/plugin.d.ts +4 -2
- package/dist/domains/requirements-validation/plugin.js +8 -5
- package/dist/domains/security-compliance/coordinator.d.ts +2 -1
- package/dist/domains/security-compliance/coordinator.js +4 -2
- package/dist/domains/security-compliance/plugin.d.ts +4 -2
- package/dist/domains/security-compliance/plugin.js +11 -6
- package/dist/domains/test-execution/coordinator.d.ts +3 -2
- package/dist/domains/test-execution/coordinator.js +6 -5
- package/dist/domains/test-execution/plugin.d.ts +4 -2
- package/dist/domains/test-execution/plugin.js +6 -4
- package/dist/domains/test-generation/coordinator.d.ts +2 -1
- package/dist/domains/test-generation/coordinator.js +4 -3
- package/dist/domains/test-generation/plugin.d.ts +4 -2
- package/dist/domains/test-generation/plugin.js +12 -7
- package/dist/domains/visual-accessibility/coordinator.d.ts +2 -1
- package/dist/domains/visual-accessibility/coordinator.js +4 -3
- package/dist/domains/visual-accessibility/plugin.d.ts +4 -2
- package/dist/domains/visual-accessibility/plugin.js +9 -6
- package/dist/init/init-wizard-hooks.js +271 -271
- package/dist/init/phases/07-hooks.d.ts +7 -0
- package/dist/init/phases/07-hooks.js +132 -96
- package/dist/kernel/interfaces.d.ts +37 -0
- package/dist/kernel/kernel.d.ts +39 -0
- package/dist/kernel/kernel.js +157 -17
- package/dist/learning/agent-routing.d.ts +19 -0
- package/dist/learning/agent-routing.js +27 -1
- package/dist/learning/dream/dream-scheduler.d.ts +11 -36
- package/dist/learning/dream/dream-scheduler.js +44 -0
- package/dist/learning/experience-consolidation.d.ts +16 -0
- package/dist/learning/experience-consolidation.js +55 -11
- package/dist/learning/pattern-lifecycle.d.ts +21 -0
- package/dist/learning/pattern-lifecycle.js +70 -6
- package/dist/mcp/bundle.js +426 -401
- package/dist/mcp/protocol-server.js +13 -14
- package/dist/mcp/qe-tool-bridge.js +8 -1
- package/dist/mcp/tools/base.d.ts +56 -0
- package/dist/mcp/tools/base.js +104 -1
- package/dist/mcp/tools/chaos-resilience/inject.js +4 -2
- package/dist/mcp/tools/code-intelligence/analyze.js +5 -3
- package/dist/mcp/tools/contract-testing/validate.js +4 -2
- package/dist/mcp/tools/coverage-analysis/index.js +11 -5
- package/dist/mcp/tools/defect-intelligence/predict.js +5 -10
- package/dist/mcp/tools/learning-optimization/optimize.js +4 -2
- package/dist/mcp/tools/registry.js +8 -1
- package/dist/mcp/tools/test-generation/generate.js +10 -6
- package/dist/mcp/tools/visual-accessibility/index.js +7 -4
- package/dist/mcp/transport/stdio.d.ts +20 -0
- package/dist/mcp/transport/stdio.js +35 -2
- package/dist/shared/llm/llm-router-service.d.ts +77 -0
- package/dist/shared/llm/llm-router-service.js +166 -0
- package/dist/shared/llm/providers/gemini.js +5 -2
- package/dist/shared/llm/router/config-store.d.ts +89 -0
- package/dist/shared/llm/router/config-store.js +261 -0
- package/dist/shared/llm/router/hybrid-router.js +33 -11
- package/dist/shared/utils/rabitq.d.ts +133 -0
- package/dist/shared/utils/rabitq.js +201 -0
- package/package.json +8 -2
- package/dist/cli/chunks/adapter-WTE6UVGP.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-LCLEBU7D.js +0 -2
- package/dist/cli/chunks/base-73I73HBF.js +0 -2
- package/dist/cli/chunks/browser-workflow-2NSV5O6W.js +0 -2
- package/dist/cli/chunks/chunk-6MONUYQ5.js +0 -2
- package/dist/cli/chunks/chunk-QL3U5VSM.js +0 -62
- package/dist/cli/chunks/chunk-VMJXNTJT.js +0 -95
- package/dist/cli/chunks/chunk-X73CRYF4.js +0 -2
- package/dist/cli/chunks/client-7GB4WWUD.js +0 -2
- package/dist/cli/chunks/cross-domain-router-7HQ74TLE.js +0 -2
- package/dist/cli/chunks/dream-G5SEFHI4.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-NG7BY3FR.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-TDSLUI7K.js +0 -2
- package/dist/cli/chunks/hnsw-index-OWLQSOQH.js +0 -2
- package/dist/cli/chunks/hybrid-router-URU2XLBD.js +0 -2
- package/dist/cli/chunks/impact-analyzer-NMTN75KA.js +0 -2
- package/dist/cli/chunks/init-wizard-SHBFYGBV.js +0 -2
- package/dist/cli/chunks/kernel-7KVY2JGO.js +0 -2
- package/dist/cli/chunks/knowledge-graph-V4G5J5B7.js +0 -2
- package/dist/cli/chunks/llm-router-G6N2OKDA.js +0 -36
- package/dist/cli/chunks/load-test-N4RNPLG4.js +0 -2
- package/dist/cli/chunks/memory-backend-HPGJ5YDQ.js +0 -2
- package/dist/cli/chunks/memory-handlers-K33YVCVQ.js +0 -2
- package/dist/cli/chunks/protocol-executor-GNVWUJUP.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-DDSBHO6D.js +0 -2
- package/dist/cli/chunks/queen-coordinator-BQJ5O63C.js +0 -2
- package/dist/cli/chunks/router-C2RKWB7J.js +0 -2
- package/dist/cli/chunks/routing-feedback-RHATTSJ6.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-QG4CXHLL.js +0 -2
- package/dist/cli/chunks/safe-db-A4KQ2IDB.js +0 -2
- package/dist/cli/chunks/schedule-O7MLASQT.js +0 -2
- package/dist/cli/chunks/scheduler-HT7RNYQ2.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-4NNKJ6CQ.js +0 -2
- package/dist/cli/chunks/unified-memory-CMNJVHOJ.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-JQLU2KI6.js +0 -2
- package/dist/cli/chunks/unified-persistence-I25TEDIU.js +0 -2
- package/dist/cli/chunks/visual-security-AJJIEV5V.js +0 -2
- package/dist/cli/chunks/witness-chain-762QQBTN.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-ZGPYISKY.js +0 -2
package/dist/kernel/kernel.js
CHANGED
|
@@ -21,6 +21,7 @@ import { PluginCache } from '../plugins/cache';
|
|
|
21
21
|
import { CapturedExperienceBridge } from '../bridge/captured-experience-bridge.js';
|
|
22
22
|
import { DreamScheduler } from '../learning/dream/dream-scheduler.js';
|
|
23
23
|
import { createDreamEngine } from '../learning/dream/dream-engine.js';
|
|
24
|
+
import { createLLMRouterService, } from '../shared/llm/llm-router-service.js';
|
|
24
25
|
// Import domain plugin factories
|
|
25
26
|
import { createTestGenerationPlugin } from '../domains/test-generation/plugin';
|
|
26
27
|
import { createTestExecutionPlugin } from '../domains/test-execution/plugin';
|
|
@@ -44,21 +45,25 @@ import '../domains/security-compliance';
|
|
|
44
45
|
import '../domains/code-intelligence';
|
|
45
46
|
import '../domains/quality-assessment';
|
|
46
47
|
import { createEnterpriseIntegrationPlugin } from '../domains/enterprise-integration/plugin';
|
|
48
|
+
// NOTE: underlying createXxxPlugin signatures are updated in Phase 2.
|
|
49
|
+
// For Phase 1, the wrappers accept llmRouter but discard it — this
|
|
50
|
+
// keeps the kernel boot path internally consistent without forcing
|
|
51
|
+
// 13 simultaneous domain-level changes.
|
|
47
52
|
const DOMAIN_FACTORIES = {
|
|
48
|
-
'test-generation': (eb, m, c) => createTestGenerationPlugin(eb, m, c),
|
|
49
|
-
'test-execution': (eb, m) => createTestExecutionPlugin(eb, m),
|
|
50
|
-
'coverage-analysis': (eb, m) => createCoverageAnalysisPlugin(eb, m),
|
|
51
|
-
'quality-assessment': (eb, m, c) => createQualityAssessmentPlugin(eb, m, c),
|
|
52
|
-
'defect-intelligence': (eb, m, c) => createDefectIntelligencePlugin(eb, m, c),
|
|
53
|
-
'requirements-validation': (eb, m, c) => createRequirementsValidationPlugin(eb, m, c),
|
|
54
|
-
'code-intelligence': (eb, m, c) => createCodeIntelligencePlugin(eb, m, c),
|
|
55
|
-
'security-compliance': (eb, m, c) => createSecurityCompliancePlugin(eb, m, c),
|
|
56
|
-
'contract-testing': (eb, m, c) => createContractTestingPlugin(eb, m, c),
|
|
57
|
-
'visual-accessibility': (eb, m, c) => createVisualAccessibilityPlugin(eb, m, c),
|
|
58
|
-
'chaos-resilience': (eb, m, c) => createChaosResiliencePlugin(eb, m, c),
|
|
59
|
-
'learning-optimization': (eb, m, c) => createLearningOptimizationPlugin(eb, m, c),
|
|
60
|
-
'enterprise-integration': (eb, m, c) => createEnterpriseIntegrationPlugin(eb, m, c),
|
|
61
|
-
'coordination': (eb, m, c) => createCoordinationPlugin(eb, m, c),
|
|
53
|
+
'test-generation': (eb, m, c, llmRouter) => createTestGenerationPlugin(eb, m, c, undefined, llmRouter),
|
|
54
|
+
'test-execution': (eb, m, _c, llmRouter) => createTestExecutionPlugin(eb, m, llmRouter),
|
|
55
|
+
'coverage-analysis': (eb, m, _c, llmRouter) => createCoverageAnalysisPlugin(eb, m, llmRouter),
|
|
56
|
+
'quality-assessment': (eb, m, c, llmRouter) => createQualityAssessmentPlugin(eb, m, c, undefined, llmRouter),
|
|
57
|
+
'defect-intelligence': (eb, m, c, llmRouter) => createDefectIntelligencePlugin(eb, m, c, undefined, llmRouter),
|
|
58
|
+
'requirements-validation': (eb, m, c, llmRouter) => createRequirementsValidationPlugin(eb, m, c, undefined, llmRouter),
|
|
59
|
+
'code-intelligence': (eb, m, c, llmRouter) => createCodeIntelligencePlugin(eb, m, c, undefined, llmRouter),
|
|
60
|
+
'security-compliance': (eb, m, c, llmRouter) => createSecurityCompliancePlugin(eb, m, c, undefined, llmRouter),
|
|
61
|
+
'contract-testing': (eb, m, c, llmRouter) => createContractTestingPlugin(eb, m, c, undefined, llmRouter),
|
|
62
|
+
'visual-accessibility': (eb, m, c, llmRouter) => createVisualAccessibilityPlugin(eb, m, c, undefined, llmRouter),
|
|
63
|
+
'chaos-resilience': (eb, m, c, llmRouter) => createChaosResiliencePlugin(eb, m, c, undefined, llmRouter),
|
|
64
|
+
'learning-optimization': (eb, m, c, llmRouter) => createLearningOptimizationPlugin(eb, m, c, undefined, llmRouter),
|
|
65
|
+
'enterprise-integration': (eb, m, c, _llmRouter) => createEnterpriseIntegrationPlugin(eb, m, c),
|
|
66
|
+
'coordination': (eb, m, c, _llmRouter) => createCoordinationPlugin(eb, m, c),
|
|
62
67
|
};
|
|
63
68
|
const DEFAULT_CONFIG = {
|
|
64
69
|
maxConcurrentAgents: AGENT_CONSTANTS.MAX_CONCURRENT_AGENTS,
|
|
@@ -93,6 +98,10 @@ export class QEKernelImpl {
|
|
|
93
98
|
// checkAndTriggerDream path so 10-second SQLite write transactions move
|
|
94
99
|
// out of short-lived hook subprocesses into the long-lived kernel.
|
|
95
100
|
_dreamScheduler;
|
|
101
|
+
// ADR-043: kernel singleton HybridRouter. Built during initialize() iff
|
|
102
|
+
// a provider key is in env or the project explicitly enables one.
|
|
103
|
+
_llmRouter;
|
|
104
|
+
_llmRouterBuild;
|
|
96
105
|
constructor(config = {}) {
|
|
97
106
|
this._config = { ...DEFAULT_CONFIG, ...config };
|
|
98
107
|
this._startTime = new Date();
|
|
@@ -118,6 +127,15 @@ export class QEKernelImpl {
|
|
|
118
127
|
get memory() {
|
|
119
128
|
return this._memory;
|
|
120
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* ADR-043: Get the LLM router built during initialize(). Returns
|
|
132
|
+
* undefined when llmRouter.enabled is false or no provider was
|
|
133
|
+
* available. Domain plugins receive this as their factory's 4th arg
|
|
134
|
+
* via DOMAIN_FACTORIES.
|
|
135
|
+
*/
|
|
136
|
+
get llmRouter() {
|
|
137
|
+
return this._llmRouter;
|
|
138
|
+
}
|
|
121
139
|
async initialize() {
|
|
122
140
|
if (this._initialized) {
|
|
123
141
|
return;
|
|
@@ -156,14 +174,20 @@ export class QEKernelImpl {
|
|
|
156
174
|
// Re-create plugins with the real memory backend
|
|
157
175
|
this._plugins = new DefaultPluginLoader(this._eventBus, this._memory, this._config.lazyLoading);
|
|
158
176
|
}
|
|
177
|
+
// ADR-043: Build the kernel-singleton LLM router before plugin
|
|
178
|
+
// factories are registered, so the closure on the next loop can
|
|
179
|
+
// capture it. Builds iff configured/auto-detected; null otherwise.
|
|
180
|
+
await this._initializeLLMRouter(projectRoot);
|
|
159
181
|
// Register domain factories for enabled domains
|
|
160
182
|
for (const domain of this._config.enabledDomains) {
|
|
161
183
|
const factory = DOMAIN_FACTORIES[domain];
|
|
162
184
|
if (factory) {
|
|
163
185
|
// Wrap factory to match PluginLoader signature (async)
|
|
164
186
|
this._plugins.registerFactory(domain, async (eventBus, memory) => {
|
|
165
|
-
// Create plugin synchronously, return as Promise
|
|
166
|
-
|
|
187
|
+
// Create plugin synchronously, return as Promise.
|
|
188
|
+
// ADR-043: pass the kernel singleton llmRouter as 4th arg —
|
|
189
|
+
// domain factories forward it to coordinators/services.
|
|
190
|
+
return Promise.resolve(factory(eventBus, memory, this._coordinator, this._llmRouter));
|
|
167
191
|
});
|
|
168
192
|
}
|
|
169
193
|
}
|
|
@@ -199,7 +223,9 @@ export class QEKernelImpl {
|
|
|
199
223
|
if (typeof createPlugin !== 'function') {
|
|
200
224
|
throw new Error(`Plugin "${manifest.name}" entry point must export a default function or "createPlugin" function`);
|
|
201
225
|
}
|
|
202
|
-
|
|
226
|
+
// ADR-043: forward llmRouter so external plugins can
|
|
227
|
+
// opt into LLM enhancement on the same terms as built-ins.
|
|
228
|
+
return createPlugin(eventBus, memory, this._coordinator, this._llmRouter);
|
|
203
229
|
});
|
|
204
230
|
}
|
|
205
231
|
}
|
|
@@ -310,6 +336,106 @@ export class QEKernelImpl {
|
|
|
310
336
|
}
|
|
311
337
|
this._initialized = true;
|
|
312
338
|
}
|
|
339
|
+
/**
|
|
340
|
+
* ADR-043: Build the kernel-singleton HybridRouter.
|
|
341
|
+
*
|
|
342
|
+
* Behavior is gated, in order:
|
|
343
|
+
* 1. AQE_LLM_ROUTER_DISABLED env var (kill-switch): if set to a truthy
|
|
344
|
+
* value, ALWAYS skip — even when config.llmRouter.enabled === true.
|
|
345
|
+
* This is the env-only opt-out for users who upgrade with a
|
|
346
|
+
* provider key already in env and don't want billing surprises.
|
|
347
|
+
* 2. config.llmRouter.enabled:
|
|
348
|
+
* 'auto' (default): build iff at least one provider key is in env,
|
|
349
|
+
* or the project's llm-config.json enables a provider
|
|
350
|
+
* true: attempt to build; emit error event if no provider
|
|
351
|
+
* false: skip entirely (sets _llmRouter to undefined)
|
|
352
|
+
*
|
|
353
|
+
* On any error we publish a structured kernel.llm-router.init-failed
|
|
354
|
+
* event so monitoring catches misconfiguration. We also keep the
|
|
355
|
+
* console.warn for direct visibility in dev. The kernel still boots —
|
|
356
|
+
* a kernel that boots without LLMs is strictly better than a kernel
|
|
357
|
+
* that won't boot — but the failure is now observable.
|
|
358
|
+
*/
|
|
359
|
+
async _initializeLLMRouter(projectRoot) {
|
|
360
|
+
// (1) Hard env kill-switch. Truthy values disable; falsy/empty pass.
|
|
361
|
+
// Same parse rule as src/mcp/tools/base.ts:isRouterKillSwitchSet
|
|
362
|
+
// so both code paths agree on what "disabled" means.
|
|
363
|
+
const killSwitch = (process.env.AQE_LLM_ROUTER_DISABLED ?? '').trim().toLowerCase();
|
|
364
|
+
if (killSwitch &&
|
|
365
|
+
killSwitch !== 'false' &&
|
|
366
|
+
killSwitch !== '0' &&
|
|
367
|
+
killSwitch !== 'no' &&
|
|
368
|
+
killSwitch !== 'off') {
|
|
369
|
+
this._llmRouter = undefined;
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const llmCfg = this._config.llmRouter ?? {};
|
|
373
|
+
const enabled = llmCfg.enabled ?? 'auto';
|
|
374
|
+
if (enabled === false) {
|
|
375
|
+
this._llmRouter = undefined;
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
try {
|
|
379
|
+
const built = await createLLMRouterService({
|
|
380
|
+
projectRoot,
|
|
381
|
+
override: llmCfg.configOverride,
|
|
382
|
+
providerManager: llmCfg.providerManager,
|
|
383
|
+
});
|
|
384
|
+
if (!built) {
|
|
385
|
+
if (enabled === true) {
|
|
386
|
+
console.warn('[QEKernel] llmRouter.enabled=true but no provider available — ' +
|
|
387
|
+
'continuing without LLM router (domain services will skip LLM enhancement)');
|
|
388
|
+
await this._publishLLMRouterEvent('init-no-provider', {
|
|
389
|
+
reason: 'no provider available in env or disk config',
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
this._llmRouter = undefined;
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
this._llmRouterBuild = built;
|
|
396
|
+
this._llmRouter = built.router;
|
|
397
|
+
// Phase 5 wiring: register as shared singleton so MCP standalone
|
|
398
|
+
// tools see the same router instance (one cost tracker, one cache,
|
|
399
|
+
// one metric collector, one circuit breaker per provider).
|
|
400
|
+
try {
|
|
401
|
+
const { setSharedLLMRouter } = await import('../mcp/tools/base.js');
|
|
402
|
+
setSharedLLMRouter(built.router);
|
|
403
|
+
}
|
|
404
|
+
catch {
|
|
405
|
+
// MCP module not loaded — fine in CLI-only contexts.
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
catch (err) {
|
|
409
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
410
|
+
console.warn('[QEKernel] LLM router init failed; continuing without LLM enhancement:', msg);
|
|
411
|
+
await this._publishLLMRouterEvent('init-failed', {
|
|
412
|
+
error: msg,
|
|
413
|
+
stack: err instanceof Error ? err.stack : undefined,
|
|
414
|
+
});
|
|
415
|
+
this._llmRouter = undefined;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* ADR-043: emit a structured event on the kernel event bus when the
|
|
420
|
+
* LLM router can't be built. Observability hook for monitoring and
|
|
421
|
+
* alerting — a silent warn is not enough for production systems where
|
|
422
|
+
* "tests run without LLM analysis" is a quality regression worth
|
|
423
|
+
* paging on.
|
|
424
|
+
*/
|
|
425
|
+
async _publishLLMRouterEvent(type, payload) {
|
|
426
|
+
try {
|
|
427
|
+
await this._eventBus.publish({
|
|
428
|
+
id: randomUUID(),
|
|
429
|
+
type: `kernel.llm-router.${type}`,
|
|
430
|
+
timestamp: new Date(),
|
|
431
|
+
source: 'qe-kernel',
|
|
432
|
+
payload,
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
catch {
|
|
436
|
+
// Event bus publish failures during boot must not crash the kernel.
|
|
437
|
+
}
|
|
438
|
+
}
|
|
313
439
|
async dispose() {
|
|
314
440
|
// ADR-094: Stop the dream scheduler first so a dream-in-progress doesn't
|
|
315
441
|
// try to write to a disposed memory backend.
|
|
@@ -332,6 +458,20 @@ export class QEKernelImpl {
|
|
|
332
458
|
await this._coordinator.dispose();
|
|
333
459
|
await this._eventBus.dispose();
|
|
334
460
|
await this._memory.dispose();
|
|
461
|
+
// ADR-043: clear the shared LLM router singleton if we registered
|
|
462
|
+
// one. Prevents test isolation problems where a stale router from
|
|
463
|
+
// a previous kernel boot leaks into the next.
|
|
464
|
+
if (this._llmRouter) {
|
|
465
|
+
try {
|
|
466
|
+
const { resetSharedLLMRouter } = await import('../mcp/tools/base.js');
|
|
467
|
+
resetSharedLLMRouter();
|
|
468
|
+
}
|
|
469
|
+
catch {
|
|
470
|
+
// MCP module not loaded — fine.
|
|
471
|
+
}
|
|
472
|
+
this._llmRouter = undefined;
|
|
473
|
+
this._llmRouterBuild = undefined;
|
|
474
|
+
}
|
|
335
475
|
this._initialized = false;
|
|
336
476
|
}
|
|
337
477
|
getDomainAPI(domain) {
|
|
@@ -78,6 +78,25 @@ export declare const MAX_Q_WEIGHT = 0.4;
|
|
|
78
78
|
* decision. Adjust downward if cold-start latency proves problematic.
|
|
79
79
|
*/
|
|
80
80
|
export declare const QWEIGHT_RAMP_VISITS = 20;
|
|
81
|
+
/**
|
|
82
|
+
* De-dilution cap for the domain-match denominator (#510 item 2).
|
|
83
|
+
*
|
|
84
|
+
* Domain score is `(domainMatch / denom) * 0.4`. The original `denom` was the
|
|
85
|
+
* full count of *detected* domains, but AQE's domain detector routinely emits
|
|
86
|
+
* 7-12 domains per task, so a perfect single-domain specialist scored
|
|
87
|
+
* `(1/11)*0.4 ≈ 0.04` — relevance washed out by detector breadth, leaving
|
|
88
|
+
* confidence dominated by the fixed performance term (measured easy task
|
|
89
|
+
* 37.3%, hard task 20.5%, with hard tasks mis-routing to high-performance
|
|
90
|
+
* but domain-irrelevant agents).
|
|
91
|
+
*
|
|
92
|
+
* Capping the denominator models the fact that a task has only a few *truly
|
|
93
|
+
* relevant* domains. With cap=3: a precise detector (1-2 domains) is
|
|
94
|
+
* unchanged, while a broad detector no longer dilutes a real match below
|
|
95
|
+
* usefulness. Proportionality across agents is preserved (an agent matching 2
|
|
96
|
+
* relevant domains still beats one matching 1). Tunable; raise toward the old
|
|
97
|
+
* behavior, lower to weight domain relevance more heavily.
|
|
98
|
+
*/
|
|
99
|
+
export declare const DOMAIN_DENOM_CAP = 3;
|
|
81
100
|
/**
|
|
82
101
|
* Q-value lookup callback supplied by the caller (QEReasoningBank.routeTask).
|
|
83
102
|
* Returns undefined when the (stateKey, agentType) pair has no recorded
|
|
@@ -99,6 +99,25 @@ export const MAX_Q_WEIGHT = 0.4;
|
|
|
99
99
|
* decision. Adjust downward if cold-start latency proves problematic.
|
|
100
100
|
*/
|
|
101
101
|
export const QWEIGHT_RAMP_VISITS = 20;
|
|
102
|
+
/**
|
|
103
|
+
* De-dilution cap for the domain-match denominator (#510 item 2).
|
|
104
|
+
*
|
|
105
|
+
* Domain score is `(domainMatch / denom) * 0.4`. The original `denom` was the
|
|
106
|
+
* full count of *detected* domains, but AQE's domain detector routinely emits
|
|
107
|
+
* 7-12 domains per task, so a perfect single-domain specialist scored
|
|
108
|
+
* `(1/11)*0.4 ≈ 0.04` — relevance washed out by detector breadth, leaving
|
|
109
|
+
* confidence dominated by the fixed performance term (measured easy task
|
|
110
|
+
* 37.3%, hard task 20.5%, with hard tasks mis-routing to high-performance
|
|
111
|
+
* but domain-irrelevant agents).
|
|
112
|
+
*
|
|
113
|
+
* Capping the denominator models the fact that a task has only a few *truly
|
|
114
|
+
* relevant* domains. With cap=3: a precise detector (1-2 domains) is
|
|
115
|
+
* unchanged, while a broad detector no longer dilutes a real match below
|
|
116
|
+
* usefulness. Proportionality across agents is preserved (an agent matching 2
|
|
117
|
+
* relevant domains still beats one matching 1). Tunable; raise toward the old
|
|
118
|
+
* behavior, lower to weight domain relevance more heavily.
|
|
119
|
+
*/
|
|
120
|
+
export const DOMAIN_DENOM_CAP = 3;
|
|
102
121
|
/**
|
|
103
122
|
* Sigmoid mapping R → (0, 1) for Q-value normalization before blending.
|
|
104
123
|
* A fresh row with q_value = 0 contributes 0.5 (neutral); negative q_values
|
|
@@ -265,7 +284,14 @@ qValueLookup) {
|
|
|
265
284
|
const reasoning = [];
|
|
266
285
|
// Domain match (0-0.4)
|
|
267
286
|
const domainMatch = detectedDomains.filter((d) => profile.domains.includes(d)).length;
|
|
268
|
-
|
|
287
|
+
// De-dilute by capping the denominator (#510 item 2): dividing by the full
|
|
288
|
+
// count of *detected* domains (7-12) washed out real matches. Cap models
|
|
289
|
+
// the few truly-relevant domains a task actually has. Math.min(...,1)
|
|
290
|
+
// guards the case where domainMatch exceeds the cap.
|
|
291
|
+
const domainDenom = Math.min(detectedDomains.length, DOMAIN_DENOM_CAP);
|
|
292
|
+
const domainScore = domainMatch > 0
|
|
293
|
+
? Math.min(domainMatch / domainDenom, 1) * 0.4
|
|
294
|
+
: 0;
|
|
269
295
|
score += domainScore * routingWeights.similarity;
|
|
270
296
|
if (domainScore > 0) {
|
|
271
297
|
reasoning.push(`Domain match: ${(domainScore * 100).toFixed(0)}%`);
|
|
@@ -101,42 +101,6 @@ export interface DreamSchedulerDependencies {
|
|
|
101
101
|
/** Memory backend for persisting scheduler state (optional) */
|
|
102
102
|
memoryBackend?: MemoryBackend;
|
|
103
103
|
}
|
|
104
|
-
/**
|
|
105
|
-
* DreamScheduler manages automatic triggering of dream cycles.
|
|
106
|
-
*
|
|
107
|
-
* It follows the dependency injection pattern - all required dependencies
|
|
108
|
-
* (DreamEngine, EventBus) must be provided via the constructor.
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* ```typescript
|
|
112
|
-
* const scheduler = new DreamScheduler({
|
|
113
|
-
* dreamEngine,
|
|
114
|
-
* eventBus,
|
|
115
|
-
* memoryBackend, // optional
|
|
116
|
-
* });
|
|
117
|
-
*
|
|
118
|
-
* await scheduler.initialize();
|
|
119
|
-
* scheduler.start();
|
|
120
|
-
*
|
|
121
|
-
* // Record experiences as they happen
|
|
122
|
-
* scheduler.recordExperience({
|
|
123
|
-
* id: 'exp-1',
|
|
124
|
-
* agentType: 'tester',
|
|
125
|
-
* domain: 'test-execution',
|
|
126
|
-
* taskType: 'run-tests',
|
|
127
|
-
* success: true,
|
|
128
|
-
* duration: 5000,
|
|
129
|
-
* timestamp: new Date(),
|
|
130
|
-
* });
|
|
131
|
-
*
|
|
132
|
-
* // Manually trigger a dream
|
|
133
|
-
* const result = await scheduler.triggerDream();
|
|
134
|
-
*
|
|
135
|
-
* // Stop and cleanup
|
|
136
|
-
* scheduler.stop();
|
|
137
|
-
* await scheduler.dispose();
|
|
138
|
-
* ```
|
|
139
|
-
*/
|
|
140
104
|
export declare class DreamScheduler {
|
|
141
105
|
private readonly config;
|
|
142
106
|
private readonly dreamEngine;
|
|
@@ -320,6 +284,17 @@ export declare class DreamScheduler {
|
|
|
320
284
|
* Publish a dream completed event.
|
|
321
285
|
*/
|
|
322
286
|
private publishDreamCompletedEvent;
|
|
287
|
+
/**
|
|
288
|
+
* #509: Reconcile the SessionStart-read `dream-scheduler:hook-state` row after
|
|
289
|
+
* a successful dream cycle. The post-task hook only ever INCREMENTS that row's
|
|
290
|
+
* experienceCount; this kernel scheduler is the entity that actually dreams
|
|
291
|
+
* (ADR-094) but historically never wrote it back, so the SessionStart readout
|
|
292
|
+
* showed lastDreamTime:null and a pendingExperiences counter that only grew.
|
|
293
|
+
* We stamp { lastDreamTime: now, experienceCount: 0, totalDreamsThisSession++ }
|
|
294
|
+
* using the SAME key + DEFAULT namespace the hook path uses. Best-effort: a
|
|
295
|
+
* failure here must never break a dream cycle.
|
|
296
|
+
*/
|
|
297
|
+
private reconcileHookState;
|
|
323
298
|
/**
|
|
324
299
|
* Save scheduler state to memory backend.
|
|
325
300
|
*/
|
|
@@ -81,6 +81,17 @@ export const DEFAULT_DREAM_SCHEDULER_CONFIG = {
|
|
|
81
81
|
* await scheduler.dispose();
|
|
82
82
|
* ```
|
|
83
83
|
*/
|
|
84
|
+
/**
|
|
85
|
+
* kv_store key that the SessionStart hook reads for its dream readout and the
|
|
86
|
+
* post-task hook increments. Mirrors `DREAM_STATE_KEY` in
|
|
87
|
+
* cli/commands/hooks-handlers/hooks-dream-learning.ts — kept as a local literal
|
|
88
|
+
* (not imported) to avoid a learning→cli layering dependency. MUST match that
|
|
89
|
+
* value and use the DEFAULT namespace (the hook path passes no namespace).
|
|
90
|
+
* #509: this scheduler is the entity that actually dreams (ADR-094) but never
|
|
91
|
+
* reset this row, so SessionStart showed lastDreamTime:null + an ever-growing
|
|
92
|
+
* pendingExperiences. reconcileHookState() below stamps the truth per cycle.
|
|
93
|
+
*/
|
|
94
|
+
const DREAM_HOOK_STATE_KEY = 'dream-scheduler:hook-state';
|
|
84
95
|
export class DreamScheduler {
|
|
85
96
|
config;
|
|
86
97
|
dreamEngine;
|
|
@@ -351,6 +362,10 @@ export class DreamScheduler {
|
|
|
351
362
|
this.totalDreamsCompleted++;
|
|
352
363
|
// Clear experience buffer after successful dream
|
|
353
364
|
this.clearExperienceBuffer();
|
|
365
|
+
// #509: reconcile the SessionStart-read hook-state row. The post-task hook
|
|
366
|
+
// only increments its experienceCount and nothing on the active dream path
|
|
367
|
+
// reset it, so the readout was perpetually stale. Best-effort.
|
|
368
|
+
await this.reconcileHookState();
|
|
354
369
|
// Auto-apply high-confidence insights if enabled
|
|
355
370
|
if (this.config.autoApplyHighConfidenceInsights) {
|
|
356
371
|
await this.autoApplyInsights(result);
|
|
@@ -698,6 +713,35 @@ export class DreamScheduler {
|
|
|
698
713
|
// ==========================================================================
|
|
699
714
|
// Private: State Persistence
|
|
700
715
|
// ==========================================================================
|
|
716
|
+
/**
|
|
717
|
+
* #509: Reconcile the SessionStart-read `dream-scheduler:hook-state` row after
|
|
718
|
+
* a successful dream cycle. The post-task hook only ever INCREMENTS that row's
|
|
719
|
+
* experienceCount; this kernel scheduler is the entity that actually dreams
|
|
720
|
+
* (ADR-094) but historically never wrote it back, so the SessionStart readout
|
|
721
|
+
* showed lastDreamTime:null and a pendingExperiences counter that only grew.
|
|
722
|
+
* We stamp { lastDreamTime: now, experienceCount: 0, totalDreamsThisSession++ }
|
|
723
|
+
* using the SAME key + DEFAULT namespace the hook path uses. Best-effort: a
|
|
724
|
+
* failure here must never break a dream cycle.
|
|
725
|
+
*/
|
|
726
|
+
async reconcileHookState() {
|
|
727
|
+
if (!this.memoryBackend)
|
|
728
|
+
return;
|
|
729
|
+
try {
|
|
730
|
+
const prev = await this.memoryBackend.get(DREAM_HOOK_STATE_KEY);
|
|
731
|
+
const next = {
|
|
732
|
+
lastDreamTime: (this.lastDreamTime ?? new Date()).toISOString(),
|
|
733
|
+
experienceCount: 0,
|
|
734
|
+
sessionStartTime: prev?.sessionStartTime,
|
|
735
|
+
totalDreamsThisSession: (prev?.totalDreamsThisSession ?? 0) + 1,
|
|
736
|
+
};
|
|
737
|
+
await this.memoryBackend.set(DREAM_HOOK_STATE_KEY, next);
|
|
738
|
+
}
|
|
739
|
+
catch (err) {
|
|
740
|
+
logger.warn('Dream hook-state reconcile failed (non-critical)', {
|
|
741
|
+
error: err instanceof Error ? err.message : String(err),
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
}
|
|
701
745
|
/**
|
|
702
746
|
* Save scheduler state to memory backend.
|
|
703
747
|
*/
|
|
@@ -18,6 +18,12 @@ import type { Database as DatabaseType } from 'better-sqlite3';
|
|
|
18
18
|
export interface ConsolidationResult {
|
|
19
19
|
/** Experiences merged into survivors */
|
|
20
20
|
merged: number;
|
|
21
|
+
/**
|
|
22
|
+
* Experiences suppressed from retrieval because they CONTRADICT a
|
|
23
|
+
* higher-quality near-duplicate (similar context, opposite outcome).
|
|
24
|
+
* Soft-suppressed (consolidated_into = 'contradicted'), not deleted.
|
|
25
|
+
*/
|
|
26
|
+
contradicted: number;
|
|
21
27
|
/** Experiences with quality recalculated */
|
|
22
28
|
qualityUpdated: number;
|
|
23
29
|
/** Experiences soft-archived (Phase 3 valueless + Phase 4 safety valve) */
|
|
@@ -54,6 +60,16 @@ export interface ConsolidationConfig {
|
|
|
54
60
|
archiveQualityThreshold: number;
|
|
55
61
|
/** Quality boost per merged experience */
|
|
56
62
|
mergeQualityBoost: number;
|
|
63
|
+
/**
|
|
64
|
+
* Contradiction detection (#510 item 7). Two experiences with cosine
|
|
65
|
+
* similarity >= this threshold but a quality delta >= contradictionQualityDelta
|
|
66
|
+
* are treated as "same context, opposite outcome" — a conflict, not a
|
|
67
|
+
* duplicate. The lower-quality loser is suppressed from retrieval instead of
|
|
68
|
+
* merged, so it can't poison recall.
|
|
69
|
+
*/
|
|
70
|
+
contradictionSimilarityThreshold: number;
|
|
71
|
+
/** Min quality gap that turns a near-duplicate into a contradiction (0-1). */
|
|
72
|
+
contradictionQualityDelta: number;
|
|
57
73
|
}
|
|
58
74
|
export declare class ExperienceConsolidator {
|
|
59
75
|
private readonly config;
|
|
@@ -25,6 +25,8 @@ const DEFAULT_CONFIG = {
|
|
|
25
25
|
archiveMinAgeDays: 30,
|
|
26
26
|
archiveQualityThreshold: 0.15,
|
|
27
27
|
mergeQualityBoost: 0.02,
|
|
28
|
+
contradictionSimilarityThreshold: 0.85,
|
|
29
|
+
contradictionQualityDelta: 0.4,
|
|
28
30
|
};
|
|
29
31
|
// ============================================================================
|
|
30
32
|
// ExperienceConsolidator
|
|
@@ -59,6 +61,7 @@ export class ExperienceConsolidator {
|
|
|
59
61
|
this.ensureInitialized();
|
|
60
62
|
const totalResult = {
|
|
61
63
|
merged: 0,
|
|
64
|
+
contradicted: 0,
|
|
62
65
|
qualityUpdated: 0,
|
|
63
66
|
archived: 0,
|
|
64
67
|
hardDeleted: 0,
|
|
@@ -73,6 +76,7 @@ export class ExperienceConsolidator {
|
|
|
73
76
|
for (const { domain, cnt } of targetDomains) {
|
|
74
77
|
const result = await this.consolidateDomain(domain, cnt);
|
|
75
78
|
totalResult.merged += result.merged;
|
|
79
|
+
totalResult.contradicted += result.contradicted;
|
|
76
80
|
totalResult.qualityUpdated += result.qualityUpdated;
|
|
77
81
|
totalResult.archived += result.archived;
|
|
78
82
|
totalResult.hardDeleted += result.hardDeleted;
|
|
@@ -81,8 +85,9 @@ export class ExperienceConsolidator {
|
|
|
81
85
|
// Count total active remaining
|
|
82
86
|
const activeCount = this.db.prepare("SELECT COUNT(*) as cnt FROM captured_experiences WHERE consolidated_into IS NULL").get();
|
|
83
87
|
totalResult.activeRemaining = activeCount.cnt;
|
|
84
|
-
if (totalResult.merged > 0 || totalResult.archived > 0) {
|
|
88
|
+
if (totalResult.merged > 0 || totalResult.archived > 0 || totalResult.contradicted > 0) {
|
|
85
89
|
console.log(`[ExperienceConsolidator] Consolidated: ${totalResult.merged} merged, ` +
|
|
90
|
+
`${totalResult.contradicted} contradicted, ` +
|
|
86
91
|
`${totalResult.archived} archived, ${totalResult.activeRemaining} active`);
|
|
87
92
|
}
|
|
88
93
|
return totalResult;
|
|
@@ -94,14 +99,17 @@ export class ExperienceConsolidator {
|
|
|
94
99
|
this.ensureInitialized();
|
|
95
100
|
const result = {
|
|
96
101
|
merged: 0,
|
|
102
|
+
contradicted: 0,
|
|
97
103
|
qualityUpdated: 0,
|
|
98
104
|
archived: 0,
|
|
99
105
|
hardDeleted: 0,
|
|
100
106
|
activeRemaining: 0,
|
|
101
107
|
domainsProcessed: [domain],
|
|
102
108
|
};
|
|
103
|
-
// Phase 1: Cluster & Merge
|
|
104
|
-
|
|
109
|
+
// Phase 1: Cluster & Merge (+ contradiction suppression)
|
|
110
|
+
const clusterResult = await this.clusterAndMerge(domain);
|
|
111
|
+
result.merged = clusterResult.merged;
|
|
112
|
+
result.contradicted = clusterResult.contradicted;
|
|
105
113
|
// Phase 2: Quality Reinforcement
|
|
106
114
|
result.qualityUpdated = this.reinforceQuality(domain);
|
|
107
115
|
// Phase 3: Archive Valueless
|
|
@@ -129,7 +137,7 @@ export class ExperienceConsolidator {
|
|
|
129
137
|
if (flag) {
|
|
130
138
|
console.log(`[ExperienceConsolidator] Domain ${domain} already bootstrapped`);
|
|
131
139
|
return {
|
|
132
|
-
merged: 0, qualityUpdated: 0, archived: 0,
|
|
140
|
+
merged: 0, contradicted: 0, qualityUpdated: 0, archived: 0,
|
|
133
141
|
hardDeleted: 0, activeRemaining: 0, domainsProcessed: [domain],
|
|
134
142
|
};
|
|
135
143
|
}
|
|
@@ -165,7 +173,7 @@ export class ExperienceConsolidator {
|
|
|
165
173
|
ORDER BY quality DESC
|
|
166
174
|
`).all(domain);
|
|
167
175
|
if (candidates.length < 2)
|
|
168
|
-
return 0;
|
|
176
|
+
return { merged: 0, contradicted: 0 };
|
|
169
177
|
// Build a temporary HNSW index for this domain
|
|
170
178
|
const hnswIndex = new HNSWEmbeddingIndex({
|
|
171
179
|
dimension: 384,
|
|
@@ -196,7 +204,9 @@ export class ExperienceConsolidator {
|
|
|
196
204
|
// Track which IDs have been absorbed
|
|
197
205
|
const absorbed = new Set();
|
|
198
206
|
let mergeCount = 0;
|
|
207
|
+
let contradictionCount = 0;
|
|
199
208
|
const markConsolidated = this.db.prepare("UPDATE captured_experiences SET consolidated_into = ? WHERE id = ?");
|
|
209
|
+
const markContradicted = this.db.prepare("UPDATE captured_experiences SET consolidated_into = 'contradicted' WHERE id = ?");
|
|
200
210
|
const boostSurvivor = this.db.prepare(`
|
|
201
211
|
UPDATE captured_experiences
|
|
202
212
|
SET consolidation_count = consolidation_count + ?,
|
|
@@ -210,7 +220,7 @@ export class ExperienceConsolidator {
|
|
|
210
220
|
`);
|
|
211
221
|
// Iterate experiences by quality DESC
|
|
212
222
|
for (const row of candidates) {
|
|
213
|
-
if (mergeCount >= this.config.maxMergesPerRun)
|
|
223
|
+
if (mergeCount + contradictionCount >= this.config.maxMergesPerRun)
|
|
214
224
|
break;
|
|
215
225
|
if (absorbed.has(row.id))
|
|
216
226
|
continue;
|
|
@@ -232,21 +242,42 @@ export class ExperienceConsolidator {
|
|
|
232
242
|
namespace: 'experiences',
|
|
233
243
|
});
|
|
234
244
|
const mergedIds = [];
|
|
245
|
+
const contradictedIds = [];
|
|
235
246
|
for (const { id: hnswId, distance } of neighbors) {
|
|
236
|
-
if (mergeCount >= this.config.maxMergesPerRun)
|
|
247
|
+
if (mergeCount + contradictionCount >= this.config.maxMergesPerRun)
|
|
237
248
|
break;
|
|
238
249
|
const neighborId = idMap.get(hnswId);
|
|
239
250
|
if (!neighborId || neighborId === row.id || absorbed.has(neighborId))
|
|
240
251
|
continue;
|
|
241
252
|
const similarity = 1 - distance;
|
|
242
|
-
|
|
253
|
+
// Gate on the lower of the two thresholds so neither merge nor
|
|
254
|
+
// contradiction detection is starved if they are configured differently.
|
|
255
|
+
if (similarity < Math.min(this.config.mergeSimilarityThreshold, this.config.contradictionSimilarityThreshold))
|
|
243
256
|
continue;
|
|
244
257
|
// Find the neighbor in candidates
|
|
245
258
|
const neighbor = candidates.find(c => c.id === neighborId);
|
|
246
259
|
if (!neighbor)
|
|
247
260
|
continue;
|
|
248
|
-
//
|
|
249
|
-
|
|
261
|
+
// Contradiction (#510 item 7): same context (high similarity) but
|
|
262
|
+
// opposite outcome (large quality delta) => a conflict, not a duplicate.
|
|
263
|
+
// Suppress the lower-quality loser from retrieval even if it was applied
|
|
264
|
+
// (a used-but-low-quality contradictory experience is exactly the
|
|
265
|
+
// recall-poisoning case). Candidates are sorted quality DESC and absorbed
|
|
266
|
+
// ones are skipped, so when a gap exists `neighbor` is the strict loser.
|
|
267
|
+
const qualityDelta = Math.abs(row.quality - neighbor.quality);
|
|
268
|
+
if (similarity >= this.config.contradictionSimilarityThreshold
|
|
269
|
+
&& qualityDelta >= this.config.contradictionQualityDelta) {
|
|
270
|
+
if (neighbor.quality < row.quality) {
|
|
271
|
+
absorbed.add(neighborId);
|
|
272
|
+
contradictedIds.push(neighborId);
|
|
273
|
+
contradictionCount++;
|
|
274
|
+
}
|
|
275
|
+
continue; // never merge a contradictory pair
|
|
276
|
+
}
|
|
277
|
+
// Only merge lower-quality, unused neighbors into the survivor (requires
|
|
278
|
+
// the normal merge similarity threshold).
|
|
279
|
+
if (similarity >= this.config.mergeSimilarityThreshold
|
|
280
|
+
&& neighbor.quality <= row.quality && neighbor.application_count === 0) {
|
|
250
281
|
absorbed.add(neighborId);
|
|
251
282
|
mergedIds.push(neighborId);
|
|
252
283
|
mergeCount++;
|
|
@@ -264,10 +295,23 @@ export class ExperienceConsolidator {
|
|
|
264
295
|
});
|
|
265
296
|
transaction();
|
|
266
297
|
}
|
|
298
|
+
// Apply contradiction suppressions in a transaction. The loser is
|
|
299
|
+
// soft-suppressed (consolidated_into = 'contradicted'), so it is excluded
|
|
300
|
+
// from retrieval (WHERE consolidated_into IS NULL) but not deleted. The
|
|
301
|
+
// survivor is NOT boosted — a contradiction is a conflict, not a duplicate.
|
|
302
|
+
if (contradictedIds.length > 0) {
|
|
303
|
+
const tx = this.db.transaction(() => {
|
|
304
|
+
for (const loserId of contradictedIds) {
|
|
305
|
+
markContradicted.run(loserId);
|
|
306
|
+
}
|
|
307
|
+
logConsolidation.run(uuidv4(), domain, 'contradiction', JSON.stringify(contradictedIds), row.id, JSON.stringify({ count: contradictedIds.length, survivorQuality: row.quality }));
|
|
308
|
+
});
|
|
309
|
+
tx();
|
|
310
|
+
}
|
|
267
311
|
}
|
|
268
312
|
// Clean up HNSW index
|
|
269
313
|
hnswIndex.clearIndex('experiences');
|
|
270
|
-
return mergeCount;
|
|
314
|
+
return { merged: mergeCount, contradicted: contradictionCount };
|
|
271
315
|
}
|
|
272
316
|
// ============================================================================
|
|
273
317
|
// Phase 2: Quality Reinforcement
|
|
@@ -42,6 +42,27 @@ export interface PatternLifecycleConfig {
|
|
|
42
42
|
* Default lifecycle configuration
|
|
43
43
|
*/
|
|
44
44
|
export declare const DEFAULT_LIFECYCLE_CONFIG: PatternLifecycleConfig;
|
|
45
|
+
/** Minimum usage_count before success_rate is trusted as an importance signal. */
|
|
46
|
+
export declare const EWC_MIN_USAGE_FOR_PROTECTION = 5;
|
|
47
|
+
/**
|
|
48
|
+
* Fraction of the base decay rate a fully-important pattern is shielded from.
|
|
49
|
+
* 0.9 => a success_rate=1.0 pattern decays at 10% of the base rate.
|
|
50
|
+
* Low-importance patterns (importance 0) decay EXACTLY as before (no regression).
|
|
51
|
+
*/
|
|
52
|
+
export declare const EWC_DECAY_PROTECTION = 0.9;
|
|
53
|
+
/**
|
|
54
|
+
* Multiplier extending the stale window by importance.
|
|
55
|
+
* effectiveStaleDays = staleDaysThreshold * (1 + importance * EWC_STALE_PROTECTION_BONUS).
|
|
56
|
+
* 2 => a fully-important pattern survives 3x longer unused (e.g. 30d -> 90d)
|
|
57
|
+
* before stale-deprecation; importance-0 patterns are unchanged.
|
|
58
|
+
*/
|
|
59
|
+
export declare const EWC_STALE_PROTECTION_BONUS = 2;
|
|
60
|
+
/**
|
|
61
|
+
* Importance proxy in [0,1] for EWC++ forgetting protection.
|
|
62
|
+
* Returns 0 (no protection) until a pattern has been used enough to trust its
|
|
63
|
+
* success rate, then equals the clamped success rate.
|
|
64
|
+
*/
|
|
65
|
+
export declare function patternImportance(successRate: number, usageCount: number): number;
|
|
45
66
|
/**
|
|
46
67
|
* Experience aggregation for pattern candidate identification
|
|
47
68
|
*/
|