agentic-qe 3.15.6 → 3.15.8
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/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +263 -0
- package/README.md +2 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/cli/bundle.js +8 -6
- package/dist/cli/chunks/adapter-FC4EY447.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-SY7UCLBL.js → agent-booster-wasm-W3V5P7LE.js} +2 -2
- package/dist/cli/chunks/{agent-handler-KAMYBU3S.js → agent-handler-2NQFHAWE.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-2CAW3KUM.js → agent-memory-branch-457ECHHK.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-AUAL6UBL.js +2 -0
- package/dist/cli/chunks/{arena-QCCVIOAH.js → arena-IYBQ3GPY.js} +4 -4
- package/dist/cli/chunks/{arena-4OFLJ3R2.js → arena-JV3WSEHU.js} +2 -2
- package/dist/cli/chunks/{audit-RBDQJQJB.js → audit-5OS3T3K6.js} +3 -3
- package/dist/cli/chunks/base-2XML4WH7.js +2 -0
- package/dist/cli/chunks/{better-sqlite3-5JRACCDQ.js → better-sqlite3-IQKBFVAO.js} +2 -2
- package/dist/cli/chunks/{brain-handler-W4QIIRT4.js → brain-handler-KA3SGAFM.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-IBNGI572.js → branch-enumerator-QZDU2VOQ.js} +2 -2
- package/dist/cli/chunks/{browser-GMSCVAOI.js → browser-ZL7OLKJQ.js} +2 -2
- package/dist/cli/chunks/browser-workflow-2IFEUAAK.js +2 -0
- package/dist/cli/chunks/{chunk-6HWARQWV.js → chunk-22DOS3PM.js} +2 -2
- package/dist/cli/chunks/{chunk-VCONCVSY.js → chunk-2DPHFCMW.js} +2 -2
- package/dist/cli/chunks/{chunk-ALCIUWFC.js → chunk-2GSAAUW3.js} +1 -1
- package/dist/cli/chunks/{chunk-AX26QJ6T.js → chunk-2JCLACCS.js} +2 -2
- package/dist/cli/chunks/{chunk-7XTANLTN.js → chunk-2QRGIEQV.js} +1 -1
- package/dist/cli/chunks/{chunk-MP3FSUNB.js → chunk-2UN4JOTN.js} +2 -2
- package/dist/cli/chunks/{chunk-CR66HNAE.js → chunk-2ZRNXEVI.js} +1 -1
- package/dist/cli/chunks/{chunk-WKDWRRDT.js → chunk-3LFLO2WK.js} +2 -2
- package/dist/cli/chunks/{chunk-QLYO3H7E.js → chunk-3N627QRU.js} +2 -2
- package/dist/cli/chunks/{chunk-VVF337SV.js → chunk-4C3RYBTT.js} +2 -2
- package/dist/cli/chunks/{chunk-MQCTLTGE.js → chunk-4C7KE2EL.js} +2 -2
- package/dist/cli/chunks/{chunk-AUN4FG7V.js → chunk-4GUVVGJX.js} +1 -1
- package/dist/cli/chunks/{chunk-ZOUEQ6DL.js → chunk-4GYFONJB.js} +1 -1
- package/dist/cli/chunks/{chunk-24ZSGYC6.js → chunk-4I35ARWW.js} +1 -1
- package/dist/cli/chunks/{chunk-6MXAJBEA.js → chunk-4NTLGGXO.js} +1 -1
- package/dist/cli/chunks/{chunk-EF5UHDCG.js → chunk-4TZLZRZ4.js} +1 -1
- package/dist/cli/chunks/{chunk-RD5BYLN7.js → chunk-4YUBWU3E.js} +1 -1
- package/dist/cli/chunks/{chunk-7TVIX4WL.js → chunk-52YRSWPS.js} +2 -2
- package/dist/cli/chunks/{chunk-LAY7NCQK.js → chunk-5DZDLOY6.js} +3 -3
- package/dist/cli/chunks/{chunk-34MDMFET.js → chunk-5MBNRTT5.js} +2 -2
- package/dist/cli/chunks/{chunk-VAYZ5QIE.js → chunk-5ONJ7AV6.js} +1 -1
- package/dist/cli/chunks/{chunk-RV6HSMKJ.js → chunk-5YOO5QSE.js} +1 -1
- package/dist/cli/chunks/{chunk-BUTGIVKW.js → chunk-62T7U25U.js} +1 -1
- package/dist/cli/chunks/{chunk-66NW3ZB4.js → chunk-6CKTLVYV.js} +2 -2
- package/dist/cli/chunks/{chunk-TUDENMAE.js → chunk-6E7EOHMN.js} +2 -2
- package/dist/cli/chunks/{chunk-GVRFSXY6.js → chunk-6GIC2263.js} +2 -2
- package/dist/cli/chunks/{chunk-KIDOBLUO.js → chunk-767SR7WH.js} +2 -2
- package/dist/cli/chunks/{chunk-NBUXM5X6.js → chunk-7C6FMLQR.js} +2 -2
- package/dist/cli/chunks/{chunk-4POOJYXA.js → chunk-7CVMT64N.js} +1 -1
- package/dist/cli/chunks/{chunk-R363XXGH.js → chunk-7DHSHD5B.js} +2 -2
- package/dist/cli/chunks/{chunk-IEPWO4XP.js → chunk-7H3GNRNA.js} +2 -2
- package/dist/cli/chunks/{chunk-DQNUPEY5.js → chunk-7SLEUVPZ.js} +2 -2
- package/dist/cli/chunks/{chunk-YNG7E26C.js → chunk-7XGM7Q2N.js} +2 -2
- package/dist/cli/chunks/{chunk-5MT7DMD7.js → chunk-A2UGPKCS.js} +2 -2
- package/dist/cli/chunks/{chunk-2CIDFR2H.js → chunk-A6GCO6ZU.js} +2 -2
- package/dist/cli/chunks/{chunk-XFPQIWEH.js → chunk-BEVWCF3Q.js} +3 -3
- package/dist/cli/chunks/{chunk-LCCTJ2PC.js → chunk-BLZEOGQE.js} +2 -2
- package/dist/cli/chunks/{chunk-6R3FBFCJ.js → chunk-BQUIZ5QT.js} +2 -2
- package/dist/cli/chunks/{chunk-ZUTFHGEO.js → chunk-BTMEOZYY.js} +1 -1
- package/dist/cli/chunks/{chunk-FU7LNUD7.js → chunk-CDLG3Q2O.js} +2 -2
- package/dist/cli/chunks/{chunk-NYS2GUNO.js → chunk-CQ3SBRDP.js} +2 -2
- package/dist/cli/chunks/chunk-CQ5G64EA.js +3 -0
- package/dist/cli/chunks/{chunk-JCE76MPP.js → chunk-CRUQ6RXU.js} +2 -2
- package/dist/cli/chunks/{chunk-XBFQJZWX.js → chunk-D4IBIMWI.js} +2 -2
- package/dist/cli/chunks/{chunk-LZWJ5BMP.js → chunk-D4O3TJI7.js} +2 -2
- package/dist/cli/chunks/{chunk-AUOSHM63.js → chunk-DAFMHM64.js} +2 -2
- package/dist/cli/chunks/{chunk-V3OLS2NG.js → chunk-DCYUHCPK.js} +2 -2
- package/dist/cli/chunks/{chunk-F7A2UBZO.js → chunk-DKFSCJEF.js} +2 -2
- package/dist/cli/chunks/{chunk-5LST62QR.js → chunk-DN3AKAPY.js} +2 -2
- package/dist/cli/chunks/{chunk-OQ4S6B7P.js → chunk-DY37YMMQ.js} +1 -1
- package/dist/cli/chunks/{chunk-XQ53PZEF.js → chunk-EUVSSIGR.js} +3 -3
- package/dist/cli/chunks/{chunk-6WOZUSSN.js → chunk-FAYXES7R.js} +2 -2
- package/dist/cli/chunks/{chunk-GNYOHZVV.js → chunk-FEN2DHFM.js} +1 -1
- package/dist/cli/chunks/{chunk-BAYGQRNP.js → chunk-FEPFXXI7.js} +2 -2
- package/dist/cli/chunks/{chunk-DLSFT6PO.js → chunk-FJAO4UX2.js} +2 -2
- package/dist/cli/chunks/{chunk-22OZIJAD.js → chunk-FWXNFPLS.js} +2 -2
- package/dist/cli/chunks/{chunk-X33F7NXH.js → chunk-G6CLO74Q.js} +3 -3
- package/dist/cli/chunks/{chunk-HAN4MS5T.js → chunk-G77Q22EN.js} +2 -2
- package/dist/cli/chunks/{chunk-5DH5QI7G.js → chunk-GENNJRNK.js} +3 -3
- package/dist/cli/chunks/{chunk-LMAEMVPA.js → chunk-GGSTLKY5.js} +1 -1
- package/dist/cli/chunks/{chunk-EJ4KZFZN.js → chunk-GSOK4M6V.js} +1 -1
- package/dist/cli/chunks/{chunk-DA7DGDTI.js → chunk-HI6OBDDY.js} +2 -2
- package/dist/cli/chunks/{chunk-XZ46CI35.js → chunk-HNGNRIZZ.js} +2 -2
- package/dist/cli/chunks/{chunk-CLAMMGY3.js → chunk-HXCGV5UJ.js} +2 -2
- package/dist/cli/chunks/{chunk-5UPIL62W.js → chunk-I4U7YCXG.js} +3 -3
- package/dist/cli/chunks/{chunk-RFDFET3O.js → chunk-I77D65X5.js} +2 -2
- package/dist/cli/chunks/{chunk-HEGGV2PT.js → chunk-IJSFZO7P.js} +2 -2
- package/dist/cli/chunks/{chunk-GWM4M5NF.js → chunk-IMSRWNWF.js} +1 -1
- package/dist/cli/chunks/{chunk-B7RHBKHL.js → chunk-J6LL25QJ.js} +2 -2
- package/dist/cli/chunks/{chunk-KYVIOC3C.js → chunk-J7FLNP5L.js} +2 -2
- package/dist/cli/chunks/{chunk-YLNYPQDR.js → chunk-J7RCI25Q.js} +1 -1
- package/dist/cli/chunks/{chunk-72MQCZSM.js → chunk-JFWQFB3S.js} +2 -2
- package/dist/cli/chunks/{chunk-SV5BUYHH.js → chunk-JLTGO5BB.js} +2 -2
- package/dist/cli/chunks/{chunk-CCL436IU.js → chunk-JWPYMRIX.js} +14 -6
- package/dist/cli/chunks/{chunk-ONPPBLRB.js → chunk-K4N2MBCE.js} +2 -2
- package/dist/cli/chunks/{chunk-7SAMMQVS.js → chunk-K5R3WUJP.js} +1 -1
- package/dist/cli/chunks/{chunk-GI5HWS4H.js → chunk-KITKQUBX.js} +1 -1
- package/dist/cli/chunks/{chunk-7TJZDRDU.js → chunk-KJNUETCB.js} +1 -1
- package/dist/cli/chunks/{chunk-JYKQVYX2.js → chunk-KMVFBYJO.js} +2 -2
- package/dist/cli/chunks/{chunk-ZSBD4FUX.js → chunk-KMZW2P3R.js} +2 -2
- package/dist/cli/chunks/{chunk-PEMSXSP2.js → chunk-KNHLOANK.js} +2 -2
- package/dist/cli/chunks/{chunk-47Q7JL3V.js → chunk-KNQUHGNY.js} +2 -2
- package/dist/cli/chunks/{chunk-A7ANPS4E.js → chunk-KVMKYUOE.js} +2 -2
- package/dist/cli/chunks/{chunk-XBEI2JBA.js → chunk-LHRVSK44.js} +2 -2
- package/dist/cli/chunks/{chunk-AJT3XDRD.js → chunk-LPSMVBB3.js} +2 -2
- package/dist/cli/chunks/{chunk-ORBODZSO.js → chunk-LVHZK7GW.js} +2 -2
- package/dist/cli/chunks/{chunk-ZTB32K5N.js → chunk-LZWBUVCK.js} +3 -3
- package/dist/cli/chunks/{chunk-OPDZBRIL.js → chunk-MMY52Y6R.js} +2 -2
- package/dist/cli/chunks/{chunk-MQTA6KIO.js → chunk-MUDBF2JC.js} +1 -1
- package/dist/cli/chunks/{chunk-GFB6BZWU.js → chunk-MV4S3TEC.js} +2 -2
- package/dist/cli/chunks/{chunk-UB6DQGWM.js → chunk-NF63NHJH.js} +2 -2
- package/dist/cli/chunks/{chunk-D5N2O5EH.js → chunk-NHOMVBCI.js} +2 -2
- package/dist/cli/chunks/{chunk-3NJ7O3OH.js → chunk-NLYUC63R.js} +2 -2
- package/dist/cli/chunks/{chunk-4CLDYT36.js → chunk-NQDYOF35.js} +2 -2
- package/dist/cli/chunks/{chunk-ORFL3YXB.js → chunk-NW7HTOSN.js} +2 -2
- package/dist/cli/chunks/{chunk-FQ5N666N.js → chunk-NWFBF3KT.js} +1 -1
- package/dist/cli/chunks/{chunk-P7DXVL2S.js → chunk-NZATJ2C6.js} +2 -2
- package/dist/cli/chunks/{chunk-HOEWMEF2.js → chunk-O4RRVTXN.js} +2 -2
- package/dist/cli/chunks/{chunk-4KOVHQXK.js → chunk-OCLAMZJG.js} +2 -2
- package/dist/cli/chunks/{chunk-TLUIO37P.js → chunk-OJWEZYLR.js} +2 -2
- package/dist/cli/chunks/{chunk-A74J23QB.js → chunk-OWBFVAEH.js} +2 -2
- package/dist/cli/chunks/{chunk-6T6AHVLF.js → chunk-P2EA62YS.js} +1 -1
- package/dist/cli/chunks/{chunk-TL5GV3PR.js → chunk-P4UT4LBE.js} +3 -3
- package/dist/cli/chunks/{chunk-IVJIHZSM.js → chunk-PICEGWGB.js} +1 -1
- package/dist/cli/chunks/{chunk-ITIJ23K2.js → chunk-PIEKGKW6.js} +2 -2
- package/dist/cli/chunks/{chunk-2ZTWPMTK.js → chunk-PJGQ2TKN.js} +2 -2
- package/dist/cli/chunks/{chunk-KCB6P463.js → chunk-PPIM7B5G.js} +2 -2
- package/dist/cli/chunks/{chunk-L2TDHJR3.js → chunk-PUYQ6EKC.js} +2 -2
- package/dist/cli/chunks/{chunk-2IWPJUVV.js → chunk-PWA6XBW4.js} +8 -8
- package/dist/cli/chunks/{chunk-XPB5BVU6.js → chunk-PZ7FJ4UG.js} +2 -2
- package/dist/cli/chunks/{chunk-SOSJWM3E.js → chunk-QFYUZYRA.js} +4 -4
- package/dist/cli/chunks/{chunk-RUTO67PT.js → chunk-R2NHGESM.js} +2 -2
- package/dist/cli/chunks/{chunk-K55EAWZ5.js → chunk-RG42LDOB.js} +2 -2
- package/dist/cli/chunks/{chunk-JAPBSSFY.js → chunk-RSMPJWQH.js} +1 -1
- package/dist/cli/chunks/{chunk-46HBVDMU.js → chunk-SFPGLUXS.js} +1 -1
- package/dist/cli/chunks/{chunk-TVLOED6O.js → chunk-SHEVM5PF.js} +2 -2
- package/dist/cli/chunks/{chunk-6RDVY26I.js → chunk-SJMZZMHP.js} +2 -2
- package/dist/cli/chunks/{chunk-3DJNKNBR.js → chunk-ST7ASEJO.js} +57 -57
- package/dist/cli/chunks/{chunk-QS5KZYUZ.js → chunk-SWY6KGMF.js} +2 -2
- package/dist/cli/chunks/{chunk-UHHMAKPE.js → chunk-T2TDTBFV.js} +1 -1
- package/dist/cli/chunks/{chunk-5HAPS6VD.js → chunk-TC52M542.js} +2 -2
- package/dist/cli/chunks/chunk-TMNEK7TP.js +2 -0
- package/dist/cli/chunks/{chunk-ELI4GDQO.js → chunk-U3BWBP6B.js} +2 -2
- package/dist/cli/chunks/{chunk-CZBIREL5.js → chunk-U7CIY3YR.js} +2 -2
- package/dist/cli/chunks/{chunk-X2DR27AY.js → chunk-UDCYQLTD.js} +2 -2
- package/dist/cli/chunks/{chunk-CEXNW5TR.js → chunk-UKKFZJME.js} +1 -1
- package/dist/cli/chunks/{chunk-5NC7QEJ6.js → chunk-UQLAN5TX.js} +4 -4
- package/dist/cli/chunks/{chunk-BIXRTOH3.js → chunk-UTFMMZ57.js} +3 -3
- package/dist/cli/chunks/{chunk-YXU35GGD.js → chunk-UTNKMPTC.js} +1 -1
- package/dist/cli/chunks/{chunk-HZFK2Z2Z.js → chunk-V4QJ3MMT.js} +1 -1
- package/dist/cli/chunks/{chunk-LJCEDTUM.js → chunk-V7VZSNDK.js} +3 -3
- package/dist/cli/chunks/{chunk-RLB7K7QP.js → chunk-VKFVJCIH.js} +1 -1
- package/dist/cli/chunks/{chunk-5GIJU2ZY.js → chunk-VQRBBR27.js} +2 -2
- package/dist/cli/chunks/{chunk-Q2RBOC7V.js → chunk-VVK4ECVJ.js} +2 -2
- package/dist/cli/chunks/{chunk-624QRKQX.js → chunk-VWRNG3UK.js} +1 -1
- package/dist/cli/chunks/{chunk-F3KS3TAB.js → chunk-VWSGWYRB.js} +2 -2
- package/dist/cli/chunks/{chunk-I7WAW7TM.js → chunk-W5A36V3Z.js} +2 -2
- package/dist/cli/chunks/chunk-WAWKAYPY.js +2 -0
- package/dist/cli/chunks/{chunk-NMY4KTWA.js → chunk-WLXGUQOZ.js} +2 -2
- package/dist/cli/chunks/{chunk-7VTKR44N.js → chunk-X3HM7SV4.js} +2 -2
- package/dist/cli/chunks/chunk-X6VYQVUM.js +2 -0
- package/dist/cli/chunks/{chunk-ZL5LJT7D.js → chunk-X7ZQIFES.js} +2 -2
- package/dist/cli/chunks/{chunk-5VUIXDY2.js → chunk-XOOBLZXR.js} +2 -2
- package/dist/cli/chunks/{chunk-L4D3TPFP.js → chunk-XZQVC3GD.js} +1 -1
- package/dist/cli/chunks/{chunk-BO7UFNYV.js → chunk-Y5ZBF7MA.js} +2 -2
- package/dist/cli/chunks/{chunk-ULCHPPW2.js → chunk-YNQPHRUZ.js} +1 -1
- package/dist/cli/chunks/{chunk-ZCP4P6O2.js → chunk-YRH7KMTU.js} +2 -2
- package/dist/cli/chunks/{chunk-QLKUCMZC.js → chunk-YTYS2XSY.js} +1 -1
- package/dist/cli/chunks/{chunk-JPJEAK4G.js → chunk-YUP3APSN.js} +1 -1
- package/dist/cli/chunks/{chunk-BXATKI5S.js → chunk-YVWMJZ6O.js} +2 -2
- package/dist/cli/chunks/{chunk-PS6WFCA4.js → chunk-Z3LDUPLQ.js} +2 -2
- package/dist/cli/chunks/{chunk-FOJRPEIP.js → chunk-ZBI7PJFX.js} +2 -2
- package/dist/cli/chunks/{chunk-NHRF3V4B.js → chunk-ZG7UKWBB.js} +2 -2
- package/dist/cli/chunks/{chunk-7XUB7U6Z.js → chunk-ZOHS32SI.js} +2 -2
- package/dist/cli/chunks/{chunk-RHIQ6QO5.js → chunk-ZOVAZTXE.js} +430 -430
- package/dist/cli/chunks/{chunk-7QVPMH25.js → chunk-ZWMFKZEQ.js} +2 -2
- package/dist/cli/chunks/{ci-GEJCXMBK.js → ci-7NUCRGWO.js} +2 -2
- package/dist/cli/chunks/{ci-config-2ZVV4OXL.js → ci-config-VQVECCFI.js} +2 -2
- package/dist/cli/chunks/{ci-output-E45OGVPR.js → ci-output-P7GQ6TKF.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-X73ITYZC.js → circuit-breaker-5YP6N6HE.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-W4PPH46C.js → claude-flow-setup-W5H7CMU6.js} +2 -2
- package/dist/cli/chunks/client-RFUSQRUZ.js +2 -0
- package/dist/cli/chunks/{cline-installer-NUEPMWDE.js → cline-installer-OYANSZ54.js} +2 -2
- package/dist/cli/chunks/{code-6WQHBS7G.js → code-OMT4UEZI.js} +3 -3
- package/dist/cli/chunks/{code-index-extractor-BXQIFIFT.js → code-index-extractor-M2JEWKNF.js} +2 -2
- package/dist/cli/chunks/{codex-installer-Z337R2KH.js → codex-installer-YBS6N5O3.js} +2 -2
- package/dist/cli/chunks/{completions-F5DMYFHV.js → completions-U7GS5RG6.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-W2SYPZDI.js → complexity-analyzer-QSXPIUIU.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-ZCHUIFTN.js → continuedev-installer-W5TTT743.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-M5JNODXF.js → copilot-installer-KC2RT24C.js} +2 -2
- package/dist/cli/chunks/core-handlers-ZC7QB432.js +2 -0
- package/dist/cli/chunks/{cost-tracker-LSYTHBHV.js → cost-tracker-OQPVR6V4.js} +2 -2
- package/dist/cli/chunks/{coverage-PGMRS5SS.js → coverage-TCO2A2NX.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-GRBK7YFZ.js +2 -0
- package/dist/cli/chunks/{cursor-installer-XPUA73UW.js → cursor-installer-MH7GWD4L.js} +2 -2
- package/dist/cli/chunks/daemon-JER6HE2J.js +12 -0
- package/dist/cli/chunks/{daemon-ITKDIYMW.js → daemon-UJEARJZ2.js} +3 -3
- package/dist/cli/chunks/{dag-attention-scheduler-T55AXLD6.js → dag-attention-scheduler-F3SUJU5O.js} +2 -2
- package/dist/cli/chunks/{detect-DR7J6K4O.js → detect-5QTCRB32.js} +2 -2
- package/dist/cli/chunks/{dist-node-LAJJBOUT.js → dist-node-XKZPHDBO.js} +2 -2
- package/dist/cli/chunks/{domain-handler-OMSHCRMK.js → domain-handler-V3UEADKW.js} +2 -2
- package/dist/cli/chunks/{domain-plugins-EQXSKC5K.js → domain-plugins-7PES4UHZ.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-FKRAGVSW.js → domain-transfer-NF7UJW7B.js} +2 -2
- package/dist/cli/chunks/dream-VALD726W.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-JZFPCNL3.js → embed-and-insert-pattern-D2HWORHF.js} +2 -2
- package/dist/cli/chunks/{eval-JSNNASBW.js → eval-UF2UBAUC.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-UPD3IZBK.js → experience-capture-middleware-2OUCEHHM.js} +3 -3
- package/dist/cli/chunks/{fast-paths-YNMIBS2E.js → fast-paths-KV5DKKHC.js} +2 -2
- package/dist/cli/chunks/{feature-flags-SRLXDKBI.js → feature-flags-6YWMTNO5.js} +2 -2
- package/dist/cli/chunks/{feature-flags-VIR7O4L7.js → feature-flags-MTW6NMR3.js} +2 -2
- package/dist/cli/chunks/file-discovery-VL73ASNI.js +2 -0
- package/dist/cli/chunks/{fleet-K2ED46EL.js → fleet-GJ66QFXK.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-QCU4ZRYW.js → gnn-wrapper-52V6ANOY.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-YYQI4WZM.js → heartbeat-handler-X7NHNRC7.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-FSX7A3ZA.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-UX2QT6RL.js +2 -0
- package/dist/cli/chunks/hnsw-index-WRDDAMXH.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-C5TJSWTZ.js → hnsw-legacy-bridge-DZBE3KMK.js} +2 -2
- package/dist/cli/chunks/{hnswlib-node-SE3MJJYS.js → hnswlib-node-2AWWUJAZ.js} +2 -2
- package/dist/cli/chunks/{hooks-C572SRDH.js → hooks-XLPVROL3.js} +10 -10
- package/dist/cli/chunks/hybrid-backend-O67NGIB5.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-35A6G3M5.js → hypergraph-engine-6TI7YP6P.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-U2756CWI.js → hypergraph-handler-DBIBBOXS.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-6VXWWYWM.js +2 -0
- package/dist/cli/chunks/init-guard-OSO6MIDD.js +2 -0
- package/dist/cli/chunks/init-handler-7S7IHMUF.js +88 -0
- package/dist/cli/chunks/init-wizard-VH34J4TL.js +2 -0
- package/dist/cli/chunks/kernel-KJD24NO7.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-32PX5YH7.js → kilocode-installer-2KBRFXMA.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-C4ROMMUS.js → kiro-installer-5VFR4OQZ.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-343O2HEZ.js +2 -0
- package/dist/cli/chunks/{learning-GEPVZGJQ.js → learning-G5NHL3DV.js} +20 -20
- package/dist/cli/chunks/{llm-router-XRKTTJTX.js → llm-router-4EAPPMHS.js} +4 -4
- package/dist/cli/chunks/llm-router-service-2M4BT2AO.js +2 -0
- package/dist/cli/chunks/{load-XVH6HW7E.js → load-UYMZPEY6.js} +2 -2
- package/dist/cli/chunks/load-test-OTQ2JQ5F.js +2 -0
- package/dist/cli/chunks/{mcp-IULSTM4Z.js → mcp-NOTDZBW5.js} +2 -2
- package/dist/cli/chunks/{memory-6K7IAU4T.js → memory-QL53YIHP.js} +5 -5
- package/dist/cli/chunks/memory-backend-4QSNRRV6.js +2 -0
- package/dist/cli/chunks/{memory-handlers-CG6DRLAW.js → memory-handlers-YFFYRSM6.js} +2 -2
- package/dist/cli/chunks/{multi-model-executor-VZDUYPLX.js → multi-model-executor-PDDDXF2B.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-QUTXKNH4.js → opencode-installer-75D2SKOT.js} +2 -2
- package/dist/cli/chunks/{orchestrator-PCKKUWOP.js → orchestrator-3WIZBV4T.js} +5 -5
- package/dist/cli/chunks/pattern-null-store-5USH5MNR.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-PX5HQVRL.js → pattern-usage-recorder-TEX2JGHA.js} +2 -2
- package/dist/cli/chunks/{pipeline-O562GTOG.js → pipeline-7ATPA6LU.js} +2 -2
- package/dist/cli/chunks/{platform-PM7Q2AZS.js → platform-WPSKRJE7.js} +2 -2
- package/dist/cli/chunks/{plugin-OTYTFGPY.js → plugin-UUFOVVMU.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-6CFXTHC2.js → prime-radiant-advanced-wasm-PDFSYWKZ.js} +2 -2
- package/dist/cli/chunks/project-root-SRTA6TBL.js +2 -0
- package/dist/cli/chunks/protocol-executor-4WYPCNBS.js +2 -0
- package/dist/cli/chunks/{protocol-handler-PPGNSAOS.js → protocol-handler-3VRYRIQB.js} +2 -2
- package/dist/cli/chunks/{prove-WQ3BKRZG.js → prove-2NAUROGF.js} +2 -2
- package/dist/cli/chunks/qe-reasoning-bank-I4D6SFS4.js +2 -0
- package/dist/cli/chunks/{quality-C5WUU3AA.js → quality-ZIEI2WGA.js} +2 -2
- package/dist/cli/chunks/{quality-gate-WSSRKD5U.js → quality-gate-KWJO4SWQ.js} +3 -3
- package/dist/cli/chunks/queen-coordinator-24UMTZTE.js +2 -0
- package/dist/cli/chunks/{real-embeddings-CFQE7IRQ.js → real-embeddings-TSZ4UIAE.js} +2 -2
- package/dist/cli/chunks/{ref-validation-DHKHXVZT.js → ref-validation-DWFFRETJ.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-3PPODABV.js → roocode-installer-XTZHLUBO.js} +2 -2
- package/dist/cli/chunks/router-AUD4GATI.js +2 -0
- package/dist/cli/chunks/routing-feedback-2FE6SIKQ.js +2 -0
- package/dist/cli/chunks/{routing-handler-JNXTGT6T.js → routing-handler-GG525TDM.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-6YLROPVP.js → ruvector-commands-QKRJDM7Z.js} +2 -2
- package/dist/cli/chunks/rvf-dual-writer-P5LEUF25.js +2 -0
- package/dist/cli/chunks/rvf-migration-adapter-ZCYD5YJS.js +2 -0
- package/dist/cli/chunks/{rvf-migration-coordinator-4DWB4WRK.js → rvf-migration-coordinator-FF52OS6Q.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-QGV6BW2W.js +2 -0
- package/dist/cli/chunks/{rvf-store-integrity-YKR2ZNBF.js → rvf-store-integrity-M6DXTAZ4.js} +2 -2
- package/dist/cli/chunks/safe-db-Q6JUKG2A.js +2 -0
- package/dist/cli/chunks/schedule-44OSMGE5.js +2 -0
- package/dist/cli/chunks/scheduler-V3HO2QQT.js +2 -0
- package/dist/cli/chunks/security-EHXSW22U.js +18 -0
- package/dist/cli/chunks/{shared-rvf-adapter-LNRLFP5I.js → shared-rvf-adapter-6EH7UVJL.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-GWU6YQNS.js → shared-rvf-dual-writer-WML274E7.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-N5T7DWMR.js +2 -0
- package/dist/cli/chunks/{standalone-memory-46KKBSSV.js → standalone-memory-C7QKAXS4.js} +2 -2
- package/dist/cli/chunks/{status-handler-35T5FTDQ.js → status-handler-VLI7MRLM.js} +2 -2
- package/dist/cli/chunks/{structural-health-P7QPQWLO.js → structural-health-3LPG6MQN.js} +2 -2
- package/dist/cli/chunks/{sync-Y43EWBSY.js → sync-4IMMQEPT.js} +2 -2
- package/dist/cli/chunks/{sync-W6Z4R4PL.js → sync-JFJEJBVK.js} +2 -2
- package/dist/cli/chunks/{task-handler-5CX3ZYT7.js → task-handler-IED3K6E4.js} +2 -2
- package/dist/cli/chunks/{task-handlers-DQZGOJNE.js → task-handlers-FH6DNTHW.js} +3 -3
- package/dist/cli/chunks/{test-TPP53VVV.js → test-GPKT3CKZ.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-WBV4UMQH.js → test-scheduling-Z42XXZP6.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-GIIDXHLC.js → token-bootstrap-HMM3AHXM.js} +2 -2
- package/dist/cli/chunks/{token-usage-AKK37RB7.js → token-usage-6Y2ERYIY.js} +2 -2
- package/dist/cli/chunks/{transformers-7MASPELS.js → transformers-MB63T2XO.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-YZKD6UGB.js → tree-sitter-wasm-parser-56GDQCMR.js} +2 -2
- package/dist/cli/chunks/{types-AZ3BTXDP.js → types-J4J6QV3I.js} +2 -2
- package/dist/cli/chunks/unified-memory-RQ3Q4CU3.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-ZOP5FEYX.js +2 -0
- package/dist/cli/chunks/unified-persistence-72OCJJKK.js +2 -0
- package/dist/cli/chunks/{upgrade-L7OTDKEK.js → upgrade-U4XU7LFM.js} +2 -2
- package/dist/cli/chunks/{validate-O3QVFIGP.js → validate-B57HA4YK.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-2UGBGLTX.js → validate-swarm-UPPA4M6T.js} +2 -2
- package/dist/cli/chunks/visual-security-7F5UV23J.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-J75IYPRO.js → web-tree-sitter-GDZMUKOZ.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-FQ5DBFCG.js → windsurf-installer-VJRWCHXP.js} +2 -2
- package/dist/cli/chunks/witness-chain-KZ57QUFE.js +2 -0
- package/dist/cli/chunks/{witness-chain-I7TN4MXZ.js → witness-chain-LFASSMZK.js} +2 -2
- package/dist/cli/chunks/{witness-chain-repair-D3NE3NQK.js → witness-chain-repair-TPHN4DXN.js} +2 -2
- package/dist/cli/chunks/{witness-chain-verifier-RU2WOP5M.js → witness-chain-verifier-Z23FVABW.js} +2 -2
- package/dist/cli/chunks/{witness-key-manager-IHQB2FR5.js → witness-key-manager-745MJ7WO.js} +2 -2
- package/dist/cli/chunks/{workflow-6BWTNVV6.js → workflow-T245QNQM.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-ZNWEUYBN.js +2 -0
- package/dist/cli/chunks/{wrappers-URVP25VU.js → wrappers-WCAYIQUX.js} +2 -2
- package/dist/cli/commands/learning.js +3 -2
- package/dist/cli/commands/security.d.ts +16 -0
- package/dist/cli/commands/security.js +76 -9
- package/dist/cli/handlers/init-guard.d.ts +21 -1
- package/dist/cli/handlers/init-guard.js +51 -8
- package/dist/cli/handlers/init-handler.js +57 -56
- package/dist/cli/index.js +11 -0
- package/dist/cli/utils/ci-output.d.ts +5 -0
- package/dist/cli/utils/ci-output.js +8 -0
- package/dist/coordination/handlers/security-handlers.js +22 -6
- package/dist/coordination/protocols/defect-investigation.js +7 -1
- package/dist/coordination/protocols/learning-consolidation.js +6 -12
- package/dist/coordination/protocols/security-audit.js +11 -0
- package/dist/coordination/result-saver.d.ts +9 -0
- package/dist/coordination/result-saver.js +34 -4
- package/dist/domains/coverage-analysis/collected-metrics.d.ts +2 -0
- package/dist/domains/coverage-analysis/collected-metrics.js +8 -1
- package/dist/domains/defect-intelligence/services/defect-predictor.js +9 -6
- package/dist/domains/learning-optimization/active-patterns.d.ts +55 -0
- package/dist/domains/learning-optimization/active-patterns.js +77 -0
- package/dist/domains/learning-optimization/coordinator.js +12 -9
- package/dist/domains/learning-optimization/services/learning-coordinator.js +15 -17
- package/dist/domains/quality-assessment/interfaces.d.ts +4 -0
- package/dist/domains/quality-assessment/quality-evidence.d.ts +1 -1
- package/dist/domains/quality-assessment/services/quality-analyzer.js +7 -5
- package/dist/domains/quality-assessment/services/quality-gate.js +12 -3
- package/dist/domains/security-compliance/dependency-advisory-engine.d.ts +52 -0
- package/dist/domains/security-compliance/dependency-advisory-engine.js +113 -0
- package/dist/domains/security-compliance/interfaces.d.ts +30 -0
- package/dist/domains/security-compliance/plugin.d.ts +7 -1
- package/dist/domains/security-compliance/plugin.js +19 -0
- package/dist/domains/security-compliance/services/scanners/dependency-resolver.d.ts +71 -0
- package/dist/domains/security-compliance/services/scanners/dependency-resolver.js +232 -0
- package/dist/domains/security-compliance/services/scanners/dependency-scanner.d.ts +21 -6
- package/dist/domains/security-compliance/services/scanners/dependency-scanner.js +142 -64
- package/dist/domains/security-compliance/services/scanners/lockfile-versions.d.ts +43 -0
- package/dist/domains/security-compliance/services/scanners/lockfile-versions.js +248 -0
- package/dist/domains/security-compliance/services/scanners/scanner-types.d.ts +30 -2
- package/dist/domains/security-compliance/services/security-auditor.d.ts +19 -6
- package/dist/domains/security-compliance/services/security-auditor.js +133 -92
- package/dist/domains/test-execution/services/retry-handler.js +34 -7
- package/dist/domains/test-execution/services/test-executor.d.ts +1 -0
- package/dist/domains/test-execution/services/test-executor.js +87 -7
- package/dist/kernel/shared-dirs.js +17 -5
- package/dist/learning/dream/dream-engine.d.ts +27 -1
- package/dist/learning/dream/dream-engine.js +56 -2
- package/dist/learning/dream/rvcow-branch-manager.d.ts +8 -0
- package/dist/learning/dream/rvcow-branch-manager.js +8 -0
- package/dist/learning/dream/speculative-dreamer.d.ts +8 -0
- package/dist/learning/dream/speculative-dreamer.js +8 -0
- package/dist/mcp/background-workers.d.ts +15 -0
- package/dist/mcp/background-workers.js +71 -0
- package/dist/mcp/bundle.js +881 -878
- package/dist/mcp/entry.js +4 -49
- package/dist/mcp/handlers/domain-handler-configs.d.ts +4 -0
- package/dist/mcp/handlers/domain-handler-configs.js +5 -1
- package/dist/mcp/protocol-server.js +2 -1
- package/dist/mcp/types.d.ts +6 -0
- package/dist/shared/security/index.d.ts +2 -2
- package/dist/shared/security/index.js +1 -1
- package/dist/shared/security/osv-client.d.ts +79 -132
- package/dist/shared/security/osv-client.js +344 -167
- package/dist/shared/security/osv-lookup.d.ts +124 -0
- package/dist/shared/security/osv-lookup.js +246 -0
- package/dist/shared/security/osv-types.d.ts +119 -0
- package/dist/shared/security/osv-types.js +6 -0
- package/dist/workers/daemon.d.ts +5 -0
- package/dist/workers/daemon.js +16 -2
- package/dist/workers/interfaces.d.ts +6 -1
- package/dist/workers/namespaced-keys.d.ts +16 -0
- package/dist/workers/namespaced-keys.js +24 -0
- package/dist/workers/quality-daemon/persistent-memory.d.ts +1 -1
- package/dist/workers/quality-daemon/persistent-memory.js +2 -2
- package/dist/workers/worker-env.d.ts +45 -0
- package/dist/workers/worker-env.js +76 -0
- package/dist/workers/worker-manager.js +5 -2
- package/dist/workers/workers/defect-predictor.d.ts +25 -8
- package/dist/workers/workers/defect-predictor.js +223 -216
- package/dist/workers/workers/learning-consolidation.d.ts +20 -0
- package/dist/workers/workers/learning-consolidation.js +53 -22
- package/dist/workers/workers/performance-baseline.d.ts +24 -9
- package/dist/workers/workers/performance-baseline.js +187 -230
- package/dist/workers/workers/quality-gate.d.ts +11 -9
- package/dist/workers/workers/quality-gate.js +125 -267
- package/dist/workers/workers/security-scan-records.d.ts +111 -0
- package/dist/workers/workers/security-scan-records.js +128 -0
- package/dist/workers/workers/security-scan.d.ts +25 -7
- package/dist/workers/workers/security-scan.js +187 -164
- package/package.json +2 -2
- package/dist/cli/chunks/adapter-PP3XIXDV.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-VDUQJKKY.js +0 -2
- package/dist/cli/chunks/base-QSYWWPCE.js +0 -2
- package/dist/cli/chunks/browser-workflow-WXXPBSCM.js +0 -2
- package/dist/cli/chunks/chunk-45MVRQG4.js +0 -2
- package/dist/cli/chunks/chunk-5VZVMO7B.js +0 -3
- package/dist/cli/chunks/chunk-EECF4CMA.js +0 -2
- package/dist/cli/chunks/client-6XKSQ4JT.js +0 -2
- package/dist/cli/chunks/core-handlers-OJYW4Y6M.js +0 -2
- package/dist/cli/chunks/cross-domain-router-QVUPQ2SC.js +0 -2
- package/dist/cli/chunks/daemon-QBYTCIMH.js +0 -10
- package/dist/cli/chunks/dream-3UABDRZJ.js +0 -2
- package/dist/cli/chunks/file-discovery-ZFGZTKZ4.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-MJ6MTPDF.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-FQWJCFVW.js +0 -2
- package/dist/cli/chunks/hnsw-index-NJYKJUHC.js +0 -2
- package/dist/cli/chunks/hybrid-backend-SL7RFID7.js +0 -2
- package/dist/cli/chunks/impact-analyzer-5ZJTXPVC.js +0 -2
- package/dist/cli/chunks/init-handler-PCLYQUSB.js +0 -88
- package/dist/cli/chunks/init-wizard-MQMDSIOF.js +0 -2
- package/dist/cli/chunks/kernel-MEJ5GMRH.js +0 -2
- package/dist/cli/chunks/knowledge-graph-XUBZSEZE.js +0 -2
- package/dist/cli/chunks/llm-router-service-QZAPAEPX.js +0 -2
- package/dist/cli/chunks/load-test-OVXIQ3AF.js +0 -2
- package/dist/cli/chunks/memory-backend-TRPOMPK4.js +0 -2
- package/dist/cli/chunks/pattern-null-store-JWYBRBZG.js +0 -2
- package/dist/cli/chunks/project-root-VVSTHIP4.js +0 -2
- package/dist/cli/chunks/protocol-executor-PXZCLZD3.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-42FRS5V3.js +0 -2
- package/dist/cli/chunks/queen-coordinator-UI3B7DI6.js +0 -2
- package/dist/cli/chunks/router-HYRPWLAY.js +0 -2
- package/dist/cli/chunks/routing-feedback-BPZ5R6F3.js +0 -2
- package/dist/cli/chunks/rvf-dual-writer-DEKDQ6KO.js +0 -2
- package/dist/cli/chunks/rvf-migration-adapter-L53VBS7I.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-I6RUGD2D.js +0 -2
- package/dist/cli/chunks/safe-db-KS65XDCP.js +0 -2
- package/dist/cli/chunks/schedule-KD2VN6GB.js +0 -2
- package/dist/cli/chunks/scheduler-ZH3RMUHY.js +0 -2
- package/dist/cli/chunks/security-PWQTGDRU.js +0 -13
- package/dist/cli/chunks/sqlite-persistence-6DTVME5D.js +0 -2
- package/dist/cli/chunks/unified-memory-FCX7NLFZ.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-VU5QJK37.js +0 -2
- package/dist/cli/chunks/unified-persistence-FM376LGE.js +0 -2
- package/dist/cli/chunks/visual-security-EU7Y3X46.js +0 -2
- package/dist/cli/chunks/witness-chain-CSEBT52D.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-ALNKOM3N.js +0 -2
|
@@ -2,13 +2,24 @@
|
|
|
2
2
|
* Agentic QE v3 - Defect Predictor Worker
|
|
3
3
|
* ADR-014: Background Workers for QE Monitoring
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* Surfaces the defect-intelligence domain's latest predictions:
|
|
6
|
+
* - High-risk files and their contributing factors
|
|
7
|
+
* - Targeted review / refactoring / coverage recommendations
|
|
8
|
+
*
|
|
9
|
+
* #1043: every prediction comes from a run of the defect-intelligence
|
|
10
|
+
* predictor (`defect-intelligence:predictor:prediction:<id>` in the
|
|
11
|
+
* `defect-intelligence` namespace, written by DefectPredictorService), and
|
|
12
|
+
* only files that exist in the project are kept. Code hotspots have no
|
|
13
|
+
* measured source and are reported unmeasured. Nothing predicted → nothing
|
|
14
|
+
* stored, an "unmeasured" info finding. A `defect:predictions` record without
|
|
15
|
+
* the measured stamp (the invented one written by <= 3.15.6) is ignored and
|
|
16
|
+
* replaced by the next measured run.
|
|
10
17
|
*/
|
|
18
|
+
import * as fs from 'fs';
|
|
19
|
+
import * as path from 'path';
|
|
20
|
+
import { bareSearchKey } from '../namespaced-keys.js';
|
|
11
21
|
import { BaseWorker } from '../base-worker.js';
|
|
22
|
+
import { findProjectRoot } from '../../kernel/project-root.js';
|
|
12
23
|
const CONFIG = {
|
|
13
24
|
id: 'defect-predictor',
|
|
14
25
|
name: 'Defect Predictor',
|
|
@@ -21,6 +32,82 @@ const CONFIG = {
|
|
|
21
32
|
retryCount: 2,
|
|
22
33
|
retryDelayMs: 15000,
|
|
23
34
|
};
|
|
35
|
+
const DEFECT_NAMESPACE = 'defect-intelligence';
|
|
36
|
+
const PREDICTION_KEY_PATTERN = 'defect-intelligence:predictor:prediction:*';
|
|
37
|
+
const PREDICTIONS_KEY = 'defect:predictions';
|
|
38
|
+
const SCHEMA_VERSION = 1;
|
|
39
|
+
/** The predictor keeps its records for 7 days; nothing older is current. */
|
|
40
|
+
const MAX_PREDICTION_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
41
|
+
const MAX_PREDICTION_RECORDS = 1000;
|
|
42
|
+
const RISK_LEVELS = ['critical', 'high', 'medium', 'low', 'info'];
|
|
43
|
+
/**
|
|
44
|
+
* Where a predicted path lies, resolved against the project root with
|
|
45
|
+
* symlinks followed: only a regular file whose real path is inside the
|
|
46
|
+
* project's real root is a project file (#1043 round 2b).
|
|
47
|
+
*/
|
|
48
|
+
function classifyPredictedFile(file, realRoot) {
|
|
49
|
+
let real;
|
|
50
|
+
try {
|
|
51
|
+
real = fs.realpathSync(path.resolve(realRoot, file));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Unresolvable: missing when it would lie inside the root, else outside.
|
|
55
|
+
const lexical = path.resolve(realRoot, file);
|
|
56
|
+
const rel = path.relative(realRoot, lexical);
|
|
57
|
+
return rel && !rel.startsWith('..') && !path.isAbsolute(rel) ? 'missing' : 'outside';
|
|
58
|
+
}
|
|
59
|
+
const rel = path.relative(realRoot, real);
|
|
60
|
+
if (rel === '' || rel.startsWith('..') || path.isAbsolute(rel))
|
|
61
|
+
return 'outside';
|
|
62
|
+
try {
|
|
63
|
+
return fs.statSync(real).isFile() ? 'inside' : 'missing';
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return 'missing';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function realProjectRoot() {
|
|
70
|
+
const root = findProjectRoot();
|
|
71
|
+
try {
|
|
72
|
+
return fs.realpathSync(root);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return path.resolve(root);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const isRecord = (v) => !!v && typeof v === 'object' && !Array.isArray(v);
|
|
79
|
+
function parseFilePrediction(raw) {
|
|
80
|
+
if (!isRecord(raw))
|
|
81
|
+
return null;
|
|
82
|
+
const { file, probability, riskLevel } = raw;
|
|
83
|
+
if (typeof file !== 'string' || file.length === 0)
|
|
84
|
+
return null;
|
|
85
|
+
if (typeof probability !== 'number' || !Number.isFinite(probability) || probability < 0 || probability > 1)
|
|
86
|
+
return null;
|
|
87
|
+
if (!RISK_LEVELS.includes(riskLevel))
|
|
88
|
+
return null;
|
|
89
|
+
const factors = Array.isArray(raw.factors)
|
|
90
|
+
? raw.factors.filter((f) => isRecord(f) && typeof f.name === 'string' && typeof f.contribution === 'number' && Number.isFinite(f.contribution))
|
|
91
|
+
: [];
|
|
92
|
+
const recommendations = Array.isArray(raw.recommendations)
|
|
93
|
+
? raw.recommendations.filter((r) => typeof r === 'string')
|
|
94
|
+
: [];
|
|
95
|
+
return { file, probability, riskLevel: riskLevel, factors, recommendations };
|
|
96
|
+
}
|
|
97
|
+
/** A recorded prediction run, or `null` when the record is not a usable one. */
|
|
98
|
+
function parsePredictionRecord(raw, now) {
|
|
99
|
+
if (!isRecord(raw) || typeof raw.id !== 'string' || typeof raw.timestamp !== 'string')
|
|
100
|
+
return null;
|
|
101
|
+
const t = Date.parse(raw.timestamp);
|
|
102
|
+
if (!Number.isFinite(t) || t > now + 60_000 || now - t > MAX_PREDICTION_AGE_MS)
|
|
103
|
+
return null;
|
|
104
|
+
if (!Array.isArray(raw.predictions) || raw.predictions.length === 0)
|
|
105
|
+
return null;
|
|
106
|
+
const predictions = raw.predictions.map(parseFilePrediction);
|
|
107
|
+
if (predictions.some((p) => p === null))
|
|
108
|
+
return null;
|
|
109
|
+
return { id: raw.id, timestamp: raw.timestamp, predictions: predictions };
|
|
110
|
+
}
|
|
24
111
|
export class DefectPredictorWorker extends BaseWorker {
|
|
25
112
|
constructor() {
|
|
26
113
|
super(CONFIG);
|
|
@@ -30,23 +117,46 @@ export class DefectPredictorWorker extends BaseWorker {
|
|
|
30
117
|
context.logger.info('Starting defect prediction analysis');
|
|
31
118
|
const findings = [];
|
|
32
119
|
const recommendations = [];
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
120
|
+
const { measured: latest, unusable } = await this.readLatestPrediction(context);
|
|
121
|
+
if (!latest) {
|
|
122
|
+
findings.push({
|
|
123
|
+
type: 'defect-prediction-unmeasured',
|
|
124
|
+
severity: 'info',
|
|
125
|
+
domain: 'defect-intelligence',
|
|
126
|
+
title: 'Defect Prediction Unmeasured',
|
|
127
|
+
description: (unusable
|
|
128
|
+
? `The latest defect prediction (${unusable.id}) names no file inside this project ` +
|
|
129
|
+
`(${unusable.outside} outside the project root, ${unusable.missing} missing), so no risk is reported. `
|
|
130
|
+
: 'No defect prediction for files in this project has been recorded in the last 7 days, so no risk is reported. ') +
|
|
131
|
+
'Run defect_predict on the files to assess.',
|
|
132
|
+
});
|
|
133
|
+
if (unusable)
|
|
134
|
+
await this.markPreviousStale(context, unusable.id);
|
|
135
|
+
context.logger.info('Defect prediction complete', { measured: false });
|
|
136
|
+
return this.createResult(Date.now() - startTime, {
|
|
137
|
+
itemsAnalyzed: 0,
|
|
138
|
+
issuesFound: 0,
|
|
139
|
+
healthScore: 100,
|
|
140
|
+
trend: 'stable',
|
|
141
|
+
domainMetrics: {
|
|
142
|
+
filesAnalyzed: 0,
|
|
143
|
+
highRiskFiles: 0,
|
|
144
|
+
hotspots: 'unmeasured',
|
|
145
|
+
avgDefectProbability: 'unmeasured',
|
|
146
|
+
},
|
|
147
|
+
}, findings, recommendations);
|
|
148
|
+
}
|
|
149
|
+
const { predictions } = latest;
|
|
38
150
|
this.analyzeHighRiskPredictions(predictions, findings, recommendations);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
await context.memory.set('defect:hotspots', hotspots);
|
|
44
|
-
await context.memory.set('defect:lastAnalysis', new Date().toISOString());
|
|
45
|
-
const healthScore = this.calculateHealthScore(predictions, hotspots);
|
|
151
|
+
await context.memory.set(PREDICTIONS_KEY, latest);
|
|
152
|
+
await context.memory.set('defect:lastAnalysis', latest.evaluatedAt);
|
|
153
|
+
const healthScore = this.calculateHealthScore(predictions);
|
|
154
|
+
const highRisk = predictions.filter(p => p.riskLevel === 'high' || p.riskLevel === 'critical').length;
|
|
46
155
|
context.logger.info('Defect prediction complete', {
|
|
156
|
+
measured: true,
|
|
47
157
|
healthScore,
|
|
158
|
+
predictionId: latest.predictionId,
|
|
48
159
|
predictionsCount: predictions.length,
|
|
49
|
-
hotspotsCount: hotspots.length,
|
|
50
160
|
});
|
|
51
161
|
return this.createResult(Date.now() - startTime, {
|
|
52
162
|
itemsAnalyzed: predictions.length,
|
|
@@ -55,237 +165,134 @@ export class DefectPredictorWorker extends BaseWorker {
|
|
|
55
165
|
trend: 'stable',
|
|
56
166
|
domainMetrics: {
|
|
57
167
|
filesAnalyzed: predictions.length,
|
|
58
|
-
highRiskFiles:
|
|
59
|
-
|
|
168
|
+
highRiskFiles: highRisk,
|
|
169
|
+
missingFilesSkipped: latest.missingFilesSkipped,
|
|
170
|
+
outsideProjectSkipped: latest.outsideProjectSkipped,
|
|
171
|
+
hotspots: 'unmeasured',
|
|
60
172
|
avgDefectProbability: (predictions.reduce((sum, p) => sum + p.probability, 0) / predictions.length).toFixed(2),
|
|
61
173
|
},
|
|
62
174
|
}, findings, recommendations);
|
|
63
175
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
{ name: 'size', weight: 0.2, description: 'Large file (1500+ lines)' },
|
|
79
|
-
{ name: 'coupling', weight: 0.15, description: 'High coupling with 8 other modules' },
|
|
80
|
-
],
|
|
81
|
-
recentChanges: 15,
|
|
82
|
-
historicalDefects: 3,
|
|
83
|
-
complexity: 28,
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
file: 'src/domains/security-compliance/services/security-scanner.ts',
|
|
87
|
-
probability: 0.65,
|
|
88
|
-
riskLevel: 'high',
|
|
89
|
-
factors: [
|
|
90
|
-
{ name: 'complexity', weight: 0.35, description: 'High cyclomatic complexity (32)' },
|
|
91
|
-
{ name: 'size', weight: 0.25, description: 'Very large file (1200+ lines)' },
|
|
92
|
-
{ name: 'test-coverage', weight: 0.2, description: 'Low test coverage (45%)' },
|
|
93
|
-
],
|
|
94
|
-
recentChanges: 8,
|
|
95
|
-
historicalDefects: 2,
|
|
96
|
-
complexity: 32,
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
file: 'src/kernel/memory-backend.ts',
|
|
100
|
-
probability: 0.45,
|
|
101
|
-
riskLevel: 'medium',
|
|
102
|
-
factors: [
|
|
103
|
-
{ name: 'change-frequency', weight: 0.4, description: 'Changed 10 times in last 30 days' },
|
|
104
|
-
{ name: 'authors', weight: 0.3, description: 'Multiple authors (4)' },
|
|
105
|
-
],
|
|
106
|
-
recentChanges: 10,
|
|
107
|
-
historicalDefects: 1,
|
|
108
|
-
complexity: 15,
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
file: 'src/shared/http/http-client.ts',
|
|
112
|
-
probability: 0.25,
|
|
113
|
-
riskLevel: 'low',
|
|
114
|
-
factors: [
|
|
115
|
-
{ name: 'stability', weight: 0.5, description: 'Stable code, few recent changes' },
|
|
116
|
-
],
|
|
117
|
-
recentChanges: 2,
|
|
118
|
-
historicalDefects: 0,
|
|
119
|
-
complexity: 8,
|
|
120
|
-
},
|
|
121
|
-
];
|
|
176
|
+
/**
|
|
177
|
+
* #1043 round 2b: the newest prediction names no usable file, so a stored
|
|
178
|
+
* measured record from an older prediction is no longer current — stamp it
|
|
179
|
+
* stale (once) instead of leaving it looking like the latest analysis.
|
|
180
|
+
*/
|
|
181
|
+
async markPreviousStale(context, supersededBy) {
|
|
182
|
+
const stored = await context.memory.get(PREDICTIONS_KEY);
|
|
183
|
+
if (!stored || typeof stored !== 'object' || stored.measured !== true || stored.schemaVersion !== SCHEMA_VERSION)
|
|
184
|
+
return;
|
|
185
|
+
if (stored.stale === true || stored.predictionId === supersededBy)
|
|
186
|
+
return;
|
|
187
|
+
await context.memory.set(PREDICTIONS_KEY, {
|
|
188
|
+
...stored, stale: true, staleSince: new Date().toISOString(), supersededBy,
|
|
189
|
+
});
|
|
122
190
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
191
|
+
/**
|
|
192
|
+
* #1043: the most recent prediction run the defect-intelligence predictor
|
|
193
|
+
* recorded, restricted to regular files whose real path is inside the
|
|
194
|
+
* project root. `measured` is `null` when there is no such prediction;
|
|
195
|
+
* `unusable` describes a newest prediction none of whose files qualify.
|
|
196
|
+
*/
|
|
197
|
+
async readLatestPrediction(context) {
|
|
198
|
+
const keys = await context.memory.search(PREDICTION_KEY_PATTERN, MAX_PREDICTION_RECORDS, { namespace: DEFECT_NAMESPACE });
|
|
199
|
+
const now = Date.now();
|
|
200
|
+
let latest = null;
|
|
201
|
+
for (const found of keys) {
|
|
202
|
+
// #1049: the in-memory backend returns `<namespace>:<key>` from a namespaced search.
|
|
203
|
+
const key = bareSearchKey(found, DEFECT_NAMESPACE, PREDICTION_KEY_PATTERN);
|
|
204
|
+
const parsed = parsePredictionRecord(await context.memory.get(key, { namespace: DEFECT_NAMESPACE }), now);
|
|
205
|
+
if (parsed && (!latest || Date.parse(parsed.timestamp) > Date.parse(latest.timestamp)))
|
|
206
|
+
latest = parsed;
|
|
207
|
+
}
|
|
208
|
+
if (!latest)
|
|
209
|
+
return { measured: null, unusable: null };
|
|
210
|
+
const realRoot = realProjectRoot();
|
|
211
|
+
const disposition = latest.predictions.map((p) => classifyPredictedFile(p.file, realRoot));
|
|
212
|
+
const existing = latest.predictions.filter((_, i) => disposition[i] === 'inside');
|
|
213
|
+
const outside = disposition.filter((d) => d === 'outside').length;
|
|
214
|
+
const missing = disposition.filter((d) => d === 'missing').length;
|
|
215
|
+
if (outside > 0) {
|
|
216
|
+
context.logger.warn('Ignoring defect predictions for paths outside the project root', { predictionId: latest.id, outside });
|
|
217
|
+
}
|
|
218
|
+
if (existing.length === 0) {
|
|
219
|
+
context.logger.info('Latest defect prediction names no file inside the project', { predictionId: latest.id });
|
|
220
|
+
return { measured: null, unusable: { id: latest.id, outside, missing } };
|
|
221
|
+
}
|
|
222
|
+
return { unusable: null, measured: {
|
|
223
|
+
measured: true,
|
|
224
|
+
schemaVersion: SCHEMA_VERSION,
|
|
225
|
+
source: 'defect-intelligence',
|
|
226
|
+
predictionId: latest.id,
|
|
227
|
+
predictedAt: latest.timestamp,
|
|
228
|
+
evaluatedAt: new Date().toISOString(),
|
|
229
|
+
predictions: existing,
|
|
230
|
+
missingFilesSkipped: missing,
|
|
231
|
+
outsideProjectSkipped: outside,
|
|
232
|
+
} };
|
|
151
233
|
}
|
|
152
234
|
analyzeHighRiskPredictions(predictions, findings, recommendations) {
|
|
153
235
|
const critical = predictions.filter(p => p.riskLevel === 'critical');
|
|
154
236
|
const high = predictions.filter(p => p.riskLevel === 'high');
|
|
155
|
-
for (const prediction of critical) {
|
|
237
|
+
for (const prediction of [...critical, ...high]) {
|
|
238
|
+
const name = prediction.file.split(/[\\/]/).pop();
|
|
156
239
|
findings.push({
|
|
157
|
-
type:
|
|
158
|
-
severity:
|
|
240
|
+
type: `${prediction.riskLevel}-defect-risk`,
|
|
241
|
+
severity: prediction.riskLevel,
|
|
159
242
|
domain: 'defect-intelligence',
|
|
160
|
-
title:
|
|
161
|
-
description: `${(prediction.probability * 100).toFixed(0)}%
|
|
243
|
+
title: `${prediction.riskLevel === 'critical' ? 'Critical' : 'High'} Defect Risk: ${name}`,
|
|
244
|
+
description: `${(prediction.probability * 100).toFixed(0)}% predicted defect probability (defect-intelligence predictor)`,
|
|
162
245
|
resource: prediction.file,
|
|
163
246
|
context: {
|
|
164
247
|
probability: prediction.probability,
|
|
165
248
|
factors: prediction.factors,
|
|
166
|
-
|
|
167
|
-
historicalDefects: prediction.historicalDefects,
|
|
249
|
+
recommendations: prediction.recommendations,
|
|
168
250
|
},
|
|
169
251
|
});
|
|
170
252
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
if (critical.length > 0 || high.length > 0) {
|
|
253
|
+
if (critical.length === 0 && high.length === 0)
|
|
254
|
+
return;
|
|
255
|
+
recommendations.push({
|
|
256
|
+
priority: 'p0',
|
|
257
|
+
domain: 'defect-intelligence',
|
|
258
|
+
action: 'Prioritize Code Review for High-Risk Files',
|
|
259
|
+
description: `${critical.length + high.length} files have elevated predicted defect risk. Schedule focused code reviews.`,
|
|
260
|
+
estimatedImpact: 'high',
|
|
261
|
+
effort: 'medium',
|
|
262
|
+
autoFixable: false,
|
|
263
|
+
});
|
|
264
|
+
const risky = [...critical, ...high];
|
|
265
|
+
const complexity = risky.filter(p => p.factors.some(f => f.name === 'codeComplexity' && f.contribution > 0.1));
|
|
266
|
+
if (complexity.length > 0) {
|
|
187
267
|
recommendations.push({
|
|
188
|
-
priority: '
|
|
268
|
+
priority: 'p1',
|
|
189
269
|
domain: 'defect-intelligence',
|
|
190
|
-
action: '
|
|
191
|
-
description: `${
|
|
270
|
+
action: 'Reduce Code Complexity',
|
|
271
|
+
description: `${complexity.length} high-risk files have code complexity as a major risk factor. Consider refactoring.`,
|
|
192
272
|
estimatedImpact: 'high',
|
|
193
|
-
effort: 'medium',
|
|
194
|
-
autoFixable: false,
|
|
195
|
-
});
|
|
196
|
-
// Specific recommendations based on factors
|
|
197
|
-
const complexityIssues = predictions.filter(p => p.factors.some(f => f.name === 'complexity' && f.weight > 0.25));
|
|
198
|
-
if (complexityIssues.length > 0) {
|
|
199
|
-
recommendations.push({
|
|
200
|
-
priority: 'p1',
|
|
201
|
-
domain: 'defect-intelligence',
|
|
202
|
-
action: 'Reduce Code Complexity',
|
|
203
|
-
description: `${complexityIssues.length} files have high complexity as a defect risk factor. Consider refactoring.`,
|
|
204
|
-
estimatedImpact: 'high',
|
|
205
|
-
effort: 'high',
|
|
206
|
-
autoFixable: false,
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
const coverageIssues = predictions.filter(p => p.factors.some(f => f.name === 'test-coverage'));
|
|
210
|
-
if (coverageIssues.length > 0) {
|
|
211
|
-
recommendations.push({
|
|
212
|
-
priority: 'p1',
|
|
213
|
-
domain: 'defect-intelligence',
|
|
214
|
-
action: 'Improve Test Coverage for Risky Files',
|
|
215
|
-
description: `${coverageIssues.length} high-risk files have low test coverage. Add targeted tests.`,
|
|
216
|
-
estimatedImpact: 'high',
|
|
217
|
-
effort: 'medium',
|
|
218
|
-
autoFixable: true,
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
analyzeHotspots(hotspots, findings, recommendations) {
|
|
224
|
-
const criticalHotspots = hotspots.filter(h => h.score > 0.7);
|
|
225
|
-
if (criticalHotspots.length > 0) {
|
|
226
|
-
findings.push({
|
|
227
|
-
type: 'code-hotspots',
|
|
228
|
-
severity: 'medium',
|
|
229
|
-
domain: 'defect-intelligence',
|
|
230
|
-
title: `${criticalHotspots.length} Code Hotspots Detected`,
|
|
231
|
-
description: 'Files with high change frequency and defect density identified',
|
|
232
|
-
context: {
|
|
233
|
-
hotspots: criticalHotspots.map(h => ({
|
|
234
|
-
file: h.file,
|
|
235
|
-
changeFrequency: h.changeFrequency,
|
|
236
|
-
score: h.score.toFixed(2),
|
|
237
|
-
})),
|
|
238
|
-
},
|
|
239
|
-
});
|
|
240
|
-
recommendations.push({
|
|
241
|
-
priority: 'p2',
|
|
242
|
-
domain: 'defect-intelligence',
|
|
243
|
-
action: 'Address Code Hotspots',
|
|
244
|
-
description: 'Consider refactoring frequently-changed, defect-prone files to improve stability.',
|
|
245
|
-
estimatedImpact: 'medium',
|
|
246
273
|
effort: 'high',
|
|
247
274
|
autoFixable: false,
|
|
248
275
|
});
|
|
249
276
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
if (silos.length > 0) {
|
|
253
|
-
findings.push({
|
|
254
|
-
type: 'knowledge-silo',
|
|
255
|
-
severity: 'medium',
|
|
256
|
-
domain: 'defect-intelligence',
|
|
257
|
-
title: 'Knowledge Silos Detected',
|
|
258
|
-
description: `${silos.length} frequently-changed files have only one author`,
|
|
259
|
-
context: {
|
|
260
|
-
files: silos.map(s => s.file),
|
|
261
|
-
},
|
|
262
|
-
});
|
|
277
|
+
const coverage = risky.filter(p => p.factors.some(f => f.name === 'testCoverage' && f.contribution > 0.1));
|
|
278
|
+
if (coverage.length > 0) {
|
|
263
279
|
recommendations.push({
|
|
264
|
-
priority: '
|
|
280
|
+
priority: 'p1',
|
|
265
281
|
domain: 'defect-intelligence',
|
|
266
|
-
action: '
|
|
267
|
-
description:
|
|
268
|
-
estimatedImpact: '
|
|
269
|
-
effort: '
|
|
270
|
-
autoFixable:
|
|
282
|
+
action: 'Improve Test Coverage for Risky Files',
|
|
283
|
+
description: `${coverage.length} high-risk files have low test coverage as a major risk factor. Add targeted tests.`,
|
|
284
|
+
estimatedImpact: 'high',
|
|
285
|
+
effort: 'medium',
|
|
286
|
+
autoFixable: true,
|
|
271
287
|
});
|
|
272
288
|
}
|
|
273
289
|
}
|
|
274
|
-
calculateHealthScore(predictions
|
|
290
|
+
calculateHealthScore(predictions) {
|
|
275
291
|
if (predictions.length === 0)
|
|
276
292
|
return 100;
|
|
277
|
-
// Base score from average defect probability (inverted)
|
|
278
293
|
const avgProbability = predictions.reduce((sum, p) => sum + p.probability, 0) / predictions.length;
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const highRiskCount = predictions.filter(p => p.riskLevel === 'critical' || p.riskLevel === 'high').length;
|
|
282
|
-
score -= (highRiskCount / predictions.length) * 20;
|
|
283
|
-
// Penalty for hotspots
|
|
284
|
-
const criticalHotspots = hotspots.filter(h => h.score > 0.7).length;
|
|
285
|
-
score -= criticalHotspots * 3;
|
|
286
|
-
// Bonus for stable codebase
|
|
287
|
-
const lowRiskRatio = predictions.filter(p => p.riskLevel === 'low').length / predictions.length;
|
|
288
|
-
score += lowRiskRatio * 20;
|
|
294
|
+
const highRisk = predictions.filter(p => p.riskLevel === 'critical' || p.riskLevel === 'high').length;
|
|
295
|
+
const score = (1 - avgProbability) * 80 - (highRisk / predictions.length) * 20 + 20;
|
|
289
296
|
return Math.max(0, Math.min(100, Math.round(score)));
|
|
290
297
|
}
|
|
291
298
|
}
|
|
@@ -14,15 +14,35 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { BaseWorker } from '../base-worker';
|
|
16
16
|
import { WorkerContext, WorkerResult } from '../interfaces';
|
|
17
|
+
/**
|
|
18
|
+
* #488 C.2: retention window for `applied = 0` dream insights comes from
|
|
19
|
+
* `AQE_DREAM_INSIGHTS_RETENTION_DAYS` (default 30, `0`/`off` disables the
|
|
20
|
+
* sweep). See `resolveDreamInsightsRetention` in `../worker-env.ts`.
|
|
21
|
+
*
|
|
22
|
+
* #1061: the sweep never runs on the first tick after the worker is created.
|
|
23
|
+
* The worker manager runs every worker immediately on startup, so without this
|
|
24
|
+
* guard every short MCP session deleted rows within seconds of starting.
|
|
25
|
+
* Retries of the first tick (30 s apart) fall inside the same window.
|
|
26
|
+
*/
|
|
17
27
|
export declare class LearningConsolidationWorker extends BaseWorker {
|
|
18
28
|
private lifecycleManager;
|
|
19
29
|
private lastRunTimestamp;
|
|
30
|
+
/** #1061: the dream_insights sweep waits one full interval after creation. */
|
|
31
|
+
private readonly dreamInsightsPruneNotBefore;
|
|
32
|
+
/** #1061: an invalid retention value is reported once per process. */
|
|
33
|
+
private retentionWarningLogged;
|
|
20
34
|
constructor();
|
|
21
35
|
/**
|
|
22
36
|
* Initialize or get the pattern lifecycle manager
|
|
23
37
|
*/
|
|
24
38
|
private getLifecycleManager;
|
|
25
39
|
protected doExecute(context: WorkerContext): Promise<WorkerResult>;
|
|
40
|
+
/**
|
|
41
|
+
* #488 C.2 / #1061: run the dream_insights retention sweep when it is
|
|
42
|
+
* enabled and the first tick after startup has passed. Returns the number
|
|
43
|
+
* of rows deleted.
|
|
44
|
+
*/
|
|
45
|
+
private pruneDreamInsights;
|
|
26
46
|
/**
|
|
27
47
|
* Phase 7: Run the continuous learning loop
|
|
28
48
|
*
|
|
@@ -22,6 +22,7 @@ import { toErrorMessage } from '../../shared/error-utils.js';
|
|
|
22
22
|
import { ExperienceConsolidator } from '../../learning/experience-consolidation.js';
|
|
23
23
|
import { recordLoopHealth } from '../../learning/loop-health.js';
|
|
24
24
|
import { pruneStaleDreamInsights } from '../../learning/dream/dream-insights-pruner.js';
|
|
25
|
+
import { resolveDreamInsightsRetention } from '../worker-env.js';
|
|
25
26
|
import { createLearningMetricsTracker } from '../../learning/metrics-tracker.js';
|
|
26
27
|
const CONFIG = {
|
|
27
28
|
id: 'learning-consolidation',
|
|
@@ -44,13 +45,22 @@ const CONFIG = {
|
|
|
44
45
|
const CONSOLIDATION_CURSOR_PREFIX = 'learning:consolidation-cursor:';
|
|
45
46
|
const DEFAULT_LOOKBACK_DAYS = 1;
|
|
46
47
|
/**
|
|
47
|
-
* #488 C.2: retention window for `applied = 0` dream insights
|
|
48
|
-
* `
|
|
48
|
+
* #488 C.2: retention window for `applied = 0` dream insights comes from
|
|
49
|
+
* `AQE_DREAM_INSIGHTS_RETENTION_DAYS` (default 30, `0`/`off` disables the
|
|
50
|
+
* sweep). See `resolveDreamInsightsRetention` in `../worker-env.ts`.
|
|
51
|
+
*
|
|
52
|
+
* #1061: the sweep never runs on the first tick after the worker is created.
|
|
53
|
+
* The worker manager runs every worker immediately on startup, so without this
|
|
54
|
+
* guard every short MCP session deleted rows within seconds of starting.
|
|
55
|
+
* Retries of the first tick (30 s apart) fall inside the same window.
|
|
49
56
|
*/
|
|
50
|
-
const DREAM_INSIGHTS_RETENTION_DAYS = 30;
|
|
51
57
|
export class LearningConsolidationWorker extends BaseWorker {
|
|
52
58
|
lifecycleManager = null;
|
|
53
59
|
lastRunTimestamp = 0;
|
|
60
|
+
/** #1061: the dream_insights sweep waits one full interval after creation. */
|
|
61
|
+
dreamInsightsPruneNotBefore = Date.now() + CONFIG.intervalMs;
|
|
62
|
+
/** #1061: an invalid retention value is reported once per process. */
|
|
63
|
+
retentionWarningLogged = false;
|
|
54
64
|
constructor() {
|
|
55
65
|
super(CONFIG);
|
|
56
66
|
}
|
|
@@ -224,6 +234,43 @@ export class LearningConsolidationWorker extends BaseWorker {
|
|
|
224
234
|
}
|
|
225
235
|
}
|
|
226
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* #488 C.2 / #1061: run the dream_insights retention sweep when it is
|
|
239
|
+
* enabled and the first tick after startup has passed. Returns the number
|
|
240
|
+
* of rows deleted.
|
|
241
|
+
*/
|
|
242
|
+
pruneDreamInsights(findings) {
|
|
243
|
+
const retention = resolveDreamInsightsRetention();
|
|
244
|
+
if (retention.warning && !this.retentionWarningLogged) {
|
|
245
|
+
this.retentionWarningLogged = true;
|
|
246
|
+
process.stderr.write(`[AQE] WARN ${retention.warning}\n`);
|
|
247
|
+
}
|
|
248
|
+
const retentionDays = retention.retentionDays;
|
|
249
|
+
if (retentionDays === null)
|
|
250
|
+
return 0;
|
|
251
|
+
if (Date.now() < this.dreamInsightsPruneNotBefore)
|
|
252
|
+
return 0;
|
|
253
|
+
const db = getUnifiedMemory().getDatabase();
|
|
254
|
+
const { pruned } = pruneStaleDreamInsights(db, { retentionDays });
|
|
255
|
+
if (pruned > 0) {
|
|
256
|
+
// Default log level, stderr only: MCP stdout carries JSON-RPC.
|
|
257
|
+
process.stderr.write(`[AQE] dream_insights retention: deleted ${pruned} unapplied insight(s) ` +
|
|
258
|
+
`older than ${retentionDays} days ` +
|
|
259
|
+
`(set AQE_DREAM_INSIGHTS_RETENTION_DAYS=off to keep them)\n`);
|
|
260
|
+
findings.push({
|
|
261
|
+
type: 'dream-insights-pruned',
|
|
262
|
+
severity: 'info',
|
|
263
|
+
domain: 'learning-optimization',
|
|
264
|
+
title: 'Stale Dream Insights Pruned',
|
|
265
|
+
description: `${pruned} unapplied dream insights older than ${retentionDays} days deleted`,
|
|
266
|
+
context: {
|
|
267
|
+
pruned,
|
|
268
|
+
retentionDays,
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
return pruned;
|
|
273
|
+
}
|
|
227
274
|
/**
|
|
228
275
|
* Phase 7: Run the continuous learning loop
|
|
229
276
|
*
|
|
@@ -367,26 +414,10 @@ export class LearningConsolidationWorker extends BaseWorker {
|
|
|
367
414
|
// Step 8 (#488 C.2): prune stale unapplied dream_insights so the
|
|
368
415
|
// table doesn't grow unbounded. Applied insights are part of the
|
|
369
416
|
// pattern-change audit trail and stay forever.
|
|
417
|
+
// #1061: configurable, skipped on the first tick, logged to stderr.
|
|
418
|
+
// Follow-up: archive rows instead of hard-deleting them.
|
|
370
419
|
try {
|
|
371
|
-
|
|
372
|
-
const db = unifiedMemory.getDatabase();
|
|
373
|
-
const pruneResult = pruneStaleDreamInsights(db, {
|
|
374
|
-
retentionDays: DREAM_INSIGHTS_RETENTION_DAYS,
|
|
375
|
-
});
|
|
376
|
-
dreamInsightsPruned = pruneResult.pruned;
|
|
377
|
-
if (dreamInsightsPruned > 0) {
|
|
378
|
-
findings.push({
|
|
379
|
-
type: 'dream-insights-pruned',
|
|
380
|
-
severity: 'info',
|
|
381
|
-
domain: 'learning-optimization',
|
|
382
|
-
title: 'Stale Dream Insights Pruned',
|
|
383
|
-
description: `${dreamInsightsPruned} unapplied dream insights older than ${DREAM_INSIGHTS_RETENTION_DAYS} days deleted`,
|
|
384
|
-
context: {
|
|
385
|
-
pruned: dreamInsightsPruned,
|
|
386
|
-
retentionDays: DREAM_INSIGHTS_RETENTION_DAYS,
|
|
387
|
-
},
|
|
388
|
-
});
|
|
389
|
-
}
|
|
420
|
+
dreamInsightsPruned = this.pruneDreamInsights(findings);
|
|
390
421
|
}
|
|
391
422
|
catch (pruneError) {
|
|
392
423
|
context.logger.warn('Dream insights pruning failed', {
|